diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-03-17 17:24:03 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-17 17:24:03 +0800 |
commit | 54db75e995f82a11f5d2a223d816d2ea0bd0467e (patch) | |
tree | b6413e4394c5b96a380fd1860de09f71396bace2 | |
parent | c52dfb6e840827a2de713e40ea8506491ec7ce0b (diff) | |
download | rneovim-54db75e995f82a11f5d2a223d816d2ea0bd0467e.tar.gz rneovim-54db75e995f82a11f5d2a223d816d2ea0bd0467e.tar.bz2 rneovim-54db75e995f82a11f5d2a223d816d2ea0bd0467e.zip |
refactor(drawline): integrate terminal hl with eol loop (#27893)
There is no test for using 'cursorline' in Normal mode in a terminal
buffer, so add a test and fix 'cursorcolumn' remaining when entering
Terminal mode.
Also move synIDattr() tests to ui/highlight_spec.lua.
-rw-r--r-- | src/nvim/drawline.c | 21 | ||||
-rw-r--r-- | src/nvim/terminal.c | 3 | ||||
-rw-r--r-- | test/functional/terminal/buffer_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/terminal/highlight_spec.lua | 172 | ||||
-rw-r--r-- | test/functional/ui/highlight_spec.lua | 112 |
5 files changed, 181 insertions, 129 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 816eb8a674..a6f3f0c4b3 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -2576,7 +2576,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s && wp->w_virtcol < grid->cols * (ptrdiff_t)(wlv.row - startrow + 1) + start_col && lnum != wp->w_cursor.lnum) || wlv.color_cols || wlv.line_attr_lowprio || wlv.line_attr - || wlv.diff_hlf != 0)) { + || wlv.diff_hlf != 0 || wp->w_buffer->terminal)) { int rightmost_vcol = get_rightmost_vcol(wp, wlv.color_cols); const int cuc_attr = win_hl_attr(wp, HLF_CUC); const int mc_attr = win_hl_attr(wp, HLF_MC); @@ -2590,7 +2590,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s : 0; const int base_attr = hl_combine_attr(wlv.line_attr_lowprio, diff_attr); - if (base_attr || wlv.line_attr) { + if (base_attr || wlv.line_attr || wp->w_buffer->terminal) { rightmost_vcol = INT_MAX; } @@ -2609,6 +2609,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s col_attr = hl_combine_attr(col_attr, mc_attr); } + if (wp->w_buffer->terminal && wlv.vcol < TERM_ATTRS_MAX) { + col_attr = hl_combine_attr(col_attr, term_attrs[wlv.vcol]); + } + col_attr = hl_combine_attr(col_attr, wlv.line_attr); linebuf_attr[wlv.off] = col_attr; @@ -2622,19 +2626,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s } } - // TODO(bfredl): integrate with the common beyond-the-end-loop - if (wp->w_buffer->terminal) { - // terminal buffers may need to highlight beyond the end of the logical line - while (wlv.col >= 0 && wlv.col < grid->cols) { - linebuf_char[wlv.off] = schar_from_ascii(' '); - linebuf_attr[wlv.off] = wlv.vcol >= TERM_ATTRS_MAX ? 0 : term_attrs[wlv.vcol]; - linebuf_vcol[wlv.off] = wlv.vcol; - wlv.off++; - wlv.vcol++; - wlv.col++; - } - } - if (kv_size(fold_vt) > 0) { draw_virt_text_item(buf, win_col_offset, fold_vt, kHlModeCombine, grid->cols, 0); } diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index edde7ff57a..3734d55a5b 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -543,6 +543,9 @@ bool terminal_enter(void) } else { curwin->w_p_cul = false; } + if (curwin->w_p_cuc) { + redraw_later(curwin, UPD_SOME_VALID); + } curwin->w_p_cuc = false; curwin->w_p_so = 0; curwin->w_p_siso = 0; diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 376b7b849e..ea9d974dc3 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -54,7 +54,7 @@ describe(':terminal buffer', function() eq({ 0, 'both' }, eval('[&l:cursorline, &l:cursorlineopt]')) end) - it('terminal-mode disables cursorline when cursorlineopt is only set to "line', function() + it('terminal-mode disables cursorline when cursorlineopt is only set to "line"', function() feed([[<C-\><C-N>]]) command('setlocal cursorline cursorlineopt=line') feed('i') diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua index ec057c6766..98d760d1ee 100644 --- a/test/functional/terminal/highlight_spec.lua +++ b/test/functional/terminal/highlight_spec.lua @@ -5,7 +5,6 @@ local feed, clear = helpers.feed, helpers.clear local api = helpers.api local testprg, command = helpers.testprg, helpers.command local nvim_prog_abs = helpers.nvim_prog_abs -local eq, eval = helpers.eq, helpers.eval local fn = helpers.fn local nvim_set = helpers.nvim_set local is_os = helpers.is_os @@ -191,6 +190,65 @@ it(':terminal highlight has lower precedence than editor #9964', function() ]]) end) +it('CursorLine and CursorColumn work in :terminal buffer in Normal mode', function() + clear() + local screen = Screen.new(50, 7) + screen:set_default_attr_ids({ + [1] = { background = Screen.colors.Grey90 }, -- CursorLine, CursorColumn + [2] = { reverse = true }, -- TermCursor + [3] = { bold = true }, -- ModeMsg + }) + screen:attach() + command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) + screen:expect([[ + ^tty ready | + |*6 + ]]) + thelpers.feed_data((' foobar'):rep(30)) + screen:expect([[ + ^tty ready | + foobar foobar foobar foobar foobar foobar foobar | + foobar foobar foobar foobar foobar foobar foobar f| + oobar foobar foobar foobar foobar foobar foobar fo| + obar foobar foobar foobar foobar foobar foobar foo| + bar foobar | + | + ]]) + command('set cursorline cursorcolumn') + feed('j10w') + screen:expect([[ + tty ready {1: } | + foobar foobar{1: }foobar foobar foobar foobar foobar | + {1:foobar foobar ^foobar foobar foobar foobar foobar f}| + oobar foobar f{1:o}obar foobar foobar foobar foobar fo| + obar foobar fo{1:o}bar foobar foobar foobar foobar foo| + bar foobar {1: } | + | + ]]) + -- Entering terminal mode disables 'cursorline' and 'cursorcolumn'. + feed('i') + screen:expect([[ + tty ready | + foobar foobar foobar foobar foobar foobar foobar | + foobar foobar foobar foobar foobar foobar foobar f| + oobar foobar foobar foobar foobar foobar foobar fo| + obar foobar foobar foobar foobar foobar foobar foo| + bar foobar{2: } | + {3:-- TERMINAL --} | + ]]) + -- Leaving terminal mode restores old values. + feed([[<C-\><C-N>]]) + screen:expect([[ + tty ready{1: } | + foobar f{1:o}obar foobar foobar foobar foobar foobar | + foobar fo{1:o}bar foobar foobar foobar foobar foobar f| + oobar foo{1:b}ar foobar foobar foobar foobar foobar fo| + obar foob{1:a}r foobar foobar foobar foobar foobar foo| + {1:bar fooba^r }| + | + ]]) +end) + describe(':terminal highlight forwarding', function() local screen @@ -276,115 +334,3 @@ describe(':terminal highlight with custom palette', function() ]]) end) end) - -describe('synIDattr()', function() - local screen - before_each(function() - clear() - screen = Screen.new(50, 7) - command('highlight Normal ctermfg=252 guifg=#ff0000 guibg=Black') - -- Salmon #fa8072 Maroon #800000 - command( - 'highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon cterm=strikethrough gui=strikethrough' - ) - end) - - it('returns cterm-color if RGB-capable UI is _not_ attached', function() - eq('252', eval('synIDattr(hlID("Normal"), "fg")')) - eq('252', eval('synIDattr(hlID("Normal"), "fg#")')) - eq('', eval('synIDattr(hlID("Normal"), "bg")')) - eq('', eval('synIDattr(hlID("Normal"), "bg#")')) - eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) - eq('79', eval('synIDattr(hlID("Keyword"), "fg#")')) - eq('', eval('synIDattr(hlID("Keyword"), "sp")')) - eq('', eval('synIDattr(hlID("Keyword"), "sp#")')) - end) - - it('returns gui-color if "gui" arg is passed', function() - eq('Black', eval('synIDattr(hlID("Normal"), "bg", "gui")')) - eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp", "gui")')) - end) - - it('returns gui-color if RGB-capable UI is attached', function() - screen:attach({ rgb = true }) - eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg")')) - eq('Black', eval('synIDattr(hlID("Normal"), "bg")')) - eq('Salmon', eval('synIDattr(hlID("Keyword"), "fg")')) - eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp")')) - end) - - it('returns #RRGGBB value for fg#/bg#/sp#', function() - screen:attach({ rgb = true }) - eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg#")')) - eq('#000000', eval('synIDattr(hlID("Normal"), "bg#")')) - eq('#fa8072', eval('synIDattr(hlID("Keyword"), "fg#")')) - eq('#800000', eval('synIDattr(hlID("Keyword"), "sp#")')) - end) - - it('returns color number if non-GUI', function() - screen:attach({ rgb = false }) - eq('252', eval('synIDattr(hlID("Normal"), "fg")')) - eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) - end) - - it('returns "1" if group has given highlight attribute', function() - local hl_attrs = { - 'underline', - 'undercurl', - 'underdouble', - 'underdotted', - 'underdashed', - 'strikethrough', - } - for _, hl_attr in ipairs(hl_attrs) do - local context = 'using ' .. hl_attr .. ' attr' - command('highlight Keyword cterm=' .. hl_attr .. ' gui=' .. hl_attr) - eq('', eval('synIDattr(hlID("Normal"), "' .. hl_attr .. '")'), context) - eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '")'), context) - eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '", "gui")'), context) - end - end) -end) - -describe('fg/bg special colors', function() - local screen - before_each(function() - clear() - screen = Screen.new(50, 7) - command('highlight Normal ctermfg=145 ctermbg=16 guifg=#ff0000 guibg=Black') - command('highlight Visual ctermfg=bg ctermbg=fg guifg=bg guibg=fg guisp=bg') - end) - - it('resolve to "Normal" values', function() - eq(eval('synIDattr(hlID("Normal"), "bg")'), eval('synIDattr(hlID("Visual"), "fg")')) - eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")')) - eq(eval('synIDattr(hlID("Normal"), "fg")'), eval('synIDattr(hlID("Visual"), "bg")')) - eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")')) - eq('bg', eval('synIDattr(hlID("Visual"), "fg", "gui")')) - eq('bg', eval('synIDattr(hlID("Visual"), "fg#", "gui")')) - eq('fg', eval('synIDattr(hlID("Visual"), "bg", "gui")')) - eq('fg', eval('synIDattr(hlID("Visual"), "bg#", "gui")')) - eq('bg', eval('synIDattr(hlID("Visual"), "sp", "gui")')) - eq('bg', eval('synIDattr(hlID("Visual"), "sp#", "gui")')) - end) - - it('resolve to "Normal" values in RGB-capable UI', function() - screen:attach({ rgb = true }) - eq('bg', eval('synIDattr(hlID("Visual"), "fg")')) - eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")')) - eq('fg', eval('synIDattr(hlID("Visual"), "bg")')) - eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")')) - eq('bg', eval('synIDattr(hlID("Visual"), "sp")')) - eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "sp#")')) - end) - - it('resolve after the "Normal" group is modified', function() - screen:attach({ rgb = true }) - local new_guibg = '#282c34' - local new_guifg = '#abb2bf' - command('highlight Normal guifg=' .. new_guifg .. ' guibg=' .. new_guibg) - eq(new_guibg, eval('synIDattr(hlID("Visual"), "fg#")')) - eq(new_guifg, eval('synIDattr(hlID("Visual"), "bg#")')) - eq(new_guibg, eval('synIDattr(hlID("Visual"), "sp#")')) - end) -end) diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index f6d262c6fd..34a7bc19c6 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -2537,3 +2537,115 @@ describe('highlight namespaces', function() } end) end) + +describe('synIDattr()', function() + local screen + before_each(function() + clear() + screen = Screen.new(50, 7) + command('highlight Normal ctermfg=252 guifg=#ff0000 guibg=Black') + -- Salmon #fa8072 Maroon #800000 + command( + 'highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon cterm=strikethrough gui=strikethrough' + ) + end) + + it('returns cterm-color if RGB-capable UI is _not_ attached', function() + eq('252', eval('synIDattr(hlID("Normal"), "fg")')) + eq('252', eval('synIDattr(hlID("Normal"), "fg#")')) + eq('', eval('synIDattr(hlID("Normal"), "bg")')) + eq('', eval('synIDattr(hlID("Normal"), "bg#")')) + eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) + eq('79', eval('synIDattr(hlID("Keyword"), "fg#")')) + eq('', eval('synIDattr(hlID("Keyword"), "sp")')) + eq('', eval('synIDattr(hlID("Keyword"), "sp#")')) + end) + + it('returns gui-color if "gui" arg is passed', function() + eq('Black', eval('synIDattr(hlID("Normal"), "bg", "gui")')) + eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp", "gui")')) + end) + + it('returns gui-color if RGB-capable UI is attached', function() + screen:attach({ rgb = true }) + eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg")')) + eq('Black', eval('synIDattr(hlID("Normal"), "bg")')) + eq('Salmon', eval('synIDattr(hlID("Keyword"), "fg")')) + eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp")')) + end) + + it('returns #RRGGBB value for fg#/bg#/sp#', function() + screen:attach({ rgb = true }) + eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg#")')) + eq('#000000', eval('synIDattr(hlID("Normal"), "bg#")')) + eq('#fa8072', eval('synIDattr(hlID("Keyword"), "fg#")')) + eq('#800000', eval('synIDattr(hlID("Keyword"), "sp#")')) + end) + + it('returns color number if non-GUI', function() + screen:attach({ rgb = false }) + eq('252', eval('synIDattr(hlID("Normal"), "fg")')) + eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) + end) + + it('returns "1" if group has given highlight attribute', function() + local hl_attrs = { + 'underline', + 'undercurl', + 'underdouble', + 'underdotted', + 'underdashed', + 'strikethrough', + } + for _, hl_attr in ipairs(hl_attrs) do + local context = 'using ' .. hl_attr .. ' attr' + command('highlight Keyword cterm=' .. hl_attr .. ' gui=' .. hl_attr) + eq('', eval('synIDattr(hlID("Normal"), "' .. hl_attr .. '")'), context) + eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '")'), context) + eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '", "gui")'), context) + end + end) +end) + +describe('fg/bg special colors', function() + local screen + before_each(function() + clear() + screen = Screen.new(50, 7) + command('highlight Normal ctermfg=145 ctermbg=16 guifg=#ff0000 guibg=Black') + command('highlight Visual ctermfg=bg ctermbg=fg guifg=bg guibg=fg guisp=bg') + end) + + it('resolve to "Normal" values', function() + eq(eval('synIDattr(hlID("Normal"), "bg")'), eval('synIDattr(hlID("Visual"), "fg")')) + eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")')) + eq(eval('synIDattr(hlID("Normal"), "fg")'), eval('synIDattr(hlID("Visual"), "bg")')) + eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")')) + eq('bg', eval('synIDattr(hlID("Visual"), "fg", "gui")')) + eq('bg', eval('synIDattr(hlID("Visual"), "fg#", "gui")')) + eq('fg', eval('synIDattr(hlID("Visual"), "bg", "gui")')) + eq('fg', eval('synIDattr(hlID("Visual"), "bg#", "gui")')) + eq('bg', eval('synIDattr(hlID("Visual"), "sp", "gui")')) + eq('bg', eval('synIDattr(hlID("Visual"), "sp#", "gui")')) + end) + + it('resolve to "Normal" values in RGB-capable UI', function() + screen:attach({ rgb = true }) + eq('bg', eval('synIDattr(hlID("Visual"), "fg")')) + eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")')) + eq('fg', eval('synIDattr(hlID("Visual"), "bg")')) + eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")')) + eq('bg', eval('synIDattr(hlID("Visual"), "sp")')) + eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "sp#")')) + end) + + it('resolve after the "Normal" group is modified', function() + screen:attach({ rgb = true }) + local new_guibg = '#282c34' + local new_guifg = '#abb2bf' + command('highlight Normal guifg=' .. new_guifg .. ' guibg=' .. new_guibg) + eq(new_guibg, eval('synIDattr(hlID("Visual"), "fg#")')) + eq(new_guifg, eval('synIDattr(hlID("Visual"), "bg#")')) + eq(new_guibg, eval('synIDattr(hlID("Visual"), "sp#")')) + end) +end) |