自定义bash完成输出:每行建议新行
当您输入内容时,您经常使用bash自动完成:例如,您开始编写命令,然后键入TAB以获取其余的单词。
您可能已经注意到,当多个选项与您的命令匹配时,bash显示如下: foobar@myserv:~$ admin- admin-addrsync admin-adduser admin-delrsync admin-deluser admin-listsvn admin-addsvn admin-chmod admin-delsvn admin-listrsync 我正在寻找一种解决方案来显示新行上的每个可能的解决方案,类似于ls -l上的最后一列。更好的是,如果我可以应用这样的规则,这将是完美的:“如果您发现少于10个建议,请逐行显示,如果更多=>实际显示”。
4.2之前的bash不允许对完成的输出格式进行任何控制,不幸的是。
Bash 4.2允许在全球范围内切换到1行建议的输出,如Grisha Levit’s helpful answer所述,它也链接到clever workaround以实现每个完成功能的解决方案。 以下是自定义完成的棘手解决方法。 测试下面的概念证明: >保存到文件并将其(。文件)导入到交互式shell中 – 这将: >定义一个名为foo的命令(一个shell函数) >调用为: >如果当前目录中的2到9个文件匹配,您将看到所需的逐行显示。 限制: >仅在正在编辑的命令行上应用于LAST参数时,完成才能正常工作。 做法: >定义和分配一个自定义完成shell函数到感兴趣的命令。 # 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 http://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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |