2015-12-13 6 views
5

Ich benutze die readline-Bibliothek in C, um eine Bash-ähnliche Eingabeaufforderung innerhalb der Bash zu erstellen. Als ich versuchte, die Eingabeaufforderung bunt zu machen, mit Farbsequenzen wie these, funktioniert die Farbgebung gut, aber der Cursorabstand ist durcheinander. Die Eingabe wird zu früh umbrochen, und der Zeilenumbruch erfolgt in derselben Zeile, sodass die Eingabeaufforderung überschrieben wird. Ich dachte, ich sollte die Farbsequenzen mit \[ und \] wieDrucken Sie ausgelassene Farbzeichen in bash

readline("\[\e[1;31m$\e[0m\] ")

entkommen Aber das druckt die eckigen Klammern, und wenn ich die Schrägstriche entkommen druckt es auch jene. Wie entkomme ich den Farbcodes, damit der Cursor noch funktioniert?

+0

Solche Escaping-Sequenzen sind eine Bash-spezifische Sache. Wenn Sie aus einem Programm drucken, benötigen Sie die umgebenden Klammern nicht. Beachten Sie auch, dass die Sequenz '" \ e "' eine Erweiterung im GCC-Compiler ist und nicht generell portabel ist. –

+0

Um meinen vorherigen Kommentar zu verdeutlichen, meine ich, dass das Paar "" und "" "Bash-spezifisch ist und Sie es nicht brauchen. –

+0

Haben Sie 'readline (" \ [\ 033 [1; 31m $ \ 033 [0m \] ")' versucht? '\ 033' anstelle von' \ e' –

Antwort

6

Die Möglichkeit, readline mitzuteilen, dass eine Zeichenfolge in einem Eingabeaufforderungsstring den Cursor bei der Ausgabe auf dem Bildschirm nicht tatsächlich mit den Markierungen RL_PROMPT_START_IGNORE umgibt (momentan ist dies das Zeichenliteral '\ 001' in) C-Header-Datei von readline) und RL_PROMPT_END_IGNORE (derzeit '\ 002').

Und wie @Joachim und @Alter sagten, verwenden Sie '\ 033' anstelle von '\ e' für die Portabilität.

2

fand ich diese Frage bei der Suche des GNU verfeinern Readline- in einem Bash-Skript veranlassen. Wie readline in C-Code, \[ und \] sind nicht speziell, aber \001 und \002 funktionieren , wenn buchstäblich gegeben über die spezielle Behandlung bash bietet zitiert Wörter der Form $'string'. Ich war schon einmal hier (und bin nicht zufrieden gewesen, weil ich nicht wusste, ob ich es mit $'…' kombinieren könnte), also dachte ich, ich würde meine Erklärung hier lassen, dass ich eine Lösung habe.

die Daten hier mit Hilfe des mitgelieferten war ich in der Lage, dieses Ergebnis zu dem Schluss:

C1=$'\001\033[1;34m\002' # blue - from \e[1;34m 
C0=$'\001\033[0;0m\002' # reset - from \e[0;0m 
while read -p "${C1}myshell>$C0 " -e command; do 
    echo "you said: $command" 
done 

ein blaues Prompt Dies gibt die myshell> und hat einen hinteren Raum sagt, ohne Farben für den aktuellen Befehl. Schlagen Up oder Eingabe und Befehl, die in die nächste Zeile umbrochen werden nicht mehr durch die nicht druckbaren Zeichen verwechselt werden.

Wie in der akzeptierten Antwort erklärt, \001 (Start of Heading) und \002 (Start of Text) ist der RL_PROMPT_START_IGNORE und RL_PROMPT_END_IGNORE Marker, die bash sagen und readline nichts zwischen ihnen zum Zweck des Terminals zählen zu malen. (Auch hier gefunden: \033 ist zuverlässiger als \e und da ich jetzt sowieso oktal Codes verwende, könnte ich auch einen mehr verwenden.)

Es scheint ziemlich der Mangel an Dokumentation zu diesem Thema; das Beste, was ich war in Perl in der Dokumentation Term::ReadLine::Gnu, die sagt finden konnten:

PROMPT können einige Escape-Sequenzen. Verwenden Sie RL_PROMPT_START_IGNORE, um eine Sequenz von nicht druckbaren Zeichen zu beginnen, und RL_PROMPT_END_IGNORE, um die Sequenz zu beenden.