Files
nuwiki/autoload/nuwiki/diary.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

111 lines
4.2 KiB
VimL

" autoload/nuwiki/diary.vim — diary-specific functions for nuwiki
" Includes calendar-vim integration functions
" ===== Calendar-Vim Integration =====
" The wiki index (0-based) of the most recently entered wiki buffer. The
" calendar shows / creates diary entries for this wiki, so opening the calendar
" while editing `ifood_wiki` diaries into ifood_wiki — not always the first
" wiki. Updated by the BufEnter autocmd in plugin/nuwiki.vim; defaults to 0.
" (The LSP-driven diary commands already follow the current buffer via its URI;
" this mirrors that for the VimL calendar-vim callbacks.)
let s:current_wiki_idx = 0
" Record the wiki that owns `file` as the current one. Called on entering a
" wiki buffer. No-op when the file is under no configured wiki.
function! nuwiki#diary#track_wiki(file) abort
let l:file = fnamemodify(a:file, ':p')
if empty(l:file)
return
endif
let l:n = 0
for l:w in nuwiki#commands#wiki_list()
let l:root = fnamemodify(expand(l:w.root), ':p')
if l:root[len(l:root) - 1:] !=# '/' | let l:root .= '/' | endif
if l:file[: len(l:root) - 1] ==# l:root
let s:current_wiki_idx = l:n
return
endif
let l:n += 1
endfor
endfunction
" Function: nuwiki#diary#calendar_action(day, month, year, week, dir)
" Called by calendar-vim when user presses Enter on a date.
" day/month/year are numeric integers; dir is 'V' for a vertical split (any
" other value means a horizontal split). week is unused.
" Opens or creates the diary entry for the given date.
function! nuwiki#diary#calendar_action(day, month, year, week, dir) abort
" Build YYYY-MM-DD from the parts passed by calendar-vim
let l:date_str = printf('%04d-%02d-%02d', a:year, a:month, a:day)
" Wiki of the buffer the calendar was opened from (falls back to the first).
let l:c = s:wiki_cfg(s:current_wiki_idx)
" Construct file path: {root}/{diary_rel}/{YYYY-MM-DD}.{ext}
let l:file_path = l:c.root . '/' . l:c.diary_rel . '/' . l:date_str . l:c.ext
" Remember the calendar window so we can close it once the diary opens.
let l:cal_winid = win_getid()
" Open the diary file in a different window. If a previous window exists go
" there; otherwise split / vsplit / new depending on a:dir.
if winnr('#') > 0
execute 'wincmd p'
if !&hidden && &modified
execute 'new'
endif
elseif a:dir ==# 'V'
execute 'vsplit'
else
execute 'split'
endif
execute 'edit ' . fnameescape(l:file_path)
" A brand-new entry has no file on disk yet, so ftdetect may not have run;
" ensure the vimwiki filetype so syntax/maps are active immediately.
if &filetype !=# 'vimwiki'
setfiletype vimwiki
endif
" Close the calendar window now that the diary is open (keep at least one).
if win_getid() != l:cal_winid && win_id2win(l:cal_winid) > 0 && winnr('$') > 1
let l:diary_winid = win_getid()
if win_gotoid(l:cal_winid)
close
endif
call win_gotoid(l:diary_winid)
endif
endfunction
" Function: nuwiki#diary#calendar_sign(day, month, year)
" Called by calendar-vim to determine which dates show markers (*)
" day, month, year are numeric integers (1-based).
" Returns a single-character string to use as marker (e.g. '*' or ''),
" or 1/0 for 1-indexed calendars.
" calendar-vim's default expects the return value to be a single character
" to display; returning any non-empty string shows a marker.
function! nuwiki#diary#calendar_sign(day, month, year) abort
" Build YYYY-MM-DD from the parts passed by calendar-vim
let l:date_str = printf('%04d-%02d-%02d', a:year, a:month, a:day)
" Wiki of the buffer the calendar was opened from (falls back to the first).
let l:c = s:wiki_cfg(s:current_wiki_idx)
" Construct expected file path
let l:file_path = l:c.root . '/' . l:c.diary_rel . '/' . l:date_str . l:c.ext
" Return a marker if the file exists, empty string otherwise
if filereadable(l:file_path)
return '*'
endif
return ''
endfunction
" Helper: get wiki configuration for wiki n (0-based). Resolves through
" nuwiki#config#wikis() so g:nuwiki_wikis AND an upstream g:vimwiki_list both
" work, falling back to the scalar g:nuwiki_* single-wiki shorthand.
function! s:wiki_cfg(n) abort
return nuwiki#util#wiki_cfg(a:n)
endfunction