4wk*_*wk_ 21 unix bash customization bash-completion
键入内容时,通常会使用bash自动完成:例如,您开始编写命令,然后键入TAB以获取其余部分.
您可能已经注意到,当多个选项与您的命令匹配时,bash会显示如下:
foobar@myserv:~$ admin-
admin-addrsync admin-adduser admin-delrsync admin-deluser admin-listsvn
admin-addsvn admin-chmod admin-delsvn admin-listrsync
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种解决方案,在新线上显示每个可能的解决方案,类似于上一栏的最后一栏ls -l.更好的是,如果我可以应用这样的规则将是完美的:"如果您发现少于10条建议,则逐行显示,如果更多=>实际显示".
mkl*_*nt0 10
bash不幸的是,版本4.2之前不允许对完成的输出格式进行任何控制.
Bash 4.2+允许在全球范围内切换到每线建议1个输出,如Grisha Levit的有用答案中所述,该答案还链接到实现每完成功能解决方案的巧妙解决方法.
下面是一个棘手的解决办法的定制完成.
解决这个问题一般,对所有定义的落成,将是非常困难(如果有调用方式readline功能直接,它可能是更容易,但我还没有找到一种方法来做到这一点).
要测试以下概念证明:
. file在你的交互shell) -这将:
foo(一个shell函数)foo实际调用时,它只是以诊断形式打印其参数.)foo [fileNamePrefix],然后按tab:
限制:
$PS1,所以解决方法(受/sf/answers/1680480511/启发)使用,它应该在典型的情况下工作,但不是万无一失的.方法:
>/dev/tty,然后手动"重绘"提示和命令行以模仿标准完成行为.# Define the command (function) for which to establish custom command completion.
# The command simply prints out all its arguments in diagnostic form.
foo() { local a i=0; for a; do echo "\$$((i+=1))=[$a]"; done; }
# Define the completion function that will generate the set of completions
# when <tab> is pressed.
# CAVEAT:
# Only works properly if <tab> is pressed at the END of the command line,
# i.e., if completion is applied to the LAST argument.
_complete_foo() {
local currToken="${COMP_WORDS[COMP_CWORD]}" matches matchCount
# Collect matches, providing the current command-line token as input.
IFS=$'\n' read -d '' -ra matches <<<"$(compgen -A file "$currToken")"
# Count matches.
matchCount=${#matches[@]}
# Output in custom format, depending on the number of matches.
if (( matchCount > 1 && matchCount < 10 )); then
# Output matches in CUSTOM format:
# print the matches line by line, directly to the terminal.
printf '\n%s' "${matches[@]}" >/dev/tty
# !! We actually *must* pass out the current token as the result,
# !! as it will otherwise be *removed* from the redrawn line,
# !! even though $COMP_LINE *includes* that token.
# !! Also, by passing out a nonempty result, we avoid the bell
# !! signal that normally indicates a failed completion.
# !! However, by passing out a single result, a *space* will
# !! be appended to the last token - unless the compspec
# !! (mapping established via `complete`) was defined with
# !! `-o nospace`.
COMPREPLY=( "$currToken" )
# Finally, simulate redrawing the command line.
# Obtain an *expanded version* of `$PS1` using a trick
# inspired by https://stackoverflow.com/a/24006864/45375.
# !! This is NOT foolproof, but hopefully works in most cases.
expandedPrompt=$(PS1="$PS1" debian_chroot="$debian_chroot" "$BASH" --norc -i </dev/null 2>&1 | sed -n '${s/^\(.*\)exit$/\1/p;}')
printf '\n%s%s' "$expandedPrompt" "$COMP_LINE" >/dev/tty
else # Just 1 match or 10 or more matches?
# Perform NORMAL completion: let bash handle it by
# reporting matches via array variable `$COMPREPLY`.
COMPREPLY=( "${matches[@]}" )
fi
}
# Map the completion function (`_complete_foo`) to the command (`foo`).
# `-o nospace` ensures that no space is appended after a completion,
# which is needed for our workaround.
complete -o nospace -F _complete_foo -- foo
Run Code Online (Sandbox Code Playgroud)
bash4.2+(更广泛地说,使用readline6.2+的应用程序)通过使用completion-display-width变量来支持此功能。
执行完成时用于显示可能的匹配项的屏幕列数。如果该值小于0或大于终端屏幕宽度,则将忽略该值。值为0将使匹配项每行显示一次。默认值为-1。
运行以下命令来设置当前会话的所有完成1的行为:
bind 'set completion-display-width 0'
Run Code Online (Sandbox Code Playgroud)
或将您的~/.inputrc2个文件修改为:
set completion-display-width 0
Run Code Online (Sandbox Code Playgroud)
更改所有新Shell的行为。
1请参见此处,了解用于控制各个自定义完成功能的此行为的方法。
2对的readline init文件搜索路径$INPUTRC,~/.inputrc,/etc/inputrc所以修改文件适合您。
| 归档时间: |
|
| 查看次数: |
1564 次 |
| 最近记录: |