refactor(lua): extract shared heading_level/is_table_row; dedup wiki_list in search
CI / editor tests (push) Successful in 48s

Pulls the duplicated heading_level (keymaps/folding/textobjects) and
is_table_row (commands/textobjects) helpers into lua/nuwiki/util.lua. The
copies had drifted — only folding capped level >6 and only commands
nil-guarded is_table_row; the unified versions keep both (cap + nil-safe),
which also aligns the keymap/textobject paths with the server's level cap.
search() now resolves config.wiki_list() once instead of twice.

No behaviour change beyond the >6 cap now applying everywhere. Full editor
harness green (10/10).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-28 12:19:21 +00:00
parent 101cb1cea9
commit ac1db1af1d
5 changed files with 39 additions and 32 deletions
+4 -5
View File
@@ -331,8 +331,9 @@ function M.search(args)
end
local config = require('nuwiki.config')
local file = vim.fn.expand('%:p')
local wikis = config.wiki_list()
local root, ext = '', '.wiki'
for _, w in ipairs(config.wiki_list()) do
for _, w in ipairs(wikis) do
local wroot = vim.fn.fnamemodify(vim.fn.expand(w.root), ':p')
if file:sub(1, #wroot) == wroot then
root, ext = wroot, w.ext or ext
@@ -340,7 +341,7 @@ function M.search(args)
end
end
if root == '' then
local first = config.wiki_list()[1]
local first = wikis[1]
if first then
root = vim.fn.fnamemodify(vim.fn.expand(first.root), ':p')
ext = first.ext or ext
@@ -818,9 +819,7 @@ end
-- *before* placing the cursor, all in a single `vim.schedule` tick.
-- The algorithm matches the LSP server's implementation in nuwiki-rs.
local function is_table_row(line)
return line ~= nil and line:match('^%s*|.*|%s*$') ~= nil
end
local is_table_row = require('nuwiki.util').is_table_row
local function table_cell_starts(line)
-- Returns 1-based byte positions of each `|` separator. Cell N spans
+1 -10
View File
@@ -9,16 +9,7 @@
local M = {}
--- Heading level from one line of source. Returns 0 for non-headings.
local function heading_level(line)
local lead = line:match('^%s*(=+)%s')
if not lead then return 0 end
local lvl = #lead
if lvl > 6 then return 0 end
-- Require a matching trailing run of `=`s.
local trail = line:match('%s(=+)%s*$')
if not trail or #trail ~= lvl then return 0 end
return lvl
end
local heading_level = require('nuwiki.util').heading_level
--- `foldexpr` body. Returns a fold-marker string per `:help fold-expr`.
function M.expr()
+1 -7
View File
@@ -29,13 +29,7 @@ end
-- vimwiki's `vimwiki#base#goto_*_header` family does, just simpler:
-- match `^\s*=` runs as heading lines.
local function heading_level(line)
local lead = line and line:match('^%s*(=+)%s')
if not lead then return 0 end
local trail = line:match('%s(=+)%s*$')
if not trail or #trail ~= #lead then return 0 end
return #lead
end
local heading_level = require('nuwiki.util').heading_level
local function jump_heading(direction, predicate)
local total = vim.api.nvim_buf_line_count(0)
+2 -10
View File
@@ -15,13 +15,7 @@ local M = {}
-- ===== Heading helpers =====
local function heading_level(line)
local lead = line and line:match('^%s*(=+)%s')
if not lead then return 0 end
local trail = line:match('%s(=+)%s*$')
if not trail or #trail ~= #lead then return 0 end
return #lead
end
local heading_level = require('nuwiki.util').heading_level
--- Find the start/end of the heading block at `lnum`.
--- `with_subtree` controls whether we descend into sub-headings:
@@ -123,9 +117,7 @@ end
-- ===== Table cell / column =====
local function is_table_row(line)
return line:match('^%s*|.*|%s*$') ~= nil
end
local is_table_row = require('nuwiki.util').is_table_row
--- Compute the byte ranges of cells on a `|`-delimited row.
--- Returns a list of `{start_byte, end_byte}` 1-based inclusive of the
+31
View File
@@ -0,0 +1,31 @@
-- lua/nuwiki/util.lua — small pure-text helpers shared across the client
-- layers (keymaps, folding, textobjects, commands). Dependency-free so any
-- module can require it without load-order concerns.
local M = {}
-- Heading level of `line` (1-6), or 0 when it isn't a heading. Mirrors the
-- server lexer: balanced leading/trailing runs of `=` around non-empty text,
-- capped at level 6 (a 7+ `=` run is not a heading). `nil`-safe.
function M.heading_level(line)
local lead = line and line:match('^%s*(=+)%s')
if not lead then
return 0
end
local lvl = #lead
if lvl > 6 then
return 0
end
local trail = line:match('%s(=+)%s*$')
if not trail or #trail ~= lvl then
return 0
end
return lvl
end
-- True when `line` looks like a table row (`| … |`). `nil`-safe.
function M.is_table_row(line)
return line ~= nil and line:match('^%s*|.*|%s*$') ~= nil
end
return M