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

Documentation around cursor shape in tmux is outdated (or needs clarification) #21938

Open
ddickstein opened this issue Jan 21, 2023 · 6 comments
Labels
bug issues reporting wrong behavior documentation

Comments

@ddickstein
Copy link
Contributor

Describe the bug

There's a section of :h tui-cursor-tmux that reads:

Unlike Nvim, if [the "Ss" and "Se" capabilities] are not in terminfo you must add them by setting "terminal-overrides" in ~/.tmux.conf .

This line confused me for a bit since they are not in my terminfo (I'm using tmux-256color and verified this with infocmp) and I do not have terminal overrides for those capabilities in my ~/.tmux.conf but cursor style is still working properly. Maybe this was fixed in a newer version of tmux? I'm using tmux 3.1c.

Steps to reproduce

  • infocmp tmux-256color: verify that Ss and Se are absent
  • tmux -V: Check the tmux the version (I tested with 3.1c)
  • In ~/.tmux.conf: set-option -g default-terminal "tmux-256color"
  • In ~/.tmux.conf, verify that the terminal-overrides setting omits Ss and Se
  • Open Neovim and enter insert mode

Expected behavior

Behavior for me is that cursor shape changes correctly - if it does, I think the documentation needs to be updated.

Neovim version (nvim -v)

0.7.0

Vim (not Nvim) behaves the same?

N/A

Operating system/version

CentOS 7.9

Terminal name/version

xfce4-terminal 0.8.10

$TERM environment variable

tmux-256color

Installation

system package manager

@ddickstein ddickstein added the bug issues reporting wrong behavior label Jan 21, 2023
@ddickstein
Copy link
Contributor Author

Possibly also related: This FAQ directs to #3165, which was merged - looks like that happened a long time ago (commit is tagged as v0.1.2)

@justinmk
Copy link
Member

PR welcome

@erw7
Copy link
Contributor

erw7 commented Jan 23, 2023

@ddickstein There is a problem with your confirmation method. I briefly checked the tmux source, and that description is still correct.

infocmp tmux-256color: verify that Ss and Se are absent

The presence of Ss, Se is never reported because the correct command line options are not given. See man terminfo(5) User-Defined Capabilities.

Also, in this case, it does not make sense to examine tmux-256color. If you knew what terminal-overrides overrides, you wouldn't think to check tmux-256color. You need to understand which of the following does terminal-overrides override.

  • The terminfo entry for the host terminal used by tmux.
  • The terminfo entries used by applications running on tmux (such as neovim).

If you can improve this description with the above understanding, PR is welcome.

@erw7
Copy link
Contributor

erw7 commented Jan 23, 2023

If you are willing to create a PR for us, please remove the following putty. Putty does not implement DECSCUSR, so the cursor shape does not change on putty.

neovim/runtime/doc/term.txt

Lines 207 to 212 in 3b75485

If your terminfo definition is missing them, then Nvim will decide whether to
add them to your terminfo definition, by looking at $TERM and other
environment variables. For the "rxvt", "putty", "linux", "screen",
"teraterm", and "iterm" terminal types, or when Konsole, a libvte-based
terminal emulator, or genuine Xterm are detected, it will add constructed
"Ss" and "Se" capabilities.

Thus, the answer to your following question in #20027 is that implement DECSCUSR in putty.

Is there something more that I need to do to make this work?

@ddickstein
Copy link
Contributor Author

ddickstein commented Jan 24, 2023

Thank you for explaining. Here's my current understanding:

  1. To see user-defined capabilities, the -x flag needs to be passed to infocmp.
  2. If I check infocmp -x outside tmux (where for me, TERM=xterm-256color), I do see Ss and Se. This means that tmux will know that the terminal supports cursor shapes.
  3. If I had not seen Ss and Se in infocmp -x outside tmux, but my terminal did in fact support cursor shapes, I would have either needed to update the terminfo for xterm-256color or have added these capabilities to terminal-overrides, which tmux uses to interpret the capabilities of the terminal in which it's running.
  4. Tmux changes TERM based on the default-terminal setting in ~/.tmux.conf. This is the TERM value applications inside tmux, such as Neovim, will see, and they will use its terminfo entry to learn about the terminal's capabilities.
  5. Neovim does more than just take terminfo at face value - if Ss and Se are missing, it adds them under the following conditions:
    If your terminfo definition is missing them, then Nvim will decide whether to add them to your
    terminfo definition, by looking at $TERM and other environment variables.  For the "rxvt", "putty",
    "linux", "screen", "teraterm", and "iterm" terminal types, or when Konsole, a libvte-based terminal
    emulator, or genuine Xterm are detected, it will add constructed "Ss" and "Se" capabilities.
    
    I take it that "tmux", though not listed here, falls under "screen". But this note in the docs is cautioning that this is behavior Neovim is choosing to perform, and assume other programs (e.g., tmux), do this same kind of augmentation.
  6. Re: the referenced putty issue, since putty actually does not have the capability required for cursor shape (i.e., proper interpretation of the DECSCUSR escape sequence), it isn't possible to update the cursor shape. Updating its terminfo wouldn't help, since terminfo is just meant to reflect the capabilities that the terminal emulator actually provides.

Is that correct?

@erw7
Copy link
Contributor

erw7 commented Jan 25, 2023

Is that correct?

Yes. However, for 5, the relevant document is outdated or incorrect. Neovim completes the missing Ss, Se in the following code. Therefore, alacritty, cygwin, hterm, st, and tmux must be added (I may have missed some, so someone please double check).

neovim/src/nvim/tui/tui.c

Lines 1906 to 1996 in 06d1e86

// Blacklist of terminals that cannot be trusted to report DECSCUSR support.
if (!(st || (vte_version != 0 && vte_version < 3900) || konsolev)) {
tui->unibi_ext.reset_cursor_style = unibi_find_ext_str(ut, "Se");
tui->unibi_ext.set_cursor_style = unibi_find_ext_str(ut, "Ss");
}
// Dickey ncurses terminfo includes Ss/Se capabilities since 2011-07-14. So
// adding them to terminal types, that have such control sequences but lack
// the correct terminfo entries, is a fixup, not an augmentation.
if (-1 == tui->unibi_ext.set_cursor_style) {
// DECSCUSR (cursor shape) is widely supported.
// https://github.com/gnachman/iTerm2/pull/92
if ((!bsdvt && (!konsolev || konsolev >= 180770))
&& ((xterm && !vte_version) // anything claiming xterm compat
// per MinTTY 0.4.3-1 release notes from 2009
|| putty
// per https://chromium.googlesource.com/apps/libapps/+/a5fb83c190aa9d74f4a9bca233dac6be2664e9e9/hterm/doc/ControlSequences.md
|| hterm
// per https://bugzilla.gnome.org/show_bug.cgi?id=720821
|| (vte_version >= 3900)
|| (konsolev >= 180770) // #9364
|| tmux // per tmux manual page
// https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html
|| screen
|| st // #7641
|| rxvt // per command.C
// per analysis of VT100Terminal.m
|| iterm || iterm_pretending_xterm
|| teraterm // per TeraTerm "Supported Control Functions" doco
|| alacritty // https://github.com/jwilm/alacritty/pull/608
|| cygwin
// Some linux-type terminals implement the xterm extension.
// Example: console-terminal-emulator from the nosh toolset.
|| (linuxvt
&& (xterm_version || (vte_version > 0) || colorterm)))) {
tui->unibi_ext.set_cursor_style =
(int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q");
if (-1 == tui->unibi_ext.reset_cursor_style) {
tui->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
"");
}
unibi_set_ext_str(ut, (size_t)tui->unibi_ext.reset_cursor_style,
"\x1b[ q");
} else if (linuxvt) {
// Linux uses an idiosyncratic escape code to set the cursor shape and
// does not support DECSCUSR.
// See http://linuxgazette.net/137/anonymous.html for more info
tui->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
"\x1b[?"
"%?"
// The parameter passed to Ss is the DECSCUSR parameter, so the
// terminal capability has to translate into the Linux idiosyncratic
// parameter.
//
// linuxvt only supports block and underline. It is also only
// possible to have a steady block (no steady underline)
"%p1%{2}%<" "%t%{8}" // blink block
"%e%p1%{2}%=" "%t%{112}" // steady block
"%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block)
"%e%p1%{4}%=" "%t%{4}" // steady underline
"%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
"%e%p1%{6}%=" "%t%{2}" // steady bar
"%e%{0}" // anything else
"%;" "%dc");
if (-1 == tui->unibi_ext.reset_cursor_style) {
tui->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
"");
}
unibi_set_ext_str(ut, (size_t)tui->unibi_ext.reset_cursor_style,
"\x1b[?c");
} else if (konsolev > 0 && konsolev < 180770) {
// Konsole before version 18.07.70: set up a nonce profile. This has
// side effects on temporary font resizing. #6798
tui->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
TMUX_WRAP(tmux,
"\x1b]50;CursorShape=%?"
"%p1%{3}%<" "%t%{0}" // block
"%e%p1%{5}%<" "%t%{2}" // underline
"%e%{1}" // everything else is bar
"%;%d;BlinkingCursorEnabled=%?"
"%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special,
"%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag.
"%;%d\x07"));
if (-1 == tui->unibi_ext.reset_cursor_style) {
tui->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
"");
}
unibi_set_ext_str(ut, (size_t)tui->unibi_ext.reset_cursor_style,
"\x1b]50;\x07");
}
}

Regarding screen, there is a patch that implements DECSCUSR, but it has not yet been merged in v4.9.0. Therefore, if this patch is not applied, screen will not change the cursor shape.

https://git.savannah.gnu.org/cgit/screen.git/tree/src/ansi.c?h=v.4.9.0
https://www.gnu.org/software/screen/manual/html_node/Control-Sequences.html

Regarding putty, DECSCUSR is not implemented in the source on this page, although it is not the latest source. Also, the cursor shape does not change when the command (printf "\x1b[4 q") is executed in 0.7.8 (latest) to actually send the DECSCUSR sequence. Therefore, it should not be implemented. The MinTTY release notes mentioned in the code comment above are too old to find.

I am skeptical about cygwin, although I can't confirm this as I don't already have an environment where TERM is cygwin(command prompt before the so-called conpty implementation). However, cygwin currently uses conpty if it is available, so setting TERM to xterm changes the cursor shape.

I was able to confirm this by using "Use legacy console". It appears that DECSCUSR is also implemented in legacy consoles, although incomplete. It was me who added cygwin in the above code in the first place lol.

https://github.com/cygwin/cygwin/blob/9ddd48ee1b8d736ebbd0b0bdf146ecf96774cd8a/winsup/cygwin/fhandler/console.cc#L3068

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug issues reporting wrong behavior documentation
Projects
None yet
Development

No branches or pull requests

4 participants