diff options
author | aycabta <aycabta@gmail.com> | 2019-06-14 07:42:53 +0900 |
---|---|---|
committer | aycabta <aycabta@gmail.com> | 2019-06-14 07:42:53 +0900 |
commit | 64310b2573a9e1e83cd405aed4a5c3351793e09d (patch) | |
tree | 862867b12f814f422b07a1d920e1481bd1456f86 /lib | |
parent | 56d595198b607d2abbb0f60ef0d9e1217d08d1af (diff) |
Add Reline.prompt_proc
Diffstat (limited to 'lib')
-rw-r--r-- | lib/reline.rb | 14 | ||||
-rw-r--r-- | lib/reline/line_editor.rb | 70 |
2 files changed, 72 insertions, 12 deletions
diff --git a/lib/reline.rb b/lib/reline.rb index 49e99d2d65..baed78ed67 100644 --- a/lib/reline.rb +++ b/lib/reline.rb @@ -177,6 +177,15 @@ module Reline @@output_modifier_proc = p end + @@prompt_proc = nil + def self.prompt_proc + @@prompt_proc + end + def self.prompt_proc=(p) + raise ArgumentError unless p.is_a?(Proc) + @@prompt_proc = p + end + @@pre_input_hook = nil def self.pre_input_hook @@pre_input_hook @@ -320,6 +329,7 @@ module Reline @@line_editor.output = @@output @@line_editor.completion_proc = @@completion_proc @@line_editor.output_modifier_proc = @@output_modifier_proc + @@line_editor.prompt_proc = @@prompt_proc @@line_editor.dig_perfect_match_proc = @@dig_perfect_match_proc @@line_editor.pre_input_hook = @@pre_input_hook @@line_editor.rerender @@ -369,6 +379,10 @@ module Reline result = @@key_stroke.match_status(buffer) case result when :matched + if @@key_stroke.expand(buffer).nil? + $stderr.puts buffer.inspect + $stderr.puts @@config.key_bindings.inspect + end block.(@@key_stroke.expand(buffer).map{ |c| Reline::Key.new(c, c, false) }) break when :matching diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index c5f00c28dc..b7383d7de9 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -11,6 +11,7 @@ class Reline::LineEditor attr_accessor :confirm_multiline_termination_proc attr_accessor :completion_proc attr_accessor :output_modifier_proc + attr_accessor :prompt_proc attr_accessor :pre_input_hook attr_accessor :dig_perfect_match_proc attr_writer :output @@ -79,7 +80,6 @@ class Reline::LineEditor def reset_variables(prompt = '', encoding = Encoding.default_external) @prompt = prompt @encoding = encoding - @prompt_width = calculate_width(@prompt, true) @is_multiline = false @finished = false @cleared = false @@ -279,14 +279,25 @@ class Reline::LineEditor prompt_width = calculate_width(prompt) else prompt = @prompt - prompt_width = @prompt_width + prompt_width = calculate_width(prompt) end if @cleared Reline::IOGate.clear_screen @cleared = false back = 0 + prompt_list = nil + if @prompt_proc + prompt_list = @prompt_proc.(whole_lines, 0) + prompt = prompt_list[@line_index] + prompt_width = calculate_width(prompt) + end modify_lines(whole_lines).each_with_index do |line, index| - height = render_partial(prompt, prompt_width, line, false) + if @prompt_proc + pr = prompt_list[index] + height = render_partial(pr, calculate_width(pr), line, false) + else + height = render_partial(prompt, prompt_width, line, false) + end if index < (@buffer_of_lines.size - 1) move_cursor_down(height) back += height @@ -297,7 +308,7 @@ class Reline::LineEditor Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last) return end - new_highest_in_this = calculate_height_by_width(@prompt_width + calculate_width(@line.nil? ? '' : @line)) + new_highest_in_this = calculate_height_by_width(prompt_width + calculate_width(@line.nil? ? '' : @line)) # FIXME: end of logical line sometimes breaks if @previous_line_index or new_highest_in_this != @highest_in_this if @previous_line_index @@ -305,8 +316,14 @@ class Reline::LineEditor else new_lines = whole_lines end + prompt_list = nil + if @prompt_proc + prompt_list = @prompt_proc.(new_lines, 0) + prompt = prompt_list[@line_index] + prompt_width = calculate_width(prompt) + end all_height = new_lines.inject(0) { |result, line| - result + calculate_height_by_width(@prompt_width + calculate_width(line)) + result + calculate_height_by_width(prompt_width + calculate_width(line)) # TODO prompt_list } diff = all_height - @highest_in_all move_cursor_down(@highest_in_all - @first_line_started_from - @started_from - 1) @@ -326,6 +343,10 @@ class Reline::LineEditor @highest_in_all = all_height back = 0 modify_lines(new_lines).each_with_index do |line, index| + if @prompt_proc + prompt = prompt_list[index] + prompt_width = calculate_width(prompt) + end height = render_partial(prompt, prompt_width, line, false) if index < (new_lines.size - 1) scroll_down(1) @@ -344,15 +365,19 @@ class Reline::LineEditor 0 else @buffer_of_lines[0..(@line_index - 1)].inject(0) { |result, line| - result + calculate_height_by_width(@prompt_width + calculate_width(line)) + result + calculate_height_by_width(prompt_width + calculate_width(line)) # TODO prompt_list } end + if @prompt_proc + prompt = prompt_list[@line_index] + prompt_width = calculate_width(prompt) + end move_cursor_down(@first_line_started_from) calculate_nearest_cursor - @started_from = calculate_height_by_width(@prompt_width + @cursor) - 1 + @started_from = calculate_height_by_width(prompt_width + @cursor) - 1 move_cursor_down(@started_from) Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last) - @highest_in_this = calculate_height_by_width(@prompt_width + @cursor_max) + @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max) @previous_line_index = nil rendered = true elsif @rerender_all @@ -360,7 +385,14 @@ class Reline::LineEditor Reline::IOGate.move_cursor_column(0) back = 0 new_buffer = whole_lines - new_buffer.each do |line| + prompt_list = nil + if @prompt_proc + prompt_list = @prompt_proc.(new_buffer, 0) + prompt = prompt_list[@line_index] + prompt_width = calculate_width(prompt) + end + new_buffer.each_with_index do |line, index| + prompt_width = calculate_width(prompt_list[index]) if @prompt_proc width = prompt_width + calculate_width(line) height = calculate_height_by_width(width) back += height @@ -378,23 +410,31 @@ class Reline::LineEditor move_cursor_up(@highest_in_all - 1) end modify_lines(new_buffer).each_with_index do |line, index| + if @prompt_proc + prompt = prompt_list[index] + prompt_width = calculate_width(prompt) + end render_partial(prompt, prompt_width, line, false) if index < (new_buffer.size - 1) move_cursor_down(1) end end move_cursor_up(back - 1) + if @prompt_proc + prompt = prompt_list[@line_index] + prompt_width = calculate_width(prompt) + end @highest_in_all = back - @highest_in_this = calculate_height_by_width(@prompt_width + @cursor_max) + @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max) @first_line_started_from = if @line_index.zero? 0 else new_buffer[0..(@line_index - 1)].inject(0) { |result, line| - result + calculate_height_by_width(@prompt_width + calculate_width(line)) + result + calculate_height_by_width(prompt_width + calculate_width(line)) # TODO prompt_list } end - @started_from = calculate_height_by_width(@prompt_width + @cursor) - 1 + @started_from = calculate_height_by_width(prompt_width + @cursor) - 1 move_cursor_down(@first_line_started_from + @started_from) Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last) @rerender_all = false @@ -402,6 +442,12 @@ class Reline::LineEditor end line = modify_lines(whole_lines)[@line_index] if @is_multiline + prompt_list = nil + if @prompt_proc + prompt_list = @prompt_proc.(whole_lines, 0) + prompt = prompt_list[@line_index] + prompt_width = calculate_width(prompt) + end if finished? # Always rerender on finish because output_modifier_proc may return a different output. render_partial(prompt, prompt_width, line) |