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,10 +1,8 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class BacktraceMode < Mode
5
3
  define_generic_command :jump_to_source_location
6
4
 
7
- BACKTRACE_MODE_MAP = Keymap.new
5
+ define_keymap :BACKTRACE_MODE_MAP
8
6
  BACKTRACE_MODE_MAP.define_key("\C-m", :jump_to_source_location_command)
9
7
 
10
8
  define_syntax :link, /^\S*?:\d+:(?:\d+:)?/
@@ -1,8 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class BufferListMode < Mode
5
- BUFFER_LIST_MODE_MAP = Keymap.new
3
+ define_keymap :BUFFER_LIST_MODE_MAP
6
4
  BUFFER_LIST_MODE_MAP.define_key("\C-m", :this_window_command)
7
5
 
8
6
  def initialize(buffer)
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  CONFIG[:c_indent_level] = 4
5
3
  CONFIG[:c_indent_tabs_mode] = true
@@ -36,6 +34,10 @@ class CMode < ProgrammingMode
36
34
  (?: ' (?: [^\\'] | \\ (?:.|\n) )* ' )
37
35
  /x
38
36
 
37
+ def comment_start
38
+ "//"
39
+ end
40
+
39
41
  def initialize(buffer)
40
42
  super(buffer)
41
43
  @buffer[:indent_level] = CONFIG[:c_indent_level]
@@ -1,10 +1,8 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class CompletionListMode < Mode
5
3
  define_generic_command :choose_completion
6
4
 
7
- COMPLETION_LIST_MODE_MAP = Keymap.new
5
+ define_keymap :COMPLETION_LIST_MODE_MAP
8
6
  COMPLETION_LIST_MODE_MAP.define_key("\C-m", :choose_completion_command)
9
7
 
10
8
  define_syntax :link, /^.+$/
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class FundamentalMode < Mode
5
3
  def symbol_pattern
@@ -1,10 +1,8 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class HelpMode < Mode
5
3
  define_generic_command :jump_to_link
6
4
 
7
- HELP_MODE_MAP = Keymap.new
5
+ define_keymap :HELP_MODE_MAP
8
6
  HELP_MODE_MAP.define_key(?\C-m, :jump_to_link_command)
9
7
  HELP_MODE_MAP.define_key(?l, :help_go_back)
10
8
  HELP_MODE_MAP.define_key("\C-c\C-b", :help_go_back)
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class ProgrammingMode < FundamentalMode
5
3
  # abstract mode
@@ -12,16 +10,18 @@ class ProgrammingMode < FundamentalMode
12
10
  define_generic_command :backward_definition
13
11
  define_generic_command :compile
14
12
  define_generic_command :toggle_test
13
+ define_generic_command :indent_new_comment_line
15
14
 
16
- PROGRAMMING_MODE_MAP = Keymap.new
15
+ define_keymap :PROGRAMMING_MODE_MAP
17
16
  PROGRAMMING_MODE_MAP.define_key("\t", :indent_line_command)
18
17
  PROGRAMMING_MODE_MAP.define_key("\C-m",
19
18
  :reindent_then_newline_and_indent_command)
20
- PROGRAMMING_MODE_MAP.define_key("\e\C-\\", :indent_region_command)
19
+ PROGRAMMING_MODE_MAP.define_key("\M-\C-\\", :indent_region_command)
21
20
  PROGRAMMING_MODE_MAP.define_key("\C-c\C-n", :forward_definition_command)
22
21
  PROGRAMMING_MODE_MAP.define_key("\C-c\C-p", :backward_definition_command)
23
22
  PROGRAMMING_MODE_MAP.define_key("\C-c\C-c", :compile_command)
24
23
  PROGRAMMING_MODE_MAP.define_key("\C-c\C-t", :toggle_test_command)
24
+ PROGRAMMING_MODE_MAP.define_key("\ej", :indent_new_comment_line_command)
25
25
 
26
26
  def initialize(buffer)
27
27
  super(buffer)
@@ -32,7 +32,7 @@ def initialize(buffer)
32
32
  def indent_line
33
33
  result = false
34
34
  level = calculate_indentation
35
- return result if level.nil?
35
+ return result if level.nil? || level < 0
36
36
  @buffer.save_excursion do
37
37
  @buffer.beginning_of_line
38
38
  @buffer.composite_edit do
@@ -88,6 +88,26 @@ def indent_region(s = @buffer.mark, e = @buffer.point)
88
88
  end
89
89
  end
90
90
 
91
+ def indent_new_comment_line
92
+ if comment_start.nil?
93
+ @buffer.newline
94
+ return
95
+ end
96
+ s = @buffer.save_excursion {
97
+ @buffer.beginning_of_line
98
+ if @buffer.looking_at?(/[ \t]*#{comment_start}+[ \t]*/)
99
+ @buffer.match_string(0)
100
+ else
101
+ ""
102
+ end
103
+ }
104
+ @buffer.insert("\n" + s)
105
+ end
106
+
107
+ def comment_start
108
+ nil
109
+ end
110
+
91
111
  private
92
112
 
93
113
  def calculate_indentation
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "ripper"
4
2
 
5
3
  module Textbringer
@@ -87,6 +85,10 @@ class | module | def | undef | begin | rescue | ensure | end |
87
85
  )
88
86
  /x
89
87
 
88
+ def comment_start
89
+ "#"
90
+ end
91
+
90
92
  def initialize(buffer)
91
93
  super(buffer)
92
94
  @buffer[:indent_level] = CONFIG[:ruby_indent_level]
@@ -175,7 +177,7 @@ def toggle_test
175
177
 
176
178
  private
177
179
 
178
- INDENT_BEG_RE = /^([ \t]*)((class|module|def|if|unless|case|while|until|for|begin|end)\b|\})/
180
+ INDENT_BEG_RE = /^([ \t]*)(class|module|def|if|unless|case|while|until|for|begin)\b/
179
181
 
180
182
  def space_width(s)
181
183
  s.gsub(/\t/, " " * @buffer[:tab_width]).size
@@ -196,6 +198,22 @@ def beginning_of_indentation
196
198
  0
197
199
  end
198
200
 
201
+ def lex(source)
202
+ line_count = source.count("\n")
203
+ s = source
204
+ lineno = 1
205
+ tokens = []
206
+ loop do
207
+ lexer = Ripper::Lexer.new(s, "-", lineno)
208
+ tokens.concat(lexer.lex)
209
+ last_line = tokens.dig(-1, 0, 0)
210
+ return tokens if last_line.nil? || last_line >= line_count
211
+ s = source.sub(/(.*\n?){#{last_line}}/, "")
212
+ return tokens if last_line + 1 <= lineno
213
+ lineno = last_line + 1
214
+ end
215
+ end
216
+
199
217
  def calculate_indentation
200
218
  if @buffer.current_line == 1
201
219
  return 0
@@ -207,8 +225,11 @@ def calculate_indentation
207
225
  base_indentation = beginning_of_indentation
208
226
  start_pos = @buffer.point
209
227
  start_line = @buffer.current_line
210
- tokens = Ripper.lex(@buffer.substring(start_pos, bol_pos))
228
+ tokens = lex(@buffer.substring(start_pos, bol_pos))
211
229
  _, event, text = tokens.last
230
+ if event == :on_nl
231
+ _, event, text = tokens[-2]
232
+ end
212
233
  if event == :on_tstring_beg ||
213
234
  event == :on_heredoc_beg ||
214
235
  event == :on_regexp_beg ||
@@ -216,7 +237,7 @@ def calculate_indentation
216
237
  event == :on_tstring_content
217
238
  return nil
218
239
  end
219
- i = find_nearest_beginning_token(tokens)
240
+ i, extra_end_count = find_nearest_beginning_token(tokens)
220
241
  (line, column), event, = i ? tokens[i] : nil
221
242
  if event == :on_lparen && tokens.dig(i + 1, 1) != :on_ignored_nl
222
243
  return column + 1
@@ -239,11 +260,12 @@ def calculate_indentation
239
260
  end
240
261
  @buffer.goto_char(bol_pos)
241
262
  if line.nil?
242
- indentation = base_indentation
263
+ indentation =
264
+ base_indentation - extra_end_count * @buffer[:indent_level]
243
265
  else
244
266
  indentation = base_indentation + @buffer[:indent_level]
245
267
  end
246
- if @buffer.looking_at?(/[ \t]*([}\])]|(end|else|elsif|when|rescue|ensure)\b)/)
268
+ if @buffer.looking_at?(/[ \t]*([}\])]|(end|else|elsif|when|in|rescue|ensure)\b)/)
247
269
  indentation -= @buffer[:indent_level]
248
270
  end
249
271
  _, last_event, last_text = tokens.reverse_each.find { |_, e, _|
@@ -261,6 +283,7 @@ def calculate_indentation
261
283
  end
262
284
 
263
285
  BLOCK_END = {
286
+ '#{' => "}",
264
287
  "{" => "}",
265
288
  "(" => ")",
266
289
  "[" => "]"
@@ -292,9 +315,9 @@ def find_nearest_beginning_token(tokens)
292
315
  when "end"
293
316
  stack.push(text)
294
317
  end
295
- when :on_rbrace, :on_rparen, :on_rbracket
318
+ when :on_rbrace, :on_rparen, :on_rbracket, :on_embexpr_end
296
319
  stack.push(text)
297
- when :on_lbrace, :on_lparen, :on_lbracket, :on_tlambeg
320
+ when :on_lbrace, :on_lparen, :on_lbracket, :on_tlambeg, :on_embexpr_beg
298
321
  if stack.empty?
299
322
  return i
300
323
  end
@@ -304,7 +327,7 @@ def find_nearest_beginning_token(tokens)
304
327
  stack.pop
305
328
  end
306
329
  end
307
- return nil
330
+ return nil, stack.grep_v(/[)\]]/).size
308
331
  end
309
332
 
310
333
  def find_test_target_path(base, namespace, name)
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  module Plugin
5
3
  class << self
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
2
  class Ring
5
3
  include Enumerable
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "rbconfig"
4
2
 
5
3
  module Textbringer
@@ -68,6 +66,9 @@ def foreground(&block)
68
66
  alias next_tick foreground
69
67
 
70
68
  def foreground!
69
+ if Thread.current == Thread.main
70
+ return yield
71
+ end
71
72
  q = Queue.new
72
73
  foreground do
73
74
  begin
@@ -104,10 +105,10 @@ def received_keyboard_quit?
104
105
  end
105
106
 
106
107
  def show_exception(e)
107
- if e.is_a?(SystemExit)
108
+ if e.is_a?(SystemExit) || e.is_a?(SignalException)
108
109
  raise
109
110
  end
110
- if Buffer.current&.name != "*Backtrace*"
111
+ if !e.is_a?(Quit) && Buffer.current&.name != "*Backtrace*"
111
112
  buffer = Buffer.find_or_new("*Backtrace*", undo_limit: 0)
112
113
  if !buffer.mode.is_a?(BacktraceMode)
113
114
  buffer.apply_mode(BacktraceMode)
@@ -240,7 +241,7 @@ def yes_or_no?(prompt)
240
241
  }
241
242
  end
242
243
 
243
- Y_OR_N_MAP = Keymap.new
244
+ define_keymap :Y_OR_N_MAP
244
245
  Y_OR_N_MAP.define_key(?y, :self_insert_and_exit_minibuffer)
245
246
  Y_OR_N_MAP.define_key(?n, :self_insert_and_exit_minibuffer)
246
247
  Y_OR_N_MAP.define_key(?\C-g, :abort_recursive_edit)
@@ -315,8 +316,8 @@ def read_key_sequence(prompt)
315
316
 
316
317
  HOOKS = Hash.new { |h, k| h[k] = [] }
317
318
 
318
- def add_hook(name, func = Proc.new)
319
- HOOKS[name].unshift(func)
319
+ def add_hook(name, func = nil, &block)
320
+ HOOKS[name].unshift(func || block)
320
321
  end
321
322
 
322
323
  def remove_hook(name, func)
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Textbringer
4
- VERSION = "0.3.2"
2
+ VERSION = "1.0.4"
5
3
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "curses"
4
2
  require "unicode/display_width"
5
3
 
@@ -457,7 +455,11 @@ def redisplay
457
455
  end
458
456
  end
459
457
  end
460
- @window.addstr(c)
458
+ if c == "\uFEFF"
459
+ # ncurses on macOS prints U+FEFF as space, so ignore it
460
+ else
461
+ @window.addstr(c)
462
+ end
461
463
  break if newx == columns && cury == lines - 2
462
464
  @buffer.forward_char
463
465
  end
Binary file
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: textbringer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-08 00:00:00.000000000 Z
11
+ date: 2020-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -176,14 +176,16 @@ extensions: []
176
176
  extra_rdoc_files: []
177
177
  files:
178
178
  - ".editorconfig"
179
+ - ".gitattributes"
180
+ - ".github/workflows/macos.yml"
181
+ - ".github/workflows/ubuntu.yml"
182
+ - ".github/workflows/windows.yml"
179
183
  - ".gitignore"
180
- - ".travis.yml"
181
184
  - CHANGES.md
182
185
  - Gemfile
183
186
  - LICENSE.txt
184
187
  - README.md
185
188
  - Rakefile
186
- - appveyor.yml
187
189
  - bin/console
188
190
  - exe/tbclient
189
191
  - exe/tbtags
@@ -227,13 +229,15 @@ files:
227
229
  - lib/textbringer/utils.rb
228
230
  - lib/textbringer/version.rb
229
231
  - lib/textbringer/window.rb
232
+ - logo/logo.jpg
233
+ - logo/logo.png
230
234
  - screenshot.png
231
235
  - textbringer.gemspec
232
236
  homepage: https://github.com/shugo/textbringer
233
237
  licenses:
234
238
  - MIT
235
239
  metadata: {}
236
- post_install_message:
240
+ post_install_message:
237
241
  rdoc_options: []
238
242
  require_paths:
239
243
  - lib
@@ -248,9 +252,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
248
252
  - !ruby/object:Gem::Version
249
253
  version: '0'
250
254
  requirements: []
251
- rubyforge_project:
252
- rubygems_version: 3.0.0.beta3
253
- signing_key:
255
+ rubygems_version: 3.2.3
256
+ signing_key:
254
257
  specification_version: 4
255
258
  summary: An Emacs-like text editor
256
259
  test_files: []
@@ -1,56 +0,0 @@
1
- language: ruby
2
- matrix:
3
- include:
4
- - os: linux
5
- dist: trusty
6
- sudo: false
7
- rvm: 2.4.5
8
- - os: linux
9
- dist: trusty
10
- sudo: false
11
- rvm: 2.5.2
12
- - os: linux
13
- dist: trusty
14
- sudo: false
15
- rvm: 2.6.0
16
- - os: linux
17
- dist: trusty
18
- sudo: false
19
- rvm: ruby-head
20
- - os: osx
21
- osx_image: xcode8.2
22
- rvm: 2.4.5
23
- - os: osx
24
- osx_image: xcode8.2
25
- rvm: 2.5.2
26
- - os: osx
27
- osx_image: xcode8.2
28
- rvm: 2.6.0
29
- - os: osx
30
- osx_image: xcode8.2
31
- rvm: ruby-head
32
- allow_failures:
33
- - os: osx
34
- - rvm: ruby-head
35
- fast_finish: true
36
- cache: bundler
37
- before_install:
38
- - gem update --system
39
- - gem install bundler-audit
40
- script:
41
- - if [ "$TRAVIS_OS_NAME" == "linux" ]; then
42
- xvfb-run bundle exec rake test;
43
- else
44
- bundle exec rake test;
45
- fi
46
- env:
47
- global:
48
- UPLOAD_TO_CODECOV: 1
49
- notifications:
50
- email:
51
- on_success: never
52
- on_failure: always
53
- addons:
54
- apt:
55
- packages:
56
- - xclip