如何在不禁用Vim搜索功能的情况下切换搜索高亮可见性

23
我希望映射一个键,例如F4,这样按下F4将切换搜索高亮的可见性,并且开始新搜索时无论当前是否可见都启用高亮显示。
我尝试过:
1. 将F4映射到:nohlsearch可以暂时禁用高亮可见性,而不关闭hlsearch设置,但它不能切换可见性。 2. 将F4映射到:set hlsearch!会切换开/关,但我不想切换hlsearch设置,只想切换可见性设置。如果hlsearch关闭,则不会自动返回到新的搜索中。
似乎没有:nohlsearch的相反形式,而且从函数调用该命令本身存在问题。
我找到了类似的问题,但它们没有提供答案。
更新: 第一个评论提供了我要求的内容,如下所示:
let hlstate=0
nnoremap <F4> :if (hlstate == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=1-hlstate<cr>
(注意:对于任何使用此功能的人来说,将地图压缩成一行而不是使用函数是必要的,因为您无法从函数内部影响高亮显示的更改。)
与稍有不同功能相关的问题:https://dev59.com/Tm7Xa4cB1Zd3GeqPp3AW#16750393

1
这是答案:第一行:“ctrl+c 切换高亮。”,第二行:“let hlstate=0”,第三行:“nnoremap <c-c> :if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<cr>。现在只需按 ctrl+c 即可切换高亮。 - trusktr
太好了!如果您将评论重新发布为答案,我会接受它。据我所知,该问题不再标记为重复。 - Ein
好的,就是这样。 :) - trusktr
谢谢您的灵感。您可能想在nnoremap和<F4>之间添加<silent>,以防止状态栏上出现垃圾信息。 - jollyroger
我花了一段时间才注意到 hlsearch 在函数中不起作用。有任何想法为什么? - dragonxlwang
13个回答

26

注意,最近的Vim(7.4.79)提供了v:hlsearch变量。这意味着您可以改进您的映射为:

:nnoremap <silent><expr> <Leader>h (&hls && v:hlsearch ? ':nohls' : ':set hls')."\n"

2
这是最佳选项,因为任何像/?nN等的搜索操作都会重新启用高亮,并且不需要重新映射它们。 - Walf
如何映射 ctrl-l 而不失去其原始功能? - SergioAraujo
1
@SergioAraujo 使用 :redraw 命令并附加 hls 命令。 - Christian Brabandt
@SergioAraujo v:hlsearch 可以正确地显示匹配是否被高亮,而 hls 则不能,它只是启用了此选项,但仍可能因为 :nohls 而被禁用。 - Christian Brabandt
如果我理解正确的话,您将<silent>等解释为占位符。它们不是,它们是文字字面意思,尖括号在vimscript中赋予其中的单词特殊含义。 - Walf
显示剩余3条评论

13
" ctrl+c to toggle highlight.
let hlstate=0
nnoremap <c-c> :if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<cr>

现在只需按下ctrl+c即可切换高亮显示。唯一的问题是,在搜索后要切换关闭高亮显示时,您需要按两次ctrl+c,因为搜索不会增加计数器。


我已经链接到另一个SO问题,展示了如何制作更好的切换。然而,它需要接受不同的功能,以便在自动启用高亮时进行操作:在其中,只有搜索会自动启用高亮,而不是替代(这是该方法的限制)。但我认为我实际上更喜欢这个。 - Ein
很酷,谢谢分享!通过一些努力,也许可以得出第三种解决方案。 :D - trusktr

12

我想要的是将一个键(例如F4)映射,以便按下F4可以切换搜索高亮的可见性,并且开始新搜索时启用可见性,无论当前的可见性如何。

我刚尝试了一下,似乎可以解决问题:

" switch higlight no matter the previous state
nmap <F4> :set hls! <cr>
" hit '/' highlights then enter search mode
nnoremap / :set hlsearch<cr>/

6
您可以使用 :set invhlsearch 切换搜索高亮显示。

5

通过高亮显示所有搜索模式匹配项, 我们可以将一个键映射为切换高亮状态的功能。与trusktr的答案不同,这里我们确实使用变量来存储状态。

"如果你想快速启用/禁用高亮显示,你可以将一个键映射为切换hlsearch选项的功能":

" Press F4 to toggle highlighting on/off, and show current value.
:noremap <F4> :set hlsearch! hlsearch?<CR>

“或者,按回车键暂时退出高亮显示的搜索”:
:nnoremap <CR> :nohlsearch<CR><CR>

2

其他答案需要切换高亮搜索,这并不是很好。

实际上,你只需要

let @/ = ''

我写了一个小函数来实现这个功能,并且高亮当前单词(就像 * 星号键一样),但不会跳到下一个匹配的单词,也不会影响跳转列表。
function! HLtoggle()
    if (@/ == '')
        let @/ = expand("<cword>")
    else
        let @/ = ''
    endif
endfunc

这很简单,但我在谷歌上找不到。

享受使用vim吧!:)


1

好的,试试这个:

:map <F12> :set nohls<CR>:let @/ = ""<CR>:set hls<CR>

然后,如果你按下 F12,它会关闭高亮显示,然后将最后的搜索字符串设置为空(即:清除它),并重新打开高亮显示。

或者,如果你想保存搜索字符串,那么可以做如下操作:

:map <F12> :set nohls<CR>:let @s = @/<CR>:let @/ = ""<CR>:set hls<CR>
:map <SHIFT><F12> :let @/=@s<CR>

现在按下SHIFTF12后,原始搜索字符串将被重置并突出显示。

如果这仍然不能满足您的需求,您仍然可以这样做:

:map <F12> :highlight Search term=None ctermfg=None ctermbg=None guifg=None guibg=None<CR>
:map <SHIFT><F12> :highlight Search term=OV1 ctermfg=OV2 ctermbg=OV3 guifg=OV4 guibg=OV5<CR>

OVx 是原始值,当您发出 :highlight Search<CR> 命令时可以记录下来。这样可以通过两个键盘快捷键关闭和重新打开它。如果您想要只用一个快捷键,您应该创建一个函数来切换它,然后为该函数创建一个映射。


这实际上与尝试1)是一样的,因为它会很好地关闭突出显示,并确保在下一次搜索时它会很好地回来。问题在于,如果没有下一个搜索,我希望该按钮关闭并打开我的最后一次搜索的突出显示,所以我们不能清除@/变量。 - Ein
请查看我的更新答案,了解如何将其设置回来和/或使用“highlight”命令。 - Zsolt Botykai
@Ein,这个问题的解决方案很简单(也许在2012年1月的vim版本中这个方法不适用),只需要执行:nohl命令就可以“隐藏”高亮显示,要“取消隐藏”则执行:set hls命令即可。你的搜索词会一直保留。只需创建一个基于变量计数器模2执行任一命令的映射即可。 - trusktr

0

我使用以下内容:

augroup onsearch                                                                                                                    
    autocmd!                                                                                                                          
    autocmd VimEnter * set hlsearch                                                                                                   
augroup END

nnoremap <leader>/ :set hlsearch!<CR>

autogroup 确保在进入 vim 时启用了高亮显示,但在重新加载您的 vimrc 文件时不会打开它。该映射可切换其开关。


0

我使用了trusktr稍加改进的版本。请注意,trusktr示例中使用的ctrl+c已经默认映射为非常方便的Escape。

" Toggle highlight search
let hlstate=0
nnomap <Leader>b :if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<CR>:echo "toggled visibility for hlsearch"<CR>
inomap <Leader>b <ESC>:if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<CR>:echo "toggled visibility for hlsearch"<CR>a

“<Leader>”是什么意思?它是一个按键吗? - Jocer
你能提供一下你所提到的源链接吗?(“trusktr”是谁?) - Jocer

0

嗯,:set hlsearch 不是与 :nohlsearch 相反的吗?

第一个命令打开匹配项的突出显示功能,而第二个命令则暂时关闭匹配项的突出显示功能。

我不明白你所说的“我不想切换'hlsearch'设置本身,只想切换可见性设置”的意思::set hlsearch 及其相关命令只关注搜索匹配项的可见性(即“突出显示”),除此之外无其他功能。

如果你想要每次搜索时都高亮匹配项,只需在你的 ~/.vimrc 文件中添加 :set hlsearch 命令即可。

如果你想要在搜索后关闭匹配项的突出显示功能,则将 F4 键映射为 :nohlsearch命令,下一次搜索时突出显示功能将自动恢复。


这就是 :nohlsearch 的作用:它是临时的。高亮将在下一次搜索时重现,这不正是你想要的吗? - romainl
是的和不。我想暂时关闭它,是的。但是我不希望这个临时时间是“直到下一次执行新的搜索”。相反,我希望它在临时关闭“直到我按 F4 执行新的搜索”。 - Ein
我也想切换它,而不必进行新的搜索。 - trusktr
Zsolt Botykai在他的回答中指出,要使搜索可见,只需执行:set hlsearch即可让它再次可见。hlsearch设置已经开启,因此:set hlsearch只是执行:nohlsearch的相反操作,而hlsearch设置一直处于开启状态。明白了吗? - trusktr
由于此问题已被关闭为重复,我无法发布答案,因此我已将我的解决方案作为评论发布在原始问题中。请查看上方。 - trusktr
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接