consider exposing Readline.completion_proc via HighLine::Question#selection
Happy Monday,
Playing around with HighLine, finding myself in a situation where I need finer-grained access to tab completion than an array. Looking at terminal.rb it seems as if it would be pretty easy to re-expose Readline.completion_proc via HighLine::Question.
Something like this would probably be all that was necessary:
def readline_read(question)
# prep auto-completion
sel = question.selection
proc = sel.is_a?(Proc) ? sel : sel.empty? ? nil : lambda do |str|
sel.grep(/\A#{Regexp.escape(str)}/)
end
Readline.completion_proc = proc
# work-around ugly readline() warnings
old_verbose = $VERBOSE
$VERBOSE = nil
raw_answer = run_preserving_stty do
Readline.readline("", true)
end
$VERBOSE = old_verbose
raw_answer
end
Then in Highline::Question, something like:
def selection
if completion.is_a?(Array) or completion.is_a?(Proc)
completion
elsif [File, Pathname].include?(completion)
Dir[File.join(directory.to_s, glob)].map do |file|
File.basename(file)
end
else
[]
end
end
This is just me eyeballing the issue for now; I can fork and PR if you're amenable.
Hi @doriantaylor , thank you for your comments/suggestions.
I'll probably have time to look at it further by the weekend.
But I can antecipate to you that if it solves an actual problem that you're having, it doesn't break the api and it doesn't raise the code's complexity too much I'll probably welcome your changes 👍
Great, I'll cook it up.
Looking over this and I have a couple questions:
- Testing strategy: Do I (can I?) use
HighLine::Simulateor do I add another manual acceptance test? - The method
HighLine#shell_style_lambdadoes something similar to what I am ultimately trying to do, but only for menus. Perhaps it would make sense to take a step back and look at this more holistically?
I found my way here because I was writing a command-line tool using commander and wanted to implement an umbrella shell command that recycled the other available commands into a readline loop. (To achieve this I had to patch some undesirable behaviour, which the maintainer graciously applied.) Commander, of course, uses HighLine for its readline component, and I want to be able to add tab completion—not just for the commands, but for the options as well.
Given that my desired functionality is at least partially present in HighLine::Menu, I should probably take it into consideration. Nevertheless, I believe it to be still overall useful to be able to access Readline.completion_proc directly, it just looks like a slightly more delicate surgery.