Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consider exposing Readline.completion_proc via HighLine::Question#selection #232

Open
doriantaylor opened this issue May 21, 2018 · 3 comments
Assignees

Comments

@doriantaylor
Copy link

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.

@abinoam
Copy link
Collaborator

abinoam commented May 24, 2018

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 👍

@doriantaylor
Copy link
Author

Great, I'll cook it up.

@doriantaylor
Copy link
Author

doriantaylor commented May 26, 2018

Looking over this and I have a couple questions:

  1. Testing strategy: Do I (can I?) use HighLine::Simulate or do I add another manual acceptance test?
  2. The method HighLine#shell_style_lambda does 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants