JEG2 / highline

A higher level command-line oriented interface.
Other
1.29k stars 137 forks source link

Prefilled answer for user to edit #188

Closed tukanos closed 8 years ago

tukanos commented 8 years ago

Hi again,

I wonder if anyone has tried to have a user predefined answer and if it is possible with current HighLine.

For example:

I would ask a user:

'Which search engine would you like to use?'

the prefilled answer would be:

www.google.com and user could edit this answer and change it to www.google.de for example.

Any suggestions?

abinoam commented 8 years ago

Hi @tukanos,

There's no recomended way of accomplishing what you are trying to do. But, it's possible if you fool readline mode.

require 'highline'

cli = HighLine.new

question = "Which search engine would you like to use? "

answer = cli.ask(question) do |q|
  q.completion = ["www.google.com", "www.github.com"]
  q.readline = true
end

cli.say "You have answered <%= color('#{answer}', :red) %>"

Try to autocomplete and then press backspace key and inline edit your answer to whatever.

Does it solve to you @tukanos? Any comment on it?

Be aware that readline mode introduces some dependencies and incompatibilities. (Sometimes breaks on JRuby, or on Windows, for example).

tukanos commented 8 years ago

Hi @abinoam,

I'm trying to solve this issue for windows now. The snippet you have posted is not working properly there as I have tested.

I have tried to come up with this workaround:

require 'highline'

cli = HighLine.new

sites = %w(www.google.com www.github.com www* www.goo.com)

answer = cli.ask("Select sites: #{sites}", sites) do |question|
  question.readline = true
  question.validate = lambda do |accepted_answer|
    if (accepted_answer =~ /w{3}.*/)==0
      question.answer_type << accepted_answer
      true
    end
  end
  question.responses[:not_valid] = 'Your answer is invalid it must contain a www.'
end
p answer

However, this solution has still some rough edges. First it does not accept answers like www.goo.com (even when the www.g.com is not listed). I think it is connected to Auto-complete. If the string is in the auto-complete path like www.g or www.goog, etc. The answer gets refused.

The error printed:

Select sites: ["www.google.com", "www.github.com", "www*"]
www.goo.com
Ambiguous choice.  Please choose one of [www.google.com, www.github.com, www*].
?  Select sites: ["www.google.com", "www.github.com", "www*"]`  
I have check to docs again.

One more issue I'm facing is that the backspace causes what I call "one space issue" (really annoying for the user). Sometimes what you see is not what is saved into the variable usually there is an issue. If you want to delete the whole printed string the first string hangs there but if you press enter nothing is saved into the variable.

An example of such behaviour:

C:\prg\ruby\_snippets\input>ruby prefilled_v2.rb       
Select Users: ["www.google.com", "www.github.com"]     
www.google.de                                          
"www.googlede"                                         

C:\prg\ruby\_snippets\input>ruby prefilled_v2.rb       
Select Users: ["www.google.com", "www.github.com"]     
www.google.de                                          
"www.googlede"                                         

C:\prg\ruby\_snippets\input>ruby prefilled_v2.rb       
Select Users: ["www.google.com", "www.github.com"]     
www.google.comde                                       
"www.google.code"                                      

C:\prg\ruby\_snippets\input>ruby prefilled_v2.rb       
Select Users: ["www.google.com", "www.github.com"]     
www.google.code                                        
"www.google.cde"                                       

C:\prg\ruby\_snippets\input>ruby prefilled_v2.rb       
Select Users: ["www.google.com", "www.github.com"]     
www.                                                   
Your answer is invalid it must contain a www.          
?  Select Users: ["www.google.com", "www.github.com"]  
www.google.com                                         
"www.google.com"                                       

C:\prg\ruby\_snippets\input>ruby prefilled_v2.rb       
Select Users: ["www.google.com", "www.github.com"]     
wwww.google.cde                                        
"www.google.cde"                                       

C:\prg\ruby\_snippets\input>ruby prefilled_v2.rb       
Select Users: ["www.google.com", "www.github.com"]     
www.google.de                                          
"www.googlede"                                         

C:\prg\ruby\_snippets\input>ruby prefilled_v2.rb       
Select Users: ["www.google.com", "www.github.com"]     
www.                                                   
"www."                                                 
abinoam commented 8 years ago

Hi @tukanos, Readline is hard to make work flawlessly at Windows and JRuby. I have spent some time on it. But have let it still for some time. Then, if you're using Windows you will surely experiment some bugs.

tukanos commented 8 years ago

Hi @abinoam,

Yes I know Readline is a pain in the ... I have now tested on

ruby 2.2.2p95 (2015-04-13 revision 50295) [x64-mingw32]

simple test and that behaves as it should:

ruby -v -rreadline -e "Readline.output=STDOUT;p Readline.readline('>>',true)"

I have even created a sample from highline source code which works too without any issues (little bit slow due to the ttys):

require 'readline'     

class Test

  def readline_read(prompt,question)
     raw_answer  = run_preserving_stty do
        Readline.readline(prompt, true)
      end
      p raw_answer
  end

    # Yield a block using stty shell commands to preserve the terminal state.
    def run_preserving_stty
      save_stty
      yield
    ensure
      restore_stty
    end

    # Saves terminal state using shell stty command.
    def save_stty
      @stty_save = `stty -g`.chomp rescue nil
    end

    # Restores terminal state using shell stty command.
    def restore_stty
      system("stty", @stty_save) if @stty_save
    end
end  

app = Test.new
app.readline_read('>>','test')

It has to be the combination of some features like Auto-complete that are creating this issue. I don't know highline code good enough to see the issue yet.

abinoam commented 8 years ago

Hi @tukanos, Closing this. Feel free to reopen it if you need.