diff --git a/autoload/nuwiki/commands.vim b/autoload/nuwiki/commands.vim index be2ebc5..9af000c 100644 --- a/autoload/nuwiki/commands.vim +++ b/autoload/nuwiki/commands.vim @@ -65,6 +65,123 @@ function! nuwiki#commands#wiki_index(count) abort \ function('s:open_uri_from')) endfunction +" Vim equivalent of the Lua `wiki_ui_select` — receives the list, asks +" via `inputlist()` (no `vim.ui.select` on plain Vim), then opens. +function! nuwiki#commands#wiki_ui_select() abort + call s:exec('nuwiki.wiki.select', [{}], + \ function('s:wiki_pick')) +endfunction + +function! s:wiki_pick(notification) abort + let l:rows = get(get(a:notification, 'response', {}), 'result', []) + if type(l:rows) != type([]) || empty(l:rows) + echom 'nuwiki: no wikis configured' + return + endif + let l:prompt = ['Pick a wiki:'] + let l:i = 0 + for l:w in l:rows + let l:i += 1 + call add(l:prompt, l:i . '. ' . get(l:w, 'name', '?') + \ . ' (' . get(l:w, 'root', '?') . ')') + endfor + let l:choice = inputlist(l:prompt) + if l:choice < 1 || l:choice > len(l:rows) + return + endif + let l:wiki_id = get(l:rows[l:choice - 1], 'id', l:choice - 1) + call s:exec('nuwiki.wiki.openIndex', [{ 'wiki': l:wiki_id }], + \ function('s:open_uri_from')) +endfunction + +" Pure-VimL bullet-continuation for `o` / `O` — mirrors the Lua side +" so re-pressing the key keeps the list marker (and checkbox if any). +function! nuwiki#commands#open_below_with_bullet() abort + let l:line = getline('.') + let l:match = matchlist(l:line, '^\(\s*\)\([-*#]\)\s') + if empty(l:match) + call feedkeys('o', 'n') + return + endif + let l:prefix = l:match[1] . l:match[2] . ' ' + if l:line =~# '^\s*[-*#]\s\+\[[ xXoO.\-]\]' + let l:prefix .= '[ ] ' + endif + call feedkeys('o' . l:prefix, 'n') +endfunction + +function! nuwiki#commands#open_above_with_bullet() abort + let l:line = getline('.') + let l:match = matchlist(l:line, '^\(\s*\)\([-*#]\)\s') + if empty(l:match) + call feedkeys('O', 'n') + return + endif + let l:prefix = l:match[1] . l:match[2] . ' ' + call feedkeys('O' . l:prefix, 'n') +endfunction + +" ===== Heading navigation (pure VimL) ===== + +function! s:heading_level(line) abort + let l:lead = matchstr(a:line, '^\s*\zs=\+\ze\s') + if l:lead ==# '' + return 0 + endif + let l:trail = matchstr(a:line, '\s\zs=\+\ze\s*$') + if len(l:trail) != len(l:lead) + return 0 + endif + return len(l:lead) +endfunction + +function! s:current_heading_level() abort + let l:lnum = line('.') + while l:lnum > 0 + let l:lvl = s:heading_level(getline(l:lnum)) + if l:lvl > 0 + return [l:lvl, l:lnum] + endif + let l:lnum -= 1 + endwhile + return [0, 0] +endfunction + +function! s:jump_heading(direction, predicate) abort + let l:total = line('$') + let l:i = line('.') + a:direction + while l:i >= 1 && l:i <= l:total + let l:lvl = s:heading_level(getline(l:i)) + if l:lvl > 0 && a:predicate(l:lvl, l:i) + call cursor(l:i, 1) + return + endif + let l:i += a:direction + endwhile +endfunction + +function! nuwiki#commands#next_header() abort + call s:jump_heading(1, {l, n -> 1}) +endfunction +function! nuwiki#commands#prev_header() abort + call s:jump_heading(-1, {l, n -> 1}) +endfunction +function! nuwiki#commands#next_sibling_header() abort + let [l:lvl, _] = s:current_heading_level() + call s:jump_heading(1, {l, n -> l <= l:lvl}) +endfunction +function! nuwiki#commands#prev_sibling_header() abort + let [l:lvl, _] = s:current_heading_level() + call s:jump_heading(-1, {l, n -> l <= l:lvl}) +endfunction +function! nuwiki#commands#parent_header() abort + let [l:lvl, _] = s:current_heading_level() + if l:lvl <= 1 + return + endif + call s:jump_heading(-1, {l, n -> l < l:lvl}) +endfunction + function! nuwiki#commands#wiki_tab_index(count) abort let l:args = a:count > 0 ? [{ 'wiki': a:count - 1 }] : [{}] call s:exec('nuwiki.wiki.tabOpenIndex', l:args, diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim index 737eaab..4584d36 100644 --- a/ftplugin/vimwiki.vim +++ b/ftplugin/vimwiki.vim @@ -113,6 +113,7 @@ if !has('nvim') " Wiki prefix nnoremap ww :call nuwiki#commands#diary_today() nnoremap wt :call nuwiki#commands#diary_today() + nnoremap ws :call nuwiki#commands#wiki_ui_select() nnoremap wi :call nuwiki#commands#diary_index() nnoremap ww :call nuwiki#commands#diary_today() nnoremap wy :call nuwiki#commands#diary_yesterday() @@ -129,10 +130,12 @@ if !has('nvim') nnoremap /\[\[:nohlsearch nnoremap ?\[\[:nohlsearch nnoremap + :echohl WarningMsgechom 'nuwiki: :VimwikiNormalizeLink not yet implemented — see SPEC §13.1'echohl None + xnoremap + :echohl WarningMsgechom 'nuwiki: :VimwikiNormalizeLink not yet implemented — see SPEC §13.1'echohl None nnoremap wn :call nuwiki#commands#wiki_goto_page('') nnoremap wd :call nuwiki#commands#delete_file() nnoremap wr :call nuwiki#commands#rename_file() nnoremap wc :echohl WarningMsgechom 'nuwiki: :VimwikiColorize not yet implemented — see SPEC §13.1'echohl None + xnoremap wc :echohl WarningMsgechom 'nuwiki: :VimwikiColorize not yet implemented — see SPEC §13.1'echohl None " Diary nav nnoremap :call nuwiki#commands#diary_next() @@ -145,20 +148,31 @@ if !has('nvim') xnoremap :call nuwiki#commands#toggle_list_item() nnoremap gnt :call nuwiki#commands#next_task() nnoremap gln :call nuwiki#commands#cycle_list_item() + xnoremap gln :call nuwiki#commands#cycle_list_item() nnoremap glp :call nuwiki#commands#cycle_list_item() + xnoremap glp :call nuwiki#commands#cycle_list_item() nnoremap glx :call nuwiki#commands#reject_list_item() + xnoremap glx :call nuwiki#commands#reject_list_item() nnoremap glh :echohl WarningMsgechom 'nuwiki: list level not yet implemented — see SPEC §13.1'echohl None nnoremap gll :echohl WarningMsgechom 'nuwiki: list level not yet implemented — see SPEC §13.1'echohl None nnoremap gLh :echohl WarningMsgechom 'nuwiki: list level subtree not yet implemented — see SPEC §13.1'echohl None nnoremap gLl :echohl WarningMsgechom 'nuwiki: list level subtree not yet implemented — see SPEC §13.1'echohl None nnoremap glr :echohl WarningMsgechom 'nuwiki: list renumber not yet implemented — see SPEC §13.1'echohl None nnoremap gLr :echohl WarningMsgechom 'nuwiki: list renumber-all not yet implemented — see SPEC §13.1'echohl None + nnoremap gl :echohl WarningMsgechom 'nuwiki: :VimwikiRemoveSingleCB not yet implemented — see SPEC §13.1'echohl None + nnoremap gL :echohl WarningMsgechom 'nuwiki: :VimwikiRemoveCBInList not yet implemented — see SPEC §13.1'echohl None + nnoremap o :call nuwiki#commands#open_below_with_bullet() + nnoremap O :call nuwiki#commands#open_above_with_bullet() " Headers nnoremap = :call nuwiki#commands#heading_add() nnoremap - :call nuwiki#commands#heading_remove() - nnoremap ]] /^\s*=\+\s:nohlsearch - nnoremap [[ ?^\s*=\+\s:nohlsearch + nnoremap ]] :call nuwiki#commands#next_header() + nnoremap [[ :call nuwiki#commands#prev_header() + nnoremap ]= :call nuwiki#commands#next_sibling_header() + nnoremap [= :call nuwiki#commands#prev_sibling_header() + nnoremap ]u :call nuwiki#commands#parent_header() + nnoremap [u :call nuwiki#commands#parent_header() " HTML export nnoremap wh :call nuwiki#commands#export_current() @@ -167,7 +181,9 @@ if !has('nvim') " Tables (deferred §13.1) nnoremap gqq :echohl WarningMsgechom 'nuwiki: :VimwikiTableAlignQ not yet implemented — see SPEC §13.1'echohl None + nnoremap gq1 :echohl WarningMsgechom 'nuwiki: :VimwikiTableAlignQ1 not yet implemented — see SPEC §13.1'echohl None nnoremap gww :echohl WarningMsgechom 'nuwiki: :VimwikiTableAlignW not yet implemented — see SPEC §13.1'echohl None + nnoremap gw1 :echohl WarningMsgechom 'nuwiki: :VimwikiTableAlignW1 not yet implemented — see SPEC §13.1'echohl None nnoremap :echohl WarningMsgechom 'nuwiki: :VimwikiTableMoveColumnLeft not yet implemented'echohl None nnoremap :echohl WarningMsgechom 'nuwiki: :VimwikiTableMoveColumnRight not yet implemented'echohl None endif