From c2ddbdb8888a8802bbd65f6d8b106d327b0ff30d Mon Sep 17 00:00:00 2001 From: Dorian Taylor Date: Thu, 9 Nov 2023 00:43:30 -0500 Subject: [PATCH 1/5] cheap way to give access to ^W, etc --- .gitignore | 3 +++ lib/tty/reader.rb | 2 +- lib/tty/reader/line.rb | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8eb3b06..87d7039 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,8 @@ /spec/reports/ /tmp/ +# gem file +*.gem + # rspec failure tracking .rspec_status diff --git a/lib/tty/reader.rb b/lib/tty/reader.rb index c30062b..7299f29 100644 --- a/lib/tty/reader.rb +++ b/lib/tty/reader.rb @@ -379,7 +379,7 @@ def read_line(prompt = "", value: "", echo: true, raw: true, previous_key_name = key_name # trigger before line is printed to allow for line changes - trigger_key_event(char, line: line.to_s) + trigger_key_event(char, line: line) if raw && echo output.print(line.to_s) diff --git a/lib/tty/reader/line.rb b/lib/tty/reader/line.rb index fb2bc57..5402a18 100644 --- a/lib/tty/reader/line.rb +++ b/lib/tty/reader/line.rb @@ -332,6 +332,10 @@ def remove(n = 1) def to_s "#{@prompt}#{@text}" end + + # to_str enables type coercion and thus `line` in + # `trigger_char_event` does not need to be flattened to a string. + alias to_str to_s alias inspect to_s # Text size From 8e73dabab46ea32bed4cc611483fdf6e34710513 Mon Sep 17 00:00:00 2001 From: Dorian Taylor Date: Thu, 9 Nov 2023 01:22:44 -0500 Subject: [PATCH 2/5] updated tests to reflect reality --- lib/tty/reader.rb | 1 + lib/tty/reader/line.rb | 7 ++++--- spec/unit/history_disabled_spec.rb | 10 ++++++++-- spec/unit/publish_keypress_event_spec.rb | 6 +++++- spec/unit/read_line_spec.rb | 12 ++++++------ 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/tty/reader.rb b/lib/tty/reader.rb index 7299f29..0c54a7a 100644 --- a/lib/tty/reader.rb +++ b/lib/tty/reader.rb @@ -337,6 +337,7 @@ def read_line(prompt = "", value: "", echo: true, raw: true, line.delete elsif key_name.to_s =~ /ctrl_/ # skip + # trigger_key_event(key_name, line: line) elsif key_name == :up @history.replace(line.text) if history_in_use if history_previous? diff --git a/lib/tty/reader/line.rb b/lib/tty/reader/line.rb index 5402a18..6c97ae6 100644 --- a/lib/tty/reader/line.rb +++ b/lib/tty/reader/line.rb @@ -303,9 +303,10 @@ def insert(chars) # Add char and move cursor # # @api public - def <<(char) - @text << char - @cursor += 1 + def <<(str) + warn str + @text << str + @cursor += str.length end # Remove char from the line at current position diff --git a/spec/unit/history_disabled_spec.rb b/spec/unit/history_disabled_spec.rb index 2643d4b..9687555 100644 --- a/spec/unit/history_disabled_spec.rb +++ b/spec/unit/history_disabled_spec.rb @@ -15,7 +15,10 @@ input.rewind chars = [] lines = [] - reader.on(:keypress) { |event| chars << event.value; lines << event.line } + reader.on(:keypress) do |event| + chars << event.value + lines << event.line.to_s + end answer = reader.read_line expect(chars).to eq(%W(a b c \e[A d e f \n)) @@ -28,7 +31,10 @@ input.rewind chars = [] lines = [] - reader.on(:keypress) { |event| chars << event.value; lines << event.line } + reader.on(:keypress) do |event| + chars << event.value + lines << event.line.to_s + end answer = reader.read_line expect(chars).to eq(%W(a b c \e[B d e f \n)) diff --git a/spec/unit/publish_keypress_event_spec.rb b/spec/unit/publish_keypress_event_spec.rb index 6638150..3180b35 100644 --- a/spec/unit/publish_keypress_event_spec.rb +++ b/spec/unit/publish_keypress_event_spec.rb @@ -12,7 +12,11 @@ input.rewind chars = [] lines = [] - reader.on(:keypress) { |event| chars << event.value; lines << event.line } + reader.on(:keypress) do |event| + chars << event.value + lines << event.line.to_s + end + answer = reader.read_line expect(chars).to eq(%W(a b c \n)) diff --git a/spec/unit/read_line_spec.rb b/spec/unit/read_line_spec.rb index aab27c5..bd32a2e 100644 --- a/spec/unit/read_line_spec.rb +++ b/spec/unit/read_line_spec.rb @@ -151,7 +151,7 @@ reader.on(:keypress) do |event| chars << event.value - lines << event.line + lines << event.line.to_s end 3.times do @@ -171,7 +171,7 @@ reader.on(:keypress) do |event| chars << event.value - lines << event.line + lines << event.line.to_s end reader.read_line @@ -206,7 +206,7 @@ answer = nil lines = [] - reader.on(:keypress) { |event| lines << event.line } + reader.on(:keypress) { |event| lines << event.line.to_s } 4.times do answer = reader.read_line @@ -250,7 +250,7 @@ answer = nil lines = [] - reader.on(:keypress) { |event| lines << event.line } + reader.on(:keypress) { |event| lines << event.line.to_s } 3.times do answer = reader.read_line @@ -271,7 +271,7 @@ answer = nil lines = [] - reader.on(:keypress) { |event| lines << event.line } + reader.on(:keypress) { |event| lines << event.line.to_s } 3.times do answer = reader.read_line @@ -289,7 +289,7 @@ answer = nil lines = [] - reader.on(:keypress) { |event| lines << event.line } + reader.on(:keypress) { |event| lines << event.line.to_s } 3.times do answer = reader.read_line From 57004b8fb8c21a083f7c86e766098d595f410172 Mon Sep 17 00:00:00 2001 From: Dorian Taylor Date: Thu, 9 Nov 2023 01:30:28 -0500 Subject: [PATCH 3/5] let's not leave a mess --- lib/tty/reader.rb | 1 - lib/tty/reader/line.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/tty/reader.rb b/lib/tty/reader.rb index 0c54a7a..7299f29 100644 --- a/lib/tty/reader.rb +++ b/lib/tty/reader.rb @@ -337,7 +337,6 @@ def read_line(prompt = "", value: "", echo: true, raw: true, line.delete elsif key_name.to_s =~ /ctrl_/ # skip - # trigger_key_event(key_name, line: line) elsif key_name == :up @history.replace(line.text) if history_in_use if history_previous? diff --git a/lib/tty/reader/line.rb b/lib/tty/reader/line.rb index 6c97ae6..dd40040 100644 --- a/lib/tty/reader/line.rb +++ b/lib/tty/reader/line.rb @@ -304,7 +304,6 @@ def insert(chars) # # @api public def <<(str) - warn str @text << str @cursor += str.length end From 1c7cd7b6f3247dd7cc09e9117768da7b330a2614 Mon Sep 17 00:00:00 2001 From: Dorian Taylor Date: Thu, 9 Nov 2023 05:57:06 -0500 Subject: [PATCH 4/5] make all triggers use the line object rather than a string --- lib/tty/reader.rb | 4 ++-- lib/tty/reader/line.rb | 12 ++++++++++++ spec/unit/complete_word_spec.rb | 5 ++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/tty/reader.rb b/lib/tty/reader.rb index 7299f29..8ff48fd 100644 --- a/lib/tty/reader.rb +++ b/lib/tty/reader.rb @@ -309,7 +309,7 @@ def read_line(prompt = "", value: "", echo: true, raw: true, key_name = console.keys[char] if exit_keys && exit_keys.include?(key_name) - trigger_key_event(char, line: line.to_s) + trigger_key_event(char, line: line) break end @@ -323,7 +323,7 @@ def read_line(prompt = "", value: "", echo: true, raw: true, direction = key_name == :shift_tab ? :previous : :next if completion = @completer.complete(line, initial: initial, direction: direction) - trigger_completion_event(completion, line.to_s) + trigger_completion_event(completion, line) end elsif key_name == :escape && completion_handler && (previous_key_name == :tab || previous_key_name == :shift_tab) diff --git a/lib/tty/reader/line.rb b/lib/tty/reader/line.rb index dd40040..17e3085 100644 --- a/lib/tty/reader/line.rb +++ b/lib/tty/reader/line.rb @@ -338,6 +338,18 @@ def to_s alias to_str to_s alias inspect to_s + # Overload equality comparison + # + # @api public + def ==(other) + if other.is_a? self.class + super other + else + other = other.to_s if other.respond_to? :to_s + to_s == other + end + end + # Text size # # @api public diff --git a/spec/unit/complete_word_spec.rb b/spec/unit/complete_word_spec.rb index 842a654..b0e12ad 100644 --- a/spec/unit/complete_word_spec.rb +++ b/spec/unit/complete_word_spec.rb @@ -302,8 +302,11 @@ it "triggers completion event after completing the first suggestion" do @completions = %w[aa ab ac] completion_event = nil + test_line = nil # state of the line at the time the event is fired + reader.on(:complete) do |event| completion_event = event + test_line = event.line.dup # we duplicate to cut the strings formatted_completions = event.completions.map do |compl| compl == event.completion ? "(#{compl})" : compl end @@ -316,7 +319,7 @@ expect(answer).to eq("x aa\n") expect(completion_event.completion).to eq("aa") expect(completion_event.completions).to eq(@completions) - expect(completion_event.line).to eq("x aa") + expect(test_line).to eq("x aa") # implicit test of to_s and == expect(completion_event.word).to eq("a") output.rewind From 49ca699aa49c3ae73ff00619b538dedf5c390dce Mon Sep 17 00:00:00 2001 From: Dorian Taylor Date: Thu, 9 Nov 2023 06:18:39 -0500 Subject: [PATCH 5/5] okay one more; explicit overloaded `inspect` --- lib/tty/reader/line.rb | 10 ++++++++-- spec/unit/history_disabled_spec.rb | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/tty/reader/line.rb b/lib/tty/reader/line.rb index 17e3085..962a3df 100644 --- a/lib/tty/reader/line.rb +++ b/lib/tty/reader/line.rb @@ -335,8 +335,14 @@ def to_s # to_str enables type coercion and thus `line` in # `trigger_char_event` does not need to be flattened to a string. - alias to_str to_s - alias inspect to_s + alias to_str to_s + + # Overload inspect + # + # @api public + def inspect + to_s.inspect + end # Overload equality comparison # diff --git a/spec/unit/history_disabled_spec.rb b/spec/unit/history_disabled_spec.rb index 9687555..5a33b6c 100644 --- a/spec/unit/history_disabled_spec.rb +++ b/spec/unit/history_disabled_spec.rb @@ -17,7 +17,7 @@ lines = [] reader.on(:keypress) do |event| chars << event.value - lines << event.line.to_s + lines << event.line.dup # sever line object end answer = reader.read_line @@ -33,7 +33,7 @@ lines = [] reader.on(:keypress) do |event| chars << event.value - lines << event.line.to_s + lines << event.line.dup end answer = reader.read_line