Visual: highlight char-at-cursor

Decide whether to highlight the visual-selected character under the
cursor, depending on 'guicursor' style:

- Highlight if cursor is blinking or non-block (vertical, horiz).
- Do NOT highlight if cursor is non-blinking block.

Traditionally Vim's visual selection does "reverse mode", which perhaps
conflicts with the non-blinking block cursor. But 'guicursor' defaults
to a vertical bar for selection=exclusive, and this confuses users who
expect to see the text highlighted.

closes #8983
This commit is contained in:
Justin M. Keyes
2019-01-03 00:09:35 +01:00
parent e2d71d11de
commit 37a499148f
5 changed files with 62 additions and 13 deletions

View File

@@ -357,6 +357,9 @@ TUI:
and has a 'ttybuiltin' setting to control how that combination works. Nvim
uses one or the other, it does not attempt to merge the two.
UI/Display:
|Visual| selection highlights the character at cursor. |visual-use|
VimL (Vim script) compatibility:
`count` does not alias to |v:count|
`errmsg` does not alias to |v:errmsg|

View File

@@ -254,6 +254,16 @@ char_u *parse_shape_opt(int what)
return NULL;
}
/// Returns true if the cursor is non-blinking "block" shape during
/// visual selection.
///
/// @param exclusive If 'selection' option is "exclusive".
bool cursor_is_block_during_visual(bool exclusive)
{
int mode_idx = exclusive ? SHAPE_IDX_VE : SHAPE_IDX_V;
return (SHAPE_BLOCK == shape_table[mode_idx].shape
&& 0 == shape_table[mode_idx].blinkon);
}
/// Map cursor mode from string to integer
///

View File

@@ -2761,9 +2761,9 @@ do_mouse (
} else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT))
&& mouse_has(MOUSE_VISUAL)) {
if (is_click || !VIsual_active) {
if (VIsual_active)
if (VIsual_active) {
orig_cursor = VIsual;
else {
} else {
VIsual = curwin->w_cursor;
orig_cursor = VIsual;
VIsual_active = true;
@@ -6401,8 +6401,8 @@ static void nv_visual(cmdarg_T *cap)
VIsual_mode = cap->cmdchar;
showmode();
}
redraw_curbuf_later(INVERTED); /* update the inversion */
} else { /* start Visual mode */
redraw_curbuf_later(INVERTED); // update the inversion
} else { // start Visual mode
if (cap->count0 > 0 && resel_VIsual_mode != NUL) {
/* use previously selected part */
VIsual = curwin->w_cursor;

View File

@@ -73,6 +73,7 @@
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/cursor_shape.h"
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
@@ -679,9 +680,9 @@ static void win_update(win_T *wp)
int old_botline = wp->w_botline;
long fold_count;
// Remember what happened to the previous line.
#define DID_NONE 1 /* didn't update a line */
#define DID_LINE 2 /* updated a normal line */
#define DID_FOLD 3 /* updated a folded line */
#define DID_NONE 1 // didn't update a line
#define DID_LINE 2 // updated a normal line
#define DID_FOLD 3 // updated a folded line
int did_update = DID_NONE;
linenr_T syntax_last_parsed = 0; /* last parsed text line */
linenr_T mod_top = 0;
@@ -2180,10 +2181,10 @@ win_line (
int syntax_attr = 0; /* attributes desired by syntax */
int has_syntax = FALSE; /* this buffer has syntax highl. */
int save_did_emsg;
int eol_hl_off = 0; /* 1 if highlighted char after EOL */
int draw_color_col = FALSE; /* highlight colorcolumn */
int *color_cols = NULL; /* pointer to according columns array */
bool has_spell = false; /* this buffer has spell checking */
int eol_hl_off = 0; // 1 if highlighted char after EOL
int draw_color_col = false; // highlight colorcolumn
int *color_cols = NULL; // pointer to according columns array
bool has_spell = false; // this buffer has spell checking
# define SPWORDLEN 150
char_u nextline[SPWORDLEN * 2]; /* text with start of the next line */
int nextlinecol = 0; /* column where nextline[] starts */
@@ -2389,8 +2390,9 @@ win_line (
}
}
// Check if the character under the cursor should not be inverted
if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin) {
// Check if the char under the cursor should be inverted (highlighted).
if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin
&& cursor_is_block_during_visual(*p_sel == 'e')) {
noinvcur = true;
}

View File

@@ -322,6 +322,40 @@ describe('highlight', function()
screen:attach()
end)
it('visual', function()
screen:detach()
screen = Screen.new(20,4)
screen:attach()
screen:set_default_attr_ids({
[1] = {background = Screen.colors.LightGrey},
[2] = {bold = true, foreground = Screen.colors.Blue1},
[3] = {bold = true},
})
insert([[
line1 foo bar
]])
-- Non-blinking block cursor: does NOT highlight char-at-cursor.
command('set guicursor=a:block-blinkon0')
feed('gg$vhhh')
screen:expect([[
line1 foo^ {1:bar} |
|
{2:~ }|
{3:-- VISUAL --} |
]])
-- Vertical cursor: highlights char-at-cursor. #8983
command('set guicursor=a:block-blinkon175')
feed('<esc>gg$vhhh')
screen:expect([[
line1 foo{1:^ bar} |
|
{2:~ }|
{3:-- VISUAL --} |
]])
end)
it('cterm=standout gui=standout', function()
screen:detach()
screen = Screen.new(20,5)