text_editor 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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