refactor(lua): extract shared heading_level/is_table_row; dedup wiki_list in search
CI / editor tests (push) Successful in 48s
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:
@@ -331,8 +331,9 @@ function M.search(args)
|
|||||||
end
|
end
|
||||||
local config = require('nuwiki.config')
|
local config = require('nuwiki.config')
|
||||||
local file = vim.fn.expand('%:p')
|
local file = vim.fn.expand('%:p')
|
||||||
|
local wikis = config.wiki_list()
|
||||||
local root, ext = '', '.wiki'
|
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')
|
local wroot = vim.fn.fnamemodify(vim.fn.expand(w.root), ':p')
|
||||||
if file:sub(1, #wroot) == wroot then
|
if file:sub(1, #wroot) == wroot then
|
||||||
root, ext = wroot, w.ext or ext
|
root, ext = wroot, w.ext or ext
|
||||||
@@ -340,7 +341,7 @@ function M.search(args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if root == '' then
|
if root == '' then
|
||||||
local first = config.wiki_list()[1]
|
local first = wikis[1]
|
||||||
if first then
|
if first then
|
||||||
root = vim.fn.fnamemodify(vim.fn.expand(first.root), ':p')
|
root = vim.fn.fnamemodify(vim.fn.expand(first.root), ':p')
|
||||||
ext = first.ext or ext
|
ext = first.ext or ext
|
||||||
@@ -818,9 +819,7 @@ end
|
|||||||
-- *before* placing the cursor, all in a single `vim.schedule` tick.
|
-- *before* placing the cursor, all in a single `vim.schedule` tick.
|
||||||
-- The algorithm matches the LSP server's implementation in nuwiki-rs.
|
-- The algorithm matches the LSP server's implementation in nuwiki-rs.
|
||||||
|
|
||||||
local function is_table_row(line)
|
local is_table_row = require('nuwiki.util').is_table_row
|
||||||
return line ~= nil and line:match('^%s*|.*|%s*$') ~= nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local function table_cell_starts(line)
|
local function table_cell_starts(line)
|
||||||
-- Returns 1-based byte positions of each `|` separator. Cell N spans
|
-- Returns 1-based byte positions of each `|` separator. Cell N spans
|
||||||
|
|||||||
+1
-10
@@ -9,16 +9,7 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
--- Heading level from one line of source. Returns 0 for non-headings.
|
--- Heading level from one line of source. Returns 0 for non-headings.
|
||||||
local function heading_level(line)
|
local heading_level = require('nuwiki.util').heading_level
|
||||||
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
|
|
||||||
|
|
||||||
--- `foldexpr` body. Returns a fold-marker string per `:help fold-expr`.
|
--- `foldexpr` body. Returns a fold-marker string per `:help fold-expr`.
|
||||||
function M.expr()
|
function M.expr()
|
||||||
|
|||||||
@@ -29,13 +29,7 @@ end
|
|||||||
-- vimwiki's `vimwiki#base#goto_*_header` family does, just simpler:
|
-- vimwiki's `vimwiki#base#goto_*_header` family does, just simpler:
|
||||||
-- match `^\s*=` runs as heading lines.
|
-- match `^\s*=` runs as heading lines.
|
||||||
|
|
||||||
local function heading_level(line)
|
local heading_level = require('nuwiki.util').heading_level
|
||||||
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 function jump_heading(direction, predicate)
|
local function jump_heading(direction, predicate)
|
||||||
local total = vim.api.nvim_buf_line_count(0)
|
local total = vim.api.nvim_buf_line_count(0)
|
||||||
|
|||||||
@@ -15,13 +15,7 @@ local M = {}
|
|||||||
|
|
||||||
-- ===== Heading helpers =====
|
-- ===== Heading helpers =====
|
||||||
|
|
||||||
local function heading_level(line)
|
local heading_level = require('nuwiki.util').heading_level
|
||||||
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
|
|
||||||
|
|
||||||
--- Find the start/end of the heading block at `lnum`.
|
--- Find the start/end of the heading block at `lnum`.
|
||||||
--- `with_subtree` controls whether we descend into sub-headings:
|
--- `with_subtree` controls whether we descend into sub-headings:
|
||||||
@@ -123,9 +117,7 @@ end
|
|||||||
|
|
||||||
-- ===== Table cell / column =====
|
-- ===== Table cell / column =====
|
||||||
|
|
||||||
local function is_table_row(line)
|
local is_table_row = require('nuwiki.util').is_table_row
|
||||||
return line:match('^%s*|.*|%s*$') ~= nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Compute the byte ranges of cells on a `|`-delimited row.
|
--- Compute the byte ranges of cells on a `|`-delimited row.
|
||||||
--- Returns a list of `{start_byte, end_byte}` 1-based inclusive of the
|
--- Returns a list of `{start_byte, end_byte}` 1-based inclusive of the
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user