feat(highlight): implement CurSearch highlight

Adds a `CurSearch` highlight group to highlight the current search result under the cursor.
This commit is contained in:
Famiu Haque 2022-04-11 22:20:24 +06:00
parent 3f2e9298bd
commit b16afe4d55
9 changed files with 87 additions and 12 deletions

View File

@ -3176,8 +3176,12 @@ A jump table for the options with a short description can be found at |Q_op|.
'hlsearch' 'hls' boolean (default on)
global
When there is a previous search pattern, highlight all its matches.
The |hl-Search| highlight group determines the highlighting. Note that
only the matching text is highlighted, any offsets are not applied.
The |hl-Search| highlight group determines the highlighting for all
matches not under the cursor while the |hl-CurSearch| highlight group
(if defined) determines the highlighting for the match under the
cursor. If |hl-CurSearch| is not defined, then |hl-Search| is used for
both. Note that only the matching text is highlighted, any offsets
are not applied.
See also: 'incsearch' and |:match|.
When you get bored looking at the highlighted matches, you can turn it
off with |:nohlsearch|. This does not change the option value, as

View File

@ -5090,6 +5090,9 @@ ColorColumn used for the columns set with 'colorcolumn'
*hl-Conceal*
Conceal placeholder characters substituted for concealed
text (see 'conceallevel')
*hl-CurSearch*
CurSearch used for highlighting a search pattern under the cursor
(see 'hlsearch')
*hl-Cursor*
Cursor character under the cursor
lCursor the character under the cursor when |language-mapping|

View File

@ -351,6 +351,8 @@ Functions:
Highlight groups:
|hl-ColorColumn|, |hl-CursorColumn| are lower priority than most other
groups
|hl-CurSearch| highlights match under cursor instead of last match found
using |n| or |N|
|hl-CursorLine| is low-priority unless foreground color is set
*hl-VertSplit* superseded by |hl-WinSeparator|

View File

@ -63,6 +63,7 @@ typedef enum {
HLF_E, // error messages
HLF_I, // incremental search
HLF_L, // last search string
HLF_LC, // current search match
HLF_M, // "--More--" message
HLF_CM, // Mode (e.g., "-- INSERT --")
HLF_N, // line number for ":number" and ":#" commands
@ -123,6 +124,7 @@ EXTERN const char *hlf_names[] INIT(= {
[HLF_E] = "ErrorMsg",
[HLF_I] = "IncSearch",
[HLF_L] = "Search",
[HLF_LC] = "CurSearch",
[HLF_M] = "MoreMsg",
[HLF_CM] = "ModeMsg",
[HLF_N] = "LineNr",

View File

@ -1927,7 +1927,7 @@ void highlight_changed(void)
}
highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id,
hlf == HLF_INACTIVE);
(hlf == HLF_INACTIVE || hlf == HLF_LC));
if (highlight_attr[hlf] != highlight_attr_last[hlf]) {
if (hlf == HLF_MSG) {

View File

@ -4,6 +4,7 @@
// match.c: functions for highlighting matches
#include <stdbool.h>
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/fold.h"
#include "nvim/highlight_group.h"
@ -667,7 +668,16 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match
if (shl->endcol < next_col) {
shl->endcol = next_col;
}
// Use "CurSearch" highlight for current search match
if (shl == search_hl
&& (HL_ATTR(HLF_LC) || wp->w_hl_ids[HLF_LC])
&& wp->w_cursor.lnum == lnum
&& wp->w_cursor.col >= shl->startcol
&& wp->w_cursor.col < shl->endcol) {
shl->attr_cur = win_hl_attr(wp, HLF_LC) ? win_hl_attr(wp, HLF_LC) : HL_ATTR(HLF_LC);
} else {
shl->attr_cur = shl->attr;
}
// Match with the "Conceal" group results in hiding
// the match.
if (cur != NULL

View File

@ -95,27 +95,31 @@ static void comp_botline(win_T *wp)
win_check_anchored_floats(wp);
}
/// Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set.
/// Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set
/// or if the 'CurSearch' highlight is defined.
/// Also when concealing is on and 'concealcursor' is not active.
void redraw_for_cursorline(win_T *wp)
FUNC_ATTR_NONNULL_ALL
{
if ((wp->w_valid & VALID_CROW) == 0 && !pum_visible()
&& (wp->w_p_rnu || win_cursorline_standout(wp))) {
// win_line() will redraw the number column and cursorline only.
&& (wp->w_p_rnu || win_cursorline_standout(wp)
|| HL_ATTR(HLF_LC) || wp->w_hl_ids[HLF_LC])) {
// win_line() will redraw the number column and cursorline only
// and also update the CurSearch highlight (if needed).
redraw_later(wp, VALID);
}
}
/// Redraw when w_virtcol changes and 'cursorcolumn' is set or 'cursorlineopt'
/// contains "screenline".
/// contains "screenline" or when the 'CurSearch' highlight is defined.
/// Also when concealing is on and 'concealcursor' 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) {
// When 'cursorcolumn' is set need to redraw with SOME_VALID.
if (wp->w_p_cuc || HL_ATTR(HLF_LC) || wp->w_hl_ids[HLF_LC]) {
// When 'cursorcolumn' is set or 'CurSearch' is defined
// need to redraw with SOME_VALID.
redraw_later(wp, SOME_VALID);
} else if (wp->w_p_cul && (wp->w_p_culopt_flags & CULOPT_SCRLINE)) {
// When 'cursorlineopt' contains "screenline" need to redraw with VALID.

View File

@ -212,10 +212,10 @@ describe('ui/cursor', function()
if m.blinkwait then m.blinkwait = 700 end
end
if m.hl_id then
m.hl_id = 61
m.hl_id = 62
m.attr = {background = Screen.colors.DarkGray}
end
if m.id_lm then m.id_lm = 62 end
if m.id_lm then m.id_lm = 63 end
end
-- Assert the new expectation.

View File

@ -109,6 +109,56 @@ describe('search highlighting', function()
]])
end)
it('works for match under cursor', function()
screen:set_default_attr_ids({
[1] = {background = Screen.colors.Yellow},
[2] = {foreground = Screen.colors.Gray100, background = Screen.colors.Gray0},
[3] = {foreground = Screen.colors.Red},
})
command('highlight CurSearch guibg=Black guifg=White')
insert([[
There is no way that a bee should be
able to fly. Its wings are too small
to get its fat little body off the
ground. The bee, of course, flies
anyway because bees don't care what
humans think is impossible.]])
feed('/bee<CR>')
screen:expect{grid=[[
There is no way that a {2:^bee} should be |
able to fly. Its wings are too small |
to get its fat little body off the |
ground. The {1:bee}, of course, flies |
anyway because {1:bee}s don't care what |
humans think is impossible. |
{3:search hit BOTTOM, continuing at TOP} |
]]}
feed('nn')
screen:expect{grid=[[
There is no way that a {1:bee} should be |
able to fly. Its wings are too small |
to get its fat little body off the |
ground. The {1:bee}, of course, flies |
anyway because {2:^bee}s don't care what |
humans think is impossible. |
/bee |
]]}
feed('N')
screen:expect{grid=[[
There is no way that a {1:bee} should be |
able to fly. Its wings are too small |
to get its fat little body off the |
ground. The {2:^bee}, of course, flies |
anyway because {1:bee}s don't care what |
humans think is impossible. |
?bee |
]]}
end)
it('highlights after EOL', function()
insert("\n\n\n\n\n\n")