【问题标题】:How would one implement bash-like tab completion?如何实现类似 bash 的制表符补全?
【发布时间】:2009-10-07 17:44:51
【问题描述】:

我正在尝试确定系统如何将字符打印到标准输入——也就是说,它如何打印用户可以删除的字符,以及如果用户点击“Enter”,哪些字符被视为输入。

我碰巧使用的是 C,但如果解决方案依赖于语言,我会感到非常惊讶。

感谢您的任何见解! : D

【问题讨论】:

  • 这里的目的是什么? GNU Readline 库包含完成支持,当然是 GPL 的。
  • 我真的很好奇。我不清楚 Bash 是如何做到这一点的,我想知道——这似乎是我可以在脚本/实用程序中充分利用的东西。感谢您将我指向 GNU Readline 库,我对它并不熟悉。如果我需要实现这个功能,我相信我会转向那个。现在我想我必须弄清楚 Readline 库是如何做到的。
  • Zack:我认为我的回答解决了“Readline 库是如何做到的”这一点。

标签: bash printing tab-completion


【解决方案1】:

正如 iny 所说,bash 使用 readline 作为输入。源码在here,有一个文件叫做complete.c。

为了回答您的问题,我认为它们实际上并未打印到标准输入中。 Readline 包含用户正在编辑的行内容的某种缓冲区,完成打印到此。当用户按下回车键时,缓冲区的内容被发送到任何程序想要读取一行,并且在 bash 的情况下,传递到标准输入。 (Readline 不这样做 - 其他使用 readline 的程序可能只是将值存储到一个字符串中以供以后使用。)

【讨论】:

  • 谢谢,有道理!还要感谢 iny。
【解决方案2】:

一些人指出 bash 使用 readline,这是真的,但我认为您真正要问的是它如何能够在您按 Enter 之前查看您输入的内容。

答案是ttys(即:终端)可以切换到“原始模式”,终端的输入处理被禁用,然后你会看到它进入的每个字符。这也禁用自动回显输入的字符。

有关更多信息,请参阅Reading a single character from a file or a terminal 上的本指南。

【讨论】:

  • 是 ttys 的“原始模式”,它允许程序以这样的方式将建议写入屏幕,当您点击“输入”时,它会被包含在内,就好像用户自己输入的一样?如果是这样,如何访问 tty 进行读写?是简单的 open('/dev/tty') 类型的调用吗?
  • 在原始模式下,程序甚至在用户点击回车之前就能看到按键。当您键入可打印的键(例如:字母、数字符号)时,程序会回显它。当您按下回车键时,它已经在跟踪您输入的内容,并且它只是“接受”缓冲区以响应回车键。
  • 在“cooked 模式”下,终端将回显您输入的所有内容,但在您按下回车之前不会将您输入的内容发送到程序。 bash 在运行其他程序之前将 tty 切换回熟模式。您可以通过运行“sleep 300”然后在 sleep 命令运行时键入来了解熟模式与原始模式的行为有何不同。请注意,您可以键入行,甚至具有非常 基本的编辑功能(例如:退格)。一旦你按回车键,那一行将被提交,当 sleep 命令完成时,bash 将尝试执行这些行(所以要小心!)。
【解决方案3】:

它使用 readline 库来处理输入,readline 提供历史和完成。

要真正实现完成,需要访问键盘输入处理。完成必须能够修改它使用的缓冲区。之后,它只是查看当前输入并检查找到了哪些完成。实际的完成逻辑可以以多种方式工作。

【讨论】:

    【解决方案4】:

    这是一个通过 readline 实现制表符补全的 C sn-p:

    http://github.com/rupa/el

    【讨论】:

      猜你喜欢
      • 2010-10-06
      • 2012-03-06
      • 1970-01-01
      • 2014-12-18
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      相关资源
      最近更新 更多