有什么类似于ruby readline并带默认值的东西吗?(涉及IT技术)

12
如果我想在终端上显示一个默认值的提示符,该怎么做? Ruby标准库中的Readline.readline()函数可以设置历史记录,但不能填充默认值(至少我没发现如何实现)。 我希望实现这样的功能:
input = Readline.readline_with_default('>', 'default_text')

控制台:

> default_text|

1
很难为交互式控制台行为举一个例子,但这里有一个尝试。 - jes5199
1
是的,我希望他们修改它。 - jes5199
1
我阅读了ext/readline.c文件,认为Ruby的Readline库不支持该功能。如果GNU Readline支持此功能,则可以创建一个扩展程序;否则,我赞同Farrel的ncurses建议。 - John Douthat
顺便提一下,最新版本的haskeline(0.6.4.0)有这样的API: getInputLineWithInitial:“此函数的行为方式与getInputLine完全相同,只是它预先填充输入区域。 输入区域中驻留的文本以两个字符串的形式给出。元组左侧的字符串将出现在光标左侧,右侧的字符串将出现在光标右侧。” - imz -- Ivan Zakharyaschev
我正在寻找类似于Curry的东西--http://stackoverflow.com/q/5737170/94687。如果不需要预填充输入文本,那么像`rlwrap`这样的简单基于readline的包装器对于任何程序都可以使用...(也许,我们可以编写一个类似于`rlwrap`的包装器,但是带有预填充输入行的协议?..) - imz -- Ivan Zakharyaschev
显示剩余2条评论
6个回答

10
你所要求的可以使用Readline实现。有一个回调函数,可以在提示显示后获取控制权并将一些文本插入到读取缓冲区中。
这对我有效:
Readline.pre_input_hook = -> do
  Readline.insert_text "hello.txt"
  Readline.redisplay

  # Remove the hook right away.
  Readline.pre_input_hook = nil
end

input = Readline.readline("Filename: ", false)
puts "-- input:#{input.inspect}"

顺便说一下,我曾经尝试使用HighLine,但对我来说它似乎没有替代品。令人失望的原因之一是HighLine#ask 将光标移动键读取为常规输入。在发现了这种情况后,我停止了继续探索。


1
这正是我正在寻找的!谢谢! - wrzasa
感谢您展示这个伟大的解决方案。特别是 Readline.pre_input_hook = nil 这个技巧。我不知道 pre_input_hook 可以像这样使用。太聪明了! - agate
2
警告!这在MacOS X上的Readline实现中不起作用。我试了一个小时才弄清楚为什么它不起作用。没有错误,没有警告,什么都没有,只是不起作用。在Ubuntu上,它可以正常工作。 - Sergio
看起来 insert_text 调用了 GNU 的 rl_insert_text,在 Ubuntu 和 MacOS 之间有所不同。https://apidock.com/ruby/Readline/insert_text/class - Ting Yi Shih
这个答案中的示例在我的电脑上无法工作(在当前的Ubuntu系统下) - 没有错误信息,提示符后面也没有插入任何东西。我无法弄清楚为什么会这样。 - Guss

5

+1 表示高亮

尝试使用以下内容:

require 'highline/import'
input = ask('> ') {|q| q.default = 'default_text'} # > |default_text|

垂直线(在注释中)代表什么意思? - imz -- Ivan Zakharyaschev
1
这是您将看到的输出。如果您没有输入任何内容,则输入将设置为“default_text”。 - rainkinz
1
@rainkinz:那么,用户必须看到垂直条,对吧?这有点不寻常:在提示之后,但在两个垂直杠之间输入东西。 - imz -- Ivan Zakharyaschev
1
它与原帖所描述的要求不同 - 默认值应该是可编辑的。 - Ting Yi Shih

3

2

我正在处理同样的问题。

我目前的做法是:

options = ["the_text_you_want"]
question = "use TAB or up arrow to show the text > "

Readline.completion_append_character = " "
Readline::HISTORY.push options.first
Readline.completion_proc = proc { |s| options.grep( /^#{Regexp.escape(s)}/ ) }

while value = Readline.readline(question, true)
  exit if value == 'q'
  puts value.chomp.strip #do something with the value here
end

是的,这很傻,但这是我找到的唯一方法。

有人找到了解决办法吗?


2
是的,有一个解决方案,请查找周围的“pre_input_hook”。 - Alex Fortuna

2

虽然这是对一个旧问题的新回答,但我想添加一下,因为我也在寻找同样的答案。

tty-prompt 看起来可以满足您的需求 - 可以要求输入并提供可编辑的默认值。这是我找到的唯一一个可以提供可编辑默认值的宝石(但可能还有其他宝石)。

完整的代码如下:

require "tty-prompt"
prompt = TTY::Prompt.new
input = prompt.ask('What is your name?', value: 'Bob')

1

Highline并不完全符合您所描述的功能,但或许它已经足够接近了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接