0d1a73a3ba
A Lua-only `setup({ wikis = … })` config is invisible to the VimL side:
the buffer helpers in autoload/nuwiki/config.vim and the vimwiki compat
shim (autoload/vimwiki/vars.vim, which third-party plugins like
vimwiki-sync call via vimwiki#vars#get_wikilocal) read g:nuwiki_wikis. So
a Neovim user who migrated from g:vimwiki_list to native setup({wikis})
would break vimwiki-sync (it'd resolve the default ~/vimwiki).
setup() now publishes the resolved wiki list to g:nuwiki_wikis when the
config came from setup() opts (the only case VimL can't already see —
g:nuwiki_wikis / g:vimwiki_list configs are global and visible). Verified
vimwiki#vars#get_wikilocal('path', n) returns the right roots from a
pure-Lua setup() config. test-global-shorthand grows two bridge checks
(17). Goldens + keymap harnesses green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
157 lines
6.9 KiB
Lua
157 lines
6.9 KiB
Lua
-- lua/nuwiki/init.lua — Neovim entry point.
|
|
--
|
|
-- Public surface:
|
|
-- require('nuwiki').setup(opts) — apply user config + register LSP
|
|
-- require('nuwiki').install() — install / build the language server
|
|
-- require('nuwiki').health() — :checkhealth nuwiki target
|
|
--
|
|
-- This layer is wiring only. Everything substantive
|
|
-- happens in the Rust language server.
|
|
|
|
local M = {}
|
|
|
|
local config = require('nuwiki.config')
|
|
local lsp = require('nuwiki.lsp')
|
|
|
|
-- Open a file directly, expanding ~ / env vars in the path.
|
|
local function _open(path, open_cmd)
|
|
vim.cmd((open_cmd or 'edit') .. ' ' .. vim.fn.fnameescape(vim.fn.expand(path)))
|
|
end
|
|
|
|
-- Return the config dict for wiki #n (0-based). See config.wiki_cfg.
|
|
local function _wiki_cfg(n)
|
|
return config.wiki_cfg(n)
|
|
end
|
|
|
|
-- Compute the wiki index path for wiki #n (0-based) from config.
|
|
local function _wiki_index_path(n)
|
|
local c = _wiki_cfg(n)
|
|
return c.root .. '/' .. c.idx .. c.ext
|
|
end
|
|
|
|
-- Compute a diary file path from config. day_offset=0 → today.
|
|
-- Pass nil to get the diary index file instead.
|
|
local function _diary_path(day_offset)
|
|
local c = _wiki_cfg(0)
|
|
if day_offset == nil then
|
|
return c.root .. '/' .. c.diary_rel .. '/' .. c.diary_idx .. c.ext
|
|
end
|
|
local t = os.time() + day_offset * 86400
|
|
return c.root .. '/' .. c.diary_rel .. '/' .. os.date('%Y-%m-%d', t) .. c.ext
|
|
end
|
|
|
|
-- Register global (non-buffer-local) entry-point keymaps so users can open
|
|
-- their wiki from any buffer, not just from inside a .wiki file. Files are
|
|
-- opened directly from config — no LSP client required; the server auto-starts
|
|
-- once the vimwiki FileType fires on the newly opened buffer.
|
|
local function _setup_global_mappings()
|
|
if vim.g.nuwiki_no_default_mappings then return end
|
|
local kmap = vim.keymap.set
|
|
local function o(d) return { silent = true, desc = 'nuwiki: ' .. d } end
|
|
-- Same configurable prefix as the buffer-local maps (vimwiki map_prefix).
|
|
local p = config.options.map_prefix or '<Leader>w'
|
|
|
|
kmap('n', p .. 'w', function() _open(_wiki_index_path(0)) end, o('wiki index'))
|
|
kmap('n', p .. 't', function() _open(_wiki_index_path(0), 'tabedit') end, o('wiki index (tab)'))
|
|
kmap('n', p .. 's', function() require('nuwiki.commands').wiki_ui_select() end, o('pick wiki'))
|
|
kmap('n', p .. 'i', function() _open(_diary_path(nil)) end, o('diary index'))
|
|
kmap('n', p .. '<Leader>w', function() _open(_diary_path(0)) end, o('today diary'))
|
|
kmap('n', p .. '<Leader>y', function() _open(_diary_path(-1)) end, o('yesterday diary'))
|
|
kmap('n', p .. '<Leader>t', function() _open(_diary_path(0), 'tabedit') end, o('today diary (tab)'))
|
|
kmap('n', p .. '<Leader>m', function() _open(_diary_path(1)) end, o('tomorrow diary'))
|
|
kmap('n', p .. '<Leader>i', function() require('nuwiki.commands').diary_generate_index() end, o('rebuild diary index'))
|
|
end
|
|
|
|
-- Global wiki-picker commands so a wiki can be chosen from any buffer before
|
|
-- a .wiki file exists. The picker reads its list from config (no LSP); the
|
|
-- buffer-local versions in ftplugin/vimwiki.vim shadow these inside wiki
|
|
-- buffers but dispatch to the same function.
|
|
local function _setup_global_commands()
|
|
local function ui_select() require('nuwiki.commands').wiki_ui_select() end
|
|
vim.api.nvim_create_user_command('VimwikiUISelect', ui_select, {})
|
|
vim.api.nvim_create_user_command('NuwikiUISelect', ui_select, {})
|
|
|
|
local function show_version() require('nuwiki.commands').show_version() end
|
|
vim.api.nvim_create_user_command('VimwikiShowVersion', show_version, {})
|
|
vim.api.nvim_create_user_command('NuwikiShowVersion', show_version, {})
|
|
|
|
-- Global Index / TabIndex entry points (upstream defines the Index family
|
|
-- globally). The buffer-local copies shadow these inside wiki buffers.
|
|
local function index(o) require('nuwiki.commands').wiki_index(o.count) end
|
|
local function tab_index(o) require('nuwiki.commands').wiki_tab_index(o.count) end
|
|
vim.api.nvim_create_user_command('VimwikiIndex', index, { count = 0 })
|
|
vim.api.nvim_create_user_command('NuwikiIndex', index, { count = 0 })
|
|
vim.api.nvim_create_user_command('VimwikiTabIndex', tab_index, { count = 0 })
|
|
vim.api.nvim_create_user_command('NuwikiTabIndex', tab_index, { count = 0 })
|
|
|
|
-- Get/set nuwiki client config (upstream's :VimwikiVar).
|
|
local function var(o) require('nuwiki.commands').var(o.args) end
|
|
vim.api.nvim_create_user_command('VimwikiVar', var, { nargs = '*' })
|
|
vim.api.nvim_create_user_command('NuwikiVar', var, { nargs = '*' })
|
|
end
|
|
|
|
function M.setup(opts)
|
|
config.apply(opts or {})
|
|
|
|
-- Bridge a Lua-only `setup({ wikis = … })` config to VimL. The buffer-side
|
|
-- VimL helpers (autoload/nuwiki/config.vim) and the vimwiki compat shim
|
|
-- (autoload/vimwiki/vars.vim — used by third-party plugins such as
|
|
-- vimwiki-sync) read `g:nuwiki_wikis`, which can't see a config that only
|
|
-- lives in Lua. Publishing the resolved list keeps both worlds in sync. (A
|
|
-- `g:nuwiki_wikis` / `g:vimwiki_list` config is already VimL-visible, so this
|
|
-- only fires for the pure-`setup()` case.)
|
|
if type(config.options.wikis) == 'table' and #config.options.wikis > 0 then
|
|
vim.g.nuwiki_wikis = config.wikis()
|
|
end
|
|
|
|
-- Neovim 0.7+ resolves filetypes via `vim.filetype.match` before any
|
|
-- `ftdetect/*.vim` autocmd fires, and its bundled rule for `*.wiki`
|
|
-- returns `mediawiki`. Register an authoritative rule here so this
|
|
-- plugin's filetype (vimwiki) wins.
|
|
if vim.filetype and vim.filetype.add then
|
|
local extensions = { wiki = 'vimwiki' }
|
|
local ext = (config.options.file_extension or '.wiki'):gsub('^%.', '')
|
|
if ext ~= 'wiki' and ext ~= '' then
|
|
extensions[ext] = 'vimwiki'
|
|
end
|
|
vim.filetype.add({ extension = extensions })
|
|
end
|
|
|
|
-- Calendar-vim wiring lives in plugin/nuwiki.vim's FileType autocmd, which
|
|
-- runs for both Vim and Neovim. Translate the Lua-side opt-out into the
|
|
-- g: flag that autocmd reads so `use_calendar = false` fully disables it.
|
|
if config.options.use_calendar == false then
|
|
vim.g.nuwiki_no_calendar = 1
|
|
end
|
|
|
|
-- vimwiki `auto_header` (default off): insert a level-1 header from the
|
|
-- filename on new wiki pages. BufNewFile (not FileType) so it only fires for
|
|
-- genuinely new files.
|
|
if config.options.auto_header == true then
|
|
local ext = (config.options.file_extension or '.wiki'):gsub('^%.', '')
|
|
local pats = { '*.wiki' }
|
|
if ext ~= 'wiki' and ext ~= '' then
|
|
pats[#pats + 1] = '*.' .. ext
|
|
end
|
|
vim.api.nvim_create_autocmd('BufNewFile', {
|
|
pattern = pats,
|
|
group = vim.api.nvim_create_augroup('nuwiki_auto_header', { clear = true }),
|
|
callback = function(a) require('nuwiki.commands').auto_header(a.buf) end,
|
|
})
|
|
end
|
|
|
|
lsp.register()
|
|
_setup_global_mappings()
|
|
_setup_global_commands()
|
|
end
|
|
|
|
function M.install()
|
|
return require('nuwiki.install').install()
|
|
end
|
|
|
|
function M.health()
|
|
return require('nuwiki.health').check()
|
|
end
|
|
|
|
return M
|