
以下は私が欲しいものです。タブの完成があいまいな場合、bashは可能性リストを印刷します。リストの各単語で押す必要がある次の文字の色を指定したいと思います。
これまで私がしたことは次のとおりです。私は.bashrcで次の関数を定義し、コマンド全体を呼び出しました。
_colourunique() {
local word=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=($(compgen -f -- "${word}"))
if [[ "$word" ]] && [[ ${#COMPREPLY[@]} -gt 1 ]]; then
local w
local i=0
for ((i=0;i<${#COMPREPLY[@]};i++)) ; do
w=${COMPREPLY[$i]}
n=${#word}
COMPREPLY[$i]="${w:0:n}\033[91m${w:n:1}\033[0m${w:$((n+1))}"
done
fi
}
complete -D -F _colourunique
しかし、うまくいきません...入力したとき
ls D[TAB]
次のように自動的に完了します。
ls D\033[91m
ドキュメント、デスクトップなどをリストする可能性の代わりに、ここで何が間違っている可能性がありますか?それともこれを達成するための他の簡単な方法はありますか?
アップデート1:
私はここで何が起こっているのか理解していると思います。 COMPREPLYのすべての単語に\ 033 [91mを追加したので、bashはこの部分がすべての人に共通していると考え、コマンドプロンプト自体にその共通用語を自動補完します。 (単にリストを印刷する代わりに)
だから私はCOMPREPY配列を編集するこの方法が正しい方法だとは思わない。別の方法がありますか?
アップデート2:
一意性を維持するために、文字列に$ iと\ bを追加してみました。
COMPREPLY[$i]="${w:0:n}$i\b\033[91m${w:n:1}\033[0m${w:$((n+1))}"
これで、以下のように可能なタブ補完が印刷されます。
D0\b\033[91mo\033[0mwnloads D1\b\033[91me\033[0msktop
これは、リストがそのまま印刷されることを意味します。 \b または \033[91m 文字は評価されませんでした。 :-(
アップデート3:
応答が次のようになるので、bashで私が望むことを達成する方法はありません(zshに行かない限り)。私は代替を受け入れることにしました。目立つように、次の一意のキーストロークを各単語の末尾に追加しようとしています。
以下はこれまでのコードです。
SanitiseString () {
local String="$1"
local j
for j in \\ \! \@ \# \$ \% \^ \& \* \( \) \+ \{ \[ \] \} \| \; \: \" \' \, \? \ ; do
String=${String//"$j"/\\"$j"}
done
echo "$String"
}
_colourunique() {
saveIFS=$IFS
IFS=$'\n'
local word=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=($(compgen -f -- "${word}"))
if [[ "$word" ]] ; then
local w
local i=0
for ((i=0;i<${#COMPREPLY[@]};i++)) ; do
w="${COMPREPLY[$i]}"
n=${#word}
w=$(SanitiseString "$w")
if [[ ${#COMPREPLY[@]} -gt 1 ]] ; then
COMPREPLY[$i]="$w :${w:n:1}"
else
COMPREPLY[$i]="$w"
fi
done
fi
IFS=$saveIFS
}
complete -D -F _colourunique
これにより、次の一意のキーストロークのオプションが次のように区切られて印刷されます。
しかし、コードにはまだ2つの迷惑な問題があります。この問題を解決する必要があります。
- オートコンプリートディレクトリの末尾に/を追加しなくなりました。
- オートコンプリート後、スマートインターバルは実行されなくなりました。
どんな提案がありますか?
答え1
正確に要求された内容ではありませんが、最初は私と同じ考えを持っていましたが、結局このように解決したところ、色付けするよりも良いと思われ、この答えを上げることになりました。
このオプションは次のように設定できます。GNUライン読み取りライブラリ:
完成プレフィックス表示長 変更なしで表示される可能性のある完成リストの共通プレフィックスの文字長。 0より大きい値に設定すると、可能な補完を表示するときにその値より長い共通接頭辞が省略記号で置き換えられます。
たとえば、この行~/.inputrc:
set completion-prefix-display-length 2
また成功します(共通プレフィックスが2文字より長い場合)。
答え2
私の.cはそれほど熱くはありませんが、内部で読んでいます。http://git.savannah.gnu.org/cgit/bash.git/snapshot/bash-master.tar.gz、私の意見では、COMPREPLYは非動作テキストデータに過ぎません。アイオ、そこにエスケープ文字を正しくインポートしても、最終的に私たちが表現するために使用する文字の非魔法的/非特殊表現として印刷されます。
単一文字「Escape」に似ている\033
か\e
、代わりに4〜2個のバックスラッシュ文字と0、3、およびEsがあります。
printf
私は.cを見る前に//echo
のさまざまな繰り返しを見て、実際にどのように見えるかを確認しました。eval
処理済みCOMPREPLY の値です。
間違っているかもしれませんが、チェックインは COMPREPLY が STRINGLIST 型の構造であるようにstrlist_print()
見えます( で定義されています)。lib/sh/stringlist.c
externs.h