Files
nuwiki/autoload/nuwiki/util.vim
T
gffranco 82444f5013
CI / editor tests (push) Successful in 44s
refactor(viml): extract shared heading_level/is_table_row/wiki_cfg; fix cap + spaceless
Mirrors the Lua util refactor. Pulls the copy-pasted VimL helpers into
autoload/nuwiki/util.vim and points the per-file s: stubs at it:

- heading_level (commands/folding/textobjects) — commands.vim's copy was
  missing the >6 level cap the others had (a 7+ `=` line returned 7). The
  unified version caps at 6 AND accepts spaceless headings (==Heading==),
  matching the server lexer + the Lua client (so fold fallback, text
  objects, and ]] navigation recognize spaceless headings too).
- is_table_row (commands/textobjects) — identical copies.
- wiki_cfg (commands/diary) — these had DRIFTED: commands.vim's included a
  `space` (links_space_char) key diary.vim's lacked. Unified to the superset
  so callers reading `.space` keep working; diary callers ignore the extra key.

Also refreshes the stale plugin/nuwiki.vim header ("all logic lives in the
Rust language server" → thin client; server is nuwiki-rs, downloaded).

Verified: 18-case heading battery in headless vim + full editor harness 10/10.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 12:38:04 +00:00

57 lines
2.3 KiB
VimL

" autoload/nuwiki/util.vim — small shared helpers used across the VimL client
" layers (commands, folding, textobjects, diary). Keeps the formerly
" copy-pasted heading / table-row / wiki-config logic in one place. Mirrors
" lua/nuwiki/util.lua so both clients behave identically.
" Heading level of `line` (1-6), or 0 when it isn't a heading. Mirrors the
" server lexer: balanced leading/trailing runs of `=` around a non-empty
" title, capped at level 6. Accepts both the spaced (`== H ==`) and spaceless
" (`==H==`) forms, matching vimwiki.
function! nuwiki#util#heading_level(line) abort
let l:lead = matchstr(a:line, '^\s*\zs=\+')
if empty(l:lead)
return 0
endif
let l:lvl = strlen(l:lead)
if l:lvl > 6
return 0
endif
" Same-length trailing run of `=` at end of line (after optional trailing ws).
let l:trail = matchstr(a:line, '=\+\ze\s*$')
if empty(l:trail) || strlen(l:trail) != l:lvl
return 0
endif
" Non-empty title between the runs (rules out marker-only lines like
" `======`). `.\{-}` is non-greedy so the `=\+` runs keep their length.
let l:body = matchstr(a:line, '^\s*=\+\zs.\{-}\ze=\+\s*$')
if l:body =~# '^\s*$'
return 0
endif
return l:lvl
endfunction
" True when `line` looks like a table row (`| … |`).
function! nuwiki#util#is_table_row(line) abort
return a:line =~# '^\s*|.*|\s*$'
endfunction
" Resolve the config dict for wiki #n (0-based), falling back to the scalar
" g:nuwiki_* globals. Returns root/ext/idx/diary_rel/diary_idx/space.
function! nuwiki#util#wiki_cfg(n) abort
let l:wikis = nuwiki#config#wikis()
let l:w = (a:n >= 0 && a:n < len(l:wikis)) ? l:wikis[a:n] : {}
let l:root = expand(get(l:w, 'root',
\ get(g:, 'nuwiki_wiki_root', '~/vimwiki')))
let l:ext = get(l:w, 'file_extension',
\ get(g:, 'nuwiki_file_extension', '.wiki'))
if l:ext[0] !=# '.' | let l:ext = '.' . l:ext | endif
let l:idx = get(l:w, 'index', 'index')
let l:diary_rel = get(l:w, 'diary_rel_path',
\ get(g:, 'nuwiki_diary_rel_path', 'diary'))
let l:diary_idx = get(l:w, 'diary_index', 'diary')
let l:space = get(l:w, 'links_space_char',
\ get(g:, 'nuwiki_links_space_char', ' '))
return { 'root': l:root, 'ext': l:ext, 'idx': l:idx,
\ 'diary_rel': l:diary_rel, 'diary_idx': l:diary_idx, 'space': l:space }
endfunction