mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Implement transpose-words
This commit is contained in:
parent
c9b74f9fd9
commit
4b7213a85a
4 changed files with 157 additions and 1 deletions
|
@ -489,7 +489,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|||
# 243 M-s
|
||||
:ed_unassigned,
|
||||
# 244 M-t
|
||||
:ed_unassigned,
|
||||
:ed_transpose_words,
|
||||
# 245 M-u
|
||||
:em_upper_case,
|
||||
# 246 M-v
|
||||
|
|
|
@ -1406,6 +1406,19 @@ class Reline::LineEditor
|
|||
end
|
||||
end
|
||||
|
||||
private def ed_transpose_words(key)
|
||||
left_word_start, middle_start, right_word_start, after_start = Reline::Unicode.ed_transpose_words(@line, @byte_pointer)
|
||||
before = @line.byteslice(0, left_word_start)
|
||||
left_word = @line.byteslice(left_word_start, middle_start - left_word_start)
|
||||
middle = @line.byteslice(middle_start, right_word_start - middle_start)
|
||||
right_word = @line.byteslice(right_word_start, after_start - right_word_start)
|
||||
after = @line.byteslice(after_start, @line.bytesize - after_start)
|
||||
@line = before + right_word + middle + left_word + after
|
||||
from_head_to_left_word = before + right_word + middle + left_word
|
||||
@byte_pointer = from_head_to_left_word.bytesize
|
||||
@cursor = calculate_width(from_head_to_left_word)
|
||||
end
|
||||
|
||||
private def em_capitol_case(key)
|
||||
if @line.bytesize > @byte_pointer
|
||||
byte_size, _, new_str = Reline::Unicode.em_forward_word_with_capitalization(@line, @byte_pointer)
|
||||
|
|
|
@ -188,6 +188,107 @@ class Reline::Unicode
|
|||
[byte_size, width]
|
||||
end
|
||||
|
||||
def self.ed_transpose_words(line, byte_pointer)
|
||||
right_word_start = nil
|
||||
size = get_next_mbchar_size(line, byte_pointer)
|
||||
mbchar = line.byteslice(byte_pointer, size)
|
||||
if size.zero?
|
||||
# ' aaa bbb [cursor]'
|
||||
byte_size = 0
|
||||
while 0 < (byte_pointer + byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
|
||||
byte_size -= size
|
||||
end
|
||||
while 0 < (byte_pointer + byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
byte_size -= size
|
||||
end
|
||||
right_word_start = byte_pointer + byte_size
|
||||
byte_size = 0
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
byte_size += size
|
||||
end
|
||||
after_start = byte_pointer + byte_size
|
||||
elsif mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
|
||||
# ' aaa bb[cursor]b'
|
||||
byte_size = 0
|
||||
while 0 < (byte_pointer + byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
byte_size -= size
|
||||
end
|
||||
right_word_start = byte_pointer + byte_size
|
||||
byte_size = 0
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
byte_size += size
|
||||
end
|
||||
after_start = byte_pointer + byte_size
|
||||
else
|
||||
byte_size = 0
|
||||
while (line.bytesize - 1) > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
|
||||
byte_size += size
|
||||
end
|
||||
if (byte_pointer + byte_size) == (line.bytesize - 1)
|
||||
# ' aaa bbb [cursor] '
|
||||
after_start = line.bytesize
|
||||
while 0 < (byte_pointer + byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
|
||||
byte_size -= size
|
||||
end
|
||||
while 0 < (byte_pointer + byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
byte_size -= size
|
||||
end
|
||||
right_word_start = byte_pointer + byte_size
|
||||
else
|
||||
# ' aaa [cursor] bbb '
|
||||
right_word_start = byte_pointer + byte_size
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
byte_size += size
|
||||
end
|
||||
after_start = byte_pointer + byte_size
|
||||
end
|
||||
end
|
||||
byte_size = right_word_start - byte_pointer
|
||||
while 0 < (byte_pointer + byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
|
||||
byte_size -= size
|
||||
end
|
||||
middle_start = byte_pointer + byte_size
|
||||
byte_size = middle_start - byte_pointer
|
||||
while 0 < (byte_pointer + byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
byte_size -= size
|
||||
end
|
||||
left_word_start = byte_pointer + byte_size
|
||||
[left_word_start, middle_start, right_word_start, after_start]
|
||||
end
|
||||
|
||||
def self.vi_big_forward_word(line, byte_pointer)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
|
|
|
@ -819,6 +819,48 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
|
|||
assert_line("か\u3099あさ")
|
||||
end
|
||||
|
||||
def test_ed_transpose_words
|
||||
input_keys('abc def')
|
||||
assert_line('abc def')
|
||||
assert_byte_pointer_size('abc def')
|
||||
assert_cursor(7)
|
||||
assert_cursor_max(7)
|
||||
input_keys("\M-t", false)
|
||||
assert_line('def abc')
|
||||
assert_byte_pointer_size('def abc')
|
||||
assert_cursor(7)
|
||||
assert_cursor_max(7)
|
||||
input_keys("\C-a\C-k", false)
|
||||
input_keys(' abc def ')
|
||||
input_keys("\C-b" * 4, false)
|
||||
assert_line(' abc def ')
|
||||
assert_byte_pointer_size(' abc de')
|
||||
assert_cursor(8)
|
||||
assert_cursor_max(12)
|
||||
input_keys("\M-t", false)
|
||||
assert_line(' def abc ')
|
||||
assert_byte_pointer_size(' def abc')
|
||||
assert_cursor(9)
|
||||
assert_cursor_max(12)
|
||||
input_keys("\C-a\C-k", false)
|
||||
input_keys(' abc def ')
|
||||
input_keys("\C-b" * 6, false)
|
||||
assert_line(' abc def ')
|
||||
assert_byte_pointer_size(' abc ')
|
||||
assert_cursor(6)
|
||||
assert_cursor_max(12)
|
||||
input_keys("\M-t", false)
|
||||
assert_line(' def abc ')
|
||||
assert_byte_pointer_size(' def abc')
|
||||
assert_cursor(9)
|
||||
assert_cursor_max(12)
|
||||
input_keys("\M-t", false)
|
||||
assert_line(' abc def')
|
||||
assert_byte_pointer_size(' abc def')
|
||||
assert_cursor(12)
|
||||
assert_cursor_max(12)
|
||||
end
|
||||
|
||||
def test_ed_digit
|
||||
input_keys('0123')
|
||||
assert_byte_pointer_size('0123')
|
||||
|
|
Loading…
Reference in a new issue