'guicursor': Empty means "block cursor in all modes".

Also: update default 'guicursor' to match the documentation.
This commit is contained in:
Justin M. Keyes 2017-04-01 13:08:42 +02:00
parent 54bab0019b
commit c2826a7830
11 changed files with 214 additions and 61 deletions

View File

@ -371,27 +371,6 @@ See
Used to set the 'shell' option, which determines the shell used by the
.Ic :terminal
command.
.It Ev NVIM_TUI_ENABLE_CURSOR_SHAPE
Set to 0 to prevent Nvim from changing the cursor shape.
Set to 1 to enable non-blinking mode-sensitive cursor (this is the default).
Set to 2 to enable blinking mode-sensitive cursor.
Host terminal must support the DECSCUSR CSI escape sequence.
.Pp
Depending on the terminal emulator, using this option with
.Nm
under
.Xr tmux 1
might require adding the following to
.Pa ~/.tmux.conf :
.Bd -literal -offset indent
set -ga terminal-overrides ',*:Ss=\eE[%p1%d q:Se=\eE[2 q'
.Ed
.Pp
See
.Ic terminal-overrides
in the
.Xr tmux 1
manual page for more information.
.El
.Sh FILES
.Bl -tag -width "~/.config/nvim/init.vim"

View File

@ -250,23 +250,21 @@ connect to another with different type codes.
==============================================================================
6. Remote UIs *rpc-remote-ui*
Nvim allows Graphical user interfaces to be implemented by separate processes
communicating with Nvim over the RPC API. Currently the ui model conists of a
terminal-like grid with one single, monospace font size, with a few elements
that could be drawn separately from the grid (for the momemnt only the popup
menu)
GUIs can be implemented as external processes communicating with Nvim over the
RPC API. Currently the UI model consists of a terminal-like grid with one
single, monospace font size. Some elements (UI "widgets") can be drawn
separately from the grid.
After connecting to a nvim instance (typically a spawned, embedded instance)
use the |nvim_ui_attach|(width, height, options) API method to tell nvim that your
program wants to draw the nvim screen on a grid with "width" times
"height" cells. "options" should be a dictionary with the following (all
optional) keys:
`rgb`: Controls what color format to use.
After connecting to Nvim (usually a spawned, embedded instance) use the
|nvim_ui_attach| API method to tell Nvim that your program wants to draw the
Nvim screen on a grid of width × height cells. `options` must be
a dictionary with these (optional) keys:
`rgb` Controls what color format to use.
Set to true (default) to use 24-bit rgb
colors.
Set to false to use terminal color codes (at
most 256 different colors).
`popupmenu_external`: Instead of drawing the completion popupmenu on
`popupmenu_external` Instead of drawing the completion popupmenu on
the grid, Nvim will send higher-level events to
the ui and let it draw the popupmenu.
Defaults to false.

View File

@ -2790,22 +2790,17 @@ A jump table for the options with a short description can be found at |Q_op|.
i-ci:ver25-Cursor/lCursor,
r-cr:hor20-Cursor/lCursor,
sm:block-Cursor
-blinkwait175-blinkoff150-blinkon175",
for Windows console:
"n-v-c:block,o:hor50,i-ci:hor15,
r-cr:hor30,sm:block")
-blinkwait175-blinkoff150-blinkon175")
global
{only available when compiled with GUI enabled, and
for Windows console}
This option tells Vim what the cursor should look like in different
modes. It fully works in the GUI. In a Windows console, only
the height of the cursor can be changed. This can be done by
specifying a block cursor, or a percentage for a vertical or
horizontal cursor.
For a console, shape is taken into account and color as well if
'termguicolors' is set. 't_SI' and 't_EI' are deprecated in neovim.
The option is a comma separated list of parts. Each part consist of a
Configures the cursor style for each mode. Works in the GUI and some
terminals. Empty means "non-blinking block cursor in all modes": >
:set guicursor=
<
With tmux you might need this in ~/.tmux.conf (see terminal-overrides
in the tmux(1) manual page): >
set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'
<
The option is a comma separated list of parts. Each part consists of a
mode-list and an argument-list:
mode-list:argument-list,mode-list:argument-list,..
The mode-list is a dash separated list of these modes:

View File

@ -113,6 +113,7 @@ Some `CTRL-SHIFT-...` key chords are distinguished from `CTRL-...` variants
Options:
'cpoptions' flags: |cpo-_|
'guicursor' works in the terminal
'inccommand' shows interactive results for |:substitute|-like commands
'statusline' supports unlimited alignment sections
'tabline' %@Func@foo%X can call any function on mouse-click

View File

@ -45,7 +45,7 @@ static cursorentry_T shape_table[SHAPE_IDX_COUNT] =
};
/// Converts cursor_shapes into a Dictionary of dictionaries
/// @return a dictionary of the form {"normal" : { "cursor_shape": ... }, ...}
/// @return dictionary of the form {"normal" : { "cursor_shape": ... }, ...}
Dictionary cursor_shape_dict(void)
{
Dictionary all = ARRAY_DICT_INIT;
@ -82,7 +82,7 @@ Dictionary cursor_shape_dict(void)
/// Parse the 'guicursor' option
///
/// @param what either SHAPE_CURSOR or SHAPE_MOUSE ('mouseshape')
/// @param what SHAPE_CURSOR or SHAPE_MOUSE ('mouseshape')
///
/// @returns error message for an illegal option, NULL otherwise.
char_u *parse_shape_opt(int what)
@ -103,10 +103,11 @@ char_u *parse_shape_opt(int what)
* First round: check for errors; second round: do it for real.
*/
for (round = 1; round <= 2; ++round) {
/*
* Repeat for all comma separated parts.
*/
// Repeat for all comma separated parts.
modep = p_guicursor;
if (*p_guicursor == NUL) {
modep = (char_u *)"a:block-blinkon0";
}
while (*modep != NUL) {
colonp = vim_strchr(modep, ':');
if (colonp == NULL)
@ -115,7 +116,7 @@ char_u *parse_shape_opt(int what)
return (char_u *)N_("E546: Illegal mode");
commap = vim_strchr(modep, ',');
// Repeat for all mode's before the colon.
// Repeat for all modes before the colon.
// For the 'a' mode, we loop to handle all the modes.
all_idx = -1;
assert(modep < colonp);

View File

@ -37,7 +37,7 @@ SHAPE_VER = 2 ///< vertical bar cursor
#define SHAPE_CURSOR 2 /* used for text cursor shape */
typedef struct cursor_entry {
char *full_name; ///< mode full name
char *full_name; ///< mode description
CursorShape shape; ///< cursor shape: one of the SHAPE_ defines
int mshape; ///< mouse shape: one of the MSHAPE defines
int percentage; ///< percentage of cell for bar

View File

@ -1000,7 +1000,7 @@ return {
deny_duplicates=true,
vi_def=true,
varname='p_guicursor',
defaults={if_true={vi="n-v-c:block,o:hor50,i-ci:hor15,r-cr:hor30,sm:block"}}
defaults={if_true={vi="n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175"}}
},
{
full_name='guifont', abbreviation='gfn',

View File

@ -148,7 +148,6 @@ static void terminfo_start(UI *ui)
data->ut = unibi_dummy();
}
fix_terminfo(data);
// Initialize the cursor shape.
// Set 't_Co' from the result of unibilium & fix_terminfo.
t_colors = unibi_get_num(data->ut, unibi_max_colors);
// Enter alternate screen and clear

View File

@ -0,0 +1,180 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, meths = helpers.clear, helpers.feed, helpers.meths
local insert, execute = helpers.insert, helpers.execute
local eq, funcs = helpers.eq, helpers.funcs
local command = helpers.command
if helpers.pending_win32(pending) then return end
describe('ui/cursor', function()
local screen
before_each(function()
clear()
screen = Screen.new(25, 5)
screen:attach()
end)
after_each(function()
screen:detach()
end)
it("'guicursor' is published as a UI event", function()
command('redraw')
screen:expect('', nil, nil, nil, true) -- Tickle the event-loop.
local expected_cursor_style = {
cmd_insert = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 25,
cursor_shape = 'vertical',
hl_id = 45,
id_lm = 46,
mouse_shape = 0,
short_name = 'ci' },
cmd_line = {
mouse_shape = 0,
short_name = 'e' },
cmd_normal = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 0,
cursor_shape = 'block',
hl_id = 45,
id_lm = 46,
mouse_shape = 0,
short_name = 'c' },
cmd_replace = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 20,
cursor_shape = 'horizontal',
hl_id = 45,
id_lm = 46,
mouse_shape = 0,
short_name = 'cr' },
drag_statusline = {
mouse_shape = 0,
short_name = 'sd' },
insert = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 25,
cursor_shape = 'vertical',
hl_id = 45,
id_lm = 46,
mouse_shape = 0,
short_name = 'i' },
match_paren = {
blinkoff = 150,
blinkon = 175,
blinkwait = 175,
cell_percentage = 0,
cursor_shape = 'block',
hl_id = 45,
id_lm = 45,
short_name = 'sm' },
more = {
mouse_shape = 0,
short_name = 'm' },
more_lastline = {
mouse_shape = 0,
short_name = 'ml' },
normal = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 0,
cursor_shape = 'block',
hl_id = 45,
id_lm = 46,
mouse_shape = 0,
short_name = 'n' },
pending = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 50,
cursor_shape = 'horizontal',
hl_id = 45,
id_lm = 45,
mouse_shape = 0,
short_name = 'o' },
replace = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 20,
cursor_shape = 'horizontal',
hl_id = 45,
id_lm = 46,
mouse_shape = 0,
short_name = 'r' },
statusline = {
mouse_shape = 0,
short_name = 's' },
vdrag = {
mouse_shape = 0,
short_name = 'vd' },
visual = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 0,
cursor_shape = 'block',
hl_id = 45,
id_lm = 46,
mouse_shape = 0,
short_name = 'v' },
visual_select = {
blinkoff = 250,
blinkon = 400,
blinkwait = 700,
cell_percentage = 35,
cursor_shape = 'vertical',
hl_id = 45,
id_lm = 45,
mouse_shape = 0,
short_name = 've' },
vsep = {
mouse_shape = 0,
short_name = 'vs' }
}
-- Default 'guicursor' published on startup.
eq(expected_cursor_style, screen._cursor_style)
eq('normal', screen.mode)
-- Event is published ONLY if the cursor style changed.
screen._cursor_style = nil
command('redraw')
screen:expect('', nil, nil, nil, true) -- Tickle the event-loop.
eq(nil, screen._cursor_style)
-- Change the cursor style.
meths.set_option('guicursor', 'n-v-c:ver35-blinkwait171-blinkoff172-blinkon173,ve:hor35,o:ver50,i-ci:block,r-cr:hor90,sm:ver42')
command('redraw')
screen:expect('', nil, nil, nil, true) -- Tickle the event-loop.
eq('vertical', screen._cursor_style.normal.cursor_shape)
eq('horizontal', screen._cursor_style.visual_select.cursor_shape)
eq('vertical', screen._cursor_style.pending.cursor_shape)
eq('block', screen._cursor_style.insert.cursor_shape)
eq('vertical', screen._cursor_style.match_paren.cursor_shape)
end)
it("empty 'guicursor' sets cursor_shape=block in all modes", function()
meths.set_option('guicursor', '')
command('redraw')
screen:expect('', nil, nil, nil, true) -- Tickle the event-loop.
for _, m in ipairs({ 'cmd_insert', 'cmd_normal', 'cmd_replace', 'insert',
'match_paren', 'normal', 'replace', 'visual',
'visual_select', }) do
eq('block', screen._cursor_style[m].cursor_shape)
end
end)
end)

View File

@ -6,7 +6,7 @@ local eq, funcs = helpers.eq, helpers.funcs
if helpers.pending_win32(pending) then return end
describe('Mouse input', function()
describe('ui/mouse/input', function()
local screen
before_each(function()

View File

@ -345,8 +345,8 @@ function Screen:_handle_resize(width, height)
}
end
function Screen:_handle_cursor_style_set(styles)
self._cursor_styles = styles
function Screen:_handle_cursor_style_set(style)
self._cursor_style = style
end
function Screen:_handle_clear()