Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor nomultiline and multiline mode difference #653

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
146 changes: 55 additions & 91 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ def set_pasting_state(in_pasting)
else
prompt = @prompt
end
if @prompt_proc
if !@is_multiline
mode_string = check_mode_string
prompt = mode_string + prompt if mode_string
[prompt] + [''] * (buffer.size - 1)
st0012 marked this conversation as resolved.
Show resolved Hide resolved
elsif @prompt_proc
prompt_list = @prompt_proc.(buffer).map { |pr| pr.gsub("\n", "\\n") }
prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
prompt_list = [prompt] if prompt_list.empty?
Expand Down Expand Up @@ -1220,7 +1224,7 @@ def call_completion_proc_with_checking_args(pre, target, post)
end

def line()
current_line unless eof?
@buffer_of_lines.join("\n") unless eof?
end

def current_line
Expand Down Expand Up @@ -1304,14 +1308,12 @@ def retrieve_completion_block(set_completion_quote_character = false)
end
target = before
end
if @is_multiline
lines = whole_lines
if @line_index > 0
preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
end
if (lines.size - 1) > @line_index
postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
end
lines = whole_lines
if @line_index > 0
preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
end
if (lines.size - 1) > @line_index
postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
end
[preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
end
Expand All @@ -1333,20 +1335,16 @@ def insert_text(text)

def delete_text(start = nil, length = nil)
if start.nil? and length.nil?
if @is_multiline
if @buffer_of_lines.size == 1
@buffer_of_lines[@line_index] = ''
@byte_pointer = 0
elsif @line_index == (@buffer_of_lines.size - 1) and @line_index > 0
@buffer_of_lines.pop
@line_index -= 1
@byte_pointer = 0
elsif @line_index < (@buffer_of_lines.size - 1)
@buffer_of_lines.delete_at(@line_index)
@byte_pointer = 0
end
else
set_current_line('', 0)
if @buffer_of_lines.size == 1
@buffer_of_lines[@line_index] = ''
@byte_pointer = 0
elsif @line_index == (@buffer_of_lines.size - 1) and @line_index > 0
@buffer_of_lines.pop
@line_index -= 1
@byte_pointer = 0
elsif @line_index < (@buffer_of_lines.size - 1)
@buffer_of_lines.delete_at(@line_index)
@byte_pointer = 0
end
elsif not start.nil? and not length.nil?
if current_line
Expand Down Expand Up @@ -1502,7 +1500,7 @@ def finish
byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
if (@byte_pointer < current_line.bytesize)
@byte_pointer += byte_size
elsif @is_multiline and @config.editing_mode_is?(:emacs) and @byte_pointer == current_line.bytesize and @line_index < @buffer_of_lines.size - 1
elsif @config.editing_mode_is?(:emacs) and @byte_pointer == current_line.bytesize and @line_index < @buffer_of_lines.size - 1
@byte_pointer = 0
@line_index += 1
end
Expand All @@ -1515,7 +1513,7 @@ def finish
if @byte_pointer > 0
byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
@byte_pointer -= byte_size
elsif @is_multiline and @config.editing_mode_is?(:emacs) and @byte_pointer == 0 and @line_index > 0
elsif @config.editing_mode_is?(:emacs) and @byte_pointer == 0 and @line_index > 0
@line_index -= 1
@byte_pointer = current_line.bytesize
end
Expand Down Expand Up @@ -1546,7 +1544,6 @@ def finish
private def generate_searcher(search_key)
search_word = String.new(encoding: @encoding)
multibyte_buf = String.new(encoding: 'ASCII-8BIT')
last_hit = nil
hit_pointer = nil
lambda do |key|
search_again = false
Expand Down Expand Up @@ -1624,18 +1621,13 @@ def finish
prompt_name = 'i-search'
end
prompt_name = "failed #{prompt_name}" unless hit
last_hit = hit if hit_pointer
[search_word, prompt_name, hit_pointer, hit, last_hit]
[search_word, prompt_name, hit_pointer]
end
end

private def incremental_search_history(key)
unless @history_pointer
if @is_multiline
@line_backup_in_history = whole_buffer
else
@line_backup_in_history = current_line
end
@line_backup_in_history = whole_buffer
end
searcher = generate_searcher(key)
@searching_prompt = "(reverse-i-search)`': "
Expand All @@ -1649,54 +1641,38 @@ def finish
else
buffer = @line_backup_in_history
end
if @is_multiline
@buffer_of_lines = buffer.split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = @buffer_of_lines.size - 1
else
@buffer_of_lines = [buffer]
end
@buffer_of_lines = buffer.split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = @buffer_of_lines.size - 1
@searching_prompt = nil
@waiting_proc = nil
@byte_pointer = 0
when "\C-g".ord
if @is_multiline
@buffer_of_lines = @line_backup_in_history.split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = @buffer_of_lines.size - 1
else
@buffer_of_lines = [@line_backup_in_history]
end
@buffer_of_lines = @line_backup_in_history.split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = @buffer_of_lines.size - 1
move_history(nil, line: :end, cursor: :end, save_buffer: false)
@searching_prompt = nil
@waiting_proc = nil
@byte_pointer = 0
else
chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
if chr.match?(/[[:print:]]/) or k == "\C-h".ord or k == "\C-?".ord or k == "\C-r".ord or k == "\C-s".ord
search_word, prompt_name, hit_pointer, hit, last_hit = searcher.call(k)
search_word, prompt_name, hit_pointer = searcher.call(k)
Reline.last_incremental_search = search_word
if @is_multiline
@searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
else
@searching_prompt = "(%s)`%s': %s" % [prompt_name, search_word, hit || last_hit]
end
@searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
@searching_prompt += ': ' unless @is_multiline
move_history(hit_pointer, line: :end, cursor: :end, save_buffer: false) if hit_pointer
else
if @history_pointer
line = Reline::HISTORY[@history_pointer]
else
line = @line_backup_in_history
end
if @is_multiline
@line_backup_in_history = whole_buffer
@buffer_of_lines = line.split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = @buffer_of_lines.size - 1
else
@line_backup_in_history = current_line
@buffer_of_lines = [line]
end
@line_backup_in_history = whole_buffer
@buffer_of_lines = line.split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = @buffer_of_lines.size - 1
@searching_prompt = nil
@waiting_proc = nil
@byte_pointer = 0
Expand Down Expand Up @@ -1770,18 +1746,14 @@ def finish
buf = Reline::HISTORY[history_pointer]
@history_pointer = history_pointer
end
if @is_multiline
@buffer_of_lines = buf.split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = line == :start ? 0 : line == :end ? @buffer_of_lines.size - 1 : line
else
@buffer_of_lines = [buf]
end
@buffer_of_lines = buf.split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = line == :start ? 0 : line == :end ? @buffer_of_lines.size - 1 : line
@byte_pointer = cursor == :start ? 0 : cursor == :end ? current_line.bytesize : cursor
end

private def ed_prev_history(key, arg: 1)
if @is_multiline and @line_index > 0
if @line_index > 0
cursor = current_byte_pointer_cursor
@line_index -= 1
calculate_nearest_cursor(cursor)
Expand All @@ -1798,7 +1770,7 @@ def finish
alias_method :previous_history, :ed_prev_history

private def ed_next_history(key, arg: 1)
if @is_multiline and @line_index < (@buffer_of_lines.size - 1)
if @line_index < (@buffer_of_lines.size - 1)
cursor = current_byte_pointer_cursor
@line_index += 1
calculate_nearest_cursor(cursor)
Expand Down Expand Up @@ -1845,7 +1817,7 @@ def finish

private def em_delete_prev_char(key, arg: 1)
arg.times do
if @is_multiline and @byte_pointer == 0 and @line_index > 0
if @byte_pointer == 0 and @line_index > 0
@byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
@buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
@line_index -= 1
Expand All @@ -1869,7 +1841,7 @@ def finish
line, deleted = byteslice!(current_line, @byte_pointer, current_line.bytesize - @byte_pointer)
set_current_line(line, line.bytesize)
@kill_ring.append(deleted)
elsif @is_multiline and @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
end
end
Expand Down Expand Up @@ -1909,15 +1881,15 @@ def finish
alias_method :kill_whole_line, :em_kill_line

private def em_delete(key)
if current_line.empty? and (not @is_multiline or @buffer_of_lines.size == 1) and key == "\C-d".ord
if current_line.empty? and @buffer_of_lines.size == 1 and key == "\C-d".ord
@eof = true
finish
elsif @byte_pointer < current_line.bytesize
splitted_last = current_line.byteslice(@byte_pointer, current_line.bytesize)
mbchar = splitted_last.grapheme_clusters.first
line, = byteslice!(current_line, @byte_pointer, mbchar.bytesize)
set_current_line(line)
elsif @is_multiline and @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
end
end
Expand Down Expand Up @@ -2160,7 +2132,7 @@ def finish
end

private def vi_delete_prev_char(key)
if @is_multiline and @byte_pointer == 0 and @line_index > 0
if @byte_pointer == 0 and @line_index > 0
@byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
@buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
@line_index -= 1
Expand Down Expand Up @@ -2257,7 +2229,7 @@ def finish
end

private def vi_list_or_eof(key)
if (not @is_multiline and current_line.empty?) or (@is_multiline and current_line.empty? and @buffer_of_lines.size == 1)
if current_line.empty? and @buffer_of_lines.size == 1
set_current_line('', 0)
@eof = true
finish
Expand Down Expand Up @@ -2293,21 +2265,13 @@ def finish

private def vi_histedit(key)
path = Tempfile.open { |fp|
if @is_multiline
fp.write whole_lines.join("\n")
else
fp.write current_line
end
fp.write whole_lines.join("\n")
fp.path
}
system("#{ENV['EDITOR']} #{path}")
if @is_multiline
@buffer_of_lines = File.read(path).split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = 0
else
@buffer_of_lines = File.read(path).split("\n")
end
@buffer_of_lines = File.read(path).split("\n")
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
@line_index = 0
finish
end

Expand Down Expand Up @@ -2479,7 +2443,7 @@ def finish
end

private def vi_join_lines(key, arg: 1)
if @is_multiline and @buffer_of_lines.size > @line_index + 1
if @buffer_of_lines.size > @line_index + 1
next_line = @buffer_of_lines.delete_at(@line_index + 1).lstrip
set_current_line(current_line + ' ' + next_line, current_line.bytesize)
end
Expand Down
2 changes: 1 addition & 1 deletion test/reline/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def input_raw_keys(input, convert = true)
def assert_line_around_cursor(before, after)
before = convert_str(before)
after = convert_str(after)
line = @line_editor.line
line = @line_editor.current_line
byte_pointer = @line_editor.instance_variable_get(:@byte_pointer)
actual_before = line.byteslice(0, byte_pointer)
actual_after = line.byteslice(byte_pointer..)
Expand Down
Loading