在Vim中,我经常想要快速执行zk或zj以跳转到文件中的前一个或后一个折叠。问题在于,我经常希望跳过所有打开的折叠,只跳到最近的闭合折叠。
有没有办法做到这一点?我在帮助中没有看到内置的按键映射。
有没有办法做到这一点?我在帮助中没有看到内置的按键映射。
让我提出以下所描述行为的实现方式。
nnoremap <silent> <leader>zj :call NextClosedFold('j')<cr>
nnoremap <silent> <leader>zk :call NextClosedFold('k')<cr>
function! NextClosedFold(dir)
let cmd = 'norm!z'..a:dir
let view = winsaveview()
let [l0, l, open] = [0, view.lnum, 1]
while l != l0 && open
exe cmd
let [l0, l] = [l, line('.')]
let open = foldclosed(l) < 0
endwhile
if open
call winrestview(view)
endif
endfunction
如果希望映射接受相应运动的重复次数,可以实现一个简单的函数重复任何给定的命令:
function! RepeatCmd(cmd) range abort
let n = v:count < 1 ? 1 : v:count
while n > 0
exe a:cmd
let n -= 1
endwhile
endfunction
然后重新定义上述映射如下:
nnoremap <silent> <leader>zj :<c-u>call RepeatCmd('call NextClosedFold("j")')<cr>
nnoremap <silent> <leader>zk :<c-u>call RepeatCmd('call NextClosedFold("k")')<cr>
据我所知,没有内置的方法可以做到这一点。不过这是个有趣的想法。
如果我现在有时间,我可能会尝试找出一种方法来实现它——不幸的是,现在很忙,我能建议你的是看看 检测折叠行或增量搜索 问题(特别是 foldclosed
函数),然后尝试自己编写一个函数。检查每一行,如果折叠是打开的,则跳过……类似这样的操作。
zj
/zk
命令在下面/上面找不到折叠时,后一行为其行为)。 - ib.[count]<leader>zj
? - travisw