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
4 changes: 2 additions & 2 deletions lib/reline/key_actor/emacs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ module Reline::KeyActor
# 152 M-^X
nil,
# 153 M-^Y
:em_yank_pop,
nil,
# 154 M-^Z
nil,
# 155 M-^[
Expand Down Expand Up @@ -499,7 +499,7 @@ module Reline::KeyActor
# 248 M-x
nil,
# 249 M-y
nil,
:em_yank_pop,
# 250 M-z
nil,
# 251 M-{
Expand Down
32 changes: 19 additions & 13 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ module CompletionState
RenderedScreen = Struct.new(:base_y, :lines, :cursor_y, keyword_init: true)

CompletionJourneyState = Struct.new(:line_index, :pre, :target, :post, :list, :pointer)
NullActionState = [nil, nil].freeze

class MenuInfo
attr_reader :list
Expand Down Expand Up @@ -253,8 +252,8 @@ def reset_variables(prompt = '')
@undo_redo_history = [[[""], 0, 0]]
@undo_redo_index = 0
@restoring = false
@prev_action_state = NullActionState
@next_action_state = NullActionState
@prev_action_state = {}
@next_action_state = {}
reset_line
end

Expand Down Expand Up @@ -1022,7 +1021,7 @@ def input_key(key)
@byte_pointer -= byte_size
end

@prev_action_state, @next_action_state = @next_action_state, NullActionState
@prev_action_state, @next_action_state = @next_action_state, {}

unless @completion_occurs
@completion_state = CompletionState::NORMAL
Expand Down Expand Up @@ -1779,17 +1778,24 @@ def finish

private def em_yank(key)
yanked = @kill_ring.yank
insert_text(yanked) if yanked
return unless yanked

before_cursor = current_line.byteslice(0, @byte_pointer)
after_cursor = current_line.byteslice(@byte_pointer, current_line.bytesize)
set_current_line(before_cursor + yanked + after_cursor, before_cursor.bytesize + yanked.bytesize)
set_next_action_state(:em_yank_line, [before_cursor, after_cursor])
end
alias_method :yank, :em_yank

private def em_yank_pop(key)
yanked, prev_yank = @kill_ring.yank_pop
if yanked
line, = byteslice!(current_line, @byte_pointer - prev_yank.bytesize, prev_yank.bytesize)
set_current_line(line, @byte_pointer - prev_yank.bytesize)
insert_text(yanked)
end
before_cursor, after_cursor = prev_action_state_value(:em_yank_line)
return unless before_cursor and after_cursor

yanked, = @kill_ring.yank_pop
return unless yanked

set_current_line(before_cursor + yanked + after_cursor, before_cursor.bytesize + yanked.bytesize)
set_next_action_state(:em_yank_line, [before_cursor, after_cursor])
end
alias_method :yank_pop, :em_yank_pop

Expand Down Expand Up @@ -2343,11 +2349,11 @@ def finish
end

private def prev_action_state_value(type)
@prev_action_state[0] == type ? @prev_action_state[1] : nil
@prev_action_state[type]
end

private def set_next_action_state(type, value)
@next_action_state = [type, value]
@next_action_state[type] = value
end

private def re_read_init_file(_key)
Expand Down
8 changes: 7 additions & 1 deletion test/reline/test_key_actor_emacs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1469,8 +1469,14 @@ def test_em_yank_pop
assert_line_around_cursor('', '')
input_keys("\C-y")
assert_line_around_cursor('def ', '')
input_keys("\e\C-y")
input_keys("\ey")
assert_line_around_cursor('hoge', '')
input_keys("\ey")
assert_line_around_cursor('def ', '')
# Moving arrows aborts yank-pop
input_keys("\C-b\C-f")
input_keys("\ey")
assert_line_around_cursor('def ', '')
end

def test_em_kill_region_with_kill_ring
Expand Down