diff options
author | aycabta <aycabta@gmail.com> | 2019-06-04 06:39:02 +0900 |
---|---|---|
committer | aycabta <aycabta@gmail.com> | 2019-06-04 07:23:36 +0900 |
commit | 4b7213a85a6700657b825f8f127ce83a3070bf1d (patch) | |
tree | a67ac0525591eefb8a467ee2cf5a731ddcfa2dc2 /lib | |
parent | c9b74f9fd95113df903fc34cc1d6ec3fb3160c85 (diff) |
Implement transpose-words
Diffstat (limited to 'lib')
-rw-r--r-- | lib/reline/key_actor/emacs.rb | 2 | ||||
-rw-r--r-- | lib/reline/line_editor.rb | 13 | ||||
-rw-r--r-- | lib/reline/unicode.rb | 101 |
3 files changed, 115 insertions, 1 deletions
diff --git a/lib/reline/key_actor/emacs.rb b/lib/reline/key_actor/emacs.rb index 7354c9279e..134f424a2c 100644 --- a/lib/reline/key_actor/emacs.rb +++ b/lib/reline/key_actor/emacs.rb @@ -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 diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index 784b8dd7c4..b1769d958a 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -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) diff --git a/lib/reline/unicode.rb b/lib/reline/unicode.rb index 5523d4fa31..4b30f044f3 100644 --- a/lib/reline/unicode.rb +++ b/lib/reline/unicode.rb @@ -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 |