textbringer 0.1.4 → 0.1.5

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.
@@ -9,4 +9,10 @@ module Textbringer
9
9
 
10
10
  class ReadOnlyError < EditorError
11
11
  end
12
+
13
+ class Quit < EditorError
14
+ def initialize
15
+ super("Quit")
16
+ end
17
+ end
12
18
  end
@@ -20,6 +20,7 @@ module Textbringer
20
20
  def indent_line
21
21
  result = false
22
22
  level = calculate_indentation
23
+ return result if level.nil?
23
24
  @buffer.save_excursion do
24
25
  @buffer.beginning_of_line
25
26
  has_space = @buffer.looking_at?(/[ \t]+/)
@@ -88,8 +89,8 @@ module Textbringer
88
89
  end
89
90
  end
90
91
 
91
- def compile
92
- cmd = read_from_minibuffer("Compile: ", default: default_compile_command)
92
+ def compile(cmd = read_from_minibuffer("Compile: ",
93
+ default: default_compile_command))
93
94
  shell_execute(cmd, "*Ruby compile result*")
94
95
  backtrace_mode
95
96
  end
@@ -98,6 +99,59 @@ module Textbringer
98
99
  /[\p{Letter}\p{Number}_$@!?]/
99
100
  end
100
101
 
102
+ def default_compile_command
103
+ @buffer[:ruby_compile_command] ||
104
+ if File.exist?("Rakefile")
105
+ prefix = File.exist?("Gemfile") ? "bundle exec " : ""
106
+ prefix + "rake"
107
+ elsif @buffer.file_name
108
+ "ruby " + @buffer.file_name
109
+ else
110
+ nil
111
+ end
112
+ end
113
+
114
+ def toggle_test
115
+ case @buffer.file_name
116
+ when %r'(.*)/test/(.*/)?test_(.*?)\.rb\z'
117
+ base = $1
118
+ namespace = $2
119
+ name = $3
120
+ if namespace
121
+ paths = Dir.glob("#{base}/{lib,app}/**/#{namespace}#{name}.rb")
122
+ if !paths.empty?
123
+ find_file(paths.first)
124
+ return
125
+ end
126
+ end
127
+ paths = Dir.glob("#{base}/{lib,app}/**/#{name}.rb")
128
+ if !paths.empty?
129
+ find_file(paths.first)
130
+ return
131
+ end
132
+ raise EditorError, "Test subject not found"
133
+ when %r'(.*)/(?:lib|app)/(.*/)?(.*?)\.rb\z'
134
+ base = $1
135
+ namespace = $2
136
+ name = $3
137
+ if namespace
138
+ paths = Dir.glob("#{base}/test/**/#{namespace}test_#{name}.rb")
139
+ if !paths.empty?
140
+ find_file(paths.first)
141
+ return
142
+ end
143
+ end
144
+ paths = Dir.glob("#{base}/test/**/test_#{name}.rb")
145
+ if !paths.empty?
146
+ find_file(paths.first)
147
+ return
148
+ end
149
+ raise EditorError, "Test not found"
150
+ else
151
+ raise EditorError, "Unknown file type"
152
+ end
153
+ end
154
+
101
155
  private
102
156
 
103
157
  def calculate_indentation
@@ -109,12 +163,29 @@ module Textbringer
109
163
  bol_pos = @buffer.point
110
164
  tokens = Ripper.lex(@buffer.substring(@buffer.point_min,
111
165
  @buffer.point))
166
+ _, event, = tokens.last
167
+ if event == :on_tstring_beg ||
168
+ event == :on_heredoc_beg ||
169
+ event == :on_tstring_content
170
+ return nil
171
+ end
112
172
  line, column, event, = find_nearest_beginning_token(tokens)
113
173
  if event == :on_lparen
114
174
  return column + 1
115
175
  end
116
176
  if line
117
177
  @buffer.goto_line(line)
178
+ while !@buffer.beginning_of_buffer?
179
+ if @buffer.save_excursion {
180
+ @buffer.backward_char
181
+ @buffer.skip_re_backward(/\s/)
182
+ @buffer.char_before == ?,
183
+ }
184
+ @buffer.backward_line
185
+ else
186
+ break
187
+ end
188
+ end
118
189
  else
119
190
  @buffer.backward_line
120
191
  end
@@ -183,56 +254,5 @@ module Textbringer
183
254
  end
184
255
  return nil
185
256
  end
186
-
187
- def default_compile_command
188
- @buffer[:ruby_compile_command] ||
189
- if File.exist?("Rakefile")
190
- prefix = File.exist?("Gemfile") ? "bundle exec " : ""
191
- prefix + "rake"
192
- else
193
- "ruby " + @buffer.file_name
194
- end
195
- end
196
-
197
- def toggle_test
198
- case @buffer.file_name
199
- when %r'(.*)/test/(.*/)?test_(.*?)\.rb\z'
200
- base = $1
201
- namespace = $2
202
- name = $3
203
- if namespace
204
- paths = Dir.glob("#{base}/{lib,app}/**/#{namespace}#{name}.rb")
205
- if !paths.empty?
206
- find_file(paths.first)
207
- return
208
- end
209
- end
210
- paths = Dir.glob("#{base}/{lib,app}/**/#{name}.rb")
211
- if !paths.empty?
212
- find_file(paths.first)
213
- return
214
- end
215
- raise EditorError, "Test subject not found"
216
- when %r'(.*)/(?:lib|app)/(.*/)?(.*?)\.rb\z'
217
- base = $1
218
- namespace = $2
219
- name = $3
220
- if namespace
221
- paths = Dir.glob("#{base}/test/**/#{namespace}test_#{name}.rb")
222
- if !paths.empty?
223
- find_file(paths.first)
224
- return
225
- end
226
- end
227
- paths = Dir.glob("#{base}/test/**/#{name}.rb")
228
- if !paths.empty?
229
- find_file(paths.first)
230
- return
231
- end
232
- raise EditorError, "Test not found"
233
- else
234
- raise EditorError, "Unknown file type"
235
- end
236
- end
237
257
  end
238
258
  end
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "rbconfig"
4
+
3
5
  module Textbringer
4
6
  module Utils
7
+ module_function
8
+
5
9
  def message(msg, log: true, sit_for: nil, sleep_for: nil)
6
10
  if log && Buffer.current.name != "*Messages*"
7
11
  buffer = Buffer["*Messages*"] ||
@@ -15,7 +19,7 @@ module Textbringer
15
19
  if buffer.current_line > 1000
16
20
  buffer.beginning_of_buffer
17
21
  10.times do
18
- buffer.next_line
22
+ buffer.forward_line
19
23
  end
20
24
  buffer.delete_region(buffer.point_min, buffer.point)
21
25
  buffer.end_of_buffer
@@ -52,7 +56,7 @@ module Textbringer
52
56
  Controller.current.received_keyboard_quit?
53
57
  end
54
58
 
55
- def handle_exception(e)
59
+ def show_exception(e)
56
60
  if e.is_a?(SystemExit)
57
61
  raise
58
62
  end
@@ -65,8 +69,10 @@ module Textbringer
65
69
  begin
66
70
  buffer.delete_region(buffer.point_min, buffer.point_max)
67
71
  buffer.insert("#{e.class}: #{e}\n")
68
- e.backtrace.each do |line|
69
- buffer.insert(line + "\n")
72
+ if e.backtrace
73
+ e.backtrace.each do |line|
74
+ buffer.insert(line + "\n")
75
+ end
70
76
  end
71
77
  buffer.beginning_of_buffer
72
78
  ensure
@@ -148,7 +154,7 @@ module Textbringer
148
154
  File.expand_path(file)
149
155
  end
150
156
 
151
- def complete(s, candidates)
157
+ def complete_for_minibuffer(s, candidates)
152
158
  xs = candidates.select { |i| i.start_with?(s) }
153
159
  if xs.size > 0
154
160
  y, *ys = xs
@@ -163,13 +169,13 @@ module Textbringer
163
169
  end
164
170
 
165
171
  def read_buffer(prompt, default: (Buffer.last || Buffer.current)&.name)
166
- f = ->(s) { complete(s, Buffer.names) }
172
+ f = ->(s) { complete_for_minibuffer(s, Buffer.names) }
167
173
  read_from_minibuffer(prompt, completion_proc: f, default: default)
168
174
  end
169
175
 
170
176
  def read_command_name(prompt)
171
177
  f = ->(s) {
172
- complete(s.tr("-", "_"), Commands.list.map(&:to_s))
178
+ complete_for_minibuffer(s.tr("-", "_"), Commands.list.map(&:to_s))
173
179
  }
174
180
  read_from_minibuffer(prompt, completion_proc: f)
175
181
  end
@@ -273,5 +279,13 @@ module Textbringer
273
279
  add_hook(:pre_command_hook, hook)
274
280
  Controller.current.overriding_map = map
275
281
  end
282
+
283
+ def ruby_install_name
284
+ RbConfig::CONFIG["ruby_install_name"]
285
+ end
286
+
287
+ def insert(s)
288
+ Buffer.current.insert(s)
289
+ end
276
290
  end
277
291
  end
@@ -1,3 +1,3 @@
1
1
  module Textbringer
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
@@ -191,7 +191,8 @@ module Textbringer
191
191
  Curses.beep
192
192
  end
193
193
 
194
- attr_reader :buffer, :lines, :columns, :y, :x
194
+ attr_reader :buffer, :lines, :columns, :y, :x, :window, :mode_line
195
+ attr_reader :top_of_window, :bottom_of_window
195
196
 
196
197
  def initialize(lines, columns, y, x)
197
198
  @lines = lines
@@ -336,8 +337,9 @@ module Textbringer
336
337
  @window.attron(Curses::A_REVERSE)
337
338
  end
338
339
  while !@buffer.end_of_buffer?
340
+ cury, curx = @window.cury, @window.curx
339
341
  if @buffer.point_at_mark?(point)
340
- y, x = @window.cury, @window.curx
342
+ y, x = cury, curx
341
343
  if current? && @buffer.visible_mark
342
344
  if @buffer.point_after_mark?(@buffer.visible_mark)
343
345
  @window.attroff(Curses::A_REVERSE)
@@ -357,16 +359,31 @@ module Textbringer
357
359
  c = @buffer.char_after
358
360
  if c == "\n"
359
361
  @window.clrtoeol
360
- break if @window.cury == lines - 2 # lines include mode line
362
+ break if cury == lines - 2 # lines include mode line
363
+ @window.setpos(cury + 1, 0)
364
+ @buffer.forward_char
365
+ next
361
366
  elsif c == "\t"
362
- n = calc_tab_width(@window.curx)
367
+ n = calc_tab_width(curx)
363
368
  c = " " * n
364
369
  else
365
370
  c = escape(c)
366
371
  end
372
+ if curx < columns - 4
373
+ newx = nil
374
+ else
375
+ newx = curx + Buffer.display_width(c)
376
+ if newx > columns
377
+ if cury == lines - 2
378
+ break
379
+ else
380
+ @window.clrtoeol
381
+ @window.setpos(cury + 1, 0)
382
+ end
383
+ end
384
+ end
367
385
  @window.addstr(c)
368
- break if @window.cury == lines - 2 && # lines include mode line
369
- @window.curx == columns
386
+ break if newx == columns && cury == lines - 2
370
387
  @buffer.forward_char
371
388
  end
372
389
  if current? && @buffer.visible_mark
@@ -504,7 +521,7 @@ module Textbringer
504
521
  @mode_line.addstr(unicode_codepoint(c))
505
522
  @mode_line.addstr(" #{line},#{column}")
506
523
  @mode_line.addstr(" (#{@buffer.mode&.name || 'None'})")
507
- @mode_line.addstr(" " * (@mode_line.maxx - @mode_line.curx))
524
+ @mode_line.addstr(" " * (columns - @mode_line.curx))
508
525
  @mode_line.attroff(Curses::A_REVERSE)
509
526
  @mode_line.noutrefresh
510
527
  end
@@ -519,13 +536,13 @@ module Textbringer
519
536
 
520
537
  def escape(s)
521
538
  if @buffer.binary?
522
- s.gsub(/[\0-\b\v-\x1f]/) { |c|
539
+ s.gsub(/[\0-\b\v-\x1f\x7f]/) { |c|
523
540
  "^" + (c.ord ^ 0x40).chr
524
541
  }.gsub(/[\x80-\xff]/n) { |c|
525
542
  "<%02X>" % c.ord
526
543
  }
527
544
  else
528
- s.gsub(/[\0-\b\v-\x1f]/) { |c|
545
+ s.gsub(/[\0-\b\v-\x1f\x7f]/) { |c|
529
546
  "^" + (c.ord ^ 0x40).chr
530
547
  }
531
548
  end
@@ -620,6 +637,7 @@ module Textbringer
620
637
  end
621
638
 
622
639
  class EchoArea < Window
640
+ attr_reader :message
623
641
  attr_accessor :prompt
624
642
  attr_writer :active
625
643
 
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Shugo Maeda"]
10
10
  spec.email = ["shugo@ruby-lang.org"]
11
11
 
12
- spec.summary = "A text editor"
13
- spec.description = "Textbringer is a member of a demon race that takes on the form of a text editor."
12
+ spec.summary = "An Emacs-like text editor"
13
+ spec.description = "Textbringer is a member of a demon race that takes on the form of an Emacs-like text editor."
14
14
  spec.homepage = "https://github.com/shugo/textbringer"
15
15
  spec.license = "MIT"
16
16
 
@@ -23,11 +23,14 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_runtime_dependency "curses", "~> 1.1"
25
25
  spec.add_runtime_dependency "unicode-display_width", "~> 1.1"
26
+ spec.add_runtime_dependency "clipboard", "~> 1.1"
27
+ spec.add_runtime_dependency "ffi"
26
28
 
27
29
  spec.add_development_dependency "bundler", "~> 1.11"
28
30
  spec.add_development_dependency "rake", "~> 10.0"
29
- spec.add_development_dependency "simplecov"
30
31
  spec.add_development_dependency "test-unit"
32
+ spec.add_development_dependency "simplecov"
33
+ spec.add_development_dependency "codecov"
31
34
  spec.add_development_dependency "bundler-audit"
32
35
  spec.add_development_dependency "guard"
33
36
  spec.add_development_dependency "guard-shell"
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.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-29 00:00:00.000000000 Z
11
+ date: 2017-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: clipboard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ffi
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: bundler
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +94,20 @@ dependencies:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
96
  version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: test-unit
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
69
111
  - !ruby/object:Gem::Dependency
70
112
  name: simplecov
71
113
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +123,7 @@ dependencies:
81
123
  - !ruby/object:Gem::Version
82
124
  version: '0'
83
125
  - !ruby/object:Gem::Dependency
84
- name: test-unit
126
+ name: codecov
85
127
  requirement: !ruby/object:Gem::Requirement
86
128
  requirements:
87
129
  - - ">="
@@ -150,8 +192,8 @@ dependencies:
150
192
  - - ">="
151
193
  - !ruby/object:Gem::Version
152
194
  version: '0'
153
- description: Textbringer is a member of a demon race that takes on the form of a text
154
- editor.
195
+ description: Textbringer is a member of a demon race that takes on the form of an
196
+ Emacs-like text editor.
155
197
  email:
156
198
  - shugo@ruby-lang.org
157
199
  executables:
@@ -173,14 +215,20 @@ files:
173
215
  - lib/textbringer.rb
174
216
  - lib/textbringer/buffer.rb
175
217
  - lib/textbringer/commands.rb
218
+ - lib/textbringer/commands/buffers.rb
219
+ - lib/textbringer/commands/clipboard.rb
176
220
  - lib/textbringer/commands/ctags.rb
177
221
  - lib/textbringer/commands/dabbrev.rb
222
+ - lib/textbringer/commands/files.rb
223
+ - lib/textbringer/commands/isearch.rb
224
+ - lib/textbringer/commands/misc.rb
225
+ - lib/textbringer/commands/replace.rb
226
+ - lib/textbringer/commands/windows.rb
178
227
  - lib/textbringer/config.rb
179
228
  - lib/textbringer/controller.rb
180
229
  - lib/textbringer/errors.rb
181
230
  - lib/textbringer/keymap.rb
182
231
  - lib/textbringer/mode.rb
183
- - lib/textbringer/modes.rb
184
232
  - lib/textbringer/modes/backtrace_mode.rb
185
233
  - lib/textbringer/modes/fundamental_mode.rb
186
234
  - lib/textbringer/modes/programming_mode.rb
@@ -209,8 +257,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
257
  version: '0'
210
258
  requirements: []
211
259
  rubyforge_project:
212
- rubygems_version: 2.6.8
260
+ rubygems_version: 2.6.10
213
261
  signing_key:
214
262
  specification_version: 4
215
- summary: A text editor
263
+ summary: An Emacs-like text editor
216
264
  test_files: []
265
+ has_rdoc: