2026-05-11 22:23:06 +00:00
|
|
|
" autoload/nuwiki/commands.vim — Vim-side wrappers around the LSP
|
|
|
|
|
" commands the server advertises (Phase 19).
|
|
|
|
|
"
|
|
|
|
|
" Lives in autoload/ so the cost is paid only when a `:Vimwiki*` /
|
|
|
|
|
" `:Nuwiki*` command is actually invoked. Dispatches via vim-lsp's
|
|
|
|
|
" `lsp#send_request`. coc.nvim's command surface is rich enough that
|
|
|
|
|
" users should just call `:CocCommand nuwiki.x` directly there — this
|
|
|
|
|
" file targets the vim-lsp path.
|
|
|
|
|
|
|
|
|
|
let s:server = 'nuwiki'
|
|
|
|
|
|
|
|
|
|
function! s:buf_uri() abort
|
|
|
|
|
return 'file://' . fnamemodify(expand('%:p'), ':p')
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:cursor_position() abort
|
|
|
|
|
return {
|
|
|
|
|
\ 'textDocument': { 'uri': s:buf_uri() },
|
|
|
|
|
\ 'position': { 'line': line('.') - 1, 'character': col('.') - 1 },
|
|
|
|
|
\ }
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:has_vimlsp() abort
|
|
|
|
|
return exists('*lsp#send_request')
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:exec(command, arguments, ...) abort
|
|
|
|
|
if !s:has_vimlsp()
|
|
|
|
|
echohl ErrorMsg
|
|
|
|
|
echom 'nuwiki: vim-lsp not loaded; cannot run ' . a:command
|
|
|
|
|
echohl None
|
|
|
|
|
return
|
|
|
|
|
endif
|
|
|
|
|
let l:opts = {
|
|
|
|
|
\ 'method': 'workspace/executeCommand',
|
|
|
|
|
\ 'params': { 'command': a:command, 'arguments': a:arguments },
|
|
|
|
|
\ }
|
|
|
|
|
if a:0 >= 1
|
|
|
|
|
let l:opts['on_notification'] = a:1
|
|
|
|
|
endif
|
|
|
|
|
call lsp#send_request(s:server, l:opts)
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:open_uri_from(response, ...) abort
|
|
|
|
|
let l:result = get(get(a:response, 'response', {}), 'result', {})
|
|
|
|
|
if type(l:result) != type({}) || !has_key(l:result, 'uri')
|
|
|
|
|
return
|
|
|
|
|
endif
|
|
|
|
|
let l:path = substitute(l:result['uri'], '^file://', '', '')
|
|
|
|
|
let l:cmd = a:0 >= 1 ? a:1 : 'edit'
|
|
|
|
|
execute l:cmd . ' ' . fnameescape(l:path)
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:notify_deferred(name) abort
|
|
|
|
|
echohl WarningMsg
|
|
|
|
|
echom 'nuwiki: ' . a:name . ' is not yet implemented — see SPEC §13.1'
|
|
|
|
|
echohl None
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" ===== Wiki picker =====
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#wiki_index(count) abort
|
|
|
|
|
let l:args = a:count > 0 ? [{ 'wiki': a:count - 1 }] : [{}]
|
|
|
|
|
call s:exec('nuwiki.wiki.openIndex', l:args,
|
|
|
|
|
\ function('s:open_uri_from'))
|
|
|
|
|
endfunction
|
|
|
|
|
|
2026-05-12 00:50:49 +00:00
|
|
|
" 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
|
|
|
|
|
|
2026-05-12 01:44:26 +00:00
|
|
|
" ===== Smart <CR>: follow or wrap-then-follow =====
|
|
|
|
|
|
|
|
|
|
function! s:cursor_inside_wikilink() abort
|
|
|
|
|
let l:line = getline('.')
|
|
|
|
|
let l:col = col('.')
|
|
|
|
|
let l:i = 1
|
|
|
|
|
let l:open = 0
|
|
|
|
|
while l:i < strlen(l:line)
|
|
|
|
|
if strpart(l:line, l:i - 1, 2) ==# '[['
|
|
|
|
|
let l:open = l:i
|
|
|
|
|
let l:i += 2
|
|
|
|
|
elseif strpart(l:line, l:i - 1, 2) ==# ']]'
|
|
|
|
|
let l:open = 0
|
|
|
|
|
let l:i += 2
|
|
|
|
|
else
|
|
|
|
|
let l:i += 1
|
|
|
|
|
endif
|
|
|
|
|
if l:i > l:col
|
|
|
|
|
break
|
|
|
|
|
endif
|
|
|
|
|
endwhile
|
|
|
|
|
return l:open > 0
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:wrap_cword_as_wikilink() abort
|
|
|
|
|
let l:word = expand('<cword>')
|
|
|
|
|
if l:word ==# ''
|
|
|
|
|
return 0
|
|
|
|
|
endif
|
|
|
|
|
let l:line = getline('.')
|
|
|
|
|
let l:col = col('.')
|
|
|
|
|
" Find word boundaries around cursor (1-based).
|
|
|
|
|
let l:left = l:col
|
|
|
|
|
while l:left > 1 && strpart(l:line, l:left - 2, 1) =~# '[A-Za-z0-9_-]'
|
|
|
|
|
let l:left -= 1
|
|
|
|
|
endwhile
|
|
|
|
|
let l:right = l:col
|
|
|
|
|
while l:right <= strlen(l:line) && strpart(l:line, l:right - 1, 1) =~# '[A-Za-z0-9_-]'
|
|
|
|
|
let l:right += 1
|
|
|
|
|
endwhile
|
|
|
|
|
let l:word_real = strpart(l:line, l:left - 1, l:right - l:left)
|
|
|
|
|
if l:word_real ==# ''
|
|
|
|
|
return 0
|
|
|
|
|
endif
|
|
|
|
|
let l:new_line = strpart(l:line, 0, l:left - 1) . '[[' . l:word_real . ']]' . strpart(l:line, l:right - 1)
|
|
|
|
|
call setline('.', l:new_line)
|
|
|
|
|
call cursor(line('.'), l:left + 2)
|
|
|
|
|
return 1
|
|
|
|
|
endfunction
|
|
|
|
|
|
2026-05-12 01:55:20 +00:00
|
|
|
" Two-step behaviour matching vimwiki:
|
|
|
|
|
" 1. First press on a bare word → wrap it as `[[word]]` and stop.
|
|
|
|
|
" 2. Cursor is now inside `[[…]]`; next press follows the link.
|
|
|
|
|
" 3. Press inside an existing `[[…]]` follows immediately.
|
2026-05-12 01:44:26 +00:00
|
|
|
function! nuwiki#commands#follow_link_or_create() abort
|
2026-05-12 01:55:20 +00:00
|
|
|
if s:cursor_inside_wikilink()
|
|
|
|
|
if exists(':LspDefinition') == 2
|
|
|
|
|
LspDefinition
|
|
|
|
|
else
|
|
|
|
|
echohl WarningMsg
|
|
|
|
|
echom 'nuwiki: :LspDefinition unavailable; install vim-lsp'
|
|
|
|
|
echohl None
|
|
|
|
|
endif
|
|
|
|
|
return
|
2026-05-12 01:44:26 +00:00
|
|
|
endif
|
2026-05-12 01:55:20 +00:00
|
|
|
if s:wrap_cword_as_wikilink()
|
|
|
|
|
" Wrapped — wait for the user's second <CR> to follow.
|
|
|
|
|
return
|
|
|
|
|
endif
|
|
|
|
|
" Nothing to wrap — fall through.
|
2026-05-12 01:44:26 +00:00
|
|
|
if exists(':LspDefinition') == 2
|
|
|
|
|
LspDefinition
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
2026-05-12 00:50:49 +00:00
|
|
|
" 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
|
|
|
|
|
|
2026-05-11 22:23:06 +00:00
|
|
|
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,
|
|
|
|
|
\ {n -> s:open_uri_from(n, 'tabedit')})
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#wiki_goto_page(name) abort
|
|
|
|
|
let l:name = a:name
|
|
|
|
|
if l:name ==# ''
|
|
|
|
|
let l:name = input('Goto page: ')
|
|
|
|
|
endif
|
|
|
|
|
if l:name ==# ''
|
|
|
|
|
return
|
|
|
|
|
endif
|
|
|
|
|
call s:exec('nuwiki.wiki.gotoPage', [{ 'page': l:name }],
|
|
|
|
|
\ function('s:open_uri_from'))
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" ===== Diary =====
|
|
|
|
|
|
|
|
|
|
function! s:diary_open(cmd_name) abort
|
|
|
|
|
call s:exec(a:cmd_name, [{ 'uri': s:buf_uri() }],
|
|
|
|
|
\ function('s:open_uri_from'))
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#diary_today() abort | call s:diary_open('nuwiki.diary.openToday') | endfunction
|
|
|
|
|
function! nuwiki#commands#diary_yesterday() abort | call s:diary_open('nuwiki.diary.openYesterday') | endfunction
|
|
|
|
|
function! nuwiki#commands#diary_tomorrow() abort | call s:diary_open('nuwiki.diary.openTomorrow') | endfunction
|
|
|
|
|
function! nuwiki#commands#diary_index() abort | call s:diary_open('nuwiki.diary.openIndex') | endfunction
|
|
|
|
|
function! nuwiki#commands#diary_next() abort | call s:diary_open('nuwiki.diary.next') | endfunction
|
|
|
|
|
function! nuwiki#commands#diary_prev() abort | call s:diary_open('nuwiki.diary.prev') | endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#diary_generate_index() abort
|
|
|
|
|
call s:exec('nuwiki.diary.generateIndex', [{ 'uri': s:buf_uri() }])
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" ===== List + heading editing =====
|
|
|
|
|
|
|
|
|
|
function! s:exec_pos(cmd) abort
|
|
|
|
|
let l:p = s:cursor_position()
|
|
|
|
|
let l:args = [{ 'uri': l:p['textDocument']['uri'], 'position': l:p['position'] }]
|
|
|
|
|
call s:exec(a:cmd, l:args)
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#toggle_list_item() abort | call s:exec_pos('nuwiki.list.toggleCheckbox') | endfunction
|
|
|
|
|
function! nuwiki#commands#cycle_list_item() abort | call s:exec_pos('nuwiki.list.cycleCheckbox') | endfunction
|
|
|
|
|
function! nuwiki#commands#reject_list_item() abort | call s:exec_pos('nuwiki.list.rejectCheckbox') | endfunction
|
|
|
|
|
function! nuwiki#commands#heading_add() abort | call s:exec_pos('nuwiki.heading.addLevel') | endfunction
|
|
|
|
|
function! nuwiki#commands#heading_remove() abort | call s:exec_pos('nuwiki.heading.removeLevel') | endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#next_task() abort
|
|
|
|
|
let l:p = s:cursor_position()
|
|
|
|
|
let l:args = [{ 'uri': l:p['textDocument']['uri'], 'position': l:p['position'] }]
|
|
|
|
|
call s:exec('nuwiki.list.nextTask', l:args,
|
|
|
|
|
\ {n -> s:goto_location(n)})
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:goto_location(notification) abort
|
|
|
|
|
let l:loc = get(get(a:notification, 'response', {}), 'result', {})
|
|
|
|
|
if type(l:loc) != type({}) || !has_key(l:loc, 'range')
|
|
|
|
|
return
|
|
|
|
|
endif
|
|
|
|
|
let l:line = l:loc['range']['start']['line'] + 1
|
|
|
|
|
let l:col = l:loc['range']['start']['character'] + 1
|
|
|
|
|
call cursor(l:line, l:col)
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" ===== Generation + workspace =====
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#toc_generate() abort | call s:exec('nuwiki.toc.generate', [{'uri': s:buf_uri()}]) | endfunction
|
|
|
|
|
function! nuwiki#commands#links_generate() abort | call s:exec('nuwiki.links.generate', [{'uri': s:buf_uri()}]) | endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#check_links() abort
|
|
|
|
|
call s:exec('nuwiki.workspace.checkLinks', [{ 'uri': s:buf_uri() }],
|
|
|
|
|
\ {n -> s:results_to_qf(n, 'broken links')})
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#find_orphans() abort
|
|
|
|
|
call s:exec('nuwiki.workspace.findOrphans', [{ 'uri': s:buf_uri() }],
|
|
|
|
|
\ {n -> s:results_to_qf(n, 'orphans')})
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:results_to_qf(notification, title) abort
|
|
|
|
|
let l:rows = get(get(a:notification, 'response', {}), 'result', [])
|
|
|
|
|
if type(l:rows) != type([]) || empty(l:rows)
|
|
|
|
|
echom 'nuwiki: no ' . a:title
|
|
|
|
|
return
|
|
|
|
|
endif
|
|
|
|
|
let l:items = []
|
|
|
|
|
for l:row in l:rows
|
|
|
|
|
let l:path = substitute(get(l:row, 'uri', ''), '^file://', '', '')
|
|
|
|
|
let l:lnum = 1
|
|
|
|
|
let l:col = 1
|
|
|
|
|
if has_key(l:row, 'range')
|
|
|
|
|
let l:lnum = l:row['range']['start']['line'] + 1
|
|
|
|
|
let l:col = l:row['range']['start']['character'] + 1
|
|
|
|
|
endif
|
|
|
|
|
let l:text = get(l:row, 'message', get(l:row, 'name', ''))
|
|
|
|
|
call add(l:items, { 'filename': l:path, 'lnum': l:lnum, 'col': l:col, 'text': l:text })
|
|
|
|
|
endfor
|
|
|
|
|
call setqflist([], ' ', { 'title': 'nuwiki ' . a:title, 'items': l:items })
|
|
|
|
|
copen
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" ===== Tags =====
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#tags_search(query) abort
|
|
|
|
|
let l:q = a:query
|
|
|
|
|
if l:q ==# ''
|
|
|
|
|
let l:q = input('Search tags: ')
|
|
|
|
|
endif
|
|
|
|
|
call s:exec('nuwiki.tags.search', [{ 'uri': s:buf_uri(), 'query': l:q }],
|
|
|
|
|
\ {n -> s:results_to_qf(n, 'tag matches')})
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#tags_generate_links(tag) abort
|
|
|
|
|
let l:args = { 'uri': s:buf_uri() }
|
|
|
|
|
if a:tag !=# ''
|
|
|
|
|
let l:args['tag'] = a:tag
|
|
|
|
|
endif
|
|
|
|
|
call s:exec('nuwiki.tags.generateLinks', [l:args])
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#tags_rebuild() abort
|
|
|
|
|
call s:exec('nuwiki.tags.rebuild', [{ 'uri': s:buf_uri() }])
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" ===== HTML export =====
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#export_current() abort | call s:exec('nuwiki.export.currentToHtml', [{'uri': s:buf_uri()}]) | endfunction
|
|
|
|
|
function! nuwiki#commands#export_all() abort | call s:exec('nuwiki.export.allToHtml', [{'uri': s:buf_uri()}]) | endfunction
|
|
|
|
|
function! nuwiki#commands#export_all_force() abort | call s:exec('nuwiki.export.allToHtmlForce', [{'uri': s:buf_uri()}]) | endfunction
|
|
|
|
|
function! nuwiki#commands#export_rss() abort | call s:exec('nuwiki.export.rss', [{'uri': s:buf_uri()}]) | endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#export_browse() abort
|
|
|
|
|
call s:exec('nuwiki.export.browse', [{ 'uri': s:buf_uri() }],
|
|
|
|
|
\ {n -> s:open_browser(n)})
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:open_browser(notification) abort
|
|
|
|
|
let l:result = get(get(a:notification, 'response', {}), 'result', {})
|
|
|
|
|
let l:url = get(l:result, 'browse', '')
|
|
|
|
|
if l:url ==# ''
|
|
|
|
|
return
|
|
|
|
|
endif
|
|
|
|
|
if has('mac')
|
|
|
|
|
silent execute '!open ' . shellescape(l:url, 1) . ' &'
|
|
|
|
|
elseif has('unix')
|
|
|
|
|
silent execute '!xdg-open ' . shellescape(l:url, 1) . ' &'
|
|
|
|
|
else
|
|
|
|
|
echom 'nuwiki: exported → ' . l:url
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" ===== File ops =====
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#delete_file() abort
|
|
|
|
|
if input('Delete current page? [y/N] ') !~? '^y'
|
|
|
|
|
return
|
|
|
|
|
endif
|
|
|
|
|
call s:exec('nuwiki.file.delete', [{ 'uri': s:buf_uri() }])
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#rename_file() abort
|
|
|
|
|
if exists('*lsp#rename')
|
|
|
|
|
LspRename
|
|
|
|
|
else
|
|
|
|
|
echohl WarningMsg
|
|
|
|
|
echom 'nuwiki: :LspRename unavailable; install vim-lsp'
|
|
|
|
|
echohl None
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" ===== §13.1 deferred =====
|
|
|
|
|
|
|
|
|
|
function! nuwiki#commands#list_change_lvl() abort | call s:notify_deferred(':VimwikiListChangeLvl') | endfunction
|
|
|
|
|
function! nuwiki#commands#list_remove_done() abort | call s:notify_deferred(':VimwikiRemoveDone') | endfunction
|
|
|
|
|
function! nuwiki#commands#table_insert() abort | call s:notify_deferred(':VimwikiTable') | endfunction
|
|
|
|
|
function! nuwiki#commands#table_move_left() abort | call s:notify_deferred(':VimwikiTableMoveColumnLeft') | endfunction
|
|
|
|
|
function! nuwiki#commands#table_move_right() abort | call s:notify_deferred(':VimwikiTableMoveColumnRight') | endfunction
|
|
|
|
|
function! nuwiki#commands#colorize(color) abort | call s:notify_deferred(':VimwikiColorize') | endfunction
|
|
|
|
|
function! nuwiki#commands#paste_link() abort | call s:notify_deferred(':VimwikiPasteLink') | endfunction
|
|
|
|
|
function! nuwiki#commands#paste_url() abort | call s:notify_deferred(':VimwikiPasteUrl') | endfunction
|