2cbabbf

dotfiles.git > main > 2cbabbf > files / nvim / .gitignore

Wikilink autocomplete in markdown files :p

Grahp, 2026-11-09

Commit: 2cbabbf3d84ab95fd1bdd08e817f48758f6a809a
Parent: 4243021

2 changed files:

nvim/lua/complete.lua modified (view file)

@@ -205,9 +205,41 @@   done(items) end +local wikilinks = {completes_digits = true}++--- Everything typed since the [[, until a ] | or # ends the note name+function wikilinks.word(before)+  return before:match("%[%[([^%[%]|#]*)$") or ""+end++function wikilinks.request_prefix()+  return ""+end++function wikilinks.completes_nothing_typed(before)+  return before:match("%[%[$") ~= nil+end++function wikilinks.fetch(_, _, done)+  local notes = require("wikilink").notes()+  local count = {}+  for _, note in ipairs(notes) do count[note.name] = (count[note.name] or 0) + 1 end++  local items = {}+  for _, note in ipairs(notes) do+    --- Obsidian only spells out the path when the name alone is ambiguous+    local label = count[note.name] > 1 and note.path or note.name+    local dir = vim.fs.dirname(note.path)+    items[#items + 1] = {label = label, word = label, ns = dir ~= "." and dir or nil,+                         note = true}+  end+  done(items)+end+ local function source_for(buf)   local ft = vim.bo[buf].filetype   if ft == "clojure" then return clojure end+  if ft == "markdown" then return wikilinks end   if vim.bo[buf].buftype == "" and not prose_filetypes[ft] then return buffer_words end end @@ -266,7 +298,7 @@ local function matching(s, word)   local c = s.candidates   if word == "" then-    return vim.tbl_filter(function(item) return item.is_local end, c.items)+    return vim.tbl_filter(function(item) return item.is_local or item.note end, c.items)   end    if word:match("^[^/]+/%.") then@@ -281,7 +313,8 @@   end    local prefixed = vim.tbl_filter(function(item)-    return vim.startswith(item.label:lower(), word:lower())+    local label = item.note and vim.fs.basename(item.label) or item.label+    return vim.startswith(label:lower(), word:lower())   end, fuzzy)   local items = (#prefixed > 0 and not word:match("^::")) and prefixed or fuzzy @@ -339,7 +372,8 @@   local wants_completion = word ~= ""                            or (source.completes_nothing_typed and source.completes_nothing_typed(before)) -  if in_string_or_comment(buf, row, col) or word:match("^%d") or not wants_completion then+  local bad_start = word:match("^%d") and not source.completes_digits+  if in_string_or_comment(buf, row, col) or bad_start or not wants_completion then     session = nil     return close()   end

nvim/lua/wikilink.lua modified (view file)

@@ -72,4 +72,20 @@   if anchor ~= "" then jump_to_anchor(anchor) end end -return {follow = follow}+local skipped_dirs = {[".git"] = true, [".obsidian"] = true, [".trash"] = true, node_modules = true}++--- Every note in the vault as {name = "Note", path = "dir/Note"}, name is what Obsidian links by+local function notes()+  local found = {}+  for path, type in vim.fs.dir(vault_root(), {depth = math.huge, skip = function(dir)+    return not skipped_dirs[vim.fs.basename(dir)]+  end}) do+    if type == "file" and path:match("%.md$") then+      local rel = path:sub(1, -4)+      found[#found + 1] = {name = vim.fs.basename(rel), path = rel}+    end+  end+  return found+end++return {follow = follow, notes = notes}