;
的默认行为是在同一方向上重复上一次f
/ F
/ t
/ T
搜索,并{{1向相反方向移动。当他们按照各自的方向到达行中的最后一次搜索时,继续按下它们会导致No-op。如何让它们回绕,以便它们在前后循环中进行搜索? E.g。
,
a [b] c foo bar baz
fb
abc foo [b] ar baz
;
abc foo bar [b] az
;
a [b] c foo bar baz
或者,我也很高兴看到一个版本在其结束时开始向另一个方向移动,例如。
;
a [b] c foo bar baz
fb
abc foo [b] ar baz
;
abc foo bar [b] az
;
abc foo [b] ar baz
答案 0 :(得分:2)
起初,我认为这很容易。事实证明并非如此。您必须基本上重新实现fFtT
和;,
的每个组合,包含许多边缘情况。这最终是32行的vimscript。这是:
function! RepeatFind(reverse)
let l:dict = getcharsearch()
if a:reverse == l:dict['forward']
let l:text = getline('.')[:col('.') - 2]
if l:dict['until']
let l:text = l:text[:-2]
endif
else
let l:text = getline('.')[col('.'):]
if l:dict['until']
let l:text = l:text[1:]
endif
endif
if index(split(l:text, '.\zs'), l:dict['char']) != -1
exe 'normal! '.(a:reverse ? ',' : ';')
else
if !a:reverse && l:dict['forward']
normal 0;
elseif !a:reverse && !l:dict['forward']
normal! $;
elseif a:reverse && l:dict['forward']
normal! $,
elseif a:reverse && !l:dict['forward']
normal! 0,
endif
endif
endfunction
nnoremap ; :<C-u>call RepeatFind(0)<cr>
nnoremap , :<C-u>call RepeatFind(1)<cr>
一个难点来自大写变体,,
是双重可否定的,向前发展。这就是16-28行的原因,硬编码了所有可能的组合。
或者,我也很高兴看到一个版本在结束时开始向另一个方向移动
考虑到有关上次搜索,当前方向等的信息已经存储,这可能不会很难实现。但它带来了一些有趣的角落案例。例如,如果您使用;
直到它向后切换,然后按,
会发生什么。该尝试是否应该向前转,然后向后切换?