text_editor 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/.text_editor.rb +81 -2
  4. data/Gemfile.lock +1 -0
  5. data/README.org +103 -0
  6. data/bin/console +1 -1
  7. data/lib/core_ext/hash.rb +2 -0
  8. data/lib/core_ext/pathname.rb +2 -0
  9. data/lib/text_editor.rb +43 -13
  10. data/lib/text_editor/buffer.rb +3 -0
  11. data/lib/text_editor/clipboard.rb +1 -1
  12. data/lib/text_editor/clipboard/cygwin.rb +0 -4
  13. data/lib/text_editor/clipboard/linux.rb +0 -4
  14. data/lib/text_editor/clipboard/mac.rb +0 -4
  15. data/lib/text_editor/clipboard/unknown.rb +0 -4
  16. data/lib/text_editor/clipboard/windows.rb +0 -4
  17. data/lib/text_editor/command.rb +4 -4
  18. data/lib/text_editor/command/append_line_and_insert.rb +11 -0
  19. data/lib/text_editor/command/change_mode.rb +9 -0
  20. data/lib/text_editor/command/cursor_end_and_insert.rb +9 -0
  21. data/lib/text_editor/command/cursor_left.rb +1 -8
  22. data/lib/text_editor/command/cursor_left_with_wrap.rb +16 -0
  23. data/lib/text_editor/command/cursor_right.rb +2 -9
  24. data/lib/text_editor/command/cursor_right_and_insert.rb +9 -0
  25. data/lib/text_editor/command/cursor_right_with_wrap.rb +19 -0
  26. data/lib/text_editor/command/cursor_start_without_whitespace.rb +11 -0
  27. data/lib/text_editor/command/cursor_up.rb +1 -1
  28. data/lib/text_editor/command/forward_word.rb +16 -0
  29. data/lib/text_editor/command/insert_tab.rb +1 -1
  30. data/lib/text_editor/command/prepend_line_and_insert.rb +11 -0
  31. data/lib/text_editor/command/replace_line.rb +13 -0
  32. data/lib/text_editor/command/resolver.rb +3 -2
  33. data/lib/text_editor/component.rb +1 -1
  34. data/lib/text_editor/configuration.rb +11 -3
  35. data/lib/text_editor/configuration/bootstrap.rb +9 -3
  36. data/lib/text_editor/configuration/flavor.rb +20 -0
  37. data/lib/text_editor/configuration/log.rb +7 -0
  38. data/lib/text_editor/configuration/mode.rb +28 -0
  39. data/lib/text_editor/configuration/operating_system.rb +21 -0
  40. data/lib/text_editor/configuration/resolver.rb +1 -1
  41. data/lib/text_editor/configuration/tab.rb +11 -0
  42. data/lib/text_editor/cursor.rb +2 -0
  43. data/lib/text_editor/keyboard.rb +1 -1
  44. data/lib/text_editor/logger.rb +11 -0
  45. data/lib/text_editor/reactor.rb +5 -3
  46. data/lib/text_editor/terminal.rb +2 -19
  47. data/lib/text_editor/window.rb +34 -5
  48. data/spec/spec_helper.rb +3 -0
  49. data/spec/support/command_helper.rb +43 -0
  50. data/spec/text_editor/clipboard_spec.rb +0 -7
  51. data/spec/text_editor/command/append_line_and_insert_spec.rb +38 -0
  52. data/spec/text_editor/command/backspace_spec.rb +54 -0
  53. data/spec/text_editor/command/change_mode_spec.rb +17 -0
  54. data/spec/text_editor/command/cursor_down_spec.rb +57 -0
  55. data/spec/text_editor/command/cursor_end_and_insert_spec.rb +35 -0
  56. data/spec/text_editor/command/cursor_end_spec.rb +30 -0
  57. data/spec/text_editor/command/cursor_left_spec.rb +46 -0
  58. data/spec/text_editor/command/cursor_left_with_wrap_spec.rb +46 -0
  59. data/spec/text_editor/command/cursor_right_and_insert_spec.rb +58 -0
  60. data/spec/text_editor/command/cursor_right_spec.rb +53 -0
  61. data/spec/text_editor/command/cursor_right_with_wrap_spec.rb +54 -0
  62. data/spec/text_editor/command/cursor_start_spec.rb +33 -0
  63. data/spec/text_editor/command/cursor_start_without_whitespace_spec.rb +46 -0
  64. data/spec/text_editor/command/cursor_up_spec.rb +56 -0
  65. data/spec/text_editor/command/forward_word_spec.rb +8 -0
  66. data/spec/text_editor/command/insert_char_spec.rb +24 -0
  67. data/spec/text_editor/command/insert_line_spec.rb +26 -0
  68. data/spec/text_editor/command/insert_tab_spec.rb +27 -0
  69. data/spec/text_editor/command/prepend_line_and_insert_spec.rb +38 -0
  70. data/spec/text_editor/command/replace_line_spec.rb +34 -0
  71. data/spec/text_editor/command/resolver_spec.rb +2 -2
  72. data/spec/text_editor/command/write_file_spec.rb +25 -0
  73. data/spec/text_editor/command_spec.rb +8 -8
  74. data/spec/text_editor/component_spec.rb +7 -0
  75. data/spec/text_editor/configuration/log_spec.rb +26 -0
  76. data/spec/text_editor/{operating_system_spec.rb → configuration/operating_system_spec.rb} +1 -1
  77. data/spec/text_editor/configuration/tab_spec.rb +41 -0
  78. data/spec/text_editor/configuration_spec.rb +11 -4
  79. data/spec/text_editor/logger_spec.rb +17 -0
  80. data/text_editor.gemspec +2 -1
  81. metadata +84 -7
  82. data/lib/text_editor/mode.rb +0 -23
  83. data/lib/text_editor/mode/nano.rb +0 -30
  84. data/lib/text_editor/operating_system.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b869a9294584c550357a869d6d61efbda2d7e9a
4
- data.tar.gz: 1eafb0f6ffa81a53b43f5b74759e0e5354ba688e
3
+ metadata.gz: ea27f5f0446c3f7dde33eedab3d63b9638249ad1
4
+ data.tar.gz: 1c0ff7ad29a6032a1fe7e15a7fd1956acab74c39
5
5
  SHA512:
6
- metadata.gz: 9c10910e79d481967bde183696d1dfe89a973b8a244d3ee36a38b46abb7769147aad71c84b56ee7153d27288d112eb271bec745c09f24dd5b71dfd2f184ffd7d
7
- data.tar.gz: e3f686ec346c8e65c27a51d402bfef9164f7926e6396c30ce129149d8b332969afb0d6c20ccd17dca7e3b8883930e7b05c0b0a2f4cb4e470affb633a77424687
6
+ metadata.gz: 44feaf376fdda1b09467ff24f48c30b0938d78bcce1c920bd93df0fd79e648c862b03f6d0179d9c46669f3f55403821f88cb0d325bd6f61e0e6f8838bfa2ca92
7
+ data.tar.gz: 6d5a26618593ad00779f110bbe891cb8dba0bbb5d921f3765a32ddf314dfb2753be91856c1021aa2076eefbaf7395f1b63c6ef9fdd54d8af1e0c8e3b4299c509
@@ -11,6 +11,9 @@ Style/CaseEquality:
11
11
  Metrics/CyclomaticComplexity:
12
12
  Enabled: false
13
13
 
14
+ Metrics/LineLength:
15
+ Enabled: false
16
+
14
17
  Metrics/MethodLength:
15
18
  Enabled: false
16
19
 
@@ -1,9 +1,88 @@
1
1
  TextEditor.configure do
2
- log.file = nil
2
+ config.default_flavor ||= :nano
3
+
4
+ log.file ||= nil
3
5
  log.level = Logger::INFO
4
6
  log.options = []
5
7
 
6
- tab.expand = true
7
8
  tab.soft = true
8
9
  tab.width = 2
10
+
11
+ flavor :nano do
12
+ mode :insert do
13
+ bind :ctrl_c, :quit
14
+
15
+ bind :up, :cursor_up
16
+ bind :down, :cursor_down
17
+ bind :left, :cursor_left_with_wrap
18
+ bind :right, :cursor_right_with_wrap
19
+
20
+ bind :ctrl_p, :cursor_up
21
+ bind :ctrl_n, :cursor_down
22
+ bind :ctrl_b, :cursor_left_with_wrap
23
+ bind :ctrl_f, :cursor_right_with_wrap
24
+
25
+ bind :ctrl_a, :cursor_start
26
+ bind :ctrl_e, :cursor_end
27
+
28
+ bind :ctrl_space, :forward_word
29
+
30
+ bind :backspace, :backspace
31
+ bind :ctrl_h, :backspace
32
+
33
+ bind :ctrl_o, :write_file
34
+
35
+ bind :enter, :insert_line
36
+ bind :tab, :insert_tab
37
+
38
+ bind(/^[[:print:]]$/, :insert_char)
39
+ end
40
+ end
41
+
42
+ flavor :vim do
43
+ mode :normal do
44
+ bind :ctrl_c, :quit
45
+
46
+ bind :k, :cursor_up
47
+ bind :j, :cursor_down
48
+ bind :h, :cursor_left
49
+ bind :l, :cursor_right
50
+
51
+ bind :^, :cursor_start_without_whitespace
52
+ bind :"0", :cursor_start
53
+ bind :"$", :cursor_end
54
+
55
+ bind :w, :forward_word
56
+
57
+ bind :S, :replace_line
58
+
59
+ bind :a, :cursor_right_and_insert
60
+ bind :A, :cursor_end_and_insert
61
+
62
+ bind :o, :append_line_and_insert
63
+ bind :O, :prepend_line_and_insert
64
+
65
+ bind :i, :change_mode, :insert
66
+ end
67
+
68
+ mode :insert do
69
+ bind :ctrl_c, :change_mode, :normal
70
+ bind :escape, :change_mode, :normal
71
+
72
+ bind :up, :cursor_up
73
+ bind :down, :cursor_down
74
+ bind :left, :cursor_left
75
+ bind :right, :cursor_right
76
+
77
+ bind :backspace, :backspace
78
+ bind :ctrl_h, :backspace
79
+
80
+ bind :ctrl_j, :insert_line
81
+ bind :enter, :insert_line
82
+
83
+ bind :tab, :insert_tab
84
+
85
+ bind(/^[[:print:]]$/, :insert_char)
86
+ end
87
+ end
9
88
  end
@@ -2,6 +2,7 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  text_editor (0.0.0)
5
+ bundler
5
6
  curses (= 1.0.2)
6
7
 
7
8
  GEM
data/README.org CHANGED
@@ -1,5 +1,108 @@
1
1
  * Text Editor
2
2
  Text editor written in [[https://www.ruby-lang.org/en/][Ruby]] and heavily inspired by [[http://www.vim.org/][vim]], [[https://www.gnu.org/software/emacs/][emacs]], [[https://www.nano-editor.org/][nano]], and [[https://github.com/grosser/ruco][ruco]].
3
+ ** Commands
4
+ All editor commands inherit the =TextEditor::Command= class. This class provides some convenience methods for referencing various text editor related components.
5
+ #+BEGIN_SRC ruby
6
+ class MoveCursorRight < TextEditor::Command
7
+ def run(*)
8
+ window.update(cursor: cursor.move_right)
9
+ end
10
+ end
11
+ #+END_SRC
12
+ ** Configuration
13
+ The =te= executable accepts a couple command line arguments:
14
+ #+BEGIN_SRC text
15
+ Usage: te [options]
16
+ -l, --log FILE
17
+ -f, --flavor FLAVOR
18
+ -v, --version
19
+ #+END_SRC
20
+
21
+ All other configuration is managed thru =.text_editor.rb= files. These files are searched and loaded in the following order:
22
+ - The root of this gem's directory
23
+ - The =/etc= directory
24
+ - The =$HOME= directory
25
+ - Any directory while traversing the tree down to the current working directory
26
+
27
+ Here's an example of the configuration file from the root of this gem:
28
+ #+BEGIN_SRC ruby
29
+ TextEditor.configure do
30
+ config.default_flavor ||= :nano
31
+
32
+ log.file ||= nil
33
+ log.level = Logger::INFO
34
+ log.options = []
35
+
36
+ tab.soft = true
37
+ tab.width = 2
38
+
39
+ flavor :nano do
40
+ mode :insert do
41
+ bind :ctrl_c, :quit
42
+
43
+ bind :up, :cursor_up
44
+ bind :down, :cursor_down
45
+ bind :left, :cursor_left_with_wrap
46
+ bind :right, :cursor_right_with_wrap
47
+
48
+ bind :ctrl_p, :cursor_up
49
+ bind :ctrl_n, :cursor_down
50
+ bind :ctrl_b, :cursor_left_with_wrap
51
+ bind :ctrl_f, :cursor_right_with_wrap
52
+
53
+ bind :ctrl_a, :cursor_start
54
+ bind :ctrl_e, :cursor_end
55
+
56
+ bind :ctrl_space, :forward_word
57
+
58
+ bind :backspace, :backspace
59
+ bind :ctrl_h, :backspace
60
+
61
+ bind :ctrl_o, :write_file
62
+
63
+ bind :enter, :insert_line
64
+ bind :tab, :insert_tab
65
+
66
+ bind(/^[[:print:]]$/, :insert_char)
67
+ end
68
+ end
69
+
70
+ flavor :vim do
71
+ mode :normal do
72
+ bind :ctrl_c, :quit
73
+
74
+ bind :k, :cursor_up
75
+ bind :j, :cursor_down
76
+ bind :h, :cursor_left
77
+ bind :l, :cursor_right
78
+
79
+ bind :^, :cursor_start
80
+ bind :"$", :cursor_end
81
+
82
+ bind :w, :forward_word
83
+
84
+ bind :S, :replace_line
85
+
86
+ bind :i, :change_mode, :insert
87
+ end
88
+
89
+ mode :insert do
90
+ bind :ctrl_c, :change_mode, :normal
91
+ bind :escape, :change_mode, :normal
92
+
93
+ bind :backspace, :backspace
94
+ bind :ctrl_h, :backspace
95
+
96
+ bind :ctrl_j, :insert_line
97
+ bind :enter, :insert_line
98
+
99
+ bind :tab, :insert_tab
100
+
101
+ bind(/^[[:print:]]$/, :insert_char)
102
+ end
103
+ end
104
+ end
105
+ #+END_SRC
3
106
  ** API
4
107
  *** Buffer
5
108
  - An in-memory text representation of a file
@@ -2,7 +2,7 @@
2
2
  require_relative "../lib/text_editor"
3
3
 
4
4
  def editor
5
- @editor ||= TextEditor.new(ARGV)
5
+ @editor ||= TextEditor.new(ARGV).tap(&:bootstrap)
6
6
  end
7
7
 
8
8
  require "irb"
@@ -1,6 +1,8 @@
1
1
  module CoreExt
2
2
  module Hash
3
3
  refine ::Hash do
4
+ # Returns a new hash with each key replaced
5
+ # with the return value of the specified block.
4
6
  def transform_keys
5
7
  reduce({}) do |hash, (key, value)|
6
8
  key = yield(key)
@@ -1,6 +1,8 @@
1
1
  module CoreExt
2
2
  module Pathname
3
3
  refine ::Pathname do
4
+ # Returns the file contents if it exists.
5
+ # Returns nil otherwise.
4
6
  def safe_read
5
7
  read if exist?
6
8
  end
@@ -15,7 +15,7 @@ require_relative "text_editor/component"
15
15
  require_relative "text_editor/buffer"
16
16
  require_relative "text_editor/cursor"
17
17
  require_relative "text_editor/keyboard"
18
- require_relative "text_editor/operating_system"
18
+ require_relative "text_editor/logger"
19
19
  require_relative "text_editor/reactor"
20
20
  require_relative "text_editor/state"
21
21
  require_relative "text_editor/terminal"
@@ -29,49 +29,77 @@ require_relative "text_editor/clipboard/unknown"
29
29
  require_relative "text_editor/clipboard/windows"
30
30
 
31
31
  require_relative "text_editor/command"
32
+ require_relative "text_editor/command/append_line_and_insert"
32
33
  require_relative "text_editor/command/backspace"
33
- require_relative "text_editor/command/quit"
34
+ require_relative "text_editor/command/change_mode"
34
35
  require_relative "text_editor/command/cursor_down"
35
36
  require_relative "text_editor/command/cursor_end"
37
+ require_relative "text_editor/command/cursor_end_and_insert"
36
38
  require_relative "text_editor/command/cursor_left"
39
+ require_relative "text_editor/command/cursor_left_with_wrap"
37
40
  require_relative "text_editor/command/cursor_right"
41
+ require_relative "text_editor/command/cursor_right_and_insert"
42
+ require_relative "text_editor/command/cursor_right_with_wrap"
38
43
  require_relative "text_editor/command/cursor_start"
44
+ require_relative "text_editor/command/cursor_start_without_whitespace"
39
45
  require_relative "text_editor/command/cursor_up"
46
+ require_relative "text_editor/command/forward_word"
40
47
  require_relative "text_editor/command/insert_char"
41
48
  require_relative "text_editor/command/insert_line"
42
49
  require_relative "text_editor/command/insert_tab"
50
+ require_relative "text_editor/command/prepend_line_and_insert"
51
+ require_relative "text_editor/command/quit"
52
+ require_relative "text_editor/command/replace_line"
43
53
  require_relative "text_editor/command/resolver"
44
54
  require_relative "text_editor/command/write_file"
45
55
 
46
56
  require_relative "text_editor/configuration"
47
57
  require_relative "text_editor/configuration/bootstrap"
48
58
  require_relative "text_editor/configuration/dsl"
59
+ require_relative "text_editor/configuration/flavor"
60
+ require_relative "text_editor/configuration/log"
61
+ require_relative "text_editor/configuration/mode"
62
+ require_relative "text_editor/configuration/operating_system"
49
63
  require_relative "text_editor/configuration/resolver"
64
+ require_relative "text_editor/configuration/tab"
50
65
 
51
- require_relative "text_editor/mode"
52
- require_relative "text_editor/mode/nano"
53
-
66
+ # Dependency injection container for the misc
67
+ # components required to run the text editor.
54
68
  class TextEditor
55
69
  extend Configuration::DSL
56
70
 
57
71
  GEMSPEC = File.expand_path("../../text_editor.gemspec", __FILE__)
58
72
 
59
- def initialize(args)
73
+ attr_writer :mode
74
+
75
+ def initialize(args = [])
60
76
  @args = args
61
77
  end
62
78
 
63
79
  def bootstrap
64
- @bootstrap ||= Configuration::Bootstrap.new(self)
80
+ Configuration::Bootstrap.new(self).configure(@args)
65
81
  end
66
82
 
67
83
  def clipboard
68
84
  @clipboard ||= Clipboard.new(self)
69
85
  end
70
86
 
87
+ def command
88
+ @command ||= Command::Resolver.new(self)
89
+ end
90
+
71
91
  def config
72
92
  @config ||= Configuration.new(self)
73
93
  end
74
94
 
95
+ def flavor
96
+ @flavor ||= flavors[config.default_flavor]
97
+ end
98
+
99
+ def flavors
100
+ @flavors ||= {}
101
+ end
102
+
75
103
  def gemspec
76
104
  @gemspec ||= Gem::Specification.load(GEMSPEC)
77
105
  end
@@ -81,17 +109,15 @@ class TextEditor
81
109
  end
82
110
 
83
111
  def logger
84
- @logger ||= Logger.new(config.log.file, *config.log.options).tap do |log|
85
- log.level = config.log.level
86
- end
112
+ @logger ||= Logger.new(self)
87
113
  end
88
114
 
89
115
  def mode
90
- @mode ||= Mode::Nano.new
116
+ @mode ||= flavor.modes.values.first # FIXME
91
117
  end
92
118
 
93
119
  def os
94
- @os ||= OperatingSystem.new(RbConfig::CONFIG["host_os"])
120
+ @os ||= Configuration::OperatingSystem.new(ruby.host_os)
95
121
  end
96
122
 
97
123
  def reactor
@@ -102,8 +128,12 @@ class TextEditor
102
128
  @root ||= Pathname.new(__FILE__).dirname.dirname
103
129
  end
104
130
 
131
+ def ruby
132
+ @ruby ||= OpenStruct.new(RbConfig::CONFIG)
133
+ end
134
+
105
135
  def start
106
- bootstrap.configure(@args)
136
+ bootstrap
107
137
  terminal.render { reactor.start }
108
138
  end
109
139
 
@@ -1,4 +1,7 @@
1
1
  class TextEditor
2
+ # An internal representation of a buffer.
3
+ # These buffers are rendered out to the
4
+ # terminal by {Window} instances.
2
5
  class Buffer
3
6
  using CoreExt::Pathname
4
7
 
@@ -3,7 +3,7 @@ class TextEditor
3
3
  extend Forwardable
4
4
  include Component
5
5
 
6
- def_delegators :adapter, :clear, :copy, :paste
6
+ def_delegators :adapter, :copy, :paste
7
7
 
8
8
  private
9
9
 
@@ -3,10 +3,6 @@ class TextEditor
3
3
  class Cygwin
4
4
  CLIPBOARD = "/dev/clipboard".freeze
5
5
 
6
- def clear
7
- copy("")
8
- end
9
-
10
6
  def copy(content)
11
7
  File.write(CLIPBOARD, content)
12
8
  content
@@ -1,10 +1,6 @@
1
1
  class TextEditor
2
2
  class Clipboard
3
3
  class Linux
4
- def clear
5
- raise NotImplementedError
6
- end
7
-
8
4
  def copy(_content)
9
5
  raise NotImplementedError
10
6
  end
@@ -1,10 +1,6 @@
1
1
  class TextEditor
2
2
  class Clipboard
3
3
  class Mac
4
- def clear
5
- copy("")
6
- end
7
-
8
4
  def copy(content)
9
5
  system("printf #{content.inspect} | pbcopy")
10
6
  content
@@ -1,10 +1,6 @@
1
1
  class TextEditor
2
2
  class Clipboard
3
3
  class Unknown
4
- def clear
5
- copy("")
6
- end
7
-
8
4
  def copy(content)
9
5
  @clipboard = content
10
6
  end