Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

instant prompt: fix DCS escape substitution to also work with tmux passthrough #2518

Closed
wants to merge 1 commit into from

Conversation

jdrouhard
Copy link

@jdrouhard jdrouhard commented Dec 26, 2023

While using instant prompt, I was occasionally getting the notice that my zsh config was producing output, but the actual output was always blank. I tracked it down to some escape codes produced by a plugin (base16-shell in my case) that was wrapping the escape codes in the tmux passthrough DCS.

Essentially it looked like: \ePtmux;\e\e]4;0;rbg:28/2c/34\e\e\\\e\\. The important thing to note is that any escape character in the passed-through escape code must be itself escaped with an escape character. This includes the ending ST (\e\\) itself if present.

Your pattern to ignore DCS in output produced after the instant prompt was almost working, but it matched the internal ST as the “end” and left a stray one in the unexpected content. The fix is seemingly to just force the substitution to match the ST that isn’t itself escaped, which just means removing the “0 or more occurrences” modifier for non-escape-character from the pattern. The * already takes care of matching anything else but it now requires a non-escape followed by ST for the “end”. This fixes the issue I was seeing. For the rare case where an empty DCS appears (\eP\e\\), I just put that as an alternate match to the *[^$'\e']($'\e\\') part.

Thanks for an incredibly fast, feature rich toolkit for zsh prompts that I only recently discovered. Wished I found it years ago!

@romkatv
Copy link
Owner

romkatv commented Jan 5, 2024

Thanks for the bug report!

The change you've suggested isn't quite right, but it's alright. Given the high quality of the issue description it's easy for me to fix the code. Please let me know if the fix works for you.

You might want to send the output intended for the TTY directly to $TTY. Alternatively, produce that output before activating instant prompt. Relying on powerlevel10k to replay the captured output is a bit of a crutch.

@jdrouhard
Copy link
Author

Yeah that seems to work too. Can't say I understand what (|* does or why this makes it ignore all double-escapes in the internal escape code, but neat! Your ZSH-fu is astonishing.

Would this also work if there was an ST in the internal escape code that wasn't at the very end?

And I agree that relying on the captured output replay is a crutch. I could make the suggestion at the base16-shell repo to write to $TTY directly if that ends up working as well.

@romkatv
Copy link
Owner

romkatv commented Jan 6, 2024

Here's the pattern: $'\eP'(|*[^$'\e'])($'\e\e')#$'\e\\'. It matches the following sequence:

  1. ESC
  2. P
  3. Either nothing, or anything followed by non-ESC.
  4. An even number of ESC.
  5. ESC
  6. \

(S) ensures that in case of multiple potential matches, the shortest match wins.

This should correctly match all DCS sequences.

@romkatv romkatv closed this Jan 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants