mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +00:00 
			
		
		
		
	fix(redraw): update Visual selection properly with splits (#27343)
This commit is contained in:
		@@ -135,32 +135,43 @@ static void comp_botline(win_T *wp)
 | 
			
		||||
  win_check_anchored_floats(wp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Redraw when w_virtcol changes and 'cursorcolumn' is set or 'cursorlineopt'
 | 
			
		||||
/// contains "screenline" or when the "CurSearch" highlight is in use.
 | 
			
		||||
/// Also when concealing is on and 'concealcursor' is active.
 | 
			
		||||
/// Redraw when w_virtcol changes and
 | 
			
		||||
/// - 'cursorcolumn' is set, or
 | 
			
		||||
/// - 'cursorlineopt' contains "screenline", or
 | 
			
		||||
/// - "CurSearch" highlight is in use, or
 | 
			
		||||
/// - 'concealcursor' is active, or
 | 
			
		||||
/// - Visual mode is active.
 | 
			
		||||
static void redraw_for_cursorcolumn(win_T *wp)
 | 
			
		||||
  FUNC_ATTR_NONNULL_ALL
 | 
			
		||||
{
 | 
			
		||||
  if ((wp->w_valid & VALID_VIRTCOL) == 0 && !pum_visible()) {
 | 
			
		||||
    if (wp->w_p_cuc
 | 
			
		||||
        || (win_hl_attr(wp, HLF_LC) != win_hl_attr(wp, HLF_L) && using_hlsearch())) {
 | 
			
		||||
      // When 'cursorcolumn' is set or "CurSearch" is in use
 | 
			
		||||
      // need to redraw with UPD_SOME_VALID.
 | 
			
		||||
      redraw_later(wp, UPD_SOME_VALID);
 | 
			
		||||
    } else if (VIsual_active) {
 | 
			
		||||
      // In Visual mode need to redraw with UPD_INVERTED.
 | 
			
		||||
      redraw_later(wp, UPD_INVERTED);
 | 
			
		||||
    } else if (wp->w_p_cul && (wp->w_p_culopt_flags & CULOPT_SCRLINE)) {
 | 
			
		||||
      // When 'cursorlineopt' contains "screenline" need to redraw with UPD_VALID.
 | 
			
		||||
      redraw_later(wp, UPD_VALID);
 | 
			
		||||
    }
 | 
			
		||||
  if (wp->w_valid & VALID_VIRTCOL) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If the cursor moves horizontally when 'concealcursor' is active, then the
 | 
			
		||||
  // current line needs to be redrawn in order to calculate the correct
 | 
			
		||||
  // cursor position.
 | 
			
		||||
  if ((wp->w_valid & VALID_VIRTCOL) == 0 && wp->w_p_cole > 0 && conceal_cursor_line(wp)) {
 | 
			
		||||
  // current line needs to be redrawn to calculate the correct cursor position.
 | 
			
		||||
  if (wp->w_p_cole > 0 && conceal_cursor_line(wp)) {
 | 
			
		||||
    redrawWinline(wp, wp->w_cursor.lnum);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (pum_visible()) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (wp->w_p_cuc
 | 
			
		||||
      || (win_hl_attr(wp, HLF_LC) != win_hl_attr(wp, HLF_L) && using_hlsearch())) {
 | 
			
		||||
    // When 'cursorcolumn' is set or "CurSearch" is in use
 | 
			
		||||
    // need to redraw with UPD_SOME_VALID.
 | 
			
		||||
    redraw_later(wp, UPD_SOME_VALID);
 | 
			
		||||
  } else if (wp->w_p_cul && (wp->w_p_culopt_flags & CULOPT_SCRLINE)) {
 | 
			
		||||
    // When 'cursorlineopt' contains "screenline" need to redraw with UPD_VALID.
 | 
			
		||||
    redraw_later(wp, UPD_VALID);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // When current buffer's cursor moves in Visual mode, redraw it with UPD_INVERTED.
 | 
			
		||||
  if (VIsual_active && wp->w_buffer == curbuf) {
 | 
			
		||||
    redraw_curbuf_later(UPD_INVERTED);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Calculates how much the 'listchars' "precedes" or 'smoothscroll' "<<<"
 | 
			
		||||
 
 | 
			
		||||
@@ -1967,8 +1967,8 @@ const char *did_set_selection(optset_T *args FUNC_ATTR_UNUSED)
 | 
			
		||||
    return e_invarg;
 | 
			
		||||
  }
 | 
			
		||||
  if (VIsual_active) {
 | 
			
		||||
    // In Visual mode cursor may be drawn differently.
 | 
			
		||||
    redrawWinline(curwin, curwin->w_cursor.lnum);
 | 
			
		||||
    // Visual selection may be drawn differently.
 | 
			
		||||
    redraw_curbuf_later(UPD_INVERTED);
 | 
			
		||||
  }
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -313,35 +313,136 @@ end)
 | 
			
		||||
describe('highlight', function()
 | 
			
		||||
  before_each(clear)
 | 
			
		||||
 | 
			
		||||
  it('visual', function()
 | 
			
		||||
    local screen = Screen.new(20, 4)
 | 
			
		||||
  it('Visual', function()
 | 
			
		||||
    local screen = Screen.new(45, 5)
 | 
			
		||||
    screen:attach()
 | 
			
		||||
    screen:set_default_attr_ids({
 | 
			
		||||
      [1] = { background = Screen.colors.LightGrey },
 | 
			
		||||
      [2] = { bold = true, foreground = Screen.colors.Blue1 },
 | 
			
		||||
      [3] = { bold = true },
 | 
			
		||||
      [4] = { reverse = true, bold = true },
 | 
			
		||||
      [5] = { reverse = true },
 | 
			
		||||
      [6] = { background = Screen.colors.Grey90 },
 | 
			
		||||
    })
 | 
			
		||||
    insert([[
 | 
			
		||||
      line1 foo bar
 | 
			
		||||
    abcdefghijklmnopqrs
 | 
			
		||||
    ABCDEFGHIJKLMNOPQRS
 | 
			
		||||
    ]])
 | 
			
		||||
    feed('gg')
 | 
			
		||||
    command('vsplit')
 | 
			
		||||
 | 
			
		||||
    -- Non-blinking block cursor: does NOT highlight char-at-cursor.
 | 
			
		||||
    command('set guicursor=a:block-blinkon0')
 | 
			
		||||
    feed('gg$vhhh')
 | 
			
		||||
    feed('V')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        line1 foo^ {1:bar}     |
 | 
			
		||||
                          |
 | 
			
		||||
      {2:~                   }|
 | 
			
		||||
      {3:-- VISUAL --}        |
 | 
			
		||||
      {1:  }^l{1:ine1 foo bar}       │{1:  line1 foo bar}       |
 | 
			
		||||
      abcdefghijklmnopqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      ABCDEFGHIJKLMNOPQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL LINE --}                            |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    feed('<Esc>$vhhh')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        line1 foo^ {1:bar}       │  line1 foo{1: bar}       |
 | 
			
		||||
      abcdefghijklmnopqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      ABCDEFGHIJKLMNOPQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL --}                                 |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    -- Vertical cursor: highlights char-at-cursor. #8983
 | 
			
		||||
    command('set guicursor=a:block-blinkon175')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        line1 foo{1:^ bar}     |
 | 
			
		||||
                          |
 | 
			
		||||
      {2:~                   }|
 | 
			
		||||
      {3:-- VISUAL --}        |
 | 
			
		||||
        line1 foo{1:^ bar}       │  line1 foo{1: bar}       |
 | 
			
		||||
      abcdefghijklmnopqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      ABCDEFGHIJKLMNOPQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL --}                                 |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    command('set selection=exclusive')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        line1 foo{1:^ ba}r       │  line1 foo{1: ba}r       |
 | 
			
		||||
      abcdefghijklmnopqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      ABCDEFGHIJKLMNOPQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL --}                                 |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    feed('o')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        line1 foo{1: ba}^r       │  line1 foo{1: ba}r       |
 | 
			
		||||
      abcdefghijklmnopqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      ABCDEFGHIJKLMNOPQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL --}                                 |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    feed('V')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
      {1:  line1 foo ba^r}       │{1:  line1 foo bar}       |
 | 
			
		||||
      abcdefghijklmnopqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      ABCDEFGHIJKLMNOPQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL LINE --}                            |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    command('set cursorcolumn')
 | 
			
		||||
    feed('<C-V>')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        line1 foo{1: ba}^r       │  line1 foo{1: ba}r       |
 | 
			
		||||
      abcdefghijklmn{6:o}pqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      ABCDEFGHIJKLMN{6:O}PQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL BLOCK --}                           |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    command('set selection&')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        line1 foo{1: ba^r}       │  line1 foo{1: bar}       |
 | 
			
		||||
      abcdefghijklmn{6:o}pqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      ABCDEFGHIJKLMN{6:O}PQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL BLOCK --}                           |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    feed('^')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        {1:^line1 foo }bar       │  {1:line1 foo }bar       |
 | 
			
		||||
      ab{6:c}defghijklmnopqrs   │abcdefghijklmnopqrs   |
 | 
			
		||||
      AB{6:C}DEFGHIJKLMNOPQRS   │ABCDEFGHIJKLMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL BLOCK --}                           |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    feed('2j')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        {1:line1 foo }bar       │  {1:line1 foo }bar       |
 | 
			
		||||
      ab{1:cdefghijkl}mnopqrs   │ab{1:cdefghijkl}mnopqrs   |
 | 
			
		||||
      AB{1:^CDEFGHIJKL}MNOPQRS   │AB{1:CDEFGHIJKL}MNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL BLOCK --}                           |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    command('set nocursorcolumn')
 | 
			
		||||
    feed('O')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        {1:line1 foo }bar       │  {1:line1 foo }bar       |
 | 
			
		||||
      ab{1:cdefghijkl}mnopqrs   │ab{1:cdefghijkl}mnopqrs   |
 | 
			
		||||
      AB{1:CDEFGHIJK^L}MNOPQRS   │AB{1:CDEFGHIJKL}MNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL BLOCK --}                           |
 | 
			
		||||
    ]])
 | 
			
		||||
 | 
			
		||||
    command('set selection=exclusive')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
        {1:line1 foo} bar       │  {1:line1 foo} bar       |
 | 
			
		||||
      ab{1:cdefghijk}lmnopqrs   │ab{1:cdefghijk}lmnopqrs   |
 | 
			
		||||
      AB{1:CDEFGHIJK}^LMNOPQRS   │AB{1:CDEFGHIJK}LMNOPQRS   |
 | 
			
		||||
      {4:[No Name] [+]          }{5:[No Name] [+]         }|
 | 
			
		||||
      {3:-- VISUAL BLOCK --}                           |
 | 
			
		||||
    ]])
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user