8000 Merge pull request #112 from aycabta/implement-F-and-T-in-vi-normal-mode · ruby/reline@298e279 · GitHub
[go: up one dir, main page]

Skip to content

Commit 298e279

Browse files
authored
Merge pull request #112 from aycabta/implement-F-and-T-in-vi-normal-mode
Implement vi_prev_char and vi_to_prev_char
2 parents c387fb3 + 0ad3ee6 commit 298e279

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

lib/reline/line_editor.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,54 @@ def finish
21312131
@waiting_proc = nil
21322132
end
21332133

2134+
private def vi_prev_char(key, arg: 1)
2135+
@waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg) }
2136+
end
2137+
2138+
private def vi_to_prev_char(key, arg: 1)
2139+
@waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg, true) }
2140+
end
2141+
2142+
private def search_prev_char(key, arg, need_next_char = false)
2143+
if key.instance_of?(String)
2144+
inputed_char = key
2145+
else
2146+
inputed_char = key.chr
2147+
end
2148+
prev_total = nil
2149+
total = nil
2150+
found = false
2151+
@line.byteslice(0..@byte_pointer).grapheme_clusters.reverse_each do |mbchar|
2152+
# total has [byte_size, cursor]
2153+
unless total
2154+
# skip cursor point
2155+
width = Reline::Unicode.get_mbchar_width(mbchar)
2156+
total = [mbchar.bytesize, width]
2157+
else
2158+
if inputed_char == mbchar
2159+
arg -= 1
2160+
if arg.zero?
2161+
found = true
2162+
break
2163+
end
2164+
end
2165+
width = Reline::Unicode.get_mbchar_width(mbchar)
2166+
prev_total = total
2167+
total = [total.first + mbchar.bytesize, total.last + width]
2168+
end
2169+
end
2170+
if not need_next_char and found and total
2171+
byte_size, width = total
2172+
@byte_pointer -= byte_size
2173+
@cursor -= width
2174+
elsif need_next_char and found and prev_total
2175+
byte_size, width = prev_total
2176+
@byte_pointer -= byte_size
2177+
@cursor -= width
2178+
end
2179+
@waiting_proc = nil
2180+
end
2181+
21342182
private def vi_join_lines(key, arg: 1)
21352183
if @is_multiline and @buffer_of_lines.size > @line_index + 1
21362184
@cursor = calculate_width(@line)

test/reline/test_key_actor_vi.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,42 @@ def test_vi_to_next_char
651651
assert_cursor_max(6)
652652
end
653653

654+
def test_vi_prev_char
655+
input_keys("abcdef\C-[")
656+
assert_line('abcdef')
657+
assert_byte_pointer_size('abcde')
658+
assert_cursor(5)
659+
assert_cursor_max(6)
660+
input_keys('Fz')
661+
assert_line('abcdef')
662+
assert_byte_pointer_size('abcde')
663+
assert_cursor(5)
664+
assert_cursor_max(6)
665+
input_keys('Fa')
666+
assert_line('abcdef')
667+
assert_byte_pointer_size('')
668+
assert_cursor(0)
669+
assert_cursor_max(6)
670+
end
671+
672+
def test_vi_to_prev_char
673+
input_keys("abcdef\C-[")
674+
assert_line('abcdef')
675+
assert_byte_pointer_size('abcde')
676+
assert_cursor(5)
677+
assert_cursor_max(6)
678+
input_keys('Tz')
679+
assert_line('abcdef')
680+
assert_byte_pointer_size('abcde')
681+
assert_cursor(5)
682+
assert_cursor_max(6)
683+
input_keys('Ta')
684+
assert_line('abcdef')
685+
assert_byte_pointer_size('a')
686+
assert_cursor(1)
687+
assert_cursor_max(6)
688+
end
689+
654690
def test_vi_delete_next_char
655691
input_keys("abc\C-[h")
656692
assert_byte_pointer_size('a')

0 commit comments

Comments
 (0)
0