commit bb6f5c3b318b9b1797920008a417aabbcc133c45
parent 3fb53abe2a7ff163dc01d80d4c38c1265a8fa2b4
Author: Gregory Anders <greg@gpanders.com>
Date: Tue, 28 Oct 2025 13:11:00 -0500
fix(tui): reset cursor style on exit (#36261)
Fix the cursor style terminfo capability (should be Se, not se). Also
include foot in the list of terminals that supports setting and
resetting cursor style (see
https://codeberg.org/dnkl/foot/issues/797#issuecomment-280305)
Diffstat:
4 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/runtime/doc/faq.txt b/runtime/doc/faq.txt
@@ -108,7 +108,8 @@ which sets different colors in insert-mode and normal-mode:
------------------------------------------------------------------------------
CURSOR STYLE ISN'T RESTORED AFTER EXITING OR SUSPENDING AND RESUMING NVIM
-Terminals do not provide a way to query the cursor style. Use autocommands to
+Nvim uses the "Se" terminfo capability to reset the cursor style on exit. If
+your terminal's terminfo does not define this capability, use autocommands to
manage the cursor style:
>vim
au VimEnter,VimResume * set guicursor=n-v-c:block,i-ci-ve:ver25,r-cr:hor20,o:hor50
@@ -116,6 +117,9 @@ manage the cursor style:
\,sm:block-blinkwait175-blinkoff150-blinkon175
au VimLeave,VimSuspend * set guicursor=a:block-blinkon0
+
+Alternatively, consider setting the desired cursor shape in your shell (e.g.
+with PROMPT_COMMAND in bash).
<
------------------------------------------------------------------------------
diff --git a/src/gen/gen_terminfo.lua b/src/gen/gen_terminfo.lua
@@ -72,7 +72,7 @@ local wanted_strings = {
local wanted_strings_ext = {
-- the following are our custom name for extensions, see "extmap"
- { 'reset_cursor_style', 'se' },
+ { 'reset_cursor_style', 'Se' },
{ 'set_cursor_style', 'Ss' },
-- terminfo describes strikethrough modes as rmxx/smxx with respect
-- to the ECMA-48 strikeout/crossed-out attributes.
diff --git a/src/nvim/tui/terminfo_defs.h b/src/nvim/tui/terminfo_defs.h
@@ -451,7 +451,7 @@ static const TerminfoEntry st_256colour_terminfo = {
[kTerm_set_attributes] = "%?%p9%t\033(0%e\033(B%;\033[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p7%t;8%;m",
[kTerm_set_lr_margin] = NULL,
[kTerm_to_status_line] = "\033]0;",
- [kTerm_reset_cursor_style] = NULL,
+ [kTerm_reset_cursor_style] = "\033[2 q",
[kTerm_set_cursor_style] = "\033[%p1%d q",
[kTerm_enter_strikethrough_mode] = "\033[9m",
[kTerm_set_rgb_foreground] = NULL,
@@ -508,7 +508,7 @@ static const TerminfoEntry tmux_256colour_terminfo = {
[kTerm_set_attributes] = "\033[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p7%t;8%;m%?%p9%t^N%e\017%;",
[kTerm_set_lr_margin] = NULL,
[kTerm_to_status_line] = "\033]0;",
- [kTerm_reset_cursor_style] = NULL,
+ [kTerm_reset_cursor_style] = "\033[2 q",
[kTerm_set_cursor_style] = "\033[%p1%d q",
[kTerm_enter_strikethrough_mode] = "\033[9m",
[kTerm_set_rgb_foreground] = NULL,
@@ -565,7 +565,7 @@ static const TerminfoEntry vte_256colour_terminfo = {
[kTerm_set_attributes] = "\033[0%?%p6%t;1%;%?%p2%t;4%;%?%p4%t;5%;%?%p5%t;2%;%?%p7%t;8%;%?%p1%p3%|%t;7%;m%?%p9%t^N%e\017%;",
[kTerm_set_lr_margin] = NULL,
[kTerm_to_status_line] = NULL,
- [kTerm_reset_cursor_style] = NULL,
+ [kTerm_reset_cursor_style] = "\033[1 q",
[kTerm_set_cursor_style] = "\033[%p1%d q",
[kTerm_enter_strikethrough_mode] = "\033[9m",
[kTerm_set_rgb_foreground] = NULL,
@@ -622,7 +622,7 @@ static const TerminfoEntry xterm_256colour_terminfo = {
[kTerm_set_attributes] = "%?%p9%t\033(0%e\033(B%;\033[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m",
[kTerm_set_lr_margin] = "\033[?69h\033[%i%p1%d;%p2%ds",
[kTerm_to_status_line] = NULL,
- [kTerm_reset_cursor_style] = NULL,
+ [kTerm_reset_cursor_style] = "\033[2 q",
[kTerm_set_cursor_style] = "\033[%p1%d q",
[kTerm_enter_strikethrough_mode] = "\033[9m",
[kTerm_set_rgb_foreground] = NULL,
@@ -736,7 +736,7 @@ static const TerminfoEntry win32con_terminfo = {
[kTerm_set_attributes] = "\033[0%?%p1%t;7%;%?%p3%t;7%;%?%p6%t;1%;m",
[kTerm_set_lr_margin] = NULL,
[kTerm_to_status_line] = NULL,
- [kTerm_reset_cursor_style] = NULL,
+ [kTerm_reset_cursor_style] = "\033[0 q",
[kTerm_set_cursor_style] = "\033[%p1%d q",
[kTerm_enter_strikethrough_mode] = NULL,
[kTerm_set_rgb_foreground] = NULL,
@@ -793,7 +793,7 @@ static const TerminfoEntry conemu_terminfo = {
[kTerm_set_attributes] = "\033[0%?%p1%p3%|%t;7%;%?%p2%t;4%;%?%p6%t;1%;m",
[kTerm_set_lr_margin] = NULL,
[kTerm_to_status_line] = NULL,
- [kTerm_reset_cursor_style] = NULL,
+ [kTerm_reset_cursor_style] = "\033[2 q",
[kTerm_set_cursor_style] = "\033[%p1%d q",
[kTerm_enter_strikethrough_mode] = NULL,
[kTerm_set_rgb_foreground] = NULL,
@@ -850,7 +850,7 @@ static const TerminfoEntry vtpcon_terminfo = {
[kTerm_set_attributes] = "\033[0%?%p1%p3%|%t;7%;%?%p2%t;4%;%?%p6%t;1%;m",
[kTerm_set_lr_margin] = NULL,
[kTerm_to_status_line] = "\033]0;",
- [kTerm_reset_cursor_style] = NULL,
+ [kTerm_reset_cursor_style] = "\033[2 q",
[kTerm_set_cursor_style] = "\033[%p1%d q",
[kTerm_enter_strikethrough_mode] = NULL,
[kTerm_set_rgb_foreground] = NULL,
@@ -903,7 +903,7 @@ static const TerminfoEntry vtpcon_terminfo = {
// end of list
#define XLIST_TERMINFO_EXT \
- X(reset_cursor_style, se) \
+ X(reset_cursor_style, Se) \
X(set_cursor_style, Ss) \
X(enter_strikethrough_mode, smxx) \
X(set_rgb_foreground, setrgbf) \
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
@@ -533,6 +533,7 @@ static void terminfo_disable(TUIData *tui)
terminfo_out(tui, kTerm_exit_attribute_mode);
// Reset cursor to normal before exiting alternate screen.
terminfo_out(tui, kTerm_cursor_normal);
+ terminfo_out(tui, kTerm_reset_cursor_style);
terminfo_out(tui, kTerm_keypad_local);
// Reset the key encoding
@@ -2020,6 +2021,7 @@ static void patch_terminfo_bugs(TUIData *tui, const char *term, const char *colo
|| terminfo_is_term_family(term, "iTerm.app")
|| terminfo_is_term_family(term, "iTerm2.app");
bool alacritty = terminfo_is_term_family(term, "alacritty");
+ bool foot = terminfo_is_term_family(term, "foot");
// None of the following work over SSH; see :help TERM .
bool iterm_pretending_xterm = xterm && iterm_env;
bool gnome_pretending_xterm = xterm && colorterm
@@ -2209,6 +2211,7 @@ static void patch_terminfo_bugs(TUIData *tui, const char *term, const char *colo
|| teraterm // per TeraTerm "Supported Control Functions" doco
|| alacritty // https://github.com/jwilm/alacritty/pull/608
|| cygwin
+ || foot
// Some linux-type terminals implement the xterm extension.
// Example: console-terminal-emulator from the nosh toolset.
|| (linuxvt