Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def eof?

def reset_variables(prompt = '')
@prompt = prompt.gsub("\n", "\\n")
@mark_pointer = nil
@mark_position = nil
@is_multiline = false
@finished = false
@history_pointer = nil
Expand Down Expand Up @@ -2303,15 +2303,22 @@ def finish
end

private def em_set_mark(key)
@mark_pointer = [@byte_pointer, @line_index]
cursor_column = Reline::Unicode.calculate_width(current_line.byteslice(0, @byte_pointer))
@mark_position = [@line_index, cursor_column]
end
alias_method :set_mark, :em_set_mark

private def em_exchange_mark(key)
return unless @mark_pointer
new_pointer = [@byte_pointer, @line_index]
@byte_pointer, @line_index = @mark_pointer
@mark_pointer = new_pointer
return unless @mark_position
line_index, cursor_column = @mark_position
em_set_mark(key)
if @buffer_of_lines.size <= line_index
@line_index = @buffer_of_lines.size - 1
@byte_pointer = current_line.bytesize
else
@line_index = line_index
calculate_nearest_cursor(cursor_column)
end
end
alias_method :exchange_point_and_mark, :em_exchange_mark

Expand Down
35 changes: 29 additions & 6 deletions test/reline/test_key_actor_emacs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1245,27 +1245,50 @@ def test_em_set_mark_and_em_exchange_mark
assert_line_around_cursor('aaa bbb ccc ddd', '')
input_keys("\C-a\eF\eF")
assert_line_around_cursor('aaa bbb', ' ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
assert_equal(nil, @line_editor.instance_variable_get(:@mark_position))
input_keys("\x00") # C-Space
assert_line_around_cursor('aaa bbb', ' ccc ddd')
assert_equal([7, 0], @line_editor.instance_variable_get(:@mark_pointer))
assert_equal([0, 7], @line_editor.instance_variable_get(:@mark_position))
input_keys("\C-a")
assert_line_around_cursor('', 'aaa bbb ccc ddd')
assert_equal([7, 0], @line_editor.instance_variable_get(:@mark_pointer))
assert_equal([0, 7], @line_editor.instance_variable_get(:@mark_position))
input_key_by_symbol(:em_exchange_mark)
assert_line_around_cursor('aaa bbb', ' ccc ddd')
assert_equal([0, 0], @line_editor.instance_variable_get(:@mark_pointer))
assert_equal([0, 0], @line_editor.instance_variable_get(:@mark_position))
end

def test_em_exchange_mark_without_mark
input_keys('aaa bbb ccc ddd')
assert_line_around_cursor('aaa bbb ccc ddd', '')
input_keys("\C-a\ef")
assert_line_around_cursor('aaa', ' bbb ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
assert_equal(nil, @line_editor.instance_variable_get(:@mark_position))
input_key_by_symbol(:em_exchange_mark)
assert_line_around_cursor('aaa', ' bbb ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
assert_equal(nil, @line_editor.instance_variable_get(:@mark_position))
end

def test_em_exchange_mark_multibyte
input_keys("aaaaaaaaaaあああああ")
input_keys("\C-b\C-b")
assert_line_around_cursor('aaaaaaaaaaあああ', 'ああ')
input_keys("\x00") # C-Space
input_keys("\C-e\C-w")
input_keys("ああbbbbbああああああ")
input_key_by_symbol(:em_exchange_mark)
assert_line_around_cursor('ああbbbbbあああ', 'あああ')
end

def test_em_exchange_mark_line_disappear
input_key_by_symbol(:insert_multiline_text, char: "aaa\nbbb\nccc")
input_keys("\C-b\C-b")
input_keys("\x00") # C-Space
assert_line_around_cursor('c', 'cc')
input_keys("\C-a\C-h\C-p\C-a")
assert_line_around_cursor('', 'aaa')
input_key_by_symbol(:em_exchange_mark)
# If mark line does not exist, moves to the end of the input
assert_line_around_cursor('bbbccc', '')
end

def test_modify_lines_with_wrong_rs
Expand Down