textbringer 0.3.2 → 1.0.4

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/macos.yml +15 -0
  4. data/.github/workflows/ubuntu.yml +25 -0
  5. data/.github/workflows/windows.yml +19 -0
  6. data/CHANGES.md +29 -0
  7. data/README.md +4 -11
  8. data/exe/textbringer +5 -0
  9. data/lib/textbringer.rb +0 -2
  10. data/lib/textbringer/buffer.rb +43 -42
  11. data/lib/textbringer/color.rb +0 -2
  12. data/lib/textbringer/commands.rb +0 -2
  13. data/lib/textbringer/commands/buffers.rb +22 -2
  14. data/lib/textbringer/commands/clipboard.rb +3 -5
  15. data/lib/textbringer/commands/ctags.rb +3 -5
  16. data/lib/textbringer/commands/dabbrev.rb +1 -3
  17. data/lib/textbringer/commands/files.rb +10 -5
  18. data/lib/textbringer/commands/fill.rb +2 -2
  19. data/lib/textbringer/commands/help.rb +25 -18
  20. data/lib/textbringer/commands/isearch.rb +11 -4
  21. data/lib/textbringer/commands/keyboard_macro.rb +0 -2
  22. data/lib/textbringer/commands/misc.rb +29 -27
  23. data/lib/textbringer/commands/register.rb +0 -2
  24. data/lib/textbringer/commands/replace.rb +0 -2
  25. data/lib/textbringer/commands/server.rb +0 -2
  26. data/lib/textbringer/commands/windows.rb +0 -2
  27. data/lib/textbringer/config.rb +0 -2
  28. data/lib/textbringer/controller.rb +2 -4
  29. data/lib/textbringer/errors.rb +0 -2
  30. data/lib/textbringer/face.rb +0 -2
  31. data/lib/textbringer/faces/basic.rb +0 -2
  32. data/lib/textbringer/faces/programming.rb +0 -2
  33. data/lib/textbringer/keymap.rb +44 -26
  34. data/lib/textbringer/mode.rb +0 -2
  35. data/lib/textbringer/modes/backtrace_mode.rb +1 -3
  36. data/lib/textbringer/modes/buffer_list_mode.rb +1 -3
  37. data/lib/textbringer/modes/c_mode.rb +4 -2
  38. data/lib/textbringer/modes/completion_list_mode.rb +1 -3
  39. data/lib/textbringer/modes/fundamental_mode.rb +0 -2
  40. data/lib/textbringer/modes/help_mode.rb +1 -3
  41. data/lib/textbringer/modes/programming_mode.rb +25 -5
  42. data/lib/textbringer/modes/ruby_mode.rb +33 -10
  43. data/lib/textbringer/plugin.rb +0 -2
  44. data/lib/textbringer/ring.rb +0 -2
  45. data/lib/textbringer/utils.rb +8 -7
  46. data/lib/textbringer/version.rb +1 -3
  47. data/lib/textbringer/window.rb +5 -3
  48. data/logo/logo.jpg +0 -0
  49. data/logo/logo.png +0 -0
  50. metadata +12 -9
  51. data/.travis.yml +0 -56
  52. data/appveyor.yml +0 -19
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: true
1
+ require "stringio"
2
2
 
3
3
  module Textbringer
4
4
  module FillExtension
@@ -38,7 +38,7 @@ def fill_paragraph
38
38
 
39
39
  def fill_string(str, column)
40
40
  input = StringIO.new(str)
41
- output = String.new
41
+ output = +""
42
42
  fill_column = CONFIG[:fill_column]
43
43
  prev_c = nil
44
44
  while c = input.getc
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  module Commands
5
3
  HELP_RING = Ring.new
@@ -23,27 +21,36 @@ def show_help
23
21
  end
24
22
  private :show_help
25
23
 
24
+ def keymap_bindings(keymap)
25
+ s = format("%-16s %s\n", "Key", "Binding")
26
+ s << format("%-16s %s\n", "---", "-------")
27
+ s << "\n"
28
+ keymap.each do |key_sequence, command|
29
+ if command != :self_insert
30
+ s << format("%-16s [%s]\n",
31
+ Keymap.key_sequence_string(key_sequence),
32
+ command)
33
+ end
34
+ end
35
+ s
36
+ end
37
+
26
38
  define_command(:describe_bindings,
27
39
  doc: "Display the key bindings.") do
28
40
  show_help do |help|
29
- s = format("%-16s %s\n", "Key", "Binding")
30
- s << format("%-16s %s\n", "---", "-------")
31
- s << "\n"
32
- bindings = {}
33
- [
34
- GLOBAL_MAP,
35
- Buffer.current.keymap,
36
- Controller.current.overriding_map
37
- ].each do |map|
38
- map&.each do |key_sequence, command|
39
- bindings[key_sequence] = command
40
- end
41
+ s = ""
42
+ if Controller.current.overriding_map
43
+ s << "Overriding Bindings:\n"
44
+ s << keymap_bindings(Controller.current.overriding_map)
45
+ s << "\n"
41
46
  end
42
- bindings.each do |key_sequence, command|
43
- s << format("%-16s [%s]\n",
44
- Keymap.key_sequence_string(key_sequence),
45
- command)
47
+ if Buffer.current.keymap
48
+ s << "Current Buffer Bindings:\n"
49
+ s << keymap_bindings(Buffer.current.keymap)
50
+ s << "\n"
46
51
  end
52
+ s << "Global Bindings:\n"
53
+ s << keymap_bindings(GLOBAL_MAP)
47
54
  help.insert(s)
48
55
  end
49
56
  push_help_command([:describe_bindings])
@@ -1,8 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  module Commands
5
- ISEARCH_MODE_MAP = Keymap.new
3
+ define_keymap :ISEARCH_MODE_MAP
6
4
  (?\x20..?\x7e).each do |c|
7
5
  ISEARCH_MODE_MAP.define_key(c, :isearch_printing_char)
8
6
  end
@@ -21,6 +19,7 @@ module Commands
21
19
  ISEARCH_MODE_MAP.define_key(?\C-w, :isearch_yank_word_or_char)
22
20
  ISEARCH_MODE_MAP.define_key(?\C-m, :isearch_exit)
23
21
  ISEARCH_MODE_MAP.define_key(?\C-g, :isearch_abort)
22
+ ISEARCH_MODE_MAP.define_key(?\C-q, :isearch_quoted_insert)
24
23
 
25
24
  ISEARCH_STATUS = {
26
25
  forward: true,
@@ -43,7 +42,7 @@ module Commands
43
42
 
44
43
  def isearch_mode(forward, recursive_edit: false)
45
44
  ISEARCH_STATUS[:forward] = forward
46
- ISEARCH_STATUS[:string] = String.new
45
+ ISEARCH_STATUS[:string] = +""
47
46
  ISEARCH_STATUS[:recursive_edit] = recursive_edit
48
47
  Controller.current.overriding_map = ISEARCH_MODE_MAP
49
48
  run_hooks(:isearch_mode_hook)
@@ -116,6 +115,14 @@ def isearch_done
116
115
  end
117
116
  end
118
117
 
118
+ define_command(:isearch_quoted_insert, doc: <<~EOD) do
119
+ Read a character, and add it to the search string and search.
120
+ EOD
121
+ c = Controller.current.read_event
122
+ ISEARCH_STATUS[:string].concat(c)
123
+ isearch_search
124
+ end
125
+
119
126
  def isearch_search
120
127
  forward = ISEARCH_STATUS[:forward]
121
128
  options = if /\A[A-Z]/.match?(ISEARCH_STATUS[:string])
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  module Commands
5
3
  KEYBOARD_MACROS = {}
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  module Commands
5
3
  define_command(:version) do
@@ -141,7 +139,7 @@ def complete_minibuffer_with_string(s)
141
139
  end
142
140
  end
143
141
 
144
- UNIVERSAL_ARGUMENT_MAP = Keymap.new
142
+ define_keymap :UNIVERSAL_ARGUMENT_MAP
145
143
  (?0..?9).each do |c|
146
144
  UNIVERSAL_ARGUMENT_MAP.define_key(c, :digit_argument)
147
145
  GLOBAL_MAP.define_key("\e#{c}", :digit_argument)
@@ -278,35 +276,39 @@ def goto_global_mark
278
276
  Window.redisplay
279
277
  signals = [:INT, :TERM, :KILL]
280
278
  begin
281
- opts = /mswin32|mingw32/ =~ RUBY_PLATFORM ? {} : {pgroup: true}
279
+ opts = /mswin|mingw/ =~ RUBY_PLATFORM ? {} : {pgroup: true}
282
280
  if CONFIG[:shell_file_name]
283
281
  cmd = [CONFIG[:shell_file_name], CONFIG[:shell_command_switch], cmd]
284
282
  end
285
- Open3.popen2e(*cmd, opts) do |input, output, wait_thread|
283
+ Open3.popen3(*cmd, opts) do |input, output, error, wait_thread|
286
284
  input.close
287
- loop do
288
- status = output.wait_readable(0.5)
289
- if status
290
- begin
291
- s = output.read_nonblock(1024).force_encoding("utf-8").
292
- scrub("\u{3013}").gsub(/\r\n/, "\n")
293
- buffer.insert(s)
294
- Window.redisplay
295
- rescue EOFError
296
- break
297
- rescue Errno::EAGAIN, Errno::EWOULDBLOCK
298
- next
285
+ catch(:finish) do
286
+ loop do
287
+ rs, = IO.select([output, error], nil, nil, 0.5)
288
+ Window.redisplay
289
+ rs&.each do |r|
290
+ begin
291
+ s = r.read_nonblock(1024).force_encoding("utf-8").
292
+ scrub("\u{3013}").gsub(/\r\n/, "\n")
293
+ buffer.insert(s)
294
+ Window.redisplay
295
+ rescue EOFError
296
+ throw(:finish)
297
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK
298
+ Window.redisplay
299
+ next
300
+ end
299
301
  end
300
- end
301
- if received_keyboard_quit?
302
- if signals.empty?
303
- keyboard_quit
304
- else
305
- sig = signals.shift
306
- pid = wait_thread.pid
307
- pid = -pid if /mswin32|mingw32/ !~ RUBY_PLATFORM
308
- message("Send #{sig} to #{pid}")
309
- Process.kill(sig, pid)
302
+ if received_keyboard_quit?
303
+ if signals.empty?
304
+ keyboard_quit
305
+ else
306
+ sig = signals.shift
307
+ pid = wait_thread.pid
308
+ pid = -pid if /mswin32|mingw32/ !~ RUBY_PLATFORM
309
+ message("Send #{sig} to #{pid}")
310
+ Process.kill(sig, pid)
311
+ end
310
312
  end
311
313
  end
312
314
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  module Commands
5
3
  class BufferPosition
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  module Commands
5
3
  RE_SEARCH_STATUS = {
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "drb"
4
2
 
5
3
  module Textbringer
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  module Commands
5
3
  define_command(:resize_window,
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  CONFIG = {
5
3
  east_asian_ambiguous_width: 1,
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  TOP_LEVEL_TAG = Object.new
5
3
  RECURSIVE_EDIT_TAG = Object.new
@@ -128,7 +126,7 @@ def read_event
128
126
  else
129
127
  wait_files = [STDIN, @next_tick_input]
130
128
  end
131
- files, = IO.select(wait_files, [], [], 1)
129
+ files, = IO.select(wait_files, nil, nil, 1)
132
130
  # KEY_RESIZE may be returned even if STDIN is not included in files.
133
131
  event = read_event_nonblock
134
132
  if event
@@ -178,7 +176,7 @@ def echo_input
178
176
  return if wait_input(1000)
179
177
  end
180
178
  @echo_immediately = true
181
- s = String.new
179
+ s = +""
182
180
  if @prefix_arg
183
181
  s << "C-u"
184
182
  if @prefix_arg != [4]
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class EditorError < StandardError
5
3
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "curses"
4
2
 
5
3
  module Textbringer
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  Face.define :mode_line, reverse: true
5
3
  Face.define :link, foreground: "blue", bold: true
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  Face.define :comment, foreground: "yellow"
5
3
  Face.define :preprocessing_directive, foreground: "green"
@@ -1,4 +1,10 @@
1
- # frozen_string_literal: true
1
+ class Module
2
+ def define_keymap(name)
3
+ unless const_defined?(name, false)
4
+ const_set(name, Textbringer::Keymap.new)
5
+ end
6
+ end
7
+ end
2
8
 
3
9
  module Textbringer
4
10
  class Keymap
@@ -74,7 +80,16 @@ def self.key_name(key)
74
80
  end
75
81
 
76
82
  def self.key_sequence_string(key_sequence)
77
- key_sequence.map { |key| key_name(key) }.join(" ")
83
+ ks = key_sequence.dup
84
+ key_names = []
85
+ while key = ks.shift
86
+ if key == "\e" && !ks.empty?
87
+ key_names.push("M-" + key_name(ks.shift))
88
+ else
89
+ key_names.push(key_name(key))
90
+ end
91
+ end
92
+ key_names.join(" ")
78
93
  end
79
94
 
80
95
  private
@@ -84,7 +99,7 @@ def kbd(key)
84
99
  when Symbol
85
100
  [key]
86
101
  when String
87
- key.chars
102
+ key.b.gsub(/[\x80-\xff]/n) { |c| "\e" + (c.ord & 0x7f).chr }.chars
88
103
  when Array
89
104
  key
90
105
  else
@@ -93,17 +108,17 @@ def kbd(key)
93
108
  end
94
109
  end
95
110
 
96
- GLOBAL_MAP = Keymap.new
111
+ define_keymap :GLOBAL_MAP
97
112
  GLOBAL_MAP.define_key(:resize, :resize_window)
98
113
  GLOBAL_MAP.define_key(:right, :forward_char)
99
114
  GLOBAL_MAP.define_key(?\C-f, :forward_char)
100
115
  GLOBAL_MAP.define_key(:left, :backward_char)
101
116
  GLOBAL_MAP.define_key(?\C-b, :backward_char)
102
- GLOBAL_MAP.define_key("\ef", :forward_word)
103
- GLOBAL_MAP.define_key("\eb", :backward_word)
104
- GLOBAL_MAP.define_key("\egc", :goto_char)
105
- GLOBAL_MAP.define_key("\egg", :goto_line)
106
- GLOBAL_MAP.define_key("\eg\eg", :goto_line)
117
+ GLOBAL_MAP.define_key("\M-f", :forward_word)
118
+ GLOBAL_MAP.define_key("\M-b", :backward_word)
119
+ GLOBAL_MAP.define_key("\M-gc", :goto_char)
120
+ GLOBAL_MAP.define_key("\M-gg", :goto_line)
121
+ GLOBAL_MAP.define_key("\M-g\M-g", :goto_line)
107
122
  GLOBAL_MAP.define_key(:down, :next_line)
108
123
  GLOBAL_MAP.define_key(?\C-n, :next_line)
109
124
  GLOBAL_MAP.define_key(:up, :previous_line)
@@ -117,8 +132,8 @@ def kbd(key)
117
132
  GLOBAL_MAP.define_key(:home, :beginning_of_line)
118
133
  GLOBAL_MAP.define_key(?\C-e, :end_of_line)
119
134
  GLOBAL_MAP.define_key(:end, :end_of_line)
120
- GLOBAL_MAP.define_key("\e<", :beginning_of_buffer)
121
- GLOBAL_MAP.define_key("\e>", :end_of_buffer)
135
+ GLOBAL_MAP.define_key("\M-<", :beginning_of_buffer)
136
+ GLOBAL_MAP.define_key("\M->", :end_of_buffer)
122
137
  (?\x20..?\x7e).each do |c|
123
138
  GLOBAL_MAP.define_key(c, :self_insert)
124
139
  end
@@ -126,15 +141,15 @@ def kbd(key)
126
141
  GLOBAL_MAP.define_key(?\C-q, :quoted_insert)
127
142
  GLOBAL_MAP.define_key("\C-@", :set_mark_command)
128
143
  GLOBAL_MAP.define_key("\C-x\C-@", :pop_global_mark)
129
- GLOBAL_MAP.define_key("\e*", :next_global_mark)
130
- GLOBAL_MAP.define_key("\e?", :previous_global_mark)
144
+ GLOBAL_MAP.define_key("\M-*", :next_global_mark)
145
+ GLOBAL_MAP.define_key("\M-?", :previous_global_mark)
131
146
  GLOBAL_MAP.define_key("\C-x\C-x", :exchange_point_and_mark)
132
- GLOBAL_MAP.define_key("\ew", :copy_region)
147
+ GLOBAL_MAP.define_key("\M-w", :copy_region)
133
148
  GLOBAL_MAP.define_key(?\C-w, :kill_region)
134
149
  GLOBAL_MAP.define_key(?\C-k, :kill_line)
135
- GLOBAL_MAP.define_key("\ed", :kill_word)
150
+ GLOBAL_MAP.define_key("\M-d", :kill_word)
136
151
  GLOBAL_MAP.define_key(?\C-y, :yank)
137
- GLOBAL_MAP.define_key("\ey", :yank_pop)
152
+ GLOBAL_MAP.define_key("\M-y", :yank_pop)
138
153
  GLOBAL_MAP.define_key(?\C-_, :undo)
139
154
  GLOBAL_MAP.define_key("\C-xu", :undo)
140
155
  GLOBAL_MAP.define_key("\C-x\C-_", :redo_command)
@@ -142,12 +157,14 @@ def kbd(key)
142
157
  GLOBAL_MAP.define_key("\C-j", :newline)
143
158
  GLOBAL_MAP.define_key("\C-m", :newline)
144
159
  GLOBAL_MAP.define_key("\C-o", :open_line)
145
- GLOBAL_MAP.define_key("\em", :back_to_indentation)
146
- GLOBAL_MAP.define_key("\e^", :delete_indentation)
160
+ GLOBAL_MAP.define_key("\M-m", :back_to_indentation)
161
+ GLOBAL_MAP.define_key("\M-^", :delete_indentation)
162
+ GLOBAL_MAP.define_key("\C-xh", :mark_whole_buffer)
163
+ GLOBAL_MAP.define_key("\M-z", :zap_to_char)
147
164
  GLOBAL_MAP.define_key("\C-l", :recenter)
148
165
  GLOBAL_MAP.define_key("\C-v", :scroll_up)
149
166
  GLOBAL_MAP.define_key(:npage, :scroll_up)
150
- GLOBAL_MAP.define_key("\ev", :scroll_down)
167
+ GLOBAL_MAP.define_key("\M-v", :scroll_down)
151
168
  GLOBAL_MAP.define_key(:ppage, :scroll_down)
152
169
  GLOBAL_MAP.define_key("\C-x0", :delete_window)
153
170
  GLOBAL_MAP.define_key("\C-x1", :delete_other_windows)
@@ -158,6 +175,7 @@ def kbd(key)
158
175
  GLOBAL_MAP.define_key("\C-x\C-c", :exit_textbringer)
159
176
  GLOBAL_MAP.define_key("\C-z", :suspend_textbringer)
160
177
  GLOBAL_MAP.define_key("\C-x\C-f", :find_file)
178
+ GLOBAL_MAP.define_key("\C-x\C-v", :find_alternate_file)
161
179
  GLOBAL_MAP.define_key("\C-xb", :switch_to_buffer)
162
180
  GLOBAL_MAP.define_key("\C-x\C-b", :list_buffers)
163
181
  GLOBAL_MAP.define_key("\C-x\C-s", :save_buffer)
@@ -166,15 +184,15 @@ def kbd(key)
166
184
  GLOBAL_MAP.define_key("\C-x\C-mf", :set_buffer_file_encoding)
167
185
  GLOBAL_MAP.define_key("\C-x\C-mn", :set_buffer_file_format)
168
186
  GLOBAL_MAP.define_key("\C-x\C-mr", :revert_buffer_with_encoding)
169
- GLOBAL_MAP.define_key("\e.", :find_tag)
170
- GLOBAL_MAP.define_key("\ex", :execute_command)
171
- GLOBAL_MAP.define_key("\e:", :eval_expression)
187
+ GLOBAL_MAP.define_key("\M-.", :find_tag)
188
+ GLOBAL_MAP.define_key("\M-x", :execute_command)
189
+ GLOBAL_MAP.define_key("\M-:", :eval_expression)
172
190
  GLOBAL_MAP.define_key(?\C-u, :universal_argument)
173
191
  GLOBAL_MAP.define_key(?\C-g, :keyboard_quit)
174
192
  GLOBAL_MAP.define_key(?\C-s, :isearch_forward)
175
193
  GLOBAL_MAP.define_key(?\C-r, :isearch_backward)
176
- GLOBAL_MAP.define_key("\e%", :query_replace_regexp)
177
- GLOBAL_MAP.define_key("\e!", :shell_execute)
194
+ GLOBAL_MAP.define_key("\M-%", :query_replace_regexp)
195
+ GLOBAL_MAP.define_key("\M-!", :shell_execute)
178
196
  GLOBAL_MAP.define_key("\C-xr ", :point_to_register)
179
197
  GLOBAL_MAP.define_key("\C-xrj", :jump_to_register)
180
198
  GLOBAL_MAP.define_key("\C-xrx", :copy_to_register)
@@ -188,7 +206,7 @@ def kbd(key)
188
206
  GLOBAL_MAP.define_key("\C-x)", :end_keyboard_macro)
189
207
  GLOBAL_MAP.define_key("\C-xe", :end_and_call_keyboard_macro)
190
208
  GLOBAL_MAP.define_key(:f4, :end_or_call_keyboard_macro)
191
- GLOBAL_MAP.define_key("\eq", :fill_paragraph)
209
+ GLOBAL_MAP.define_key("\M-q", :fill_paragraph)
192
210
  GLOBAL_MAP.define_key([:f1, "b"], :describe_bindings)
193
211
  GLOBAL_MAP.define_key([:f1, "f"], :describe_command)
194
212
  GLOBAL_MAP.define_key([:f1, "k"], :describe_key)
@@ -201,7 +219,7 @@ def kbd(key)
201
219
  end
202
220
  end
203
221
 
204
- MINIBUFFER_LOCAL_MAP = Keymap.new
222
+ define_keymap :MINIBUFFER_LOCAL_MAP
205
223
  MINIBUFFER_LOCAL_MAP.define_key("\C-j", :exit_recursive_edit)
206
224
  MINIBUFFER_LOCAL_MAP.define_key("\C-m", :exit_recursive_edit)
207
225
  MINIBUFFER_LOCAL_MAP.define_key(?\t, :complete_minibuffer)
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class Mode
5
3
  extend Commands