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

Consider supporting [extension to VT,] DECSCUSR "0" to restore cursor to user default to help vim/others #1604

Closed
jtourlamain opened this issue Jun 25, 2019 · 27 comments · Fixed by #7379
Labels
Area-VT Virtual Terminal sequence support good first issue This is a fix that might be easier for someone to do as a first contribution Help Wanted We encourage anyone to jump in on these. Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.

Comments

@jtourlamain
Copy link

Environment

Windows build number: 1903
Windows Terminal version (if applicable): 0.2.1715

Any other software? neovim v0.3.4

Steps to reproduce

  • Create a profile that uses cursorShape "vintage"
  • Open nvim
  • close nvim

Expected behavior

After closing nvim I would expect to have the "vintage" cursor again.

Actual behavior

Cursor is a filledBox that doesn't blink anymore

@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Jun 25, 2019
@egmontkob
Copy link

I'm not sure what escape sequences Windows Terminal supports for changing the cursor shape, nor what (Neo)Vim outputs, so sorry if I get it wrong.

I assume that the DECSCUSR escape sequence is being used (see e.g. at ctlseqs.html).

In gnome-terminal (vte) we intentionally deviate from the xterm's behavior (the behavior documented on the linked page). For parameters 1–6 we go with the given mode. However, if the parameter is 0 (or missing), we revert to whichever cursor shape the user specified as their favorite in the terminal's preferences.

This might be a behavior for WIndows Terminal to consider, too.

@carlos-zamora carlos-zamora added Issue-Bug It either shouldn't be doing this or needs an investigation. Product-Terminal The new Windows Terminal. labels Jun 25, 2019
@xtremeperf
Copy link

This is actually intended behavior for Vim/Nvim and I can't recall any sort of "restore cursor leaving application mode" termcap that could be implemented in the terminal.

And yes, that's correct... DECSCUSR has been implemented in WindowsTerminal for changing cursor shape (1-6).

Vim explicitly changes the cursor shape for each of it's editing modes and it requires that you assign the ESC sequences in your vimrc file, as they are not using any sort of standard termcap variable for this.

Vim does not change the cursor shape on exit. The cursor shape from normal mode will remain, since you must exit from normal mode.

For more info in Vim:
:help termcap-cursor-shape

It's easy to change the cursor shape upon exit for yourself using an autocmd VimLeave
:help VimLeave

I hope that helps!

@jtourlamain
Copy link
Author

@xtremeperf Thanks for your tip!
Found a possible solution on neovim/neovim#4867.
Adding au VimLeave * set guicursor=a:hor10-blinkon1 gives a blinking underscore when you exit vim

@egmontkob
Copy link

The DECSCUSR sequence is a poorly designed one.

One problem is the lack of save/restore or revert, which we somewhat address in gnome-terminal by deviating from the standard. This way vim could restore the user's preferred version on exit.

The other problem is that two orthogonal properties are tied together. For an app like vim, it really makes sense to toggle between two different shapes, while leave blinking at the user's preferred setting. It's currently not possible.

The best solution could be to cooperate between terminal emulators and apps to come up with a better designed escape sequence. Until then, we live with the limitations, and optionally come up with hacks to mitigate the problems.

@DHowett-MSFT
Copy link
Contributor

I like the idea of using a nonstandard DECSCUSR extension to reset the cursor to "user default."

@DHowett-MSFT
Copy link
Contributor

I'll float that to @zadjii-msft -- if we don't want to do it, we'll close this issue as "unfortunately by design". 😄

@DHowett-MSFT DHowett-MSFT added Area-VT Virtual Terminal sequence support Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase and removed Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Jun 27, 2019
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Jun 27, 2019
@DHowett-MSFT DHowett-MSFT changed the title Bug Report Cursor shape changes after closing vim Consider supporting [extension to VT,] DECSCUSR "0" to restore cursor to user default to help vim/others Jun 27, 2019
@DHowett-MSFT DHowett-MSFT added the Needs-Attention The core contributors need to come back around and look at this ASAP. label Jun 27, 2019
@xtremeperf
Copy link

xtremeperf commented Jun 28, 2019

I looked into this a little more. The main reason the cursor doesn't get reset when returning to the shell is because neovim doesn't enter alternate screen mode upon startup... therefore it doesn't return from any sort of alternate screen mode upon exit.

Here's how it's done in Vim using xterm sequences (as in DECRC)
t_ti=^[[?1049h
t_te=^[[?1049l

@egmontkob
Copy link

I don't get it, what's the connection between cursor shape and alternate screen? At least in xterm and gnome-terminal it's the same shape for both screens, not one per screen. Is it different in Windows Terminal?

@xtremeperf
Copy link

xtremeperf commented Jun 29, 2019

There are some XTERM-specific capabilities for an Alternate Screen Buffer and Save/Reset Cursor, among others. The intent is provide a picture of the full-screen application's display on the scrollback, but without wiping out the text that would be shown before the application was initialized. The display and cursor properties are saved and then the terminal switches to an alternate buffer with it's own properties. When done, the initial display, along with it's cursor, are restored.

DEC Private Mode Set (DECSET) --- CSI ? P m h
DEC Private Mode Reset (DECRST) --- CSI ? P m l

P s = 1 0 4 7 --- Use Alternate Screen Buffer
P s = 1 0 4 8 --- Save cursor as in DECSC
P s = 1 0 4 9 --- Save cursor as in DECSC and use Alternate Screen Buffer, clearing the screen first. (This mode actually just combines the effects of the 1 0 4 7 and 1 0 4 8 modes.)

I haven't tested these sequences while using various different combinations of cursor shape between each screen buffer specifically, but after running vim and changing the normal cursor to a solid line, the original underscore cursor shape, blink, position, etc. was restore upon exiting the alt. screen buffer mode.

@egmontkob
Copy link

In Xterm and VTE, the same cursor shape+blinking is shared across the normal and alternate screen. Also, saving/restoring the cursor does not save/restore its shape+blinking. That is, it looks to me that the following three are independent:

  1. normal vs. alternate screen
  2. cursor, as in location, plus color and similar attributes used for printing subsequently arriving text
  3. cursor shape and blinking

and there just happens to be an escape sequence which sets 1. and 2. at the same time.

the original underscore cursor shape, blink, position, etc. was restore upon exiting the alt. screen buffer mode.

It could be that Windows Terminal differs from Xterm and VTE here.

@egmontkob
Copy link

Also note that showing/hiding the cursor (DECTCEM) seems to be an exempt from saving/restoring or alternate screen switching.

So in bullet point 2 above, "cursor" stands for the logical concept, "active data/presentation position" as ECMA-48's calls it; whereas in bullet point 3 "cursor" refers to its graphical representation.

(ECMA-48: "In general, the active presentation position is indicated in a display by a cursor.")

ctlseqs.html doesn't have this clear distinction, it uses the word "cursor" for both concepts, just as probably most people do.

@zadjii-msft
Copy link
Member

To add my 2c: Looking at the spec for DECSCUSR, it seems like 0 is strictly redundant.

CSI Ps SP q
          Set cursor style (DECSCUSR), VT520.
            Ps = 0  -> blinking block.
            Ps = 1  -> blinking block (default).
            Ps = 2  -> steady block.
            Ps = 3  -> blinking underline.
            Ps = 4  -> steady underline.
            Ps = 5  -> blinking bar (xterm).
            Ps = 6  -> steady bar (xterm).

I'm definitely okay with having 0 act as "restore to user default", especially considering there's precedent in other terminal emulators for this behavior.

@j4james
Copy link
Collaborator

j4james commented Mar 5, 2020

I should also mention that there is already a DEC standard for querying (and thus being able to restore) the user's cursor settings - the DECRQSS command. We don't yet support that, but it is on my long term TODO list.

@craigbarnes
Copy link

craigbarnes commented Mar 6, 2020

There are some XTERM-specific capabilities for an Alternate Screen Buffer and Save/Reset Cursor, among others. The intent is provide a picture of the full-screen application's display on the scrollback, but without wiping out the text that would be shown before the application was initialized. The display and cursor properties are saved and then the terminal switches to an alternate buffer with it's own properties. When done, the initial display, along with it's cursor, are restored.

DEC Private Mode Set (DECSET) --- CSI ? P m h
DEC Private Mode Reset (DECRST) --- CSI ? P m l

P s = 1 0 4 7 --- Use Alternate Screen Buffer
P s = 1 0 4 8 --- Save cursor as in DECSC
P s = 1 0 4 9 --- Save cursor as in DECSC and use Alternate Screen Buffer, clearing the screen first. (This mode actually just combines the effects of the 1 0 4 7 and 1 0 4 8 modes.)

I haven't tested these sequences...

@xtremeperf I have...

In xterm, DECSET 1049 seems to behave as documented, i.e. the effects on the cursor are the same as for DECSC, which doesn't save the cursor style.

Requesting the current state with DECRQSS might work, but it's subject to all the usual problems -- request/response latency, lack of widespread support, etc.

@j4james
Copy link
Collaborator

j4james commented Mar 6, 2020

Requesting the current state with DECRQSS might work, but it's subject to all the usual problems -- request/response latency, lack of widespread support, etc.

I know of a number of terminal emulators that support DECRQSS. Those I've personally tested include xterm, kitty, mintty, and tera term, and I've seen many more references online claiming to have implemented it. I know the support isn't universal, but is this DECSCUSR 0 hack any better?

As for latency, that's surely not an issue for something like an editor (which was the original use case for this issue) . You fire off the request sequence at startup and then just carry as normal. If you receive a response at some point before shutting down, then you've got what you need to restore the cursor. If not, it's hardly the end of the world.

@craigbarnes
Copy link

craigbarnes commented Mar 7, 2020

As for latency, that's surely not an issue for something like an editor (which was the original use case for this issue) . You fire off the request sequence at startup and then just carry as normal. If you receive a response at some point before shutting down, then you've got what you need to restore the cursor. If not, it's hardly the end of the world.

Yeah, that's how I envisioned doing it for this particular issue too, although the latency can be annoying for other uses of DECRQSS. I've tried half a dozen terminals and the only problem I've run into is with tmux not supporting it. However, tmux does seem to support the DECSCUSR 0 hack, so the obvious thing to do would be use the DECRQSS response if there is one, otherwise fall back to DECSCUSR 0.

@gnachman
Copy link

I'm supportive of the proposal to repurpose 0 to restore the user's default in iTerm2, which came to my attention here: https://gitlab.com/gnachman/iterm2/-/issues/8769

I'd like to see one or two more terminals commit to this before making the change, though. I'm sure it will break some users' configurations, and it's only justifiable if it's the clear path forward.

@j4james
Copy link
Collaborator

j4james commented Mar 14, 2020

@gnachman I've done a bit of testing on the terminals I have installed, and there are actually a few that support this extension. Other than VTE, there's also mintty and alacritty, which support both 0 and a missing parameter for selecting the user's preferred cursor. Then there is kitty (the Linux terminal, not the putty fork) which supports only 0 (a missing parameter selects the block cursor).

I still think DECRQSS makes more sense for apps that actually want to restore the cursor shape (rather than just resetting it to a default value), but DECSCUSR 0 is not a bad fall back option.

@gnachman
Copy link

Thanks for providing the additional context, @j4james . I'm not a fan of DECRQSS for two reasons:

  1. Using it casually (like in a shell script) is too hard.
  2. Reporting in general is full of race conditions, where the reported code sometimes gets printed to the screen if the user hits a key, a program crashes, or an ssh connection ends at just the wrong moment.

I think the strongest argument in favor of adopting this change is that 0 is the same as 1. Anyone who has problems can fix them without too much trouble. Considering VTTY, mintty, and alacritty already support it, that's strong evidence that there is a lot of hard-to-fix software in the wild.

@gnachman
Copy link

FYI I've implemented DECSCUSR 0 to reset cursor style & blink in gnachman/iTerm2@5680f97

@zadjii-msft zadjii-msft removed their assignment May 14, 2020
@zadjii-msft zadjii-msft added the Help Wanted We encourage anyone to jump in on these. label May 14, 2020
@zadjii-msft zadjii-msft added the good first issue This is a fix that might be easier for someone to do as a first contribution label Aug 7, 2020
@ghost ghost added the In-PR This issue has a related PR label Sep 4, 2020
@ghost ghost closed this as completed in #7379 Sep 4, 2020
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Sep 4, 2020
ghost pushed a commit that referenced this issue Sep 4, 2020
This PR is about the behavior of DECSCUSR. This PR changes the meaning
of DECSCUSR 0 to restore the cursor style back to user default. This
differs from what VT spec says but it’s used in popular terminal
emulators like iTerm2 and VTE-based ones. See #1604. 

Another change is that for parameter greater than 6, DECSCUSR should be
ignored, instead of restoring the cursor to legacy. This PR fixes it.
See #7382.

Fixes #1604.
@ghost
Copy link

ghost commented Sep 22, 2020

🎉This issue was addressed in #7379, which has now been successfully released as Windows Terminal Preview v1.4.2652.0.:tada:

Handy links:

@DHowett
Copy link
Member

DHowett commented Oct 14, 2020

The fix for this issue was just released as part of Windows in Insider Build 20236!

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-VT Virtual Terminal sequence support good first issue This is a fix that might be easier for someone to do as a first contribution Help Wanted We encourage anyone to jump in on these. Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.