vimcode-folding

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


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.


Solution

  • 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>
    
    func! NextClosedFold(dir)
        let cmd = 'norm!z'..a:dir
        let view = winsaveview()
        let [l0, l, open] = [0, view.lnum, 1]
        while l != l0 && open
            exec cmd
            let [l0, l] = [l, line('.')]
            let open = foldclosed(l) < 0
        endwhile
        if open
            call winrestview(view)
        endif
    endfunc
    

    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:

    func! RepeatCmd(cmd) range abort
        let n = v:count < 1 ? 1 : v:count
        while n > 0
            exec a:cmd
            let n -= 1
        endwhile
    endfunc
    

    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>