^ C bewirkt, dass PROMPT = '$ (my_prompt_function)' niemals aufgerufen wird

2

Ich versuche, eine komplexere Funktion auszuführen, die den PROMPT-String in ZSH erstellt, und unter normalen Umständen funktioniert es. Da ich jedoch den folgenden TRAPINT habe, um "^ C" zu drucken, wenn ich SIGINT an der Eingabeaufforderung sende, funktioniert es nicht (es ruft meine Funktion nicht auf).

.zshrc

TRAPINT() {
    print -n "^C"
    return $(( 128 + $1 ))
}
my_prompt_function() {
    echo '>'
}
setopt PROMPT_SUBST
PROMPT='$(my_prompt_function)'

Wenn ich jedoch drücke ^ C an der Eingabeaufforderung hängt es nur:

>
>^C
# ...hangs here until I press <Enter>

Wie kann ich in TRAPINT feststellen, dass ich an der Eingabeaufforderung im Vergleich zu einem laufenden Programm bin, sodass ich keinen Fehler zurückgeben kann?

Jrop
quelle

Antworten:

1

Es scheint, dass die Befehlsersetzung nicht ausgewertet wird, nachdem die Shell auf diese Weise unterbrochen wurde.

Sie können es umgehen, indem Sie die precmd Haken:

precmd () {
    MYPROMPT='>'
}
setopt PROMPT_SUBST
PROMPT='${MYPROMPT}'

precmd wird vor jeder Eingabeaufforderung ausgeführt. Beachten Sie, dass precmd wird nicht erneut ausgeführt, wenn die Eingabeaufforderung nur ohne Ausführen einer Befehlszeile neu gezeichnet wird (wie in diesem Fall). Es funktioniert immer noch als der Wert von MYPROMPT bleibt auch ohne rennen precmd.


  • Sie können auch mehrere haben precmd funktionen. Sie können sie mit dem verwalten add-zsh-hook Modul:

    autoload -Uz add-zsh-hook
    myprompt_function () {
        MYPROMPT='>'
    }
    add-zsh-hook precmd myprompt_function
    setopt PROMPT_SUBST
    PROMPT='${MYPROMPT}'
    
  • Sie können auch die spezielle Array-Variable verwenden psvarAuf deren Mitglieder kann mit dem Prompt-Escape zugegriffen werden %v oder %Nv woher N ist der anzuzeigende Array-Index:

    precmd () {
        psvar[3]='>'
    }
    PROMPT='%3v'
    
Adaephon
quelle
0

Ich akzeptiere Adaephons Antwort, poste aber hier, um meine endgültige Lösung zu zeigen:

TRAPINT() {
  if [ "$IS_PROMPTING" == true ]; then
    print -n "^C"
    return $(( 128 + $1 ))
  fi
}
precmd() {
  IS_PROMPTING=true
  PROMPT=$(command-that-generates-prompt-string)
}
preexec() {
  IS_PROMPTING=false
}

TRAPINT prüft unter bestimmten Bedingungen, ob der Benutzer an der Eingabeaufforderung oder innerhalb eines Ausführungsbefehls ist, und zwar über ein Flag, das über precmd / preexec entsprechend gesetzt ist.

Jrop
quelle