textbringer 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +9 -0
- data/.travis.yml +3 -0
- data/CHANGES.md +8 -0
- data/README.md +42 -8
- data/appveyor.yml +3 -0
- data/lib/textbringer.rb +2 -0
- data/lib/textbringer/buffer.rb +46 -28
- data/lib/textbringer/commands/buffers.rb +4 -8
- data/lib/textbringer/commands/clipboard.rb +8 -2
- data/lib/textbringer/commands/files.rb +26 -0
- data/lib/textbringer/commands/misc.rb +56 -14
- data/lib/textbringer/config.rb +1 -0
- data/lib/textbringer/controller.rb +34 -0
- data/lib/textbringer/modes/c_mode.rb +286 -0
- data/lib/textbringer/modes/completion_list_mode.rb +34 -0
- data/lib/textbringer/modes/programming_mode.rb +37 -0
- data/lib/textbringer/modes/ruby_mode.rb +9 -36
- data/lib/textbringer/utils.rb +17 -26
- data/lib/textbringer/version.rb +1 -1
- data/lib/textbringer/window.rb +47 -29
- data/textbringer.gemspec +2 -1
- metadata +21 -4
@@ -7,46 +7,17 @@ module Textbringer
|
|
7
7
|
CONFIG[:ruby_indent_tabs_mode] = false
|
8
8
|
|
9
9
|
class RubyMode < ProgrammingMode
|
10
|
-
self.file_name_pattern =
|
11
|
-
|
10
|
+
self.file_name_pattern =
|
11
|
+
/\A(?:.*\.(?:rb|ru|rake|thor|jbuilder|gemspec|podspec)|
|
12
|
+
(?:Gem|Rake|Cap|Thor|Vagrant|Guard|Pod)file)\z/ix
|
12
13
|
self.interpreter_name_pattern = /ruby/i
|
13
14
|
|
14
15
|
def initialize(buffer)
|
15
16
|
super(buffer)
|
17
|
+
@buffer[:indent_level] = CONFIG[:ruby_indent_level]
|
16
18
|
@buffer[:indent_tabs_mode] = CONFIG[:ruby_indent_tabs_mode]
|
17
19
|
end
|
18
20
|
|
19
|
-
# Return true if modified.
|
20
|
-
def indent_line
|
21
|
-
result = false
|
22
|
-
level = calculate_indentation
|
23
|
-
return result if level.nil?
|
24
|
-
@buffer.save_excursion do
|
25
|
-
@buffer.beginning_of_line
|
26
|
-
has_space = @buffer.looking_at?(/[ \t]+/)
|
27
|
-
if has_space
|
28
|
-
s = @buffer.match_string(0)
|
29
|
-
break if /\t/ !~ s && s.size == level
|
30
|
-
@buffer.delete_region(@buffer.match_beginning(0),
|
31
|
-
@buffer.match_end(0))
|
32
|
-
else
|
33
|
-
break if level == 0
|
34
|
-
end
|
35
|
-
@buffer.indent_to(level)
|
36
|
-
if has_space
|
37
|
-
@buffer.merge_undo(2)
|
38
|
-
end
|
39
|
-
result = true
|
40
|
-
end
|
41
|
-
pos = @buffer.point
|
42
|
-
@buffer.beginning_of_line
|
43
|
-
@buffer.forward_char while /[ \t]/ =~ @buffer.char_after
|
44
|
-
if @buffer.point < pos
|
45
|
-
@buffer.goto_char(pos)
|
46
|
-
end
|
47
|
-
result
|
48
|
-
end
|
49
|
-
|
50
21
|
def forward_definition(n = number_prefix_arg || 1)
|
51
22
|
tokens = Ripper.lex(@buffer.to_s)
|
52
23
|
@buffer.forward_line
|
@@ -163,9 +134,11 @@ module Textbringer
|
|
163
134
|
bol_pos = @buffer.point
|
164
135
|
tokens = Ripper.lex(@buffer.substring(@buffer.point_min,
|
165
136
|
@buffer.point))
|
166
|
-
_, event, = tokens.last
|
137
|
+
_, event, text = tokens.last
|
167
138
|
if event == :on_tstring_beg ||
|
168
139
|
event == :on_heredoc_beg ||
|
140
|
+
event == :on_regexp_beg ||
|
141
|
+
(event == :on_regexp_end && text.size > 1) ||
|
169
142
|
event == :on_tstring_content
|
170
143
|
return nil
|
171
144
|
end
|
@@ -197,14 +170,14 @@ module Textbringer
|
|
197
170
|
@buffer.looking_at?(/[ \t]*([}\])]|(end|else|elsif|when|rescue|ensure)\b)/)
|
198
171
|
indentation = base_indentation
|
199
172
|
else
|
200
|
-
indentation = base_indentation + @buffer[:
|
173
|
+
indentation = base_indentation + @buffer[:indent_level]
|
201
174
|
end
|
202
175
|
_, last_event, last_text = tokens.reverse_each.find { |_, e, _|
|
203
176
|
e != :on_sp && e != :on_nl && e != :on_ignored_nl
|
204
177
|
}
|
205
178
|
if (last_event == :on_op && last_text != "|") ||
|
206
179
|
last_event == :on_period
|
207
|
-
indentation += @buffer[:
|
180
|
+
indentation += @buffer[:indent_level]
|
208
181
|
end
|
209
182
|
indentation
|
210
183
|
end
|
data/lib/textbringer/utils.rb
CHANGED
@@ -7,6 +7,7 @@ module Textbringer
|
|
7
7
|
module_function
|
8
8
|
|
9
9
|
def message(msg, log: true, sit_for: nil, sleep_for: nil)
|
10
|
+
str = msg.to_s
|
10
11
|
if log && Buffer.current.name != "*Messages*"
|
11
12
|
buffer = Buffer["*Messages*"] ||
|
12
13
|
Buffer.new_buffer("*Messages*", undo_limit: 0).tap { |b|
|
@@ -15,7 +16,7 @@ module Textbringer
|
|
15
16
|
buffer.read_only = false
|
16
17
|
begin
|
17
18
|
buffer.end_of_buffer
|
18
|
-
buffer.insert(
|
19
|
+
buffer.insert(str + "\n")
|
19
20
|
if buffer.current_line > 1000
|
20
21
|
buffer.beginning_of_buffer
|
21
22
|
10.times do
|
@@ -28,7 +29,7 @@ module Textbringer
|
|
28
29
|
buffer.read_only = true
|
29
30
|
end
|
30
31
|
end
|
31
|
-
Window.echo_area.show(
|
32
|
+
Window.echo_area.show(str)
|
32
33
|
if sit_for
|
33
34
|
sit_for(sit_for)
|
34
35
|
Window.echo_area.clear_message
|
@@ -83,6 +84,11 @@ module Textbringer
|
|
83
84
|
Window.beep
|
84
85
|
end
|
85
86
|
|
87
|
+
COMPLETION = {
|
88
|
+
original_buffer: nil,
|
89
|
+
completions_window: nil
|
90
|
+
}
|
91
|
+
|
86
92
|
def read_from_minibuffer(prompt, completion_proc: nil, default: nil,
|
87
93
|
keymap: MINIBUFFER_LOCAL_MAP)
|
88
94
|
if Window.echo_area.active?
|
@@ -126,46 +132,31 @@ module Textbringer
|
|
126
132
|
Buffer.minibuffer[:completion_proc] = old_completion_proc
|
127
133
|
Buffer.minibuffer.keymap = old_minibuffer_map
|
128
134
|
Controller.current.current_prefix_arg = old_current_prefix_arg
|
135
|
+
if COMPLETION[:original_buffer]
|
136
|
+
COMPLETION[:completions_window].buffer = COMPLETION[:original_buffer]
|
137
|
+
COMPLETION[:completions_window] = nil
|
138
|
+
COMPLETION[:original_buffer] = nil
|
139
|
+
end
|
129
140
|
end
|
130
141
|
end
|
131
142
|
|
132
143
|
def read_file_name(prompt, default: nil)
|
133
144
|
f = ->(s) {
|
134
145
|
s = File.expand_path(s) if s.start_with?("~")
|
135
|
-
|
136
|
-
|
137
|
-
x, *xs = files
|
138
|
-
file = x.size.downto(1).lazy.map { |i|
|
139
|
-
x[0, i]
|
140
|
-
}.find { |i|
|
141
|
-
xs.all? { |j| j.start_with?(i) }
|
142
|
-
}
|
143
|
-
if file && files.size == 1 &&
|
144
|
-
File.directory?(file) && !file.end_with?(?/)
|
146
|
+
Dir.glob(s + "*").map { |file|
|
147
|
+
if File.directory?(file) && !file.end_with?(?/)
|
145
148
|
file + "/"
|
146
149
|
else
|
147
150
|
file
|
148
151
|
end
|
149
|
-
|
150
|
-
nil
|
151
|
-
end
|
152
|
+
}
|
152
153
|
}
|
153
154
|
file = read_from_minibuffer(prompt, completion_proc: f, default: default)
|
154
155
|
File.expand_path(file)
|
155
156
|
end
|
156
157
|
|
157
158
|
def complete_for_minibuffer(s, candidates)
|
158
|
-
|
159
|
-
if xs.size > 0
|
160
|
-
y, *ys = xs
|
161
|
-
y.size.downto(1).lazy.map { |i|
|
162
|
-
y[0, i]
|
163
|
-
}.find { |i|
|
164
|
-
ys.all? { |j| j.start_with?(i) }
|
165
|
-
}
|
166
|
-
else
|
167
|
-
nil
|
168
|
-
end
|
159
|
+
candidates.select { |i| i.start_with?(s) }
|
169
160
|
end
|
170
161
|
|
171
162
|
def read_buffer(prompt, default: (Buffer.last || Buffer.current)&.name)
|
data/lib/textbringer/version.rb
CHANGED
data/lib/textbringer/window.rb
CHANGED
@@ -5,22 +5,40 @@ require "unicode/display_width"
|
|
5
5
|
require "fiddle/import"
|
6
6
|
|
7
7
|
module Textbringer
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# These features should be provided by curses.gem.
|
9
|
+
module PDCurses
|
10
|
+
KEY_OFFSET = 0xec00
|
11
|
+
ALT_0 = KEY_OFFSET + 0x97
|
12
|
+
ALT_9 = KEY_OFFSET + 0xa0
|
13
|
+
ALT_A = KEY_OFFSET + 0xa1
|
14
|
+
ALT_Z = KEY_OFFSET + 0xba
|
15
|
+
ALT_NUMBER_BASE = ALT_0 - ?0.ord
|
16
|
+
ALT_ALPHA_BASE = ALT_A - ?a.ord
|
17
|
+
|
18
|
+
KEY_MODIFIER_SHIFT = 1
|
19
|
+
KEY_MODIFIER_CONTROL = 2
|
20
|
+
KEY_MODIFIER_ALT = 4
|
21
|
+
KEY_MODIFIER_NUMLOCK = 8
|
22
|
+
|
23
|
+
@dll_loaded = false
|
24
|
+
|
25
|
+
class << self
|
26
|
+
attr_writer :dll_loaded
|
27
|
+
|
28
|
+
def dll_loaded?
|
29
|
+
@dll_loaded
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
11
34
|
extend Fiddle::Importer
|
12
35
|
dlload "pdcurses.dll"
|
13
36
|
extern "unsigned long PDC_get_key_modifiers(void)"
|
14
37
|
extern "int PDC_save_key_modifiers(unsigned char)"
|
15
38
|
extern "int PDC_return_key_modifiers(unsigned char)"
|
16
|
-
|
17
|
-
|
18
|
-
KEY_MODIFIER_CONTROL = 2
|
19
|
-
KEY_MODIFIER_ALT = 4
|
20
|
-
KEY_MODIFIER_NUMLOCK = 8
|
39
|
+
@dll_loaded = true
|
40
|
+
rescue Fiddle::DLError
|
21
41
|
end
|
22
|
-
rescue
|
23
|
-
remove_const :PDCurses
|
24
42
|
end
|
25
43
|
|
26
44
|
class Window
|
@@ -30,18 +48,6 @@ module Textbringer
|
|
30
48
|
name.slice(/\AKEY_(.*)/, 1).downcase.intern
|
31
49
|
end
|
32
50
|
|
33
|
-
ALT_IS_FUNCTION_KEY =
|
34
|
-
/mswin32|mingw32/ =~ RUBY_PLATFORM && /PDCurses/ =~ Curses::VERSION
|
35
|
-
if ALT_IS_FUNCTION_KEY
|
36
|
-
KEY_OFFSET = 0xec00
|
37
|
-
ALT_0 = KEY_OFFSET + 0x97
|
38
|
-
ALT_9 = KEY_OFFSET + 0xa0
|
39
|
-
ALT_A = KEY_OFFSET + 0xa1
|
40
|
-
ALT_Z = KEY_OFFSET + 0xba
|
41
|
-
ALT_NUMBER_BASE = ALT_0 - ?0.ord
|
42
|
-
ALT_ALPHA_BASE = ALT_A - ?a.ord
|
43
|
-
end
|
44
|
-
|
45
51
|
@@windows = []
|
46
52
|
@@current = nil
|
47
53
|
@@echo_area = nil
|
@@ -267,12 +273,12 @@ module Textbringer
|
|
267
273
|
def read_char
|
268
274
|
key = get_char
|
269
275
|
if key.is_a?(Integer)
|
270
|
-
if
|
271
|
-
if ALT_0 <= key && key <= ALT_9
|
272
|
-
@key_buffer.push((key - ALT_NUMBER_BASE).chr)
|
276
|
+
if PDCurses.dll_loaded?
|
277
|
+
if PDCurses::ALT_0 <= key && key <= PDCurses::ALT_9
|
278
|
+
@key_buffer.push((key - PDCurses::ALT_NUMBER_BASE).chr)
|
273
279
|
return "\e"
|
274
|
-
elsif ALT_A <= key && key <= ALT_Z
|
275
|
-
@key_buffer.push((key - ALT_ALPHA_BASE).chr)
|
280
|
+
elsif PDCurses::ALT_A <= key && key <= PDCurses::ALT_Z
|
281
|
+
@key_buffer.push((key - PDCurses::ALT_ALPHA_BASE).chr)
|
276
282
|
return "\e"
|
277
283
|
end
|
278
284
|
end
|
@@ -292,6 +298,9 @@ module Textbringer
|
|
292
298
|
end
|
293
299
|
|
294
300
|
def wait_input(msecs)
|
301
|
+
unless @key_buffer.empty?
|
302
|
+
return @key_buffer.first
|
303
|
+
end
|
295
304
|
@window.timeout = msecs
|
296
305
|
begin
|
297
306
|
c = @window.get_char
|
@@ -305,6 +314,9 @@ module Textbringer
|
|
305
314
|
end
|
306
315
|
|
307
316
|
def has_input?
|
317
|
+
unless @key_buffer.empty?
|
318
|
+
return true
|
319
|
+
end
|
308
320
|
@window.nodelay = true
|
309
321
|
begin
|
310
322
|
c = @window.get_char
|
@@ -446,6 +458,9 @@ module Textbringer
|
|
446
458
|
end
|
447
459
|
|
448
460
|
def scroll_up
|
461
|
+
if @bottom_of_window.location == @buffer.point_max
|
462
|
+
raise EditorError, "End of buffer"
|
463
|
+
end
|
449
464
|
@buffer.point_to_mark(@bottom_of_window)
|
450
465
|
@buffer.previous_line
|
451
466
|
@buffer.beginning_of_line
|
@@ -453,6 +468,9 @@ module Textbringer
|
|
453
468
|
end
|
454
469
|
|
455
470
|
def scroll_down
|
471
|
+
if @top_of_window.location == @buffer.point_min
|
472
|
+
raise EditorError, "Beginning of buffer"
|
473
|
+
end
|
456
474
|
@buffer.point_to_mark(@top_of_window)
|
457
475
|
@buffer.next_line
|
458
476
|
@buffer.beginning_of_line
|
@@ -607,11 +625,11 @@ module Textbringer
|
|
607
625
|
|
608
626
|
def get_char
|
609
627
|
if @key_buffer.empty?
|
610
|
-
PDCurses.PDC_save_key_modifiers(1) if
|
628
|
+
PDCurses.PDC_save_key_modifiers(1) if PDCurses.dll_loaded?
|
611
629
|
begin
|
612
630
|
need_retry = false
|
613
631
|
key = @window.get_char
|
614
|
-
if
|
632
|
+
if PDCurses.dll_loaded?
|
615
633
|
mods = PDCurses.PDC_get_key_modifiers
|
616
634
|
if key.is_a?(String) && key.ascii_only?
|
617
635
|
if (mods & PDCurses::KEY_MODIFIER_CONTROL) != 0
|
data/textbringer.gemspec
CHANGED
@@ -25,9 +25,10 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_runtime_dependency "unicode-display_width", "~> 1.1"
|
26
26
|
spec.add_runtime_dependency "clipboard", "~> 1.1"
|
27
27
|
spec.add_runtime_dependency "ffi"
|
28
|
+
spec.add_runtime_dependency "editorconfig"
|
28
29
|
|
29
30
|
spec.add_development_dependency "bundler", "~> 1.11"
|
30
|
-
spec.add_development_dependency "rake", "~>
|
31
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
31
32
|
spec.add_development_dependency "test-unit"
|
32
33
|
spec.add_development_dependency "simplecov"
|
33
34
|
spec.add_development_dependency "codecov"
|
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
|
+
version: 0.1.7
|
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-02-
|
11
|
+
date: 2017-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: editorconfig
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: bundler
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +100,14 @@ dependencies:
|
|
86
100
|
requirements:
|
87
101
|
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
103
|
+
version: '12.0'
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
108
|
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
110
|
+
version: '12.0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: test-unit
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -201,6 +215,7 @@ executables:
|
|
201
215
|
extensions: []
|
202
216
|
extra_rdoc_files: []
|
203
217
|
files:
|
218
|
+
- ".editorconfig"
|
204
219
|
- ".gitignore"
|
205
220
|
- ".travis.yml"
|
206
221
|
- CHANGES.md
|
@@ -230,6 +245,8 @@ files:
|
|
230
245
|
- lib/textbringer/keymap.rb
|
231
246
|
- lib/textbringer/mode.rb
|
232
247
|
- lib/textbringer/modes/backtrace_mode.rb
|
248
|
+
- lib/textbringer/modes/c_mode.rb
|
249
|
+
- lib/textbringer/modes/completion_list_mode.rb
|
233
250
|
- lib/textbringer/modes/fundamental_mode.rb
|
234
251
|
- lib/textbringer/modes/programming_mode.rb
|
235
252
|
- lib/textbringer/modes/ruby_mode.rb
|