6

Currently my init.vim (neovim's equivalent to the .vimrc) sets the foldmethod to marker:

set foldmethod=marker

When I open a file all sections are folded and if the curser is placed in the according line and moved to the left it will open automatically.

It would be awesome if there was a way to have a similar experience when moving to the left (ergo: When I move to the left up against the start of the line. I want the section to be folded).

How is this possible?

  • 2
    You can, of course, map h to try to fold current section if cursor is at line start. But, IMHO, it is a little inconvenient to do so, because you have to have (or move) the cursor there in the first place. While the default key maps (zc, or zC) don't have that shortcoming. – VanLaser Dec 1 '15 at 12:43
3

Here is a script that will test if the movement will be going up or down a fold level and then open or close if appropriate.

function! MoveAndFold(dir)
  let pos = getpos('.')[1]
  let nxt = l:pos + a:dir
  let src = foldlevel(l:pos)
  let dst = foldlevel(l:nxt)

  if l:src < l:dst
    exec l:nxt . "foldopen"
  elseif l:src > l:dst
    exec l:pos . "foldclose"
  endif
  exec ":" . l:nxt
endfunction

nnoremap j :call MoveAndFold(1)<cr>
nnoremap k :call MoveAndFold(-1)<cr>

Its a little verbose and can probably be reduced but it shows you what all the actions are.

3

I wrote the following script that allows you to close a fold while "moving" left when you are at the beginning of a line and to open a closed fold by trying to move right when on the fold line.

When trying to move right opens the fold, the cursor does not actually move but stays on the same column.

That way, one can move up and down in the leftmost column and use "moves" right/left to quickly open/close folds which makes browsing folded code efficient!

(Disclaimer: not tested on documents using hard tabs at the start of lines)

function! MoveAndFoldLeft()
    let line = getpos('.')[1]
    let col  = getpos('.')[2]

    if l:col ==# 1 && foldlevel(l:line)
        execute "foldclose"
    else    
        execute "normal! h"
    endif   
endfunction

function! MoveAndFoldRight()
    let line = getpos('.')[1]

    if foldlevel(line) && foldclosed(line) != -1
        execute "foldopen"
    else    
        execute "normal! l"
    endif   
endfunction

nnoremap <silent> <Left>  :call MoveAndFoldLeft()<cr>
nnoremap <silent> h       :call MoveAndFoldLeft()<cr>
nnoremap <silent> <Right> :call MoveAndFoldRight()<cr>
nnoremap <silent> l       :call MoveAndFoldRight()<cr>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.