summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2021-09-04 07:29:23 +0900
committeraycabta <aycabta@gmail.com>2021-09-04 21:40:12 +0900
commitec36ceb072be5b08dbdd747443192901a1c771e9 (patch)
tree86ec57709ebc82de833df50a98a4f5289f71b1eb /lib
parentff372ed74b4cedd8252e589d2b89c59b0bd8d763 (diff)
[ruby/reline] Implement scrollbar
https://github.com/ruby/reline/commit/4c7fc42151
Diffstat (limited to 'lib')
-rw-r--r--lib/reline.rb4
-rw-r--r--lib/reline/line_editor.rb19
2 files changed, 21 insertions, 2 deletions
diff --git a/lib/reline.rb b/lib/reline.rb
index d440b2d7ba..735a5afad8 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -24,7 +24,7 @@ module Reline
end
end
CursorPos = Struct.new(:x, :y)
- DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :width, :height, keyword_init: true)
+ DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :width, :height, :scrollbar, keyword_init: true)
class Core
ATTR_READER_NAMES = %i(
@@ -228,7 +228,7 @@ module Reline
context.clear
context.push(cursor_pos_to_render, result, pointer, dialog)
end
- DialogRenderInfo.new(pos: cursor_pos_to_render, contents: result, pointer: pointer, height: 15)
+ DialogRenderInfo.new(pos: cursor_pos_to_render, contents: result, pointer: pointer, scrollbar: true, height: 15)
}
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index d3020087bf..e52c4e5fd3 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -661,6 +661,13 @@ class Reline::LineEditor
reset_dialog(dialog, old_dialog)
move_cursor_down(dialog.vertical_offset)
Reline::IOGate.move_cursor_column(dialog.column)
+ if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
+ bar_max_height = height * 2
+ moving_distance = (dialog_render_info.contents.size - height) * 2
+ position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance)
+ bar_height = (bar_max_height * ((dialog.contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
+ position = ((bar_max_height - bar_height) * position_ratio).floor.to_i
+ end
dialog.contents.each_with_index do |item, i|
if i == pointer
bg_color = '45'
@@ -672,10 +679,22 @@ class Reline::LineEditor
end
end
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, dialog.width), dialog.width)
+ if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
+ if position <= (i * 2) and (i * 2) <= (position + bar_height)
+ str += '█'
+ elsif position <= (i * 2) and (i * 2 - 1) <= (position + bar_height)
+ str += '▀'
+ elsif position <= (i * 2 + 1) and (i * 2) <= (position + bar_height)
+ str += '▄'
+ else
+ str += ' '
+ end
+ end
@output.write "\e[#{bg_color}m#{str}\e[49m"
Reline::IOGate.move_cursor_column(dialog.column)
move_cursor_down(1) if i < (dialog.contents.size - 1)
end
+ dialog.width += 1 if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
Reline::IOGate.move_cursor_column(cursor_column)
move_cursor_up(dialog.vertical_offset + dialog.contents.size - 1)
Reline::IOGate.show_cursor