Vim有(至少)两组在相反方向上搜索的命令。键入/,然后将在整个文档中向前搜索该模式;输入?,然后模式将向后搜索。 *#命令之间存在相同的关系。

我不喜欢这些命令还设置了nN命令的搜索方向。使用/后,n在文档中前进,而N在文档后退;使用?后,n向后前进,而N向后前进。 (换句话说,n始终与原始搜索方向相同,而N始终与原始搜索方向相同。)

我怎样才能使n前进通过文档,而N前进向后,无论我开始搜索哪个方向?

#1 楼

您可以使用以下命令来更改nN的行为,使其始终向下/向上搜索:

nnoremap <expr> n 'Nn'[v:searchforward]
nnoremap <expr> N 'nN'[v:searchforward]


更新:它如何工作?

这使用expression-maps,每次遇到lhs时,它将映射的lhs映射到将要评估的表达式。请参阅帮助中的:h map-expression

发生的事情是,将v:searchforward变量(它确定最后一次搜索的方向的内部状态,请参见:h v:searchforward)用作该字符串的索引。前面。因此,在第一个地图的情况下,如果最后一个搜索方向是向前,则n将被映射到'n'(索引为1,表示返回第二个字符),如果它是向后的,则'n'将被映射到'N'(因为v:searchforward变量为0,因此将返回'N'。)

写这些映射的另一种方法是(可能更清楚):

nnoremap <expr> n (v:searchforward ? 'n' : 'N')
nnoremap <expr> N (v:searchforward ? 'N' : 'n')


还有一些插件可以做到这一点(即SearchRepeat插件,也可能还有其他插件)。

评论


感谢您提及我的插件;我只是建议推荐一种替代方法:-)

– Ingo Karkat
15年3月4日在20:54

巧妙使用下标!

– wchargin
2015年3月4日22:00

你能补充一个解释吗?我以前没有看过这种语法,我想知道它是如何工作的。

–EvergreenTree
15年3月4日在22:37

@EvergreenTree:添加了更多说明

–克里斯蒂安·布拉班特(Christian Brabandt)
2015年3月5日在7:00

@ChristianBrabandt这很聪明。我从未想到您使用v:searchforward作为索引。

–EvergreenTree
15年5月5日在12:40

#2 楼

基于Christian Brabandt的解决方案,我想出了

nnoremap <expr> n 'Nn'[v:searchforward].(&fdo=~'search\|all'?'zv':'')
nnoremap <expr> N 'nN'[v:searchforward].(&fdo=~'search\|all'?'zv':'')


这些映射也遵循foldopen设置

#3 楼

我正在使用SearchIndex插件。要使用Christian Brabandt的答案,但保持插件每次显示n或N时显示匹配号的功能,请将其放在vimrc中:

nnoremap <silent><expr> n (v:searchforward ? 'n' : 'N') . ":SearchIndex<CR>"
nnoremap <silent><expr> N (v:searchforward ? 'N' : 'n') . ":SearchIndex<CR>"