summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2019-05-13 02:26:31 +0900
committeraycabta <aycabta@gmail.com>2019-05-13 02:26:31 +0900
commit5837290af1216eaadbee3204e40ef16931da2fdb (patch)
tree6f3a5886d5b0755415aa09df0d8cfaa9516eeb1b /lib
parentc137f015ab2283e885168f983e36e4bd2c1aa29e (diff)
Implement Reline's class methods for compatibility
- insert_text - redisplay - line_buffer - point - point= - vi_editing_mode - emacs_editing_mode - vi_editing_mode? - emacs_editing_mode? - get_screen_size
Diffstat (limited to 'lib')
-rw-r--r--lib/reline.rb50
-rw-r--r--lib/reline/key_stroke.rb3
-rw-r--r--lib/reline/line_editor.rb62
3 files changed, 113 insertions, 2 deletions
diff --git a/lib/reline.rb b/lib/reline.rb
index 66375faabd..bf8f9c3f58 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -84,8 +84,29 @@ module Reline
@@dig_perfect_match_proc = p
end
+ def self.insert_text(text)
+ @@line_editor&.insert_text(text)
+ self
+ end
+
+ def self.redisplay
+ @@line_editor&.rerender
+ end
+
+ def self.line_buffer
+ @@line_editor&.line
+ end
+
+ def self.point
+ @@line_editor ? @@line_editor.byte_pointer : 0
+ end
+
+ def self.point=(val)
+ @@line_editor.byte_pointer = val
+ end
+
def self.delete_text(start = nil, length = nil)
- raise NotImplementedError
+ @@line_editor&.delete_text(start, length)
end
def self.input=(val)
@@ -103,6 +124,28 @@ module Reline
@@output = val
end
+ def self.vi_editing_mode
+ @@config.editing_mode = :vi_insert
+ nil
+ end
+
+ def self.emacs_editing_mode
+ @@config.editing_mode = :emacs
+ nil
+ end
+
+ def self.vi_editing_mode?
+ @@config.editing_mode_is?(:vi_insert, :vi_command)
+ end
+
+ def self.emacs_editing_mode?
+ @@config.editing_mode_is?(:emacs)
+ end
+
+ def self.get_screen_size
+ Reline::IO.get_screen_size
+ end
+
def retrieve_completion_block(line, byte_pointer)
break_regexp = /[#{Regexp.escape(@@basic_word_break_characters)}]/
before_pointer = line.byteslice(0, byte_pointer)
@@ -131,6 +174,7 @@ module Reline
Reline::HISTORY << whole_buffer
end
+ @@line_editor.reset_line if @@line_editor.whole_buffer.nil?
whole_buffer
end
@@ -143,6 +187,7 @@ module Reline
Reline::HISTORY << line.chomp
end
+ @@line_editor.reset_line if @@line_editor.line.nil?
line
end
@@ -189,7 +234,8 @@ module Reline
key_stroke = Reline::KeyStroke.new(config)
begin
- while c = Reline::IO.getc
+ loop do
+ c = Reline::IO.getc
key_stroke.input_to!(c)&.then { |inputs|
inputs.each { |c|
@@line_editor.input_key(c)
diff --git a/lib/reline/key_stroke.rb b/lib/reline/key_stroke.rb
index ac0a820759..fdfe74a6ee 100644
--- a/lib/reline/key_stroke.rb
+++ b/lib/reline/key_stroke.rb
@@ -28,6 +28,9 @@ class Reline::KeyStroke
end
def input_to!(bytes)
+ if bytes.nil?
+ return @buffer.push(nil)&.tap { clear }
+ end
@buffer.concat Array(bytes)
input_to(@buffer)&.tap { clear }
end
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 21616ddd96..1b60b67923 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -7,6 +7,7 @@ require 'pathname'
class Reline::LineEditor
# TODO: undo
attr_reader :line
+ attr_reader :byte_pointer
attr_accessor :confirm_multiline_termination_proc
attr_accessor :completion_proc
attr_accessor :pre_input_hook
@@ -106,6 +107,10 @@ class Reline::LineEditor
@first_prompt = true
@searching_prompt = nil
@first_char = true
+ reset_line
+ end
+
+ def reset_line
@cursor = 0
@cursor_max = 0
@byte_pointer = 0
@@ -636,6 +641,63 @@ class Reline::LineEditor
end
end
+ def insert_text(text)
+ width = calculate_width(text)
+ if @cursor == @cursor_max
+ @line += text
+ else
+ @line = byteinsert(@line, @byte_pointer, text)
+ end
+ @byte_pointer += text.bytesize
+ @cursor += width
+ @cursor_max += width
+ end
+
+ def delete_text(start = nil, length = nil)
+ if start.nil? and length.nil?
+ @line&.clear
+ @byte_pointer = 0
+ @cursor = 0
+ @cursor_max = 0
+ elsif not start.nil? and not length.nil?
+ if @line
+ before = @line.byteslice(0, start)
+ after = @line.byteslice(start + length, @line.bytesize)
+ @line = before + after
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
+ end
+ elsif start.is_a?(Range)
+ range = start
+ first = range.first
+ last = range.last
+ last = @line.bytesize - 1 if last > @line.bytesize
+ last += @line.bytesize if last < 0
+ first += @line.bytesize if first < 0
+ range = range.exclude_end? ? first...last : first..last
+ @line = @line.bytes.reject.with_index{ |c, i| range.include?(i) }.map{ |c| c.chr(Encoding::ASCII_8BIT) }.join.force_encoding(@encoding)
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
+ else
+ @line = @line.byteslice(0, start)
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
+ end
+ end
+
+ def byte_pointer=(val)
+ @byte_pointer = val
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
+ end
+
def whole_buffer
temp_lines = @buffer_of_lines.dup
temp_lines[@line_index] = @line