*muwiki* *muwiki.nvim* A lightweight wiki plugin for Neovim ============================================================================== CONTENTS *muwiki-contents* 1. Introduction ............................................ |muwiki-intro| 2. Requirements ............................................ |muwiki-requirements| 3. Installation ............................................ |muwiki-installation| 4. Configuration ........................................... |muwiki-configuration| 5. Keymaps ................................................. |muwiki-keymaps| 6. Lua API ................................................. |muwiki-api| 7. Autocommands & Recipes .................................. |muwiki-autocmd| 7.1 Auto-create directories ............................. |muwiki-autocmd-mkdir| 7.2 Add template for new files .......................... |muwiki-autocmd-template| 7.3 Open with menu examples ............................. |muwiki-autocmd-open-with| 7.4 Toggle checkbox ..................................... |muwiki-autocmd-toggle-checkbox| 8. Health Check ............................................ |muwiki-health| ============================================================================== 1. INTRODUCTION *muwiki-intro* MuWiki is a lightweight wiki plugin for Neovim using standard markdown syntax. It provides: - Standard markdown links `[text](url)` - Multiple wiki directories - Link navigation and xdg-open for web/file links - Extensible via autocmds (mkdir, templates, custom handlers) ============================================================================== 2. REQUIREMENTS *muwiki-requirements* - Neovim v0.10+ - Treesitter markdown parsers (`:TSInstall markdown markdown_inline`) ============================================================================== 3. INSTALLATION *muwiki-installation* Using vim.pack (Neovim 0.12+)~ > vim.pack.add({ { src = "https://git.3kgcat.fi/muwiki.nvim", name = "muwiki" } { src = "https://github.com/nvim-treesitter/nvim-treesitter", name = "treesitter" } }) < Using lazy.nvim~ > { url = "https://git.3kgcat.fi/muwiki.nvim", dependencies = { "nvim-treesitter/nvim-treesitter" }, keys = { { "ww", function() require("muwiki").open_index("default") end, desc = "Open wiki index" }, }, opts = { dirs = {{ name = 'default', path = '~/wiki' }}, }, } < ============================================================================== 4. CONFIGURATION *muwiki-configuration* The plugin is configured using the |muwiki.setup()| function. Configuration Options~ *muwiki-opt-dirs* dirs List of wiki directories. Each entry is a table with: - name: Wiki name for reference - path: Absolute path to wiki directory Default: nil *muwiki-opt-index_file* index_file Name of the index file for each wiki. Default: 'index.md' *muwiki-opt-text_extensions* text_extensions List of file extensions that open directly in Neovim for file:// links. Files with matching extensions bypass xdg-open and open in a Neovim buffer. Extensions can be specified with or without leading dot (e.g., 'txt' or '.txt'). Default: {} Example Configuration~ > local muwiki = require('muwiki') muwiki.setup({ dirs = { { name = 'default', path = '~/wiki' }, { name = 'work', path = '~/work/wiki' }, }, index_file = 'index.md', -- Open these file types directly in Neovim (bypass xdg-open) -- Note: Even binary files like PNG can be opened in Neovim text_extensions = { 'txt', 'md', 'png' }, }) < ============================================================================== 5. KEYMAPS *muwiki-keymaps* Keymaps should be configured by the user. Here are recommended keymaps: > -- Quick access to wiki index vim.keymap.set('n', 'ww', function() muwiki.open_index("default") end, { desc = "Open wiki index" }) -- Keymaps for wiki navigation (only active in wiki files) vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", callback = function(args) if not muwiki.wiki_root(args.buf) then return end local opts = { buffer = args.buf, silent = true } vim.keymap.set('n', '', muwiki.open_link, opts) vim.keymap.set('n', '', muwiki.next_link, opts) vim.keymap.set('n', '', muwiki.prev_link, opts) vim.keymap.set('v', '', muwiki.create_link, opts) end, }) < ============================================================================== 6. LUA API *muwiki-api* muwiki.setup({opts}) *muwiki.setup()* Configure the plugin. See |muwiki-configuration| for options. muwiki.open_link() *muwiki.open_link()* Open the link under cursor. - Wiki links: open in Neovim buffer - Web links (http/https): open with xdg-open - File links (file://): open with xdg-open, unless the file extension matches |muwiki-opt-text_extensions|, in which case opens in Neovim muwiki.next_link() *muwiki.next_link()* Jump to the next markdown link in the buffer. muwiki.prev_link() *muwiki.prev_link()* Jump to the previous markdown link in the buffer. muwiki.create_link() *muwiki.create_link()* Create a link from visual selection. In visual mode, select text and call this function to convert it to a markdown link. The text will be normalized to create a filename (lowercase, spaces to underscores). muwiki.get_link() *muwiki.get_link()* Get information about the link under cursor. Returns a table with: - text: Link display text - target: Link destination - type: Link type ('web', 'file', or 'wiki') muwiki.open_with_menu({handlers}, {link}) *muwiki.open_with_menu()* Open link with a selectable handler from a menu. {handlers} is a list of handler tables: > { name = "Handler Name", cmd = "command" or function(url), exts = {"pdf", "doc"} -- optional file extensions } < {link} is optional; if not provided, gets link under cursor. muwiki.open_index({name}) *muwiki.open_index()* Open the index file of a wiki by name. {name} is the wiki name from configuration. muwiki.wiki_root({bufnr}) *muwiki.wiki_root()* Get the wiki root directory for a buffer. Returns the path or nil if buffer is not in a wiki. muwiki.toggle_checkbox() *muwiki.toggle_checkbox()* Toggle the checkbox at cursor position using treesitter. Also toggles all nested child checkboxes to match the parent's new state. Works when cursor is anywhere on the line. ============================================================================== 7. AUTOCOMMANDS & RECIPES *muwiki-autocmd* Auto-create directories when saving~ *muwiki-autocmd-mkdir* > vim.api.nvim_create_autocmd("BufWritePre", { pattern = "*.md", callback = function(args) local wiki_root = muwiki.wiki_root(args.buf) if not wiki_root then return end local dir = vim.fn.fnamemodify(args.file, ":h") if vim.fn.isdirectory(dir) == 0 then vim.fn.mkdir(dir, "p") end end, }) < Add template for new files~ *muwiki-autocmd-template* > vim.api.nvim_create_autocmd("BufNewFile", { pattern = "*.md", callback = function(args) local wiki_root = muwiki.wiki_root(args.buf) if not wiki_root then return end local filename = vim.fn.fnamemodify(args.file, ":t:r") local date = os.date("%Y-%m-%d") local template = string.format("# %s\n\nCreated: %s\n\n", filename, date) vim.api.nvim_buf_set_lines(args.buf, 0, 0, false, vim.split(template, "\n")) end, }) < Open with menu example~ *muwiki-autocmd-open-with* > vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", callback = function(args) if not muwiki.wiki_root(args.buf) then return end vim.keymap.set('n', 'o', function() muwiki.open_with_menu({ { name = "Zathura", cmd = "zathura", exts = {"pdf"} }, { name = "swayimg", cmd = "swayimg", exts = {"png", "jpg", "jpeg", "gif", "webp"} }, { name = "mpv", cmd = "mpv", exts = {"mp4", "mkv", "avi", "mov", "webm"} }, { name = "Copy URL", cmd = function(url) vim.system({ 'wl-copy', url }, { detach = true }) vim.notify('URL copied to clipboard', vim.log.levels.INFO) end }, { name = "xdg-open", cmd = "xdg-open" }, }) end, { buffer = args.buf, desc = "Open with..." }) end, }) < Custom open handler using get_link()~ *muwiki-autocmd-open-custom* > vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", callback = function(args) if not muwiki.wiki_root(args.buf) then return end vim.keymap.set('n', '', function() local link = muwiki.get_link() if not link then vim.notify('No link under cursor', vim.log.levels.WARN) return end -- Custom logic based on link type if link.type == 'web' then vim.system({ 'xdg-open', link.target }, { detach = true }) elseif link.type == 'file' then local ext = link.target:match('%.([^%.]+)$') if ext == 'png' or ext == 'jpg' or ext == 'jpeg' or ext == 'gif' or ext == 'webp' then vim.system({ 'swayimg', link.target }, { detach = true }) elseif ext == 'mp4' or ext == 'mkv' or ext == 'avi' or ext == 'mov' or ext == 'webm' then vim.system({ 'mpv', link.target }, { detach = true }) elseif ext == 'pdf' then vim.system({ 'zathura', link.target }, { detach = true }) else -- Open in Neovim for other file types local utils = require('muwiki.utils') local file_path = utils.resolve(link.target) vim.cmd('edit ' .. vim.fn.fnameescape(file_path)) end else -- Wiki link: open in Neovim local utils = require('muwiki.utils') local file_path = utils.resolve(link.target) vim.cmd('edit ' .. vim.fn.fnameescape(file_path)) end end, { buffer = args.buf, desc = "Open link (custom handler)" }) end, }) < Toggle checkbox with Shift+T~ *muwiki-autocmd-toggle-checkbox* > vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", callback = function(args) if not muwiki.wiki_root(args.buf) then return end vim.keymap.set('n', '', muwiki.toggle_checkbox, { buffer = args.buf, desc = "Toggle checkbox" }) end, }) < This will toggle the checkbox at cursor position and all nested child checkboxes to match the parent's new state. ============================================================================== 8. HEALTH CHECK *muwiki-health* Run |:checkhealth muwiki| to verify: - Wiki directories are configured and exist - Treesitter markdown parser is installed - Treesitter markdown_inline parser is installed ============================================================================== RECOMMENDED PLUGINS These plugins work well with muwiki.nvim: - render-markdown.nvim - Improve markdown rendering in Neovim - outline.nvim - Navigate document structure with symbols outline ============================================================================== vim:tw=78:ts=8:ft=help:norl: