textbringer 25 → 27
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.
- checksums.yaml +4 -4
- data/README.ja.md +24 -0
- data/README.md +28 -0
- data/lib/textbringer/color.rb +46 -0
- data/lib/textbringer/commands/clipboard.rb +7 -4
- data/lib/textbringer/commands/misc.rb +68 -36
- data/lib/textbringer/face.rb +18 -0
- data/lib/textbringer/input_methods/skk_input_method.rb +1 -1
- data/lib/textbringer/keymap.rb +2 -0
- data/lib/textbringer/modes/dired_mode.rb +0 -1
- data/lib/textbringer/modes/ruby_mode.rb +49 -40
- data/lib/textbringer/themes/catppuccin.rb +53 -52
- data/lib/textbringer/themes/github.rb +17 -20
- data/lib/textbringer/themes/gruvbox.rb +34 -33
- data/lib/textbringer/themes/iceberg.rb +88 -0
- data/lib/textbringer/themes/kanagawa.rb +94 -0
- data/lib/textbringer/themes/molokai.rb +20 -22
- data/lib/textbringer/themes/sonokai.rb +22 -18
- data/lib/textbringer/themes/tokyonight.rb +3 -3
- data/lib/textbringer/utils.rb +16 -0
- data/lib/textbringer/version.rb +1 -1
- data/lib/textbringer/window.rb +4 -1
- data/screenshot.png +0 -0
- data/textbringer.gemspec +1 -2
- metadata +14 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be4c934800d0492229b1476d4541825533ff3e824490ad23ef331926ee8d6492
|
|
4
|
+
data.tar.gz: 9157e0ba963f1dd77eab7a50f929c91b1ae6a7689c1ad41cda22876c32d6c0fb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3f70f40322ad8fed8ef2044839e3df7fee67922b1cfe975283516cf3a10fac6566248d0a5fbcc98ef319155302105c0c37d9f30fa602f6a3b3b2069dbf5a1314
|
|
7
|
+
data.tar.gz: 6348a9ecddb8423d4fb07b8291dcda1ce7945cf049e997770347deb309ad8c3a507bfb6815a5db2c7f277677680c4023793cf9fd221ea96bd4ed60e5863e68e6
|
data/README.ja.md
CHANGED
|
@@ -58,6 +58,14 @@ Textbringerが依存するcurses.gemをインストールする前に、ncursesw
|
|
|
58
58
|
mod_meta_key = alt
|
|
59
59
|
mod_meta_mode = esc
|
|
60
60
|
|
|
61
|
+
### True color (24ビットカラー)
|
|
62
|
+
|
|
63
|
+
端末エミュレータがtrue colorに対応している場合、`TERM`に`xterm-direct`を設定すると24ビットカラーが有効になります。
|
|
64
|
+
|
|
65
|
+
$ TERM=xterm-direct txtb
|
|
66
|
+
|
|
67
|
+
テーマで指定されたhex色が256色パレットに近似されず、そのまま表示されるようになります。
|
|
68
|
+
|
|
61
69
|
### 東アジアの曖昧な文字幅
|
|
62
70
|
|
|
63
71
|
[曖昧な文字](http://unicode.org/reports/tr11/#Ambiguous)を全角扱いするには、以下の設定を~/.textbringer.rbに記述してください。
|
|
@@ -91,6 +99,22 @@ xterm、 mlterm、screenにはそれぞれ独自の設定項目があります
|
|
|
91
99
|
|
|
92
100
|
cjkwidth on
|
|
93
101
|
|
|
102
|
+
## テーマ
|
|
103
|
+
|
|
104
|
+
`Alt+x load_theme RET` で[textbringer/themes](lib/textbringer/themes)または~/.textbringer/themes内のテーマを読み込むことができます。
|
|
105
|
+
|
|
106
|
+
~/.textbringer.rbでテーマを設定することもできます。
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
load_theme "catppuccin"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
テーマが独自の背景色を設定している場合に、端末のデフォルト背景色を使いたいときは`load_theme`の後に以下を追加してください。
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
set_background_color "default"
|
|
116
|
+
```
|
|
117
|
+
|
|
94
118
|
## プラグイン
|
|
95
119
|
|
|
96
120
|
* [Mournmail](https://github.com/shugo/mournmail): 電子メールクライアント
|
data/README.md
CHANGED
|
@@ -31,6 +31,10 @@ Install ncursesw before installing curses.gem, on which textbringer depends.
|
|
|
31
31
|
$ sudo apt-get install libncursesw5-dev
|
|
32
32
|
$ gem install curses
|
|
33
33
|
|
|
34
|
+
You need ffi to use clipboard commands on Windows.
|
|
35
|
+
|
|
36
|
+
$ gem install ffi
|
|
37
|
+
|
|
34
38
|
## Usage
|
|
35
39
|
|
|
36
40
|
$ txtb
|
|
@@ -60,6 +64,14 @@ Add the following lines to ~/.mlterm/main.
|
|
|
60
64
|
mod_meta_key = alt
|
|
61
65
|
mod_meta_mode = esc
|
|
62
66
|
|
|
67
|
+
### True color (24-bit color)
|
|
68
|
+
|
|
69
|
+
If your terminal emulator supports true color, set `TERM` to `xterm-direct` to enable 24-bit color.
|
|
70
|
+
|
|
71
|
+
$ TERM=xterm-direct txtb
|
|
72
|
+
|
|
73
|
+
This allows themes to display their exact hex colors instead of approximating to the 256-color palette.
|
|
74
|
+
|
|
63
75
|
### East asian ambiguous width
|
|
64
76
|
|
|
65
77
|
Add the following line to ~/.textbringer.rb to treat
|
|
@@ -103,6 +115,22 @@ Add the following line to ~/.screenrc.
|
|
|
103
115
|
* [textbringer-presentation](https://github.com/shugo/textbringer-presentation): a presentation tool
|
|
104
116
|
* [textbringer-ghost_text](https://github.com/shugo/textbringer-ghost_text): a [GhostText](https://github.com/fregante/GhostText) plugin
|
|
105
117
|
|
|
118
|
+
## Themes
|
|
119
|
+
|
|
120
|
+
Type `Alt+x load_theme RET` to load a theme from [textbringer/themes](lib/textbringer/themes) or ~/.textbringer/themes.
|
|
121
|
+
|
|
122
|
+
Themes can also be loaded in ~/.textbringer.rb.
|
|
123
|
+
|
|
124
|
+
```ruby
|
|
125
|
+
load_theme "catppuccin"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
If a theme sets its own background color but you prefer to use the terminal's default background, add the following after `load_theme`:
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
set_background_color "default"
|
|
132
|
+
```
|
|
133
|
+
|
|
106
134
|
## Development
|
|
107
135
|
|
|
108
136
|
After checking out the repo, run `bundle install` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/textbringer/color.rb
CHANGED
|
@@ -22,6 +22,30 @@ module Textbringer
|
|
|
22
22
|
"brightwhite" => 15
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
DIRECT_COLOR_THRESHOLD = 256 * 256 * 256
|
|
26
|
+
|
|
27
|
+
# Canonical RGB values for basic ANSI colors (xterm defaults),
|
|
28
|
+
# packed as 0xRRGGBB for use in direct color mode.
|
|
29
|
+
BASIC_COLORS_RGB = {
|
|
30
|
+
"default" => -1,
|
|
31
|
+
"black" => 0x000000,
|
|
32
|
+
"red" => 0xCD0000,
|
|
33
|
+
"green" => 0x00CD00,
|
|
34
|
+
"yellow" => 0xCDCD00,
|
|
35
|
+
"blue" => 0x0000EE,
|
|
36
|
+
"magenta" => 0xCD00CD,
|
|
37
|
+
"cyan" => 0x00CDCD,
|
|
38
|
+
"white" => 0xE5E5E5,
|
|
39
|
+
"brightblack" => 0x7F7F7F,
|
|
40
|
+
"brightred" => 0xFF0000,
|
|
41
|
+
"brightgreen" => 0x00FF00,
|
|
42
|
+
"brightyellow" => 0xFFFF00,
|
|
43
|
+
"brightblue" => 0x5C5CFF,
|
|
44
|
+
"brightmagenta" => 0xFF00FF,
|
|
45
|
+
"brightcyan" => 0x00FFFF,
|
|
46
|
+
"brightwhite" => 0xFFFFFF
|
|
47
|
+
}
|
|
48
|
+
|
|
25
49
|
RGBColor = Struct.new(:r, :g, :b, :number)
|
|
26
50
|
|
|
27
51
|
ADDITIONAL_COLORS = []
|
|
@@ -46,10 +70,17 @@ module Textbringer
|
|
|
46
70
|
end
|
|
47
71
|
end
|
|
48
72
|
|
|
73
|
+
def self.direct_color?
|
|
74
|
+
Window.colors >= DIRECT_COLOR_THRESHOLD
|
|
75
|
+
end
|
|
76
|
+
|
|
49
77
|
def self.find_color_number(name)
|
|
50
78
|
if name.is_a?(Integer)
|
|
51
79
|
return name
|
|
52
80
|
end
|
|
81
|
+
if direct_color?
|
|
82
|
+
return find_direct_color(name)
|
|
83
|
+
end
|
|
53
84
|
case name
|
|
54
85
|
when /\A\#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})\z/
|
|
55
86
|
r = $1.to_i(16)
|
|
@@ -65,5 +96,20 @@ module Textbringer
|
|
|
65
96
|
BASIC_COLORS[name]
|
|
66
97
|
end
|
|
67
98
|
end
|
|
99
|
+
|
|
100
|
+
def self.find_direct_color(name)
|
|
101
|
+
case name
|
|
102
|
+
when /\A\#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})\z/
|
|
103
|
+
r = $1.to_i(16)
|
|
104
|
+
g = $2.to_i(16)
|
|
105
|
+
b = $3.to_i(16)
|
|
106
|
+
(r << 16) | (g << 8) | b
|
|
107
|
+
else
|
|
108
|
+
unless BASIC_COLORS_RGB.key?(name)
|
|
109
|
+
raise EditorError, "No such color: #{name}"
|
|
110
|
+
end
|
|
111
|
+
BASIC_COLORS_RGB[name]
|
|
112
|
+
end
|
|
113
|
+
end
|
|
68
114
|
end
|
|
69
115
|
end
|
|
@@ -2,12 +2,15 @@ module Clipboard
|
|
|
2
2
|
@implementation = nil
|
|
3
3
|
end
|
|
4
4
|
|
|
5
|
-
require "clipboard"
|
|
6
|
-
|
|
7
5
|
module Textbringer
|
|
8
6
|
module Commands
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
begin
|
|
8
|
+
require "clipboard"
|
|
9
|
+
CLIPBOARD_AVAILABLE =
|
|
10
|
+
Clipboard.implementation.name != "Clipboard::File"
|
|
11
|
+
rescue LoadError
|
|
12
|
+
CLIPBOARD_AVAILABLE = false
|
|
13
|
+
end
|
|
11
14
|
|
|
12
15
|
if CLIPBOARD_AVAILABLE
|
|
13
16
|
GLOBAL_MAP.define_key("\M-w", :clipboard_copy_region)
|
|
@@ -291,46 +291,48 @@ module Textbringer
|
|
|
291
291
|
if CONFIG[:shell_file_name]
|
|
292
292
|
cmd = [CONFIG[:shell_file_name], CONFIG[:shell_command_switch], cmd]
|
|
293
293
|
end
|
|
294
|
-
|
|
295
|
-
input
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
294
|
+
with_clean_env do |env|
|
|
295
|
+
Open3.popen3(env, *cmd, opts) do |input, output, error, wait_thread|
|
|
296
|
+
input.close
|
|
297
|
+
catch(:finish) do
|
|
298
|
+
loop do
|
|
299
|
+
rs, = IO.select([output, error], nil, nil, 0.5)
|
|
300
|
+
Window.redisplay
|
|
301
|
+
rs&.each do |r|
|
|
302
|
+
begin
|
|
303
|
+
s = r.read_nonblock(1024).force_encoding("utf-8").
|
|
304
|
+
scrub("\u{3013}").gsub(/\r\n/, "\n")
|
|
305
|
+
buffer.insert(s)
|
|
306
|
+
Window.redisplay
|
|
307
|
+
rescue EOFError
|
|
308
|
+
throw(:finish) if output.eof? && error.eof?
|
|
309
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
|
|
310
|
+
Window.redisplay
|
|
311
|
+
next
|
|
312
|
+
end
|
|
311
313
|
end
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
314
|
+
if received_keyboard_quit?
|
|
315
|
+
if signals.empty?
|
|
316
|
+
keyboard_quit
|
|
317
|
+
else
|
|
318
|
+
sig = signals.shift
|
|
319
|
+
pid = wait_thread.pid
|
|
320
|
+
pid = -pid if /mswin32|mingw32/ !~ RUBY_PLATFORM
|
|
321
|
+
message("Send #{sig} to #{pid}")
|
|
322
|
+
Process.kill(sig, pid)
|
|
323
|
+
end
|
|
322
324
|
end
|
|
323
325
|
end
|
|
324
326
|
end
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
327
|
+
status = wait_thread.value
|
|
328
|
+
pid = status.pid
|
|
329
|
+
if status.exited?
|
|
330
|
+
code = status.exitstatus
|
|
331
|
+
message("Process #{pid} exited with status code #{code}")
|
|
332
|
+
elsif status.signaled?
|
|
333
|
+
signame = Signal.signame(status.termsig)
|
|
334
|
+
message("Process #{pid} was killed by #{signame}")
|
|
335
|
+
end
|
|
334
336
|
end
|
|
335
337
|
end
|
|
336
338
|
ensure
|
|
@@ -352,6 +354,36 @@ module Textbringer
|
|
|
352
354
|
RubyVM::MJIT.resume
|
|
353
355
|
end
|
|
354
356
|
|
|
357
|
+
define_command(:forward_page,
|
|
358
|
+
doc: "Move forward to page boundary.") do
|
|
359
|
+
|n = number_prefix_arg|
|
|
360
|
+
buffer = Buffer.current
|
|
361
|
+
n.times do
|
|
362
|
+
unless buffer.re_search_forward(/^\f/, raise_error: false)
|
|
363
|
+
buffer.end_of_buffer
|
|
364
|
+
break
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
define_command(:backward_page,
|
|
370
|
+
doc: "Move backward to page boundary.") do
|
|
371
|
+
|n = number_prefix_arg|
|
|
372
|
+
buffer = Buffer.current
|
|
373
|
+
n.times do
|
|
374
|
+
if buffer.point == 0
|
|
375
|
+
break
|
|
376
|
+
end
|
|
377
|
+
buffer.backward_char
|
|
378
|
+
if buffer.re_search_backward(/^\f/, raise_error: false)
|
|
379
|
+
buffer.forward_char
|
|
380
|
+
else
|
|
381
|
+
buffer.beginning_of_buffer
|
|
382
|
+
break
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
355
387
|
define_command(:what_cursor_position,
|
|
356
388
|
doc: "Print info on cursor position.") do
|
|
357
389
|
|arg = current_prefix_arg|
|
data/lib/textbringer/face.rb
CHANGED
|
@@ -7,6 +7,8 @@ module Textbringer
|
|
|
7
7
|
@@face_table = {}
|
|
8
8
|
@@next_color_pair = 1
|
|
9
9
|
@@color_pair_cache = {}
|
|
10
|
+
@@default_foreground = -1
|
|
11
|
+
@@default_background = -1
|
|
10
12
|
|
|
11
13
|
def self.[](name)
|
|
12
14
|
@@face_table[name]
|
|
@@ -26,6 +28,20 @@ module Textbringer
|
|
|
26
28
|
@@face_table.delete(name)
|
|
27
29
|
end
|
|
28
30
|
|
|
31
|
+
# Set the concrete color numbers substituted for -1 (default color).
|
|
32
|
+
# PDCurses resolves -1 when init_pair is called and
|
|
33
|
+
# assume_default_colors only affects color pair 0, so faces must be
|
|
34
|
+
# re-resolved with concrete colors to get the new default colors.
|
|
35
|
+
def self.set_default_color_numbers(fg_num, bg_num)
|
|
36
|
+
return if fg_num == @@default_foreground &&
|
|
37
|
+
bg_num == @@default_background
|
|
38
|
+
@@default_foreground = fg_num
|
|
39
|
+
@@default_background = bg_num
|
|
40
|
+
@@face_table.each_value do |face|
|
|
41
|
+
face.send(:resolve_inheritance)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
29
45
|
def initialize(name, **opts)
|
|
30
46
|
@name = name
|
|
31
47
|
update(**opts)
|
|
@@ -68,6 +84,8 @@ module Textbringer
|
|
|
68
84
|
@reverse = @explicit_reverse.nil? ? (parent&.instance_variable_get(:@reverse) || false) : @explicit_reverse
|
|
69
85
|
fg_num = Color[@foreground]
|
|
70
86
|
bg_num = Color[@background]
|
|
87
|
+
fg_num = @@default_foreground if fg_num == -1
|
|
88
|
+
bg_num = @@default_background if bg_num == -1
|
|
71
89
|
key = [fg_num, bg_num]
|
|
72
90
|
unless @@color_pair_cache.key?(key)
|
|
73
91
|
@@color_pair_cache[key] = @@next_color_pair
|
data/lib/textbringer/keymap.rb
CHANGED
|
@@ -167,6 +167,8 @@ module Textbringer
|
|
|
167
167
|
GLOBAL_MAP.define_key(:npage, :scroll_up)
|
|
168
168
|
GLOBAL_MAP.define_key("\M-v", :scroll_down)
|
|
169
169
|
GLOBAL_MAP.define_key(:ppage, :scroll_down)
|
|
170
|
+
GLOBAL_MAP.define_key("\C-x]", :forward_page)
|
|
171
|
+
GLOBAL_MAP.define_key("\C-x[", :backward_page)
|
|
170
172
|
GLOBAL_MAP.define_key("\C-x0", :delete_window)
|
|
171
173
|
GLOBAL_MAP.define_key("\C-x1", :delete_other_windows)
|
|
172
174
|
GLOBAL_MAP.define_key("\C-x2", :split_window)
|
|
@@ -188,7 +188,6 @@ module Textbringer
|
|
|
188
188
|
doc: "Delete files flagged for deletion.") do
|
|
189
189
|
files = collect_flagged_files
|
|
190
190
|
return if files.empty?
|
|
191
|
-
list = files.map { |f| " #{f}" }.join("\n")
|
|
192
191
|
if yes_or_no?("Delete these files?")
|
|
193
192
|
files.each do |name|
|
|
194
193
|
next if name == "." || name == ".."
|
|
@@ -8,7 +8,7 @@ module Textbringer
|
|
|
8
8
|
class RubyMode < ProgrammingMode
|
|
9
9
|
self.file_name_pattern =
|
|
10
10
|
/\A(?:.*\.(?:rb|ru|rake|thor|jbuilder|gemspec|podspec)|
|
|
11
|
-
(?:Gem|Rake|Cap|Thor|Vagrant|Guard|Pod)file)\z/ix
|
|
11
|
+
(?:Gem|Rake|Cap|Thor|Vagrant|Guard|Pod)file|.irbrc)\z/ix
|
|
12
12
|
self.interpreter_name_pattern = /ruby/i
|
|
13
13
|
|
|
14
14
|
def comment_start
|
|
@@ -22,18 +22,13 @@ module Textbringer
|
|
|
22
22
|
@prism_version = nil
|
|
23
23
|
@prism_tokens = nil
|
|
24
24
|
@prism_ast = nil
|
|
25
|
-
@
|
|
25
|
+
@prism_method_name_locs = nil
|
|
26
26
|
@literal_levels = nil
|
|
27
27
|
@literal_levels_version = nil
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def forward_definition(n = number_prefix_arg || 1)
|
|
31
|
-
|
|
32
|
-
tokens = @prism_tokens.filter_map { |token, _state|
|
|
33
|
-
type = token.type
|
|
34
|
-
next if type == :EOF
|
|
35
|
-
[token.location.start_line, type]
|
|
36
|
-
}
|
|
31
|
+
tokens = filter_prism_tokens_line_and_type
|
|
37
32
|
@buffer.forward_line
|
|
38
33
|
n.times do |i|
|
|
39
34
|
tokens = tokens.drop_while { |l, type|
|
|
@@ -54,12 +49,7 @@ module Textbringer
|
|
|
54
49
|
end
|
|
55
50
|
|
|
56
51
|
def backward_definition(n = number_prefix_arg || 1)
|
|
57
|
-
|
|
58
|
-
tokens = @prism_tokens.filter_map { |token, _state|
|
|
59
|
-
type = token.type
|
|
60
|
-
next if type == :EOF
|
|
61
|
-
[token.location.start_line, type]
|
|
62
|
-
}.reverse
|
|
52
|
+
tokens = filter_prism_tokens_line_and_type.reverse
|
|
63
53
|
@buffer.beginning_of_line
|
|
64
54
|
n.times do |i|
|
|
65
55
|
tokens = tokens.drop_while { |l, type|
|
|
@@ -120,12 +110,11 @@ module Textbringer
|
|
|
120
110
|
def highlight(ctx)
|
|
121
111
|
ensure_prism_tokens
|
|
122
112
|
return unless @prism_tokens
|
|
123
|
-
|
|
113
|
+
ensure_method_name_locs
|
|
124
114
|
base_pos = ctx.buffer.point_min
|
|
125
115
|
hl_start = ctx.highlight_start
|
|
126
116
|
hl_end = ctx.highlight_end
|
|
127
117
|
in_symbol = false
|
|
128
|
-
after_def = false
|
|
129
118
|
after_class_or_module = false
|
|
130
119
|
@prism_tokens.each do |token_info|
|
|
131
120
|
token = token_info[0]
|
|
@@ -139,26 +128,18 @@ module Textbringer
|
|
|
139
128
|
face_name = PRISM_TOKEN_FACES[type]
|
|
140
129
|
if in_symbol
|
|
141
130
|
face_name = :string if face_name.nil? || face_name == :constant ||
|
|
142
|
-
face_name == :operator
|
|
143
|
-
elsif
|
|
144
|
-
face_name = :function_name
|
|
145
|
-
type == :CONSTANT || type == :METHOD_NAME ||
|
|
146
|
-
PRISM_TOKEN_FACES[type] == :operator
|
|
131
|
+
face_name == :keyword || face_name == :operator
|
|
132
|
+
elsif @prism_method_name_locs.key?(offset)
|
|
133
|
+
face_name = :function_name
|
|
147
134
|
elsif face_name == :constant &&
|
|
148
135
|
(after_class_or_module || token.location.slice.match?(/\p{Lower}/))
|
|
149
136
|
face_name = :type
|
|
150
|
-
elsif @prism_method_call_locs.key?(offset)
|
|
151
|
-
face_name = :function_name
|
|
152
137
|
end
|
|
153
138
|
if face_name && (face = Face[face_name])
|
|
154
139
|
ctx.highlight(pos, pos_end, face)
|
|
155
140
|
end
|
|
156
141
|
end
|
|
157
142
|
in_symbol = type == :SYMBOL_BEGIN
|
|
158
|
-
after_def = type == :KEYWORD_DEF ||
|
|
159
|
-
(after_def && (type == :KEYWORD_SELF || type == :DOT ||
|
|
160
|
-
type == :NEWLINE || type == :IGNORED_NEWLINE ||
|
|
161
|
-
type == :COMMENT))
|
|
162
143
|
after_class_or_module = (type == :KEYWORD_CLASS || type == :KEYWORD_MODULE) ||
|
|
163
144
|
(after_class_or_module && !(type == :NEWLINE || type == :SEMICOLON))
|
|
164
145
|
end
|
|
@@ -199,6 +180,9 @@ module Textbringer
|
|
|
199
180
|
# Strings and string-like
|
|
200
181
|
STRING_BEGIN: :string, STRING_CONTENT: :string, STRING_END: :string,
|
|
201
182
|
SYMBOL_BEGIN: :string, REGEXP_BEGIN: :string, REGEXP_END: :string,
|
|
183
|
+
PERCENT_LOWER_I: :string, PERCENT_UPPER_I: :string,
|
|
184
|
+
PERCENT_LOWER_W: :string, PERCENT_UPPER_W: :string,
|
|
185
|
+
PERCENT_LOWER_X: :string,
|
|
202
186
|
HEREDOC_START: :string, HEREDOC_END: :string,
|
|
203
187
|
LABEL: :property,
|
|
204
188
|
|
|
@@ -273,6 +257,8 @@ module Textbringer
|
|
|
273
257
|
EQUAL_GREATER
|
|
274
258
|
].to_set
|
|
275
259
|
|
|
260
|
+
OPERATORS = %i(!= !~ =~ == === <=> > >= < <= & | ^ >> << - + % / * ** -@ +@ ~ ! [] []=)
|
|
261
|
+
|
|
276
262
|
BLOCK_END = {
|
|
277
263
|
EMBEXPR_BEGIN: :EMBEXPR_END,
|
|
278
264
|
BRACE_LEFT: :BRACE_RIGHT,
|
|
@@ -489,6 +475,15 @@ module Textbringer
|
|
|
489
475
|
@literal_levels[i][1] > 0
|
|
490
476
|
end
|
|
491
477
|
|
|
478
|
+
def filter_prism_tokens_line_and_type
|
|
479
|
+
ensure_prism_tokens
|
|
480
|
+
@prism_tokens.filter_map { |token, _state|
|
|
481
|
+
type = token.type
|
|
482
|
+
next if type == :EOF
|
|
483
|
+
[token.location.start_line, type]
|
|
484
|
+
}
|
|
485
|
+
end
|
|
486
|
+
|
|
492
487
|
def ensure_prism_tokens
|
|
493
488
|
return if @prism_version == @buffer.version
|
|
494
489
|
source = @buffer.to_s
|
|
@@ -499,27 +494,41 @@ module Textbringer
|
|
|
499
494
|
@prism_ast = nil
|
|
500
495
|
@prism_tokens = []
|
|
501
496
|
end
|
|
502
|
-
@
|
|
497
|
+
@prism_method_name_locs = nil
|
|
503
498
|
@prism_version = @buffer.version
|
|
504
499
|
@literal_levels_version = nil
|
|
505
500
|
end
|
|
506
501
|
|
|
507
|
-
def
|
|
508
|
-
return if @
|
|
509
|
-
@
|
|
502
|
+
def ensure_method_name_locs
|
|
503
|
+
return if @prism_method_name_locs
|
|
504
|
+
@prism_method_name_locs = {}
|
|
510
505
|
return unless @prism_ast
|
|
511
|
-
|
|
506
|
+
collect_method_name_locs(@prism_ast)
|
|
512
507
|
end
|
|
513
508
|
|
|
514
|
-
def
|
|
515
|
-
if node.
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
509
|
+
def collect_method_name_locs(node)
|
|
510
|
+
if node.type == :def_node
|
|
511
|
+
@prism_method_name_locs[node.name_loc.start_offset] = true
|
|
512
|
+
elsif node.type == :alias_method_node
|
|
513
|
+
add_alias_method_name_locs(node.new_name)
|
|
514
|
+
add_alias_method_name_locs(node.old_name)
|
|
515
|
+
elsif ((node.type == :call_node &&
|
|
516
|
+
!(node.call_operator_loc.nil? && OPERATORS.include?(node.name)) && # exclude operators
|
|
517
|
+
!((node.call_operator_loc.nil? || node.call_operator_loc.slice == "::") && # exclude constants
|
|
518
|
+
/\A\p{Upper}/.match?(node.name))) ||
|
|
519
|
+
node.type == :call_operator_write_node ||
|
|
520
|
+
node.type == :call_and_write_node ||
|
|
521
|
+
node.type == :call_or_write_node) &&
|
|
522
|
+
node.message_loc
|
|
523
|
+
@prism_method_name_locs[node.message_loc.start_offset] = true
|
|
524
|
+
end
|
|
525
|
+
node.compact_child_nodes.each { |child| collect_method_name_locs(child) }
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
def add_alias_method_name_locs(node)
|
|
529
|
+
if node.type == :symbol_node && node.opening_loc.nil?
|
|
530
|
+
@prism_method_name_locs[node.value_loc.start_offset] = true
|
|
521
531
|
end
|
|
522
|
-
node.compact_child_nodes.each { |child| collect_method_call_locs(child) }
|
|
523
532
|
end
|
|
524
533
|
|
|
525
534
|
def ensure_literal_levels
|