3

When you don't properly complete a quote or a complex command in zsh before pressing Enter, you're prompted to complete it with the secondary prompt defined by PS2, e.g. >.

Is there any way to disable the secondary prompt? I don't mean changing the PS2 setting, but switching off the whole feature. I couldn't find one in the options.

For me, it's much more likely that the secondary prompt appears due to a mistake on my part, rather than due to actually wanting to continue the command. Therefore, a syntax error would be more useful than the secondary prompt, particularly as you can't immediately go back up to the original line when the secondary prompt appears.

(When I actually do need to enter a multiline command, I can do that with Shift+Enter to insert a line break. Unlike with the secondary prompt, the zsh line editor allows going back to previous lines in that case.)

2 Answers 2

2

There's likely a cleaner and more reliable way to do it, but as a hack, you could do something like:

accept-line() {
  {
    unfunction _al_f_
    functions[_al_f_]=$BUFFER
  } 2> /dev/null
  if (( $+functions[_al_f_] )); then
    zle .$WIDGET
  else
    zle beep
    zle -M "Command unfinished or invalid."
  fi
}
zle -N accept-line

(and repeat for other line-accepting widgets if needed).

That is, upon accept-line, try to define a function with the editing buffer as the body, and if that fails, report an error to the user instead of accepting the line.

Note that aliases are not expanded upon assignments to functions[_al_f_], so if you have an alias that modifies the syntax, such as a alias not_before=until, that will throw things off.

4
  • Thank you very much for this idea. I haven't tried implementing it fully yet, but I see the function assignment actually yields a useful error error message such as unmatched ` or parse error near `fi', so I'll try to make use of that.
    – ak2
    Jul 3, 2023 at 15:11
  • Supplementary question: is there a way to make it behave the same way as .accept-line does for a parse error that doesn't result in continuation? I know how to pick the relevant error message out of the output of the failed function assignment, and about print -S for putting the line into the history, but not how to abandon the current line and start a new one after printing the error message.
    – ak2
    Jul 10, 2023 at 11:14
  • Alternatively, is there a way to clear the message printed by zle -M on the next key press? Ideally one that doesn't involve overriding every relevant widget.
    – ak2
    Jul 10, 2023 at 11:15
  • 1
    @ak2, BUFFER= to clear the editing buffer, Possibly zle send-break Jul 17, 2023 at 9:30
2

There is a zsh plugin that disables secondary prompt: https://github.com/romkatv/zsh-no-ps2. If the currently typed command is well-formed, pressing Enter executes it as usual. Otherwise it inserts a newline.

Disclaimer: I'm the author of this plugin.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .