UI: fix cursor not displayed after hiding and un-hiding #12811

- TUI: Fix a case where the cursor was not displayed after hiding the
  cursor and then setting it to be displayed again.
- Change to reset everything before setting guicursor.

fixes #12800
close #12811

Steps to reproduce:

    nvim -u NORC
    :set termguicolors
    :hi nCursor guifg=red guibg=red
    :hi iCursor guifg=green guibg=green
    :hi cCursor guifg=blue guibg=blue
    :set guicursor=n:block-nCursor,i:hor25-iCursor,c:ver25-cCursor
    :set guicursor-=c:ver25-cCursor

Actual behaviour: Cursor is a blue vertical.
Expected behaviour: Cursor should be the default color block.
This commit is contained in:
erw7 2020-09-12 11:38:49 -07:00 committed by Justin M. Keyes
parent 1e10342382
commit 397be5d380
4 changed files with 60 additions and 20 deletions

View File

@ -2738,21 +2738,26 @@ A jump table for the options with a short description can be found at |Q_op|.
hor{N} horizontal bar, {N} percent of the character height
ver{N} vertical bar, {N} percent of the character width
block block cursor, fills the whole character
[only one of the above three should be present]
- Only one of the above three should be present.
- Default is "block" for each mode.
blinkwait{N} *cursor-blinking*
blinkon{N}
blinkoff{N}
blink times for cursor: blinkwait is the delay before
the cursor starts blinking, blinkon is the time that
the cursor is shown and blinkoff is the time that the
cursor is not shown. The times are in msec. When one
of the numbers is zero, there is no blinking. E.g.: >
cursor is not shown. Times are in msec. When one of
the numbers is zero, there is no blinking. E.g.: >
:set guicursor=n:blinkon0
< {group-name}
Highlight group name that sets the color and font for
the cursor. |inverse|/reverse and no group-name are
interpreted as "the host terminal default cursor
colors" which usually invert bg and fg colors.
< - Default is "blinkon0" for each mode.
{group-name}
Highlight group that decides the color and font of the
cursor.
In the |TUI|:
- |inverse|/reverse and no group-name are interpreted
as "host-terminal default cursor colors" which
typically means "inverted bg and fg colors".
- |ctermfg| and |guifg| are ignored.
{group-name}/{group-name}
Two highlight group names, the first is used when
no language mappings are used, the other when they

View File

@ -13,6 +13,10 @@
#include "nvim/api/private/helpers.h"
#include "nvim/ui.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor_shape.c.generated.h"
#endif
/// Handling of cursor and mouse pointer shapes in various modes.
cursorentry_T shape_table[SHAPE_IDX_COUNT] =
{
@ -77,7 +81,9 @@ Array mode_style_array(void)
return all;
}
/// Parse the 'guicursor' option
/// Parses the 'guicursor' option.
///
/// Clears `shape_table` if 'guicursor' is empty.
///
/// @param what SHAPE_CURSOR or SHAPE_MOUSE ('mouseshape')
///
@ -99,11 +105,17 @@ char_u *parse_shape_opt(int what)
// First round: check for errors; second round: do it for real.
for (round = 1; round <= 2; round++) {
if (round == 2 || *p_guicursor == NUL) {
// Set all entries to default (block, blinkon0, default color).
// This is the default for anything that is not set.
clear_shape_table();
if (*p_guicursor == NUL) {
ui_mode_info_set();
return NULL;
}
}
// Repeat for all comma separated parts.
modep = p_guicursor;
if (*p_guicursor == NUL) {
modep = (char_u *)"a:block-blinkon0";
}
while (modep != NULL && *modep != NUL) {
colonp = vim_strchr(modep, ':');
commap = vim_strchr(modep, ',');
@ -144,14 +156,6 @@ char_u *parse_shape_opt(int what)
if (all_idx >= 0) {
idx = all_idx--;
} else if (round == 2) {
{
// Set the defaults, for the missing parts
shape_table[idx].shape = SHAPE_BLOCK;
shape_table[idx].blinkwait = 0L;
shape_table[idx].blinkon = 0L;
shape_table[idx].blinkoff = 0L;
}
}
/* Parse the part after the colon */
@ -330,3 +334,16 @@ int cursor_get_mode_idx(void)
return SHAPE_IDX_N;
}
}
/// Clears all entries in shape_table to block, blinkon0, and default color.
static void clear_shape_table(void)
{
for (int idx = 0; idx < SHAPE_IDX_COUNT; idx++) {
shape_table[idx].shape = SHAPE_BLOCK;
shape_table[idx].blinkwait = 0L;
shape_table[idx].blinkon = 0L;
shape_table[idx].blinkoff = 0L;
shape_table[idx].id = 0;
shape_table[idx].id_lm = 0;
}
}

View File

@ -1083,6 +1083,7 @@ static void tui_set_mode(UI *ui, ModeShape mode)
}
} else if (c.id == 0) {
// No cursor color for this mode; reset to default.
data->want_invisible = false;
unibi_out_ext(ui, data->unibi_ext.reset_cursor_color);
}

View File

@ -286,6 +286,21 @@ describe('ui/cursor', function()
eq(173, named.normal.blinkon)
eq(42, named.showmatch.cell_percentage)
end)
-- If there is no setting for guicursor, it becomes the default setting.
meths.set_option('guicursor', 'n:ver35-blinkwait171-blinkoff172-blinkon173-Cursor/lCursor')
screen:expect(function()
for _,m in ipairs(screen._mode_info) do
if m.name ~= 'normal' then
eq('block', m.cursor_shape or 'block')
eq(0, m.blinkon or 0)
eq(0, m.blinkoff or 0)
eq(0, m.blinkwait or 0)
eq(0, m.hl_id or 0)
eq(0, m.id_lm or 0)
end
end
end)
end)
it("empty 'guicursor' sets cursor_shape=block in all modes", function()
@ -297,6 +312,8 @@ describe('ui/cursor', function()
if m['cursor_shape'] ~= nil then
eq('block', m.cursor_shape)
eq(0, m.blinkon)
eq(0, m.hl_id)
eq(0, m.id_lm)
end
end
end)