From a9208db2e465553a634f3c00f3c72f8090c299a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Fr=C3=B3es=20Franco?= Date: Sun, 28 Jun 2026 12:28:37 +0000 Subject: [PATCH] fix(lua): recognize spaceless headings (==Heading==) in client helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shared heading_level helper still required spaces around the title, so the client-side regex paths — fold fallback, text objects (ah/ih), and heading navigation (]] etc.) — skipped spaceless headings, even though the server (and HTML export) accept them since the #7 fix. Rewrite to match the lexer: balanced leading/trailing `=` runs (cap 6) around a non-empty title, spaced or spaceless. Marker-only (`======`), unbalanced (`==a==b`, `==> x`) and 7+ runs still return 0. Verified against an 18-case battery + full editor harness (10/10). Co-Authored-By: Claude Opus 4.8 --- lua/nuwiki/util.lua | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lua/nuwiki/util.lua b/lua/nuwiki/util.lua index 86c8d05..d82f38b 100644 --- a/lua/nuwiki/util.lua +++ b/lua/nuwiki/util.lua @@ -6,9 +6,14 @@ 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. +-- capped at level 6 (a 7+ `=` run is not a heading). Both the spaced +-- (`== H ==`) and spaceless (`==H==`) forms are accepted, matching vimwiki. +-- `nil`-safe. function M.heading_level(line) - local lead = line and line:match('^%s*(=+)%s') + if not line then + return 0 + end + local lead = line:match('^%s*(=+)') if not lead then return 0 end @@ -16,10 +21,17 @@ function M.heading_level(line) if lvl > 6 then return 0 end - local trail = line:match('%s(=+)%s*$') + -- Same-length trailing run of `=` at end of line (after optional trailing ws). + local trail = line:match('(=+)%s*$') if not trail or #trail ~= lvl then return 0 end + -- Non-empty title between the two runs (rules out marker-only lines like + -- `======`). `(.-)` is lazy, so the leading/trailing `=+` keep their runs. + local body = line:match('^%s*=+(.-)=+%s*$') + if not body or body:match('^%s*$') then + return 0 + end return lvl end