[ruby/reline] Support mode icon

Co-authored-by: aycabta <aycabta@gmail.com>

https://github.com/ruby/reline/commit/067b618123
This commit is contained in:
Mark Delk 2020-07-13 06:47:43 +09:00 коммит произвёл aycabta
Родитель 0bc748db36
Коммит 44b24ab4c1
4 изменённых файлов: 82 добавлений и 1 удалений

Просмотреть файл

@ -222,7 +222,6 @@ module Reline
line_editor.auto_indent_proc = auto_indent_proc
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
line_editor.pre_input_hook = pre_input_hook
line_editor.rerender
unless config.test_mode
config.read
@ -232,6 +231,8 @@ module Reline
end
end
line_editor.rerender
begin
loop do
read_io(config.keyseq_timeout) { |inputs|

Просмотреть файл

@ -35,6 +35,10 @@ class Reline::Config
show-all-if-ambiguous
show-all-if-unmodified
visible-stats
show-mode-in-prompt
vi-cmd-mode-icon
vi-ins-mode-icon
emacs-mode-string
}
VARIABLE_NAME_SYMBOLS = VARIABLE_NAMES.map { |v| :"#{v.tr(?-, ?_)}" }
VARIABLE_NAME_SYMBOLS.each do |v|
@ -52,6 +56,9 @@ class Reline::Config
@key_actors[:emacs] = Reline::KeyActor::Emacs.new
@key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
@key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
@vi_cmd_mode_icon = '(cmd)'
@vi_ins_mode_icon = '(ins)'
@emacs_mode_string = '@'
# https://tiswww.case.edu/php/chet/readline/readline.html#IDX25
@history_size = -1 # unlimited
@keyseq_timeout = 500
@ -253,6 +260,21 @@ class Reline::Config
end
when 'keyseq-timeout'
@keyseq_timeout = value.to_i
when 'show-mode-in-prompt'
case value
when 'off'
@show_mode_in_prompt = false
when 'on'
@show_mode_in_prompt = true
else
@show_mode_in_prompt = false
end
when 'vi-cmd-mode-string'
@vi_cmd_mode_icon = value
when 'vi-ins-mode-string'
@vi_ins_mode_icon = value
when 'emacs-mode-string'
@emacs_mode_string = value
when *VARIABLE_NAMES then
variable_name = :"@#{name.tr(?-, ?_)}"
instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')

Просмотреть файл

@ -76,11 +76,35 @@ class Reline::LineEditor
if @prompt_proc
prompt_list = @prompt_proc.(buffer)
prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
if @config.show_mode_in_prompt
if @config.editing_mode_is?(:vi_command)
mode_icon = @config.vi_cmd_mode_icon
elsif @config.editing_mode_is?(:vi_insert)
mode_icon = @config.vi_ins_mode_icon
elsif @config.editing_mode_is?(:emacs)
mode_icon = @config.emacs_mode_string
else
mode_icon = '?'
end
prompt_list.map!{ |pr| mode_icon + pr }
end
prompt = prompt_list[@line_index]
prompt_width = calculate_width(prompt, true)
[prompt, prompt_width, prompt_list]
else
prompt_width = calculate_width(prompt, true)
if @config.show_mode_in_prompt
if @config.editing_mode_is?(:vi_command)
mode_icon = @config.vi_cmd_mode_icon
elsif @config.editing_mode_is?(:vi_insert)
mode_icon = @config.vi_ins_mode_icon
elsif @config.editing_mode_is?(:emacs)
mode_icon = @config.emacs_mode_string
else
mode_icon = '?'
end
prompt = mode_icon + prompt
end
[prompt, prompt_width, nil]
end
end

Просмотреть файл

@ -81,6 +81,40 @@ begin
prompt>
EOC
end
def test_mode_icon_emacs
File.open(@inputrc_file, 'w') do |f|
f.write <<~LINES
set show-mode-in-prompt on
LINES
end
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl})
sleep 0.5
close
assert_screen(<<~EOC)
Multiline REPL.
@prompt>
EOC
end
def test_mode_icon_vi
File.open(@inputrc_file, 'w') do |f|
f.write <<~LINES
set editing-mode vi
set show-mode-in-prompt on
LINES
end
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/bin/multiline_repl})
sleep 0.5
write(":a\n\C-[k")
close
assert_screen(<<~EOC)
Multiline REPL.
(ins)prompt> :a
=> :a
(cmd)prompt> :a
EOC
end
end
rescue LoadError, NameError
# On Ruby repository, this test suit doesn't run because Ruby repo doesn't