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

Redraw prompt on resize #684

Open
fdncred opened this issue Dec 19, 2023 · 6 comments
Open

Redraw prompt on resize #684

fdncred opened this issue Dec 19, 2023 · 6 comments
Labels
bug Something isn't working

Comments

@fdncred
Copy link
Collaborator

fdncred commented Dec 19, 2023

Platform WSLg
Terminal software ghostty and iterm2

The prompt is disappearing when terminal window is resized in Ghostty
disappearing-prompt

This is the explanation I received from the author of the Ghostty terminal @mitchellh (thank you for the answer).


When Ghostty sees a "prompt start" semantic prompt message from shell integration, it also assumes that the shell integration is capable of redrawing the prompt on resize events. On future resize events, Ghostty will clear the currently active prompt line if the cursor is at a prompt and assume the shell will redraw it. This should be the same behavior as Kitty.

The reason for this is that it enables complex and multi-line prompts to cleanly redraw when being resized. For example, look at the message with my prompt and iTerm2 (which doesn't have this feature). My shell is fish. The code to do this is in the src/shell-integration folder in Ghostty.

Notice iTerm2 the prompt gets completely screwed up, but on Ghostty the prompt and text remains clean throughout multiple text reflows. This is due to this redraw feature.

iterm2

iterm2-CleanShot_2023-12-18_at_18.52.20.mov

Ghostty

ghostty-CleanShot_2023-12-18_at_18.51.55.mov

My guess is nushell is sending the "prompt start" semantic prompt OSC sequence, but is NOT doing the prompt redraw behavior. I'm not sure how Kitty handles this with nushell... (if at all)


We've been seeing weird prompt-drawing/redrawing issues for a while. I, for one, had no idea that terminals would erase the prompt while waiting for a resize. We need to look into this because that seems to be the case. We need to detect the resize and repaint the prompt. I'm not sure if it's a good idea to try and detect the terminal (kitty, ghostty, iterm2, etc) and only redraw for a few terminals or if we should just keep-it-simple and always redraw the prompt on resize. I'm also not sure if we should wait for all the resize messages to stop coming in before we repaint the prompt, or what heuristic we should use exactly.

Also not sure if this is better or worse since #675. I haven't tried an earlier version. /cc @danielsomerfield

One last note, there is a shell_integration script for Ghostty + fish/bash/zsh. The one above is fish. The script does some ansi escape sequence calls like set the cursor, set prompt start, stop, pre_exec, post_exec (OSC133), and set title (OSC7) but it seems the important thing in the script is set --global fish_handle_reflow 1 to tell fish to redraw the prompt. At least I think that is what that line means.

@fdncred fdncred added the bug Something isn't working label Dec 19, 2023
@danielsomerfield
Copy link
Contributor

Thanks for the detailed submission. I can take a look at this one. I can imagine how this might happen but I'll have to confirm. I feel like I also need to be a little more disciplined about keeping a test plan against all the various terminals. There are a lot of opportunity for a fix in one shell that breaks another and automated testing would be very challenging. I'll put together a matrix of sorts so it's easier to remember all the edge cases to check.

@fdncred
Copy link
Collaborator Author

fdncred commented Dec 19, 2023

Sounds good. I'm not sure which terminals support this "prompt erasure" other than Ghostty and Kitty. I commonly test with WezTerm, Alacritty, Windows Terminal, Ghostty, iTerm2, Tabby, gnome-terminal, and maybe a few others.

@danielsomerfield
Copy link
Contributor

danielsomerfield commented Dec 19, 2023

A couple of things:

  • from what I can see, the behaviour is better with Better behaviour on resize #675, but still not great. I'm also not 100% confident since I've only tested it with a very simple prompt. It's possible that more complex prompts would behave a bit differently. Do you happen to know what is rendering the prompt from @mitchellh?
  • I see you have a UX Test Checklist already. I missed that before. If I add said matrix, I can add it there or at least make sure not to duplicate what' already there.

@fdncred
Copy link
Collaborator Author

fdncred commented Dec 19, 2023

Mitchell's prompt is from fish. My prompt is from oh-my.nu in the nu_scripts/modules/prompt folder and this is in the config.nu.

# prompt
use "modules/prompt/oh-my.nu" git_prompt
$env.PROMPT_COMMAND = {|| (git_prompt).left_prompt }
$env.PROMPT_COMMAND_RIGHT = {|| (git_prompt).right_prompt }
$env.PROMPT_INDICATOR = {|| if ($env.LAST_EXIT_CODE == 0) {$"(ansi green_bold)\n❯ (ansi reset)"} else {$"(ansi red_bold)\n❯ (ansi reset)"}}
$env.TRANSIENT_PROMPT_COMMAND = { "" }
$env.TRANSIENT_PROMPT_COMMAND_RIGHT = { || (git_prompt).right_prompt }
$env.TRANSIENT_PROMPT_INDICATOR = {|| if ($env.LAST_EXIT_CODE == 0) {$"(ansi light_yellow_bold)❯ (ansi reset)"} else {$"(ansi light_red_bold)❯ (ansi reset)"}}

@mitchellh
Copy link

mitchellh commented Dec 19, 2023

Do you happen to know what is rendering the prompt from @mitchellh?

I use fish, and I believe it is this: set --global fish_handle_reflow 1 that tells fish to handle reflow on resize for the prompt area.

Note that this isn't just the prompt itself. If you create a multiline input, it redraws the input as well. This isn't the terminal doing this, it's the shell. Example:

CleanShot.2023-12-19.at.12.30.37.mp4

The best bet to learn more about this would be studying the Kitty shell integration scripts: https://github.com/kovidgoyal/kitty/tree/master/shell-integration Kitty was the first terminal I found that did this behavior and their shell integration enables it for all of the shells they support I think...

@fdncred
Copy link
Collaborator Author

fdncred commented Dec 27, 2023

Further research from fish-shell's fish_handle_reflow environment variable.

The reflow issue: fish-shell/fish-shell#7491
The reflow PR: fish-shell/fish-shell#7623

And the latest version of these changes.
https://github.com/fish-shell/fish-shell/blob/b1a1a3b0a72211310e96d5f14631519df8bd3438/share/functions/__fish_config_interactive.fish#L240-L267

Interesting enough, this is all handled in fish-script and with their internal commandline built-in command. Which is kind of written in rust https://github.com/fish-shell/fish-shell/blob/b1a1a3b0a72211310e96d5f14631519df8bd3438/fish-rust/src/builtins/commandline.rs#L3 but not really.

pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> Option<c_int> {
    run_builtin_ffi(crate::ffi::builtin_commandline, parser, streams, args)
}

https://github.com/fish-shell/fish-shell/blob/b1a1a3b0a72211310e96d5f14631519df8bd3438/fish-rust/src/builtins/shared.rs#L1027-L1055

C code to commandline (i think)
https://github.com/fish-shell/fish-shell/blob/b1a1a3b0a72211310e96d5f14631519df8bd3438/src/builtins/commandline.cpp#L133

or maybe it is in rust? it's kind of hard to follow.
https://github.com/fish-shell/fish-shell/blob/b1a1a3b0a72211310e96d5f14631519df8bd3438/fish-rust/src/screen.rs#L251

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants