summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2019-06-14 07:42:53 +0900
committeraycabta <aycabta@gmail.com>2019-06-14 07:42:53 +0900
commit64310b2573a9e1e83cd405aed4a5c3351793e09d (patch)
tree862867b12f814f422b07a1d920e1481bd1456f86 /lib
parent56d595198b607d2abbb0f60ef0d9e1217d08d1af (diff)
Add Reline.prompt_proc
Diffstat (limited to 'lib')
-rw-r--r--lib/reline.rb14
-rw-r--r--lib/reline/line_editor.rb70
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)