diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-06-07 20:58:17 +0200 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-06-08 12:37:59 +0200 |
| commit | 3b71d66f2a2066868c8f621753bc817cd07ecf74 (patch) | |
| tree | 75e4642b682a74076b3517d341d586293f4a2fc6 /plugin/50-notes.lua | |
| parent | 726ecec2c16f8743a30825e22806fb88b9fa3689 (diff) | |
| download | nvim-config-3b71d66f2a2066868c8f621753bc817cd07ecf74.tar.gz nvim-config-3b71d66f2a2066868c8f621753bc817cd07ecf74.zip | |
refactor(nvim): extract follow engine into dotfiles.follow module
Diffstat (limited to 'plugin/50-notes.lua')
| -rw-r--r-- | plugin/50-notes.lua | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/plugin/50-notes.lua b/plugin/50-notes.lua index dee4da3..fec0dd2 100644 --- a/plugin/50-notes.lua +++ b/plugin/50-notes.lua @@ -325,3 +325,75 @@ vim.api.nvim_create_user_command("NotesRenameSection", function(opts) end) end end, { nargs = "*", desc = "Rename the heading at the cursor and update wiki-links" }) + +------------------------------------------------------------------------------------------------------------------------ +-- Following notes (`notes://` scheme and `[[wiki-links]]`), wired into the follow engine +------------------------------------------------------------------------------------------------------------------------ + +local follow = require("dotfiles.follow") + +-- `notes://<path>` resolves to `<path>` relative to the notes dir. +follow.register_scheme("notes", { + resolve = function(uri) + return notes_dir .. "/" .. uri + end, +}) + +-- Returns the inner text of a `[[wiki-link]]` under the cursor, or `nil`. +local function get_wikilink_target() + local line = vim.api.nvim_get_current_line() + local col = vim.api.nvim_win_get_cursor(0)[2] + 1 + local init = 1 + while true do + local s, e, inner = line:find("%[%[(.-)%]%]", init) + if s == nil then + return nil + end + if col >= s and col <= e then + return inner + end + init = e + 1 + end +end + +-- Follow a `[[note]]` / `[[note#Heading]]` / `[[dir/]]` wiki-link relative to the +-- notes dir, creating parent directories (and the note itself on save) as needed. +local function follow_wikilink(inner, edit_cmd) + local name, heading = inner:match("^(.-)#(.*)$") + if name == nil then + name = inner + end + local target = notes_dir .. "/" .. name + if name:sub(-1) == "/" then -- directory link: create and open it + vim.fn.mkdir(target, "p") + vim.cmd(edit_cmd .. " " .. vim.fn.fnameescape(target)) + return + end + if not name:match("%.%w+$") then -- default to a Markdown note + target = target .. ".md" + end + vim.fn.mkdir(vim.fs.dirname(target), "p") + vim.cmd(edit_cmd .. " " .. vim.fn.fnameescape(target)) + if heading ~= nil and heading ~= "" then + vim.fn.cursor(1, 1) + -- `\V` matches the heading literally; `\v` brackets the heading markers. + local pat = [[\v^#+\s+\V]] .. vim.fn.escape(heading, [[\]]) .. [[\v\s*$]] + if vim.fn.search(pat, "cW") == 0 then + vim.notify("No heading '" .. heading .. "' in " .. name, vim.log.levels.WARN) + end + end +end + +-- Wiki-links take precedence over generic URL/file following, but only on a +-- `[[...]]` under the cursor in a markdown buffer in normal mode. +follow.register_handler(function(edit_cmd) + if vim.fn.mode() ~= "n" or vim.bo.filetype ~= "markdown" then + return false + end + local inner = get_wikilink_target() + if inner == nil then + return false + end + follow_wikilink(inner, edit_cmd) + return true +end) |
