如何使 bash 自动完成在行中间工作?
How to make bash autocomplete work in the middle of line?
如何在 bash 中编写自动完成,这样如果我有:
mycommand first_argument|garbage
其中 |
表示光标,它应该将 "first_argument"
而不是 "first_argumentgarbage"
传递给 compgen?
在我的示例中,它的行为方式有误
COMPREPLY=( $(compgen -W "add remove list use current" -- "$cur") ) # buggy
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]}
将 return ${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
请注意,默认情况下,remove
和 garbage
之间不会有 space。如果这是您想要的行为,您将不得不尝试完成机制。
如何在 bash 中编写自动完成,这样如果我有:
mycommand first_argument|garbage
其中 |
表示光标,它应该将 "first_argument"
而不是 "first_argumentgarbage"
传递给 compgen?
在我的示例中,它的行为方式有误
COMPREPLY=( $(compgen -W "add remove list use current" -- "$cur") ) # buggy
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]}
将 return ${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
请注意,默认情况下,remove
和 garbage
之间不会有 space。如果这是您想要的行为,您将不得不尝试完成机制。