textbringer 0.3.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
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