vimwiki

Personal wiki for vim
git clone https://github.com/vimwiki/vimwiki.git
Log | Files | Refs | README | LICENSE

commit 2941913ccc2ca1e5bd2f482c770407a712810c1b
parent a3b100ccaaa0f43113e0dab5ecf4e3b59db1ab17
Author: EinfachToll <istjanichtzufassen@googlemail.com>
Date:   Fri,  6 Apr 2018 21:11:40 +0200

Add keys for motions between headers

Fix #462
Inspired by #23

Diffstat:
Mautoload/vimwiki/base.vim | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mdoc/vimwiki.txt | 28++++++++++++++++++++++++++++
Mftplugin/vimwiki.vim | 30++++++++++++++++++++++++++++++
3 files changed, 146 insertions(+), 25 deletions(-)

diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim @@ -1365,15 +1365,7 @@ function! vimwiki#base#TO_header(inner, including_subheaders, count) let current_line = line('.') - " look for the header under which the cursor sits - if current_line >= headers[-1][0] - let current_header_index = len(headers) - 1 - else - let current_header_index = -1 - while headers[current_header_index+1][0] <= current_line - let current_header_index += 1 - endwhile - endif + let current_header_index = s:current_header(headers, current_line) if current_header_index < 0 return @@ -1418,22 +1410,6 @@ function! vimwiki#base#TO_header(inner, including_subheaders, count) endfunction -function! s:get_another_header(headers, current_index, direction, operation) - let current_level = a:headers[a:current_index][1] - let index = a:current_index + a:direction - - while 1 - if index < 0 || index >= len(a:headers) - return -1 - endif - if eval('a:headers[index][1] ' . a:operation . ' current_level') - return index - endif - let index += a:direction - endwhile -endfunction - - " vimwiki#base#TO_table_cell function! vimwiki#base#TO_table_cell(inner, visual) "{{{ if col('.') == col('$')-1 @@ -1713,6 +1689,93 @@ function! s:collect_headers() endfunction +function! s:current_header(headers, line_number) + if empty(a:headers) + return -1 + endif + + if a:line_number >= a:headers[-1][0] + return len(a:headers) - 1 + endif + + let current_header_index = -1 + while a:headers[current_header_index+1][0] <= a:line_number + let current_header_index += 1 + endwhile + return current_header_index +endfunction + + +function! s:get_another_header(headers, current_index, direction, operation) + if empty(a:headers) || a:current_index < 0 + return -1 + endif + let current_level = a:headers[a:current_index][1] + let index = a:current_index + a:direction + + while 1 + if index < 0 || index >= len(a:headers) + return -1 + endif + if eval('a:headers[index][1] ' . a:operation . ' current_level') + return index + endif + let index += a:direction + endwhile +endfunction + + +function! vimwiki#base#goto_parent_header() + let headers = s:collect_headers() + let current_header_index = s:current_header(headers, line('.')) + let parent_header = s:get_another_header(headers, current_header_index, -1, '<') + if parent_header >= 0 + call cursor(headers[parent_header][0], 1) + else + echo 'Vimwiki: no parent header found' + endif +endfunction + + +function! vimwiki#base#goto_next_header() + let headers = s:collect_headers() + let current_header_index = s:current_header(headers, line('.')) + if current_header_index >= 0 && current_header_index < len(headers) - 1 + call cursor(headers[current_header_index + 1][0], 1) + else + echo 'Vimwiki: no next header found' + endif +endfunction + + +function! vimwiki#base#goto_prev_header() + let headers = s:collect_headers() + let current_header_index = s:current_header(headers, line('.')) + " if the cursor already was on a header, jump to the previous one + if current_header_index >= 1 && headers[current_header_index][0] == line('.') + let current_header_index -= 1 + endif + if current_header_index >= 0 + call cursor(headers[current_header_index][0], 1) + else + echom 'Vimwiki: no previous header found' + endif +endfunction + + +function! vimwiki#base#goto_sibling(direction) + let headers = s:collect_headers() + let current_header_index = s:current_header(headers, line('.')) + let next_potential_sibling = s:get_another_header(headers, current_header_index, a:direction, '<=') + if next_potential_sibling >= 0 && headers[next_potential_sibling][1] == + \ headers[current_header_index][1] + call cursor(headers[next_potential_sibling][0], 1) + else + echo 'Vimwiki: no sibling header found' + endif +endfunction + + " a:create == 1: creates or updates TOC in current file " a:create == 0: update if TOC exists function! vimwiki#base#table_of_contents(create) diff --git a/doc/vimwiki.txt b/doc/vimwiki.txt @@ -325,6 +325,34 @@ NORMAL MODE *vimwiki-local-mappings* To remap: > :nmap -- <Plug>VimwikiRemoveHeaderLevel < + *vimwiki_[[* +[[ Go to the previous header in the buffer. + To remap: > + :nmap <- <Plug>VimwikiGoToPrevHeader +< + *vimwiki_]]* +]] Go to the next header in the buffer. + To remap: > + :nmap -> <Plug>VimwikiGoToNextHeader +< + *vimwiki_[=* +[= Go to the previous header which has the same level as + the header the cursor is currently under. + To remap: > + :nmap <= <Plug>VimwikiGoToPrevSiblingHeader +< + *vimwiki_]=* +]= Go to the next header which has the same level as the + header the cursor is currently under. + To remap: > + :nmap => <Plug>VimwikiGoToNextSiblingHeader +< + *vimwiki_]u* *vimwiki_[u* +]u [u Go one level up -- that is, to the parent header of + the header the cursor is currently under. + To remap: > + :nmap -^ <Plug>VimwikiGoToParentHeader +< *vimwiki_+* + Create and/or decorate links. Depending on the context, this command will: convert words into diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim @@ -662,6 +662,36 @@ endif nnoremap <silent><buffer> <Plug>VimwikiRemoveHeaderLevel : \<C-U>call vimwiki#base#RemoveHeaderLevel()<CR> +if !hasmapto('<Plug>VimwikiGoToParentHeader') + nmap <silent><buffer> ]u <Plug>VimwikiGoToParentHeader + nmap <silent><buffer> [u <Plug>VimwikiGoToParentHeader +endif +nnoremap <silent><buffer> <Plug>VimwikiGoToParentHeader : + \<C-u>call vimwiki#base#goto_parent_header()<CR> + +if !hasmapto('<Plug>VimwikiGoToNextHeader') + nmap <silent><buffer> ]] <Plug>VimwikiGoToNextHeader +endif +nnoremap <silent><buffer> <Plug>VimwikiGoToNextHeader : + \<C-u>call vimwiki#base#goto_next_header()<CR> + +if !hasmapto('<Plug>VimwikiGoToPrevHeader') + nmap <silent><buffer> [[ <Plug>VimwikiGoToPrevHeader +endif +nnoremap <silent><buffer> <Plug>VimwikiGoToPrevHeader : + \<C-u>call vimwiki#base#goto_prev_header()<CR> + +if !hasmapto('<Plug>VimwikiGoToNextSiblingHeader') + nmap <silent><buffer> ]= <Plug>VimwikiGoToNextSiblingHeader +endif +nnoremap <silent><buffer> <Plug>VimwikiGoToNextSiblingHeader : + \<C-u>call vimwiki#base#goto_sibling(+1)<CR> + +if !hasmapto('<Plug>VimwikiGoToPrevSiblingHeader') + nmap <silent><buffer> [= <Plug>VimwikiGoToPrevSiblingHeader +endif +nnoremap <silent><buffer> <Plug>VimwikiGoToPrevSiblingHeader : + \<C-u>call vimwiki#base#goto_sibling(-1)<CR> " }}}