Is it possible to jump to the next closed fold in Vim?
Asked Answered
S

2

39

In Vim, I often find myself wanting to do a quick zk or zj to jump to the previous or next fold in a file. The problem is, I frequently want to skip all the open folds, and just jump to the nearest closed fold.

Is there a way to do this? I see no built-in keymap in the help.

Slattern answered 22/2, 2012 at 21:12 Comment(0)
G
43

Let me propose the following implementation of the described behavior.

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

If it is desirable for the mappings to accept a count for the number of repetitions of the corresponding movement, one can implement a simple function for repeating any given command:

function! RepeatCmd(cmd) range abort
    let n = v:count < 1 ? 1 : v:count
    while n > 0
        exe a:cmd
        let n -= 1
    endwhile
endfunction

and then redefine the above mappings as follows:

nnoremap <silent> <leader>zj :<c-u>call RepeatCmd('call NextClosedFold("j")')<cr>
nnoremap <silent> <leader>zk :<c-u>call RepeatCmd('call NextClosedFold("k")')<cr>
Getaway answered 23/2, 2012 at 4:6 Comment(5)
@David: Thanks! I have made a refactoring on the code to simplify the jumping loop and to keep the cursor in place if there is no closed fold in desired direction. (The latter behavior conforms to that of zj/zk commands when no fold can be found below/above.)Getaway
@Getaway could you please provide the changed script?Suanne
@Glenn: If you refer to the refactoring I mentioned in my comment, the code in the answer has been already updated to include it.Getaway
Is there any way to adapt this function to allow a count, such as [count]<leader>zj?Nigger
@travisw: There is. I have updated the answer to show one way to support the count for repetitions in the proposed mappings.Getaway
T
1

No, there isn't, as far as I know, a build-in method to do that. Interesting idea, though.

If I had some time at the moment, I might try to figure out a way to do it — unfortunately, being busy nowadays, all I can suggest you is to look at the Detecting a folded line or an incremental search question (particularly the foldclosed function) and try to make a function yourself. Checking every line, if fold is open, skip… something along those lines.

Thiosinamine answered 23/2, 2012 at 3:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.