Folgendes möchte ich haben. Wenn die Tab-Vervollständigung nicht eindeutig ist und Bash die Liste der Möglichkeiten druckt. Ich möchte, dass es das nächste Zeichen färbt, das ich in jedes Wort in der Liste drücken soll.
Folgendes habe ich bisher getan. In meiner .bashrc habe ich folgende Funktion definiert und den vollständigen Befehl aufgerufen
_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
Aber es funktioniert nicht ... Wenn ich tippe
ls D[TAB]
Es wird automatisch vervollständigt als
ls D\033[91m
Anstatt die Möglichkeiten Dokumente, Desktop usw. aufzulisten. Was könnte hier falsch laufen? Oder gibt es einen anderen direkten Weg, um dies zu erreichen?
UPDATE 1:
Ich glaube ich verstehe was hier passiert. Da ich jedem Wort in COMPREPLY \ 033 [91m] hinzufüge, sieht bash, dass dieser Teil allen gemeinsam ist, und vervollständigt diesen gemeinsamen Begriff automatisch in der Eingabeaufforderung selbst. (anstatt einfach die Liste zu drucken)
Daher denke ich nicht, dass diese Methode zum Bearbeiten des COMPREPLY-Arrays der richtige Weg ist. Gibt es eine andere Methode?
UPDATE 2:
Um die Einheitlichkeit zu bewahren, habe ich versucht, ein $ i und \ b in den String einzufügen.
COMPREPLY[$i]="${w:0:n}$i\b\033[91m${w:n:1}\033[0m${w:$((n+1))}"
Jetzt werden die möglichen Tab-Vervollständigungen wie folgt gedruckt.
D0\b\033[91mo\033[0mwnloads D1\b\033[91me\033[0msktop
Das heißt, die Liste wird als solche gedruckt. Es gibt keine Auswertung von \ b oder \ 033 [91m Zeichen. :-(
UPDATE 3:
Da die Antworten so aussehen, gibt es keine Möglichkeit, das zu erreichen, was ich in Bash will (es sei denn, ich wechsle zu zsh). Ich entschied mich für eine andere Option. Ich werde versuchen, den nächsten eindeutigen Tastenanschlag an das Ende jedes Wortes anzuhängen, damit es auffällt.
Es folgt der bisherige Code.
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
Dadurch werden die Optionen mit dem nächsten eindeutigen Tastendruck gedruckt, der durch Folgendes getrennt ist:
Der Code weist jedoch immer noch zwei irritierende Probleme auf. was ich lösen muss
- Das / am Ende von automatisch vervollständigten Verzeichnissen wird nicht mehr angehängt
- Der intelligente Abstand nach der automatischen Vervollständigung wird nicht mehr ausgeführt.
Irgendwelche Vorschläge?
quelle
bash
bieten jedoch einfach keinen Hook für die benutzerdefinierte Formatierung der möglichen Vervollständigungen.Antworten:
Obwohl dies nicht genau das ist, wonach Sie gefragt haben, habe ich beschlossen, diese Antwort zu posten, weil ich ursprünglich die gleiche Idee hatte wie Sie, aber am Ende löse ich sie so und finde sie sogar besser als das Färben.
Diese Option kann für die GNU-Readline-Bibliothek festgelegt werden :
Vervollständigungspräfix-Anzeigelänge Die Länge des allgemeinen Präfixes einer Liste möglicher Vervollständigungen in Zeichen, die ohne Änderung angezeigt wird. Bei einem Wert größer als Null werden häufig verwendete Präfixe, die länger als dieser Wert sind, durch Auslassungspunkte ersetzt, wenn mögliche Abschlüsse angezeigt werden.
So zum Beispiel diese Zeile in ~ / .inputrc :
macht den Trick auch (wenn das gemeinsame Präfix länger als zwei Zeichen ist).
quelle
Meine .c ist nicht so heiß, aber wenn ich in http://git.savannah.gnu.org/cgit/bash.git/snapshot/bash-master.tar.gz herumlese, sieht es für mich so aus, als wäre COMPREPLY nichts weiter als nicht aktivierte Textdaten. iow, selbst wenn ein Escape korrekt eingefügt wird, wird es als nicht magische / nicht spezielle Darstellung der Zeichen gedruckt, mit denen wir sie ausdrücken.
wie
\033
oder\e
nicht das einzelne Zeichen "Escape", sondern die vier oder zwei Zeichen von Backslashes und Nullen, Dreien und Es.Ich stieß mit verschiedenen Iterationen
printf
/echo
/eval
vor dem Tauchen in die .c , um zu sehen , wie es tatsächlich behandeln die Werte in COMPREPLY.könnte falsch sein, aber überprüfen Sie
strlist_print()
inlib/sh/stringlist.c
aussieht wie COMPREPLY eine Struktur vom Typ String ist (wie definiert inexterns.h
).quelle