Skip to content

Commit

Permalink
Add support for adding a custom suffix to suggested word completion
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmurach committed Jul 17, 2021
1 parent 1b0d89e commit 116a710
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@
### Added
* Add to line the ability to find a word to complete before the cursor
* Add ability to complete words
* Add support for adding a custom suffix to suggested word completion
* Add :history_size keyword to allow configuration of maximum history size
* Add the ability to replace a current line in the history buffer
* Add support for preserving edits to lines stored in history
Expand Down
24 changes: 22 additions & 2 deletions lib/tty/reader.rb
Expand Up @@ -62,6 +62,11 @@ def self.windows?
# @api public
attr_reader :completion_handler

# The suffix to add to suggested word completion
#
# @api public
attr_reader :completion_suffix

attr_reader :console

attr_reader :cursor
Expand All @@ -86,14 +91,16 @@ def self.windows?
# exclude lines from history, by default all lines are stored
# @param [Proc] completion_handler
# the hanlder for finding word completion suggestions
# @param [String] completion_suffix
# the suffix to add to suggested word completion
#
# @api public
def initialize(input: $stdin, output: $stdout, interrupt: :error,
env: ENV, track_history: true, history_cycle: false,
history_exclude: History::DEFAULT_EXCLUDE,
history_size: History::DEFAULT_SIZE,
history_duplicates: false,
completion_handler: nil)
completion_handler: nil, completion_suffix: "")
@input = input
@output = output
@interrupt = interrupt
Expand All @@ -104,7 +111,9 @@ def initialize(input: $stdin, output: $stdout, interrupt: :error,
@history_duplicates = history_duplicates
@history_size = history_size
@completion_handler = completion_handler
@completer = Completer.new(handler: completion_handler)
@completion_suffix = completion_suffix
@completer = Completer.new(handler: completion_handler,
suffix: completion_suffix)

@console = select_console(input)
@history = History.new(history_size) do |h|
Expand All @@ -126,6 +135,17 @@ def completion_handler=(handler)
@completer.handler = handler
end

# Set completion suffix
#
# @param [String] suffix
# the suffix to add to suggested word completion
#
# @api public
def completion_suffix=(suffix)
@completion_suffix = suffix
@completer.suffix = suffix
end

alias old_subcribe subscribe

# Subscribe to receive key events
Expand Down
15 changes: 11 additions & 4 deletions lib/tty/reader/completer.rb
Expand Up @@ -14,14 +14,18 @@ class Completer
# The handler for finding word completion suggestions
attr_accessor :handler

# The suffix to add to suggested word completion
attr_accessor :suffix

# The word to complete
attr_reader :word

# Create a Completer instance
#
# @api private
def initialize(handler: nil)
def initialize(handler: nil, suffix: "")
@handler = handler
@suffix = suffix
@completions = Completions.new
@show_initial = false
@word = ""
Expand Down Expand Up @@ -60,7 +64,7 @@ def complete_initial(line)
completed_word = completions.get

line.remove(word.length)
line.insert(completed_word)
line.insert(completed_word + suffix)

completed_word
end
Expand Down Expand Up @@ -90,8 +94,11 @@ def complete_next(line)
completed_word = completions.get
end

line.remove(previous_suggestion.length)
line.insert(completed_word)
length_to_remove = previous_suggestion.length
length_to_remove += suffix.length if previous_suggestion != word

line.remove(length_to_remove)
line.insert("#{completed_word}#{suffix unless @show_initial}")

completed_word
end
Expand Down
50 changes: 50 additions & 0 deletions spec/unit/complete_word_spec.rb
Expand Up @@ -144,4 +144,54 @@

expect(answer).to eq(%W[aa\n ab])
end

it "adds space suffix to suggested word completion on the first tab" do
@completions = %w[aa ab ac]
options[:completion_suffix] = " "
reader = described_class.new(**options)
input << "x " << "a" << "\t" << "\n"
input.rewind

answer = reader.read_line

expect(answer).to eq("x aa \n")
end

it "adds space suffix to suggested word completion on the second tab" do
@completions = %w[aa ab ac]
options[:completion_suffix] = " "
reader = described_class.new(**options)
input << "x " << "a" << "\t" << "\t" << "\n"
input.rewind

answer = reader.read_line

expect(answer).to eq("x ab \n")
end

it "skips adding space suffix to the original word" do
@completions = %w[aa ab ac]
options[:completion_suffix] = " "
reader = described_class.new(**options)
input << "x " << "a" << "\t" << "\t" << "\t" << "\t" << "\n"
input.rewind

answer = reader.read_line

expect(answer).to eq("x a\n")
expect(reader.completion_suffix).to eq(" ")
end

it "adds two chars suffix to suggested word completion" do
@completions = %w[aa ab ac]
reader = described_class.new(**options)
reader.completion_suffix = "??"
input << "x " << "a" << "\t" << "\t" << "\n"
input.rewind

answer = reader.read_line

expect(answer).to eq("x ab??\n")
expect(reader.completion_suffix).to eq("??")
end
end

0 comments on commit 116a710

Please sign in to comment.