;
的默认行为是重复最后一个f
/F
/t
/ T
同向搜索,,
反方向移动。当他们在各自的方向到达行中的最后一个搜索时,继续按它们会导致无操作。我怎样才能让它们回绕,以便它们在向前和向后的循环中搜索?例如
fb
a[b]c foo bar baz
;
abc foo [b]ar baz
;
abc foo bar [b]az
;
a[b]c foo bar baz
或者,我也很高兴有一个版本一旦结束就开始朝另一个方向移动,例如
fb
a[b]c foo bar baz
;
abc foo [b]ar baz
;
abc foo bar [b]az
;
abc foo [b]ar baz
最佳答案
起初,我认为这很容易。结果不是。您基本上必须重新实现 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 行的内容,对所有可能的组合进行硬编码。
Alternatively, I would also be happy with a version that started moving in the other direction once it hit the end
考虑到有关上次搜索、当前方向等的信息已经存储,这可能不会很难实现。但它带来了一些有趣的极端情况。例如,如果您使用 ;
直到它切换到向后,然后按 ,
应该会发生什么。应该尝试前进然后向后切换吗?
关于Vim - 制作分号循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42463309/