Implement transpose-words
This commit is contained in:
parent
c9b74f9fd9
commit
4b7213a85a
@ -489,7 +489,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
|||||||
# 243 M-s
|
# 243 M-s
|
||||||
:ed_unassigned,
|
:ed_unassigned,
|
||||||
# 244 M-t
|
# 244 M-t
|
||||||
:ed_unassigned,
|
:ed_transpose_words,
|
||||||
# 245 M-u
|
# 245 M-u
|
||||||
:em_upper_case,
|
:em_upper_case,
|
||||||
# 246 M-v
|
# 246 M-v
|
||||||
|
@ -1406,6 +1406,19 @@ class Reline::LineEditor
|
|||||||
end
|
end
|
||||||
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)
|
private def em_capitol_case(key)
|
||||||
if @line.bytesize > @byte_pointer
|
if @line.bytesize > @byte_pointer
|
||||||
byte_size, _, new_str = Reline::Unicode.em_forward_word_with_capitalization(@line, @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]
|
[byte_size, width]
|
||||||
end
|
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)
|
def self.vi_big_forward_word(line, byte_pointer)
|
||||||
width = 0
|
width = 0
|
||||||
byte_size = 0
|
byte_size = 0
|
||||||
|
@ -819,6 +819,48 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
|
|||||||
assert_line("か\u3099あさ")
|
assert_line("か\u3099あさ")
|
||||||
end
|
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
|
def test_ed_digit
|
||||||
input_keys('0123')
|
input_keys('0123')
|
||||||
assert_byte_pointer_size('0123')
|
assert_byte_pointer_size('0123')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user