【问题标题】:How to make bash autocomplete work in the middle of line?如何使 bash 自动完成在中间工作?
【发布时间】:2016-11-30 14:37:29
【问题描述】:

如何在 bash 中编写自动完成功能,如果我有:

mycommand first_argument|garbage

其中| 表示光标,它应该将"first_argument" 而不是"first_argumentgarbage" 传递给compgen?

在我的示例中,它的行为方式错误

COMPREPLY=( $(compgen -W "add remove list use current" -- "$cur") ) # buggy

【问题讨论】:

  • 按原样,您的示例没有显示任何内容。你说的越野车是什么意思?你有完成脚本的来源吗? $cur 的内容是什么?当您将 echo ${COMP_WORDS[COMP_CWORD]} 放在您的 COMPREPLY 声明之前时,它会显示什么?
  • 按空格、左键、制表符?
  • @Aserre:cur=${COMP_WORDS[COMP_CWORD]}。由于光标处没有空格,当然是first_argumentgarbage。

标签: bash compgen


【解决方案1】:

Bash 补全使用lot of different variables。其中一些用于处理输入并确定要完成哪个参数。

对于下面的解释,我将使用这个测试输入(以|为光标):

./test.sh ad re|garbage
  • ${COMP_WORDS} :以数组的形式包含输入的所有单词。在这种情况下,它包含:${COMP_WORDS[@]} == {"./test.sh", "ad", "regarbage"}
    • $COMP_WORDBREAKS 变量中找到单词分隔符
  • $COMP_CWORD :包含光标当前选择的单词的位置。在这种情况下,它包含:$COMP_CWORD == 2
  • $COMP_LINE :包含字符串形式的整个输入。在这种情况下,它包含:$COMP_LINE == "./test.sh ad regarbage"
  • $COMP_POINT :包含光标在整行中的位置。在这种情况下,它包含:$COMP_POINT == 15

仍然使用相同的数据,执行cur=${COMP_WORDS[COMP_CWORD]} 将返回${COMP_WORD} 数组中索引2 处的元素,即regarbage

为了规避这种行为,您还必须使用 $COMP_LINE$COMP_POINT 变量。这是我想出的:

# we truncate our line up to the position of our cursor
# we transform the result into an array
cur=(${COMP_LINE:0:$COMP_POINT})

# we use ${cur} the same way we would use ${COMP_WORDS}
COMPREPLY=( $( compgen -W "add remove list use current" -- "${cur[$COMP_CWORD]}" ) )

输出:

> ./test2.sh ad re|garbage
# press TAB
> ./test2.sh ad remove|garbage

请注意,默认情况下,removegarbage 之间没有空格。如果这是您想要的行为,您将不得不玩转完成机制。

【讨论】:

  • 感谢您的深入解释。我知道你提到的大部分变量,但我错过了一个优雅的使用模式,这是你最后一次给我的。顺便说一句,${cur[$COMP_CWORD]}$cur[COMP_CWORD]} 是如何工作的?
  • ${cur[$COMP_CWORD]}$cur[COMP_CWORD] 返回相同结果的事实纯属运气。你可以阅读更多关于数组解引用here
  • 我不会称之为纯粹的运气。提到的页面说这类似于将索引放入(( )):>INDEXNR 被视为必须计算为正数的算术表达式。
猜你喜欢
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
  • 2011-07-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多