nushell
nushell copied to clipboard
`nushell` replicates prompt line with every keystroke on `wezterm`
Describe the bug
Every keystroke duplicates the prompt line for no reason.
See wez/wezterm#1999.
I had to post a bug here, as I'm beginning to think that this is
very much tied to nushell and not the wezterm (or atleast both).
How to reproduce
Nothing but type in your terminal and see the prompt replicate.
Expected behavior
I don't expect the terminal to fill up with the line before the keystroke.
Screenshots
No response
Configuration
| key | value |
|---|---|
| version | 0.62.0 |
| branch | |
| tag | |
| build_os | windows-x86_64 |
| rust_version | rustc 1.60.0 (7737e0b5c 2022-04-04) |
| rust_channel | stable-x86_64-pc-windows-msvc |
| cargo_version | cargo 1.60.0 (d1fd9fe2c 2022-03-01) |
| pkg_version | 0.62.0 |
| build_time | 2022-05-09 20:50:11 +02:00 |
| build_rust_channel | release |
| features | default, trash, which, zip |
| installed_plugins |
Additional context
I'm on Windows. I tried with nightly wezterm, latest stable of nu, with no configuration in wezterm, and with default configuration for nushell; We also tried to no configuration files for nushell.
one idea is to try to compile and run reedline by itself, just to see if there's something odd going on there.
I've installed nu from main, i.e. 0.62.1 and the issue is not present here.
I did this by
cargo install nu --git https://github.com/nushell/nushell.git
let's close this if the problem doesn't exist any longer. thanks!
Issue still presents if linebreak characters (\n \f \t) in right prompt and caret on last terminal line (frequently after long outputs)
tested on wezterm alacritty and conemu \n\r causes issue on all of them
I'm not sure how to reproduce this. Do I need to change my right prompt to something special?
- put something like
"\n\r"(default newline sequence in windows) or"\nsomething"inlet-env PROMPT_COMMAND_RIGHT = {} - than move caret to last line in terminal (hold enter or ls big folder...whatever)
- type anything
https://user-images.githubusercontent.com/98133511/171510289-a078d2c0-e36d-413b-a3b2-ef461028e842.mp4
I tested with different escape symbols (win10)
Legend ? any character, + one or more character
- conemu
+?\b\f+\n++\t+ - wezterm
\f\n+\t+ - alacritty
\f+\n+\t
\r+ has no issue just overrides left prompt
Of course its edge case and i could define function preparing prompt with str trim or str replace
But if right prompt mandatory one liner i think it need some internal fixes
Thanks for the information.
- I'm not sure it really matters but the default newline sequence in windows is
\r\ninstead of\n\r. - I'm not really clear why one would want to put a CRLF in the right prompt. I'm really not sure what problem we're trying to solve. What's the real-world use case for having a CRLF or just a LF FF or Tab in the right prompt?
this still exists at win10/wezterm/nu0.67.0
Yeah I saw it again with my setup and I don't know what to do about it.
On Fri, 19 Aug 2022, 08:33 zhijia,.zhang, @.***> wrote:
this still exists at win10/wezterm/nu0.67.0
— Reply to this email directly, view it on GitHub https://github.com/nushell/nushell/issues/5585#issuecomment-1220304878, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIDVSDNZNMBNVLCFPEFN43VZ4TDVANCNFSM5WLUDRUQ . You are receiving this because you authored the thread.Message ID: @.***>
I only notice this on the Windows version of WezTerm. The Mac version works great. Does this still happen with shell_integration set to false in the nushell config.nu?
I only notice this on the Windows version of WezTerm. The Mac version works great. Does this still happen with shell_integration set to false in the nushell config.nu?
it works at win10/wezterm/nu0.67.0
I only notice this on the Windows version of WezTerm. The Mac version works great. Does this still happen with shell_integration set to false in the nushell config.nu?
Setting this to false fixes the issue for me as well - wezterm 20220807-113146-c2fee766, nu 0.67, win 10
It's sad that WezTerm behaves this way to our ansi escape sequences. I have no idea why it repeats the prompt with every character typed. It's not like we're sending the escape sequences for every character. It only happens around the time the prompt is drawn.
The way that PTYs work on Windows is a bit different from unix systems. The ConPTY layer needs to translate from the stream of escapes and apply that data to the internal windows console screen model, and then translates from that to a stream of output escapes. That processed stream is what wezterm, conemu and alacritty see.
What I suspect may be happening here is that you are tickling an edge case that causes conpty to emit something unexpected that results in the output shown above.
Earlier comments indicate that this isn't a wezterm issue and that it manifests in other windows terminals.
In wezterm, you can use wezterm ssh host to use its integrated ssh client to connect to a remote system and bypass using the ConPTY layer. I suspect that if you use that to run a remote nushell with the same configuration you won't be able to reproduce this problem.
I would recommend opening an issue at https://github.com/microsoft/terminal to get input from the team that owns ConPTY who can perhaps advise on how to deal with this.
See https://github.com/wez/wezterm/issues/2442#issuecomment-1221670772 for an example of how surprising some of the conpty-transformed output can be
@wez Thanks a bunch for chiming in and giving us your perspective!!
Earlier comments indicate that this isn't a wezterm issue and that it manifests in other windows terminals.
We definitely see a pretty serious flicker with Windows Terminal Preview but not in Windows Terminal, nor Alacritty. We have an issue open already here https://github.com/microsoft/terminal/issues/13710.
We haven't seen anything as serious as how WezTerm reacts on windows. Out of respect for you, I created this gif to show you what I see in Windows using WezTerm. I'm definitely not trying to lay this problem at your feet for fixing and running away, but I wanted to be clear about what I see as it's a little bit different than what is posted above.

While I haven't tried every possible Windows terminal software, my usual test scenarios include Windows Terminal (sometimes preview too), Alacritty, and WezTerm.
PS. Can someone please test Wez's suggestion with wezterm ssh host? I don't really have a good way to do that since I don't use ssh anywhere.
Please capture a terminal recording:
- Launch wezterm. If possible, please use 80x24 (the default size) for the terminal dimensions as it helps to keep things smaller and easier to manage.
- Inside that terminal run
wezterm recordto start a recording session. - Run through your reproduction steps with nushell.
- Then type
exit - You should see a message like:
*** Finished recording to /var/tmp/wezterm-recording-sF6B3u.cast.txt
- Attach the file that it produced to this issue.
The file is an asciicast (compatible with https://asciinema.org/) and can also be replayed using wezterm replay.
The terminal recording allows me to replicate what is being sent to the terminal without requiring me to install the same applications as you and replicate your configuration for everything.
It would be great to get one capture on Windows and another on a unix system so we can compare what wezterm is seeing.
I mentioned this over at #6214, but:
Setting "shell_integration: false" in config.nu fixes the problem (tested on alacritty, wezterm, and Windows Terminal)
@wez Here's the Windows one wezterm-recording-hX0ZFK.cast.txt
Here's one from my m1 MacBookPro wezterm-recording-paeqle.cast.txt
If you wezterm replay those files on a unix system, then the windows one shows the stepping behavior, but the macos one does not.
If you replay them both on windows, then they both show the stepping behavior.
If I reduce the cast to just one of the lines that is causing problems:
\u001b[?25l\u001b[38;2;8;8;8m\u001b[48;2;206;215;207m\u001b[1m\r \u001b[38;2;206;215;207m\u001b[48;2;52;101;164m \u001b[38;2;228;228;228m~\u001b[38;2;206;215;207m\u001b[22m \u001b[38;2;52;101;164m\u001b[48;2;12;12;12m\u001b[38;5;14m\u001b[49m\u001b[1m \u001b[36mls\u001b[m \u001b[90m| where type == dir \u001b[K\u001b[38;2;96;96;96m\u001b[1m 0823 \u001b[38;2;211;215;207m\u001b[48;2;12;12;12m\u001b[22m\u001b[38;2;12;12;12m\u001b[48;2;211;215;207m 07:36:11 AM \u001b[m\r\n\u001b[K\u001b[23;15H\u001b[?25h
and run wezterm replay --explain on it:
> SENT
Action(CSI(Mode(ResetDecPrivateMode(Code(ShowCursor)))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.03137255, 0.03137255, 0.03137255, 1.0))))))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.80784315, 0.84313726, 0.8117647, 1.0))))))
Action(CSI(Sgr(Intensity(Bold))))
Action(Control(CarriageReturn))
Print(" \u{f17a} ")
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.80784315, 0.84313726, 0.8117647, 1.0))))))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Print("\u{e0b0} \u{f015} ")
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.89411765, 0.89411765, 0.89411765, 1.0))))))
Print("~")
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.80784315, 0.84313726, 0.8117647, 1.0))))))
Action(CSI(Sgr(Intensity(Normal))))
Print(" ")
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.047058824, 0.047058824, 0.047058824, 1.0))))))
Print("\u{e0b0}")
Action(CSI(Sgr(Foreground(PaletteIndex(14)))))
Action(CSI(Sgr(Background(Default))))
Action(CSI(Sgr(Intensity(Bold))))
Print(" ")
Action(CSI(Sgr(Foreground(PaletteIndex(6)))))
Print("ls")
Action(CSI(Sgr(Reset)))
Print(" ")
Action(CSI(Sgr(Foreground(PaletteIndex(8)))))
Print("| where type == dir ")
Action(CSI(Edit(EraseInLine(EraseToEndOfLine))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.3764706, 0.3764706, 0.3764706, 1.0))))))
Action(CSI(Sgr(Intensity(Bold))))
Print("\u{e0b3} 0823 ")
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.827451, 0.84313726, 0.8117647, 1.0))))))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.047058824, 0.047058824, 0.047058824, 1.0))))))
Action(CSI(Sgr(Intensity(Normal))))
Print("\u{e0b2}")
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.047058824, 0.047058824, 0.047058824, 1.0))))))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.827451, 0.84313726, 0.8117647, 1.0))))))
Print(" 07:36:11 AM ")
Action(CSI(Sgr(Reset)))
Action(Control(CarriageReturn))
Action(Control(LineFeed))
Action(CSI(Edit(EraseInLine(EraseToEndOfLine))))
Action(CSI(Cursor(Position { line: OneBased { value: 23 }, col: OneBased { value: 15 } })))
Action(CSI(Mode(SetDecPrivateMode(Code(ShowCursor)))))
< RECV
it's a little bit easier to see that after printing the AM portion of the time, CarriageReturn and LineFeed are output, and that is what moves the cursor to the next line.
If you look at an equivalent line from the macOS output:
\u001b[?25l\u001b[24;1H\u001b[J\u001b[38;5;10m\u001b[1m\u001b]133;A\u001b\\\u001b[48;2;206;215;207;38;2;8;8;8m \u001b[48;2;52;101;164;38;2;206;215;207m \u001b[48;2;52;101;164;38;2;188;188;188m~\u001b[48;2;52;101;164;38;2;188;188;188m/\u001b[48;2;52;101;164;38;2;188;188;188ms\u001b[0m\u001b[48;2;52;101;164;38;2;188;188;188m/\u001b[48;2;52;101;164;38;2;188;188;188mf\u001b[0m\u001b[48;2;52;101;164;38;2;188;188;188m/\u001b[1;48;2;52;101;164;38;2;228;228;228mnushell\u001b[0m\u001b[48;2;52;101;164;38;2;206;215;207m \u001b[48;2;78;154;6;38;2;52;101;164m \u001b[48;2;78;154;6;38;2;12;12;12m main \u001b[48;2;196;160;0;38;2;78;154;6m \u001b[0m\u001b[48;2;196;160;0;38;2;0;0;0m✚1\u001b[0m\u001b[1;48;2;196;160;0;38;2;0;0;0m*\u001b[0m\u001b[48;2;12;12;12;38;2;196;160;0m\u001b[0m\u001b]133;B\u001b\\\u001b[38;5;14m\u001b[1m \u001b[38;5;5m\u001b[1m\u001b7\u001b[24;60H\u001b[38;2;96;96;96m\u001b[49m 0823 \u001b[0m\u001b[48;2;12;12;12;38;2;211;215;207m\u001b[48;2;211;215;207;38;2;12;12;12m 06:54:58 PM \u001b[0m\u001b8\u001b[0m\u001b[1;36mls\u001b[0m | \u001b[1;36mwhere\u001b[0m \u001b[32ms\u001b[0m\u001b7\u001b[90mize > 100b\u001b[0m\u001b8\u001b[?25h
and --explain it:
Action(CSI(Mode(ResetDecPrivateMode(Code(ShowCursor)))))
Action(CSI(Cursor(Position { line: OneBased { value: 24 }, col: OneBased { value: 1 } })))
Action(CSI(Edit(EraseInDisplay(EraseToEndOfDisplay))))
Action(CSI(Sgr(Foreground(PaletteIndex(10)))))
Action(CSI(Sgr(Intensity(Bold))))
Action(OperatingSystemCommand(FinalTermSemanticPrompt(FreshLineAndStartPrompt { aid: None, cl: None })))
Action(Esc(Code(StringTerminator)))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.80784315, 0.84313726, 0.8117647, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.03137255, 0.03137255, 0.03137255, 1.0))))))
Print(" \u{f179} ")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.80784315, 0.84313726, 0.8117647, 1.0))))))
Print("\u{e0b0} \u{f07c} ")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.7372549, 0.7372549, 0.7372549, 1.0))))))
Print("~")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.7372549, 0.7372549, 0.7372549, 1.0))))))
Print("/")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.7372549, 0.7372549, 0.7372549, 1.0))))))
Print("s")
Action(CSI(Sgr(Reset)))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.7372549, 0.7372549, 0.7372549, 1.0))))))
Print("/")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.7372549, 0.7372549, 0.7372549, 1.0))))))
Print("f")
Action(CSI(Sgr(Reset)))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.7372549, 0.7372549, 0.7372549, 1.0))))))
Print("/")
Action(CSI(Sgr(Intensity(Bold))))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.89411765, 0.89411765, 0.89411765, 1.0))))))
Print("nushell")
Action(CSI(Sgr(Reset)))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.80784315, 0.84313726, 0.8117647, 1.0))))))
Print(" ")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.30588236, 0.6039216, 0.023529412, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.20392157, 0.39607844, 0.6431373, 1.0))))))
Print("\u{e0b0} ")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.30588236, 0.6039216, 0.023529412, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.047058824, 0.047058824, 0.047058824, 1.0))))))
Print("\u{e0a0} main ")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.76862746, 0.627451, 0.0, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.30588236, 0.6039216, 0.023529412, 1.0))))))
Print("\u{e0b0} ")
Action(CSI(Sgr(Reset)))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.76862746, 0.627451, 0.0, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.0, 0.0, 0.0, 1.0))))))
Print("✚1")
Action(CSI(Sgr(Reset)))
Action(CSI(Sgr(Intensity(Bold))))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.76862746, 0.627451, 0.0, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.0, 0.0, 0.0, 1.0))))))
Print("*")
Action(CSI(Sgr(Reset)))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.047058824, 0.047058824, 0.047058824, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.76862746, 0.627451, 0.0, 1.0))))))
Print("\u{e0b0}")
Action(CSI(Sgr(Reset)))
Action(OperatingSystemCommand(FinalTermSemanticPrompt(MarkEndOfPromptAndStartOfInputUntilNextMarker)))
Action(Esc(Code(StringTerminator)))
Action(CSI(Sgr(Foreground(PaletteIndex(14)))))
Action(CSI(Sgr(Intensity(Bold))))
Print(" ")
Action(CSI(Sgr(Foreground(PaletteIndex(5)))))
Action(CSI(Sgr(Intensity(Bold))))
Action(Esc(Code(DecSaveCursorPosition)))
Action(CSI(Cursor(Position { line: OneBased { value: 24 }, col: OneBased { value: 60 } })))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.3764706, 0.3764706, 0.3764706, 1.0))))))
Action(CSI(Sgr(Background(Default))))
Print("\u{e0b3} 0823 ")
Action(CSI(Sgr(Reset)))
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.047058824, 0.047058824, 0.047058824, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.827451, 0.84313726, 0.8117647, 1.0))))))
Print("\u{e0b2}")
Action(CSI(Sgr(Background(TrueColor(SrgbaTuple(0.827451, 0.84313726, 0.8117647, 1.0))))))
Action(CSI(Sgr(Foreground(TrueColor(SrgbaTuple(0.047058824, 0.047058824, 0.047058824, 1.0))))))
Print(" 06:54:58 PM ")
Action(CSI(Sgr(Reset)))
Action(Esc(Code(DecRestoreCursorPosition)))
Action(CSI(Sgr(Reset)))
Action(CSI(Sgr(Intensity(Bold))))
Action(CSI(Sgr(Foreground(PaletteIndex(6)))))
Print("ls")
Action(CSI(Sgr(Reset)))
Print(" | ")
Action(CSI(Sgr(Intensity(Bold))))
Action(CSI(Sgr(Foreground(PaletteIndex(6)))))
Print("where")
Action(CSI(Sgr(Reset)))
Print(" ")
Action(CSI(Sgr(Foreground(PaletteIndex(2)))))
Print("s")
Action(CSI(Sgr(Reset)))
Action(Esc(Code(DecSaveCursorPosition)))
Action(CSI(Sgr(Foreground(PaletteIndex(8)))))
Print("ize > 100b")
Action(CSI(Sgr(Reset)))
Action(Esc(Code(DecRestoreCursorPosition)))
Action(CSI(Mode(SetDecPrivateMode(Code(ShowCursor)))))
< RECV
you can see that the stream uses cursor position escapes along with escapes to save/restore the cursor position.
If I edit the macos capture and remove the OSC 133 A and OSC 133 B sequences, and replay that file on windows, then the output looks correct. Those are the FinalTerm style shell integration escape sequences.
It looks to me as though this is a ConPTY issue where unexpected/unknown OSC sequences confuse it about cursor positioning or some other similar concern that triggers it to rewrite the output stream.
A workaround would be to skip outputting OSC 133 on Windows or if you know that ConPTY is present.
@wez That matches with what we're seeing. If people turn off shell_integration in nushell this behavior doesn't show up in WezTerm. However, if we remove OSC 133 and friends in Windows, we won't get the fancy marking in Windows Terminal Preview nor in VSCode's terminal. I'm going to link your speculation to the Windows Terminal issue to see if it helps. I think this issue and the WT issue are related since the problem in both terminals started happening with the OSC 133 sequences.
Just wanted to chime in to confirm I still get this with v 0.78.0 of nushell and wezterm 20230408 (69ae472)
https://user-images.githubusercontent.com/44531564/235368974-ebd122b0-3431-4686-8630-5862cdb9886b.mp4
Still getting this on windows 11.
~> nu -v
0.79.0
~> wezterm -V
wezterm 20230408-112425-69ae8472
Is it possible for now to disable shell_integration in Nushell only when it is running inside Wezterm? Because it is the only terminal emulator I have a problem with.
Is it possible for now to disable
shell_integrationin Nushell only when it is running inside Wezterm? Because it is the only terminal emulator I have a problem with.
well, I know wezterm will set certain environment variables prefixed with WEZTERM_ such as WEZTERM_EXECUTABLE, WEZTERM_PANE, etc. but I don't know the syntax of the nu script. I think it's possible in the config.nu script to conditionally set shell_integration based on whether certain environment variable is defined or not.
Linked issue of microsoft/terminal has been fixed - https://github.com/microsoft/terminal/issues/13710
anyone built windows terminal to see if it's fixed? i'm not brave enough right now. hopefully we'll get a new WT version soon.
Is it possible for now to disable
shell_integrationin Nushell only when it is running inside Wezterm? Because it is the only terminal emulator I have a problem with.well, I know wezterm will set certain environment variables prefixed with
WEZTERM_such asWEZTERM_EXECUTABLE,WEZTERM_PANE, etc. but I don't know the syntax of thenuscript. I think it's possible in theconfig.nuscript to conditionally setshell_integrationbased on whether certain environment variable is defined or not.
One way to do this is to edit config.nu and set shell_integration line to:
shell_integration: ("WEZTERM_PANE" not-in $env)
So that shell_integration is disabled when nushell is loaded by WezTerm.
I wanted to note that wezterm's nightly build has included the upstream conpty fixes for the past week or so.