content on opening tag line", function()
- local lines = render_doc({
+ local lines = render_doc {
"
first line content",
"second line",
"
",
- })
+ }
local has_first, has_second = false, false
for _, l in ipairs(lines) do
- if l:match("first line content") then has_first = true end
- if l:match("second line") then has_second = true end
+ if l:match "first line content" then has_first = true end
+ if l:match "second line" then has_second = true end
end
assert_eq(has_first, true, "div inline open: first line content")
assert_eq(has_second, true, "div inline open: second line content")
end)
test("html block comment: single-line comment is skipped", function()
- local lines = render_doc({
+ local lines = render_doc {
"before",
"",
"after",
- })
+ }
for _, l in ipairs(lines) do
- assert_eq(l:match("comment"), nil, "html block comment: should not show comment")
+ assert_eq(l:match "comment", nil, "html block comment: should not show comment")
end
local has_before, has_after = false, false
for _, l in ipairs(lines) do
- if l:match("before") then has_before = true end
- if l:match("after") then has_after = true end
+ if l:match "before" then has_before = true end
+ if l:match "after" then has_after = true end
end
assert_eq(has_before, true, "html block comment: before should show")
assert_eq(has_after, true, "html block comment: after should show")
end)
test("html block comment: multi-line comment is skipped", function()
- local lines = render_doc({
+ local lines = render_doc {
"before",
"",
"after",
- })
+ }
for _, l in ipairs(lines) do
- assert_eq(l:match("multi"), nil, "html multi comment: should not show first line")
- assert_eq(l:match("line comment"), nil, "html multi comment: should not show middle")
+ assert_eq(l:match "multi", nil, "html multi comment: should not show first line")
+ assert_eq(l:match "line comment", nil, "html multi comment: should not show middle")
end
local has_before, has_after = false, false
for _, l in ipairs(lines) do
- if l:match("before") then has_before = true end
- if l:match("after") then has_after = true end
+ if l:match "before" then has_before = true end
+ if l:match "after" then has_after = true end
end
assert_eq(has_before, true, "html multi comment: before should show")
assert_eq(has_after, true, "html multi comment: after should show")
@@ -946,7 +946,7 @@ end)
test("link with inline code: underline covers full text", function()
local Markdown = require "md-render.markdown"
- local text, highlights, links = Markdown.render("[`async.wrap`](#31-asyncwrap)")
+ local text, highlights, links = Markdown.render "[`async.wrap`](#31-asyncwrap)"
assert_eq(text, "async.wrap", "code-in-link: text should strip backticks and link syntax")
-- Find Underlined highlight
local underline
@@ -991,9 +991,7 @@ test("multiple code spans with link: underline position correct", function()
for _, hl in ipairs(highlights) do
if hl.hl == "Underlined" then
local covered = text:sub(hl.col + 1, hl.end_col)
- if covered:find("target") then
- target_hl = hl
- end
+ if covered:find "target" then target_hl = hl end
end
end
assert_eq(target_hl ~= nil, true, "multi-code-link: should have Underlined for target.func")
@@ -1005,6 +1003,4 @@ end)
-- Print summary
print(string.format("\n%d passed, %d failed", pass_count, fail_count))
-if fail_count > 0 then
- os.exit(1)
-end
+if fail_count > 0 then os.exit(1) end
diff --git a/tests/toggle_test.lua b/tests/toggle_test.lua
index 1972f69..806a4a8 100644
--- a/tests/toggle_test.lua
+++ b/tests/toggle_test.lua
@@ -53,9 +53,7 @@ local function setup_md_buffer(lines)
end
local function cleanup_buffer(buf)
- if vim.api.nvim_buf_is_valid(buf) then
- pcall(vim.api.nvim_buf_delete, buf, { force = true })
- end
+ if vim.api.nvim_buf_is_valid(buf) then pcall(vim.api.nvim_buf_delete, buf, { force = true }) end
end
local function clear_win_state(win)
@@ -67,7 +65,9 @@ end
-- window, so nvim_get_current_win() does NOT identify the new split.
local function find_new_win(before_wins)
local before_set = {}
- for _, w in ipairs(before_wins) do before_set[w] = true end
+ for _, w in ipairs(before_wins) do
+ before_set[w] = true
+ end
for _, w in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
if not before_set[w] then return w end
end
@@ -78,7 +78,7 @@ end
-- Test 1: source → render swaps the buffer in the same window
-- ----------------------------------------------------------------------
test("source → render swaps buffer in the same window", function()
- local source = setup_md_buffer({ "# Hello", "", "Some text" })
+ local source = setup_md_buffer { "# Hello", "", "Some text" }
local win = vim.api.nvim_get_current_win()
preview.toggle()
@@ -108,12 +108,12 @@ end)
-- Test 2: render → source swaps back to the original buffer
-- ----------------------------------------------------------------------
test("render → source swaps back to original buffer", function()
- local source = setup_md_buffer({ "# Hello", "", "Some text" })
+ local source = setup_md_buffer { "# Hello", "", "Some text" }
local win = vim.api.nvim_get_current_win()
- preview.toggle() -- → render
+ preview.toggle() -- → render
local render_buf = vim.api.nvim_win_get_buf(win)
- preview.toggle() -- → source
+ preview.toggle() -- → source
assert_eq(vim.api.nvim_win_get_buf(win), source, "should be back on source buffer")
@@ -128,7 +128,7 @@ end)
-- Test 3: round-trip reuses the same render buffer (cached session)
-- ----------------------------------------------------------------------
test("round-trip reuses the same render buffer", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
preview.toggle()
@@ -146,7 +146,7 @@ end)
-- Test 4: cursor position survives source → render → source
-- ----------------------------------------------------------------------
test("cursor position survives round-trip via source_line_map", function()
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"# Heading 1",
"",
"First paragraph.",
@@ -156,7 +156,7 @@ test("cursor position survives round-trip via source_line_map", function()
"Second paragraph.",
"",
"Last line.",
- })
+ }
local win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_cursor(win, { 7, 0 }) -- "Second paragraph."
@@ -166,10 +166,7 @@ test("cursor position survives round-trip via source_line_map", function()
local final_line = vim.api.nvim_win_get_cursor(win)[1]
-- Source line 7 should round-trip back close to itself (allow ±1 for mapping
-- artifacts on heading-adjacent lines).
- assert_true(
- math.abs(final_line - 7) <= 2,
- "cursor should return near source line 7 (got " .. final_line .. ")"
- )
+ assert_true(math.abs(final_line - 7) <= 2, "cursor should return near source line 7 (got " .. final_line .. ")")
cleanup_buffer(source)
end)
@@ -200,7 +197,7 @@ end)
-- Test 6: BufWipeout on source clears the cached session
-- ----------------------------------------------------------------------
test("BufWipeout on source clears cached session", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
preview.toggle()
assert_true(preview._toggle_sessions[source] ~= nil, "session should be cached")
@@ -216,23 +213,25 @@ end)
-- Test 7: source change is reflected on next toggle
-- ----------------------------------------------------------------------
test("source change is reflected on next source → render toggle", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
preview.toggle()
local first_render = vim.api.nvim_win_get_buf(win)
local first_lines = vim.api.nvim_buf_get_lines(first_render, 0, -1, false)
- preview.toggle() -- back to source
+ preview.toggle() -- back to source
vim.api.nvim_buf_set_lines(source, 0, -1, false, { "# Hello", "", "Added paragraph." })
- preview.toggle() -- back to render — should reflect new source
+ preview.toggle() -- back to render — should reflect new source
local render_buf = vim.api.nvim_win_get_buf(win)
local new_lines = vim.api.nvim_buf_get_lines(render_buf, 0, -1, false)
-- Line count should have grown (new paragraph added)
- assert_true(#new_lines > #first_lines, "render content should reflect source changes (lines: "
- .. #first_lines .. " → " .. #new_lines .. ")")
+ assert_true(
+ #new_lines > #first_lines,
+ "render content should reflect source changes (lines: " .. #first_lines .. " → " .. #new_lines .. ")"
+ )
cleanup_buffer(source)
end)
@@ -241,7 +240,7 @@ end)
-- Test 8: live update autocmds are installed for the source buffer
-- ----------------------------------------------------------------------
test("live update autocmds are installed on first toggle", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
preview.toggle()
local autocmds = vim.api.nvim_get_autocmds {
@@ -249,7 +248,9 @@ test("live update autocmds are installed on first toggle", function()
buffer = source,
}
local events = {}
- for _, ac in ipairs(autocmds) do events[ac.event] = true end
+ for _, ac in ipairs(autocmds) do
+ events[ac.event] = true
+ end
assert_true(events.TextChanged, "TextChanged autocmd should be registered")
assert_true(events.TextChangedI, "TextChangedI autocmd should be registered")
@@ -264,10 +265,10 @@ end)
-- Test 9: live rebuild fires after debounce when render is visible
-- ----------------------------------------------------------------------
test("live rebuild fires after debounce when render is visible", function()
- local source = setup_md_buffer({ "# Hello", "", "para" })
+ local source = setup_md_buffer { "# Hello", "", "para" }
local source_win = vim.api.nvim_get_current_win()
- preview.toggle() -- render in source_win
+ preview.toggle() -- render in source_win
local render_buf = vim.api.nvim_win_get_buf(source_win)
local before_lines = #vim.api.nvim_buf_get_lines(render_buf, 0, -1, false)
@@ -279,7 +280,9 @@ test("live rebuild fires after debounce when render is visible", function()
vim.api.nvim_buf_set_lines(source, -1, -1, false, { "", "appended paragraph" })
preview._schedule_live_rebuild(preview._toggle_sessions[source])
- vim.wait(300, function() return false end)
+ vim.wait(300, function()
+ return false
+ end)
local after_lines = #vim.api.nvim_buf_get_lines(render_buf, 0, -1, false)
assert_true(
@@ -295,11 +298,11 @@ end)
-- Test 10: hidden render → edit only marks dirty (no rebuild, no timer)
-- ----------------------------------------------------------------------
test("hidden render → edit sets dirty without scheduling a rebuild", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
- preview.toggle() -- → render
- preview.toggle() -- → source (render now hidden)
+ preview.toggle() -- → render
+ preview.toggle() -- → source (render now hidden)
local session = preview._toggle_sessions[source]
assert_true(session ~= nil, "session should exist")
@@ -312,7 +315,9 @@ test("hidden render → edit sets dirty without scheduling a rebuild", function(
assert_true(session._debounce_timer == nil, "no debounce timer should be running")
-- Wait past the debounce window to be extra sure nothing fires
- vim.wait(250, function() return false end)
+ vim.wait(250, function()
+ return false
+ end)
assert_true(session._debounce_timer == nil, "still no debounce timer after wait")
-- Re-toggle should consume dirty and rebuild
@@ -323,7 +328,10 @@ test("hidden render → edit sets dirty without scheduling a rebuild", function(
local lines = vim.api.nvim_buf_get_lines(render_buf, 0, -1, false)
local found = false
for _, l in ipairs(lines) do
- if l:find("new line", 1, true) then found = true; break end
+ if l:find("new line", 1, true) then
+ found = true
+ break
+ end
end
assert_true(found, "edited content should appear after re-toggle")
@@ -336,12 +344,12 @@ end)
-- the stale content. Regression test for issue #5.
-- ----------------------------------------------------------------------
test("re-entering dirty render buf via :buffer rebuilds stale content", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
- preview.toggle() -- → render
+ preview.toggle() -- → render
local render_buf = vim.api.nvim_win_get_buf(win)
- preview.toggle() -- → source (render now hidden)
+ preview.toggle() -- → source (render now hidden)
local session = preview._toggle_sessions[source]
assert_true(session ~= nil, "session should exist")
@@ -359,7 +367,10 @@ test("re-entering dirty render buf via :buffer rebuilds stale content", function
local lines = vim.api.nvim_buf_get_lines(render_buf, 0, -1, false)
local found = false
for _, l in ipairs(lines) do
- if l:find("fresh after hide", 1, true) then found = true; break end
+ if l:find("fresh after hide", 1, true) then
+ found = true
+ break
+ end
end
assert_true(found, "edited content should appear after re-entering render buf")
@@ -370,10 +381,10 @@ end)
-- Test 11: rapid edits coalesce into a single rebuild via debounce
-- ----------------------------------------------------------------------
test("rapid edits coalesce into a single rebuild", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local source_win = vim.api.nvim_get_current_win()
- preview.toggle() -- render in source_win
+ preview.toggle() -- render in source_win
vim.cmd "vsplit"
local edit_win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(edit_win, source)
@@ -390,12 +401,18 @@ test("rapid edits coalesce into a single rebuild", function()
for i = 1, 5 do
vim.api.nvim_buf_set_lines(source, -1, -1, false, { "edit " .. i })
preview._schedule_live_rebuild(session)
- vim.wait(20, function() return false end)
+ vim.wait(20, function()
+ return false
+ end)
end
-- Wait for the debounce to fire (last edit + 150ms + slack)
- vim.wait(300, function() return rebuild_count > 0 end)
- vim.wait(50, function() return false end)
+ vim.wait(300, function()
+ return rebuild_count > 0
+ end)
+ vim.wait(50, function()
+ return false
+ end)
assert_eq(rebuild_count, 1, "5 rapid edits should coalesce into exactly 1 rebuild")
@@ -408,7 +425,7 @@ end)
-- Test 12: BufWipeout cleanly stops a pending debounce timer
-- ----------------------------------------------------------------------
test("BufWipeout stops pending debounce timer cleanly", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
preview.toggle()
vim.cmd "vsplit"
vim.api.nvim_win_set_buf(0, source)
@@ -422,7 +439,9 @@ test("BufWipeout stops pending debounce timer cleanly", function()
-- Wait past the original 150ms — if the timer wasn't stopped, the deferred
-- callback would fire on a wiped buffer and could throw. The assertion below
-- will only succeed if cleanup ran.
- vim.wait(250, function() return false end)
+ vim.wait(250, function()
+ return false
+ end)
assert_true(preview._toggle_sessions[source] == nil, "session should be cleared")
end)
@@ -432,18 +451,22 @@ end)
-- ----------------------------------------------------------------------
test("live rebuild preserves render window topline", function()
local lines = {}
- for i = 1, 100 do table.insert(lines, "line " .. i) end
+ for i = 1, 100 do
+ table.insert(lines, "line " .. i)
+ end
local source = setup_md_buffer(lines)
local source_win = vim.api.nvim_get_current_win()
- preview.toggle() -- render in source_win
+ preview.toggle() -- render in source_win
local render_win = source_win
-- Scroll the render window so topline > 1
vim.api.nvim_win_call(render_win, function()
vim.fn.winrestview { topline = 50, lnum = 60 }
end)
- local before = vim.api.nvim_win_call(render_win, function() return vim.fn.winsaveview() end)
+ local before = vim.api.nvim_win_call(render_win, function()
+ return vim.fn.winsaveview()
+ end)
-- Edit source from a separate window (prepend a line)
vim.cmd "vsplit"
@@ -451,9 +474,13 @@ test("live rebuild preserves render window topline", function()
vim.api.nvim_win_set_buf(edit_win, source)
vim.api.nvim_buf_set_lines(source, 0, 0, false, { "prepended" })
preview._schedule_live_rebuild(preview._toggle_sessions[source])
- vim.wait(300, function() return false end)
+ vim.wait(300, function()
+ return false
+ end)
- local after = vim.api.nvim_win_call(render_win, function() return vim.fn.winsaveview() end)
+ local after = vim.api.nvim_win_call(render_win, function()
+ return vim.fn.winsaveview()
+ end)
assert_true(
math.abs(after.topline - before.topline) <= 5,
"topline should be ~preserved (was " .. before.topline .. ", now " .. after.topline .. ")"
@@ -467,7 +494,7 @@ end)
-- Test 13a: render buffer is named after the source for statusline display
-- ----------------------------------------------------------------------
test("render buffer name has [render] suffix", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local source_name = vim.api.nvim_buf_get_name(source)
preview.toggle()
local render_buf = vim.api.nvim_win_get_buf(0)
@@ -482,7 +509,7 @@ end)
-- Test 13b: BufWriteCmd is registered on the render buffer to forward :w
-- ----------------------------------------------------------------------
test("BufWriteCmd is registered on render buffer to forward :w", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
preview.toggle()
local render_buf = vim.api.nvim_win_get_buf(0)
@@ -499,7 +526,7 @@ end)
-- Test 14: auto_on swaps to render and sets b:md_render_auto
-- ----------------------------------------------------------------------
test("auto_on flips to render and marks the buffer", function()
- local source = setup_md_buffer({ "# Hello", "", "para" })
+ local source = setup_md_buffer { "# Hello", "", "para" }
local win = vim.api.nvim_get_current_win()
preview.auto_on()
@@ -517,7 +544,7 @@ end)
-- driven by buffer-local keymaps on the render buffer instead)
-- ----------------------------------------------------------------------
test("auto_on registers InsertLeave autocmd", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
preview.auto_on()
local autocmds = vim.api.nvim_get_autocmds {
@@ -525,7 +552,9 @@ test("auto_on registers InsertLeave autocmd", function()
buffer = source,
}
local events = {}
- for _, ac in ipairs(autocmds) do events[ac.event] = true end
+ for _, ac in ipairs(autocmds) do
+ events[ac.event] = true
+ end
assert_true(events.InsertLeave, "InsertLeave autocmd should be registered")
assert_false(events.InsertEnter, "InsertEnter autocmd should NOT be registered (handled via keymap)")
@@ -538,7 +567,7 @@ end)
-- Test 15b: auto_on installs Insert-entry keymaps on the render buffer
-- ----------------------------------------------------------------------
test("auto_on installs i/I/a/A/o/O keymaps on render buffer", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
preview.auto_on()
@@ -546,9 +575,11 @@ test("auto_on installs i/I/a/A/o/O keymaps on render buffer", function()
local keymaps = vim.api.nvim_buf_get_keymap(render_buf, "n")
local mapped = {}
- for _, km in ipairs(keymaps) do mapped[km.lhs] = true end
+ for _, km in ipairs(keymaps) do
+ mapped[km.lhs] = true
+ end
- for _, key in ipairs({ "i", "I", "a", "A", "o", "O" }) do
+ for _, key in ipairs { "i", "I", "a", "A", "o", "O" } do
assert_true(mapped[key], "key '" .. key .. "' should be mapped on render buf")
end
@@ -556,9 +587,11 @@ test("auto_on installs i/I/a/A/o/O keymaps on render buffer", function()
local keymaps_after = vim.api.nvim_buf_get_keymap(render_buf, "n")
local mapped_after = {}
- for _, km in ipairs(keymaps_after) do mapped_after[km.lhs] = true end
+ for _, km in ipairs(keymaps_after) do
+ mapped_after[km.lhs] = true
+ end
- for _, key in ipairs({ "i", "I", "a", "A", "o", "O" }) do
+ for _, key in ipairs { "i", "I", "a", "A", "o", "O" } do
assert_false(mapped_after[key], "key '" .. key .. "' should be removed after auto_off")
end
@@ -569,15 +602,17 @@ end)
-- Test 16: schedule_auto_transition("source") flips render → source after debounce
-- ----------------------------------------------------------------------
test("auto-transition to source swaps render → source after 50ms", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
- preview.auto_on() -- now on render
+ preview.auto_on() -- now on render
local rendered = vim.api.nvim_win_get_buf(win)
assert_false(rendered == source, "should start on render")
preview._schedule_auto_transition(source, "source")
- vim.wait(120, function() return vim.api.nvim_win_get_buf(win) == source end)
+ vim.wait(120, function()
+ return vim.api.nvim_win_get_buf(win) == source
+ end)
assert_eq(vim.api.nvim_win_get_buf(win), source, "should be back on source after debounce")
@@ -589,16 +624,20 @@ end)
-- Test 17: schedule_auto_transition("render") flips source → render after debounce
-- ----------------------------------------------------------------------
test("auto-transition to render swaps source → render after 50ms", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
- preview.auto_on() -- render
+ preview.auto_on() -- render
preview._schedule_auto_transition(source, "source")
- vim.wait(120, function() return vim.api.nvim_win_get_buf(win) == source end)
+ vim.wait(120, function()
+ return vim.api.nvim_win_get_buf(win) == source
+ end)
assert_eq(vim.api.nvim_win_get_buf(win), source, "precondition: source")
preview._schedule_auto_transition(source, "render")
- vim.wait(120, function() return vim.api.nvim_win_get_buf(win) ~= source end)
+ vim.wait(120, function()
+ return vim.api.nvim_win_get_buf(win) ~= source
+ end)
assert_false(vim.api.nvim_win_get_buf(win) == source, "should be back on render after debounce")
@@ -610,7 +649,7 @@ end)
-- Test 18: auto_off clears autocmds and restores source display
-- ----------------------------------------------------------------------
test("auto_off clears autocmds and swaps render back to source", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
preview.auto_on()
@@ -638,7 +677,7 @@ end)
-- Test 18b: auto_toggle twice returns to the original (source, auto-off) state
-- ----------------------------------------------------------------------
test("auto_toggle twice returns to original source/auto-off state", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
assert_eq(vim.api.nvim_win_get_buf(win), source, "precondition: source")
@@ -659,7 +698,7 @@ end)
-- Test 18c: auto_off leaves displayed mode unchanged when not showing render
-- ----------------------------------------------------------------------
test("auto_off does not swap when current window is not showing render", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local win = vim.api.nvim_get_current_win()
preview.auto_on()
@@ -696,7 +735,7 @@ end)
-- Test 20: split from source opens a horizontal split showing render
-- ----------------------------------------------------------------------
test("split from source opens a split showing render", function()
- local source = setup_md_buffer({ "# Hello", "", "para" })
+ local source = setup_md_buffer { "# Hello", "", "para" }
local source_win = vim.api.nvim_get_current_win()
local before_wins = vim.api.nvim_tabpage_list_wins(0)
@@ -706,8 +745,7 @@ test("split from source opens a split showing render", function()
assert_eq(#after_wins, #before_wins + 1, "should add exactly one window")
-- split() returns focus to source; the new split is identified by diff.
- assert_eq(vim.api.nvim_get_current_win(), source_win,
- "focus should return to source window after split")
+ assert_eq(vim.api.nvim_get_current_win(), source_win, "focus should return to source window after split")
local new_win = find_new_win(before_wins)
assert_true(new_win ~= nil, "a new window should exist")
@@ -730,21 +768,22 @@ end)
-- Test 21: vertical modifier produces a vertical split
-- ----------------------------------------------------------------------
test("split with mods.vertical = true produces a vertical split", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local source_win = vim.api.nvim_get_current_win()
local before_height = vim.api.nvim_win_get_height(source_win)
local before_width = vim.api.nvim_win_get_width(source_win)
local before_wins = vim.api.nvim_tabpage_list_wins(0)
- preview.split({ mods = { vertical = true } })
+ preview.split { mods = { vertical = true } }
local new_win = find_new_win(before_wins)
local after_height = vim.api.nvim_win_get_height(source_win)
local after_width = vim.api.nvim_win_get_width(source_win)
- assert_true(math.abs(after_height - before_height) <= 1,
- "heights should be ~unchanged in a vertical split")
- assert_true(after_width < before_width,
- "source width should shrink (was " .. before_width .. ", now " .. after_width .. ")")
+ assert_true(math.abs(after_height - before_height) <= 1, "heights should be ~unchanged in a vertical split")
+ assert_true(
+ after_width < before_width,
+ "source width should shrink (was " .. before_width .. ", now " .. after_width .. ")"
+ )
vim.api.nvim_win_close(new_win, true)
cleanup_buffer(source)
@@ -754,7 +793,7 @@ end)
-- Test 22: split from a render-mode window opens source in the new split
-- ----------------------------------------------------------------------
test("split from render window opens source in the new split", function()
- local source = setup_md_buffer({ "# Hello", "", "body" })
+ local source = setup_md_buffer { "# Hello", "", "body" }
local orig_win = vim.api.nvim_get_current_win()
preview.toggle()
@@ -774,7 +813,7 @@ test("split from render window opens source in the new split", function()
assert_false(has_state, "new source split should have no md_render_state")
vim.api.nvim_win_close(new_win, true)
- preview.toggle() -- restore orig_win to source for clean teardown
+ preview.toggle() -- restore orig_win to source for clean teardown
clear_win_state(orig_win)
cleanup_buffer(source)
end)
@@ -783,20 +822,19 @@ end)
-- Test 23: split shares the cached toggle render buffer
-- ----------------------------------------------------------------------
test("split shares the cached toggle render buffer", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local orig_win = vim.api.nvim_get_current_win()
preview.toggle()
local toggle_render = vim.api.nvim_win_get_buf(orig_win)
- preview.toggle() -- back to source
+ preview.toggle() -- back to source
local before_wins = vim.api.nvim_tabpage_list_wins(0)
preview.split()
local split_win = find_new_win(before_wins)
local split_render = vim.api.nvim_win_get_buf(split_win)
- assert_eq(split_render, toggle_render,
- "split must reuse the cached render buffer from the toggle session")
+ assert_eq(split_render, toggle_render, "split must reuse the cached render buffer from the toggle session")
vim.api.nvim_win_close(split_win, true)
clear_win_state(orig_win)
@@ -807,7 +845,7 @@ end)
-- Test 24: live update propagates to the split's render window
-- ----------------------------------------------------------------------
test("live update propagates to the split's render window", function()
- local source = setup_md_buffer({ "# Hello", "", "para" })
+ local source = setup_md_buffer { "# Hello", "", "para" }
local source_win = vim.api.nvim_get_current_win()
local before_wins = vim.api.nvim_tabpage_list_wins(0)
@@ -821,12 +859,15 @@ test("live update propagates to the split's render window", function()
vim.api.nvim_buf_set_lines(source, -1, -1, false, { "", "appended paragraph" })
preview._schedule_live_rebuild(preview._toggle_sessions[source])
- vim.wait(300, function() return false end)
+ vim.wait(300, function()
+ return false
+ end)
local after_lines = #vim.api.nvim_buf_get_lines(render_buf, 0, -1, false)
- assert_true(after_lines > before_lines,
- "render in split should grow after live update (was "
- .. before_lines .. ", now " .. after_lines .. ")")
+ assert_true(
+ after_lines > before_lines,
+ "render in split should grow after live update (was " .. before_lines .. ", now " .. after_lines .. ")"
+ )
vim.api.nvim_win_close(split_win, true)
cleanup_buffer(source)
@@ -836,7 +877,7 @@ end)
-- Test 25: closing split window keeps render buf alive; toggle still works
-- ----------------------------------------------------------------------
test("closing split window keeps render buf alive; subsequent toggle works", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local source_win = vim.api.nvim_get_current_win()
local before_wins = vim.api.nvim_tabpage_list_wins(0)
@@ -846,17 +887,18 @@ test("closing split window keeps render buf alive; subsequent toggle works", fun
vim.api.nvim_win_close(split_win, true)
- assert_true(vim.api.nvim_buf_is_valid(render_buf),
- "render buf should outlive the split window (bufhidden=hide)")
- assert_true(preview._toggle_sessions[source] ~= nil,
- "session should remain cached for the source")
+ assert_true(vim.api.nvim_buf_is_valid(render_buf), "render buf should outlive the split window (bufhidden=hide)")
+ assert_true(preview._toggle_sessions[source] ~= nil, "session should remain cached for the source")
vim.api.nvim_set_current_win(source_win)
preview.toggle()
- assert_eq(vim.api.nvim_win_get_buf(source_win), render_buf,
- "toggle should reuse the same render buf after split close")
+ assert_eq(
+ vim.api.nvim_win_get_buf(source_win),
+ render_buf,
+ "toggle should reuse the same render buf after split close"
+ )
- preview.toggle() -- back to source for clean teardown
+ preview.toggle() -- back to source for clean teardown
clear_win_state(source_win)
cleanup_buffer(source)
end)
@@ -866,18 +908,18 @@ end)
-- restores them on render -> source
-- ----------------------------------------------------------------------
test("toggle hides number/relativenumber/list and restores them", function()
- local source = setup_md_buffer({ "# Hello", "", "body" })
+ local source = setup_md_buffer { "# Hello", "", "body" }
local win = vim.api.nvim_get_current_win()
vim.wo[win].number = true
vim.wo[win].relativenumber = true
vim.wo[win].list = true
- preview.toggle() -- source -> render
+ preview.toggle() -- source -> render
assert_false(vim.wo[win].number, "render: number off")
assert_false(vim.wo[win].relativenumber, "render: relativenumber off")
assert_false(vim.wo[win].list, "render: list off")
- preview.toggle() -- render -> source
+ preview.toggle() -- render -> source
assert_true(vim.wo[win].number, "source: number restored")
assert_true(vim.wo[win].relativenumber, "source: relativenumber restored")
assert_true(vim.wo[win].list, "source: list restored")
@@ -891,7 +933,7 @@ end)
-- keeps its original options
-- ----------------------------------------------------------------------
test("split render window hides nu/rnu/list; source unchanged", function()
- local source = setup_md_buffer({ "# Hello" })
+ local source = setup_md_buffer { "# Hello" }
local source_win = vim.api.nvim_get_current_win()
vim.wo[source_win].number = true
vim.wo[source_win].relativenumber = true
@@ -936,7 +978,7 @@ end)
-- Test 27: source CursorMoved syncs render cursor to the corresponding line
-- ----------------------------------------------------------------------
test("source cursor move syncs render window cursor", function()
- local source = setup_md_buffer({ "# Heading", "", "para 1", "", "para 2" })
+ local source = setup_md_buffer { "# Heading", "", "para 1", "", "para 2" }
local source_win = vim.api.nvim_get_current_win()
local before_wins = vim.api.nvim_tabpage_list_wins(0)
@@ -955,8 +997,7 @@ test("source cursor move syncs render window cursor", function()
local expected = session:source_to_rendered(5)
local total = vim.api.nvim_buf_line_count(session.buf)
expected = math.min(expected, total)
- assert_eq(vim.api.nvim_win_get_cursor(render_win)[1], expected,
- "render cursor should follow source to mapped line")
+ assert_eq(vim.api.nvim_win_get_cursor(render_win)[1], expected, "render cursor should follow source to mapped line")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -966,7 +1007,7 @@ end)
-- Test 28: render CursorMoved syncs source cursor to the corresponding line
-- ----------------------------------------------------------------------
test("render cursor move syncs source window cursor", function()
- local source = setup_md_buffer({ "# Heading", "", "para 1", "", "para 2" })
+ local source = setup_md_buffer { "# Heading", "", "para 1", "", "para 2" }
local source_win = vim.api.nvim_get_current_win()
local before_wins = vim.api.nvim_tabpage_list_wins(0)
@@ -984,8 +1025,11 @@ test("render cursor move syncs source window cursor", function()
local expected_source = session:rendered_to_source(target_render)
if expected_source then
- assert_eq(vim.api.nvim_win_get_cursor(source_win)[1], expected_source,
- "source cursor should follow render to mapped line")
+ assert_eq(
+ vim.api.nvim_win_get_cursor(source_win)[1],
+ expected_source,
+ "source cursor should follow render to mapped line"
+ )
end
vim.api.nvim_win_close(render_win, true)
@@ -996,19 +1040,18 @@ end)
-- Test 29: cursor sync is a no-op when only one side has a window
-- ----------------------------------------------------------------------
test("cursor sync no-op when only source is visible", function()
- local source = setup_md_buffer({ "# A", "", "B", "", "C" })
+ local source = setup_md_buffer { "# A", "", "B", "", "C" }
local source_win = vim.api.nvim_get_current_win()
-- Create the session via toggle then return to source so render is hidden.
preview.toggle()
- preview.toggle() -- back to source
+ preview.toggle() -- back to source
-- Should not error: no render window exists, sync handler returns early.
vim.api.nvim_win_set_cursor(source_win, { 3, 0 })
vim.cmd "doautocmd CursorMoved"
- assert_eq(vim.api.nvim_win_get_cursor(source_win)[1], 3,
- "source cursor unchanged when no render window")
+ assert_eq(vim.api.nvim_win_get_cursor(source_win)[1], 3, "source cursor unchanged when no render window")
clear_win_state(source_win)
cleanup_buffer(source)
@@ -1018,7 +1061,7 @@ end)
-- Test 30: BufWipeout removes the scroll-sync augroup
-- ----------------------------------------------------------------------
test("BufWipeout removes the scroll-sync augroup", function()
- local source = setup_md_buffer({ "# A" })
+ local source = setup_md_buffer { "# A" }
preview.toggle()
local augroup_name = "md_render_toggle_sync_" .. source
@@ -1056,7 +1099,9 @@ local function clear_sync_locks()
for _, session in pairs(preview._toggle_sessions or {}) do
session._syncing = false
if session._sync_unlock_timer then
- pcall(function() session._sync_unlock_timer:stop() end)
+ pcall(function()
+ session._sync_unlock_timer:stop()
+ end)
session._sync_unlock_timer = nil
end
end
@@ -1099,8 +1144,7 @@ test("source at file top -> render at file top", function()
local render_view = vim.api.nvim_win_call(render_win, function()
return vim.fn.winsaveview()
end)
- assert_eq(render_view.topline, 1,
- "render.topline should be 1 when source is at file top")
+ assert_eq(render_view.topline, 1, "render.topline should be 1 when source is at file top")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1126,10 +1170,9 @@ test("source at file bottom -> render at file bottom", function()
vim.cmd "doautocmd CursorMoved"
local render_botline = vim.api.nvim_win_call(render_win, function()
- return vim.fn.line("w$")
+ return vim.fn.line "w$"
end)
- assert_eq(render_botline, render_lines,
- "render.botline should equal render_lines when source is at file bottom")
+ assert_eq(render_botline, render_lines, "render.botline should equal render_lines when source is at file bottom")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1152,8 +1195,7 @@ test("render at file top -> source at file top", function()
local source_view = vim.api.nvim_win_call(source_win, function()
return vim.fn.winsaveview()
end)
- assert_eq(source_view.topline, 1,
- "source.topline should be 1 when render is at file top")
+ assert_eq(source_view.topline, 1, "source.topline should be 1 when render is at file top")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1179,10 +1221,9 @@ test("render at file bottom -> source at file bottom", function()
vim.cmd "doautocmd CursorMoved"
local source_botline = vim.api.nvim_win_call(source_win, function()
- return vim.fn.line("w$")
+ return vim.fn.line "w$"
end)
- assert_eq(source_botline, source_lines,
- "source.botline should equal source_lines when render is at file bottom")
+ assert_eq(source_botline, source_lines, "source.botline should equal source_lines when render is at file bottom")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1231,10 +1272,9 @@ test("source at bottom -> render at bottom (with wrapped lines)", function()
vim.cmd "doautocmd CursorMoved"
local render_botline = vim.api.nvim_win_call(render_win, function()
- return vim.fn.line("w$")
+ return vim.fn.line "w$"
end)
- assert_eq(render_botline, render_lines,
- "render.botline should equal render_lines even when source has wrapped lines")
+ assert_eq(render_botline, render_lines, "render.botline should equal render_lines even when source has wrapped lines")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1259,10 +1299,9 @@ test("render at bottom -> source at bottom (with wrapped lines)", function()
vim.cmd "doautocmd CursorMoved"
local source_botline = vim.api.nvim_win_call(source_win, function()
- return vim.fn.line("w$")
+ return vim.fn.line "w$"
end)
- assert_eq(source_botline, source_lines,
- "source.botline should equal source_lines even when render has wrapped lines")
+ assert_eq(source_botline, source_lines, "source.botline should equal source_lines even when render has wrapped lines")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1282,10 +1321,9 @@ test("source at top -> render at top (with wrapped lines)", function()
set_source_view(source_win, 1, 1)
local render_topline = vim.api.nvim_win_call(render_win, function()
- return vim.fn.line("w0")
+ return vim.fn.line "w0"
end)
- assert_eq(render_topline, 1,
- "render.topline should be 1 when source snaps to file top")
+ assert_eq(render_topline, 1, "render.topline should be 1 when source snaps to file top")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1306,10 +1344,9 @@ test("render at top -> source at top (with wrapped lines)", function()
set_view(render_win, 1, 1)
local source_topline = vim.api.nvim_win_call(source_win, function()
- return vim.fn.line("w0")
+ return vim.fn.line "w0"
end)
- assert_eq(source_topline, 1,
- "source.topline should be 1 when render snaps to file top")
+ assert_eq(source_topline, 1, "source.topline should be 1 when render snaps to file top")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1326,7 +1363,9 @@ local function get_shadow_lines(buf)
if not vim.api.nvim_buf_is_valid(buf) then return {} end
local marks = vim.api.nvim_buf_get_extmarks(buf, SHADOW_NS, 0, -1, {})
local lines = {}
- for _, m in ipairs(marks) do table.insert(lines, m[2] + 1) end
+ for _, m in ipairs(marks) do
+ table.insert(lines, m[2] + 1)
+ end
table.sort(lines)
return lines
end
@@ -1340,12 +1379,12 @@ local function trigger_shadow(source_buf)
end
test("split paints render shadow on initial source cursor line", function()
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"# Heading",
"",
"paragraph one",
"paragraph two",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_cursor(source_win, { 3, 0 })
@@ -1357,22 +1396,20 @@ test("split paints render shadow on initial source cursor line", function()
trigger_shadow(source)
local render_shadow = get_shadow_lines(session.buf)
- assert_true(#render_shadow > 0,
- "render buf should carry shadow extmarks for source line 3")
- assert_eq(get_shadow_lines(source), {},
- "source buf has no shadow while it owns focus")
+ assert_true(#render_shadow > 0, "render buf should carry shadow extmarks for source line 3")
+ assert_eq(get_shadow_lines(source), {}, "source buf has no shadow while it owns focus")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
end)
test("focus on render buffer paints shadow on source side and clears render side", function()
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"# Heading",
"",
"paragraph one",
"paragraph two",
- })
+ }
preview.split()
local session = preview._toggle_sessions[source]
local render_win = find_render_win(source)
@@ -1385,20 +1422,19 @@ test("focus on render buffer paints shadow on source side and clears render side
local source_shadow = get_shadow_lines(source)
assert_eq(#source_shadow, 1, "source side should hold a single-line shadow")
- assert_eq(get_shadow_lines(session.buf), {},
- "render side should clear its shadow once it owns focus")
+ assert_eq(get_shadow_lines(session.buf), {}, "render side should clear its shadow once it owns focus")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
end)
test("focus back to source clears source shadow and re-paints render", function()
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"# Heading",
"",
"paragraph one",
"paragraph two",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
preview.split()
local session = preview._toggle_sessions[source]
@@ -1421,7 +1457,7 @@ test("source cursor movement updates render shadow", function()
-- Blank lines between paragraphs so each is its own block; otherwise
-- join_paragraph_continuations collapses them and only the first
-- source line of the paragraph appears in source_line_map.
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"# Heading",
"",
"paragraph one",
@@ -1429,7 +1465,7 @@ test("source cursor movement updates render shadow", function()
"paragraph two",
"",
"paragraph three",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
preview.split()
local session = preview._toggle_sessions[source]
@@ -1443,21 +1479,19 @@ test("source cursor movement updates render shadow", function()
trigger_shadow(source)
local second = get_shadow_lines(session.buf)
- assert_true(#first > 0 and #second > 0,
- "both positions should produce shadows")
- assert_false(vim.deep_equal(first, second),
- "shadow should differ between source cursor positions")
+ assert_true(#first > 0 and #second > 0, "both positions should produce shadows")
+ assert_false(vim.deep_equal(first, second), "shadow should differ between source cursor positions")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
end)
test("heading source line maps to a contiguous render shadow range", function()
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"# Heading One",
"",
"body line",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
preview.split()
local session = preview._toggle_sessions[source]
@@ -1470,8 +1504,7 @@ test("heading source line maps to a contiguous render shadow range", function()
assert_true(#shadow >= 1, "heading should yield at least one shadow line")
if #shadow > 1 then
for i = 2, #shadow do
- assert_eq(shadow[i], shadow[i - 1] + 1,
- "shadow lines should be contiguous (no gaps)")
+ assert_eq(shadow[i], shadow[i - 1] + 1, "shadow lines should be contiguous (no gaps)")
end
end
@@ -1480,11 +1513,11 @@ test("heading source line maps to a contiguous render shadow range", function()
end)
test("source cursor on the last line does not crash (sentinel handling)", function()
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"# Heading",
"",
"tail line",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
preview.split()
local session = preview._toggle_sessions[source]
@@ -1500,11 +1533,11 @@ test("source cursor on the last line does not crash (sentinel handling)", functi
end)
test("closing the render split clears shadows on both sides", function()
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"# Heading",
"",
"body",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
preview.split()
local session = preview._toggle_sessions[source]
@@ -1517,12 +1550,12 @@ test("closing the render split clears shadows on both sides", function()
vim.api.nvim_set_current_win(source_win)
vim.api.nvim_win_close(render_win, true)
-- WinClosed handler defers via vim.schedule.
- vim.wait(50, function() return false end)
+ vim.wait(50, function()
+ return false
+ end)
- assert_eq(get_shadow_lines(source), {},
- "source shadow cleared after split closes")
- assert_eq(get_shadow_lines(session.buf), {},
- "render shadow cleared after split closes")
+ assert_eq(get_shadow_lines(source), {}, "source shadow cleared after split closes")
+ assert_eq(get_shadow_lines(session.buf), {}, "render shadow cleared after split closes")
cleanup_buffer(source)
end)
@@ -1531,13 +1564,13 @@ test("source line inside a joined paragraph highlights the whole block", functio
-- Three consecutive non-blank lines form a single paragraph in
-- CommonMark; only the first source line appears in source_line_map,
-- so cursor on lines 2 or 3 must fall back to the owner block (line 1).
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"first paragraph line",
"continuation line",
"another continuation",
"",
"next paragraph",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
preview.split()
local session = preview._toggle_sessions[source]
@@ -1551,14 +1584,12 @@ test("source line inside a joined paragraph highlights the whole block", functio
vim.api.nvim_win_set_cursor(source_win, { 2, 0 })
trigger_shadow(source)
local block_for_line_2 = get_shadow_lines(session.buf)
- assert_eq(block_for_line_2, block_for_line_1,
- "continuation line 2 should highlight the same block as line 1")
+ assert_eq(block_for_line_2, block_for_line_1, "continuation line 2 should highlight the same block as line 1")
vim.api.nvim_win_set_cursor(source_win, { 3, 0 })
trigger_shadow(source)
local block_for_line_3 = get_shadow_lines(session.buf)
- assert_eq(block_for_line_3, block_for_line_1,
- "continuation line 3 should also highlight the owner block")
+ assert_eq(block_for_line_3, block_for_line_1, "continuation line 3 should also highlight the owner block")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
@@ -1571,13 +1602,13 @@ test("render shadow skips rows occupied by image placements", function()
-- fires from CursorMoved inside the render window, so source-side
-- cursor moves would leave the image gone. Image rows must be
-- excluded from the shadow line set.
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"first paragraph line",
"continuation line",
"another continuation",
"",
"next paragraph",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
preview.split()
local session = preview._toggle_sessions[source]
@@ -1586,8 +1617,7 @@ test("render shadow skips rows occupied by image placements", function()
vim.api.nvim_win_set_cursor(source_win, { 1, 0 })
trigger_shadow(source)
local before = get_shadow_lines(session.buf)
- assert_true(#before >= 1,
- "paragraph block should produce at least one shadow row")
+ assert_true(#before >= 1, "paragraph block should produce at least one shadow row")
-- Inject a fake image placement that occupies one of the rows the
-- shadow currently covers. Use 0-indexed line + rows like real
@@ -1604,26 +1634,23 @@ test("render shadow skips rows occupied by image placements", function()
trigger_shadow(source)
local after = get_shadow_lines(session.buf)
for _, l in ipairs(after) do
- assert_false(l == target,
- "image-occupied row " .. tostring(target) ..
- " should be absent from the shadow line set")
+ assert_false(l == target, "image-occupied row " .. tostring(target) .. " should be absent from the shadow line set")
end
- assert_eq(#after, #before - 1,
- "shadow should drop exactly the image-occupied row")
+ assert_eq(#after, #before - 1, "shadow should drop exactly the image-occupied row")
vim.api.nvim_win_close(render_win, true)
cleanup_buffer(source)
end)
test("render shadow excludes multi-row image placements entirely", function()
- local source = setup_md_buffer({
+ local source = setup_md_buffer {
"first paragraph line",
"continuation line",
"another continuation",
"tail line",
"",
"next paragraph",
- })
+ }
local source_win = vim.api.nvim_get_current_win()
preview.split()
local session = preview._toggle_sessions[source]
@@ -1632,8 +1659,7 @@ test("render shadow excludes multi-row image placements entirely", function()
vim.api.nvim_win_set_cursor(source_win, { 1, 0 })
trigger_shadow(source)
local before = get_shadow_lines(session.buf)
- assert_true(#before >= 1,
- "paragraph block should produce at least one shadow row")
+ assert_true(#before >= 1, "paragraph block should produce at least one shadow row")
-- Place a 3-row image starting at the first shadow row. Even if the
-- block is shorter than 3 render lines, the placement still claims
@@ -1650,8 +1676,10 @@ test("render shadow excludes multi-row image placements entirely", function()
trigger_shadow(source)
local after = get_shadow_lines(session.buf)
for _, l in ipairs(after) do
- assert_false(l >= start_render and l < start_render + 3,
- "row " .. tostring(l) .. " falls inside the image span and should be excluded")
+ assert_false(
+ l >= start_render and l < start_render + 3,
+ "row " .. tostring(l) .. " falls inside the image span and should be excluded"
+ )
end
vim.api.nvim_win_close(render_win, true)
@@ -1659,6 +1687,4 @@ test("render shadow excludes multi-row image placements entirely", function()
end)
print(string.format("toggle_test: %d passed, %d failed", pass_count, fail_count))
-if fail_count > 0 then
- os.exit(1)
-end
+if fail_count > 0 then os.exit(1) end
diff --git a/tests/tty_test.lua b/tests/tty_test.lua
index b06a88b..e6210dd 100644
--- a/tests/tty_test.lua
+++ b/tests/tty_test.lua
@@ -48,7 +48,7 @@ pcall(ffi.cdef, "int open(const char *path, int flags); int close(int fd);")
test("isatty returns 0 for a regular file fd", function()
local tmpfile = os.tmpname()
local f = io.open(tmpfile, "w")
- f:write("test")
+ f:write "test"
f:close()
local fd = ffi.C.open(tmpfile, 0) -- O_RDONLY
assert_true(fd >= 0, "open regular file should succeed")
@@ -60,7 +60,7 @@ end)
test("ttyname returns nil for a non-tty fd", function()
local tmpfile = os.tmpname()
local f = io.open(tmpfile, "w")
- f:write("test")
+ f:write "test"
f:close()
local fd = ffi.C.open(tmpfile, 0)
local name = ffi.C.ttyname(fd)
@@ -75,8 +75,10 @@ test("_detect_direct returns nil in headless mode", function()
tty.reset()
local result = tty._detect_direct()
-- result can be nil (headless) or a string (real terminal) — both are valid
- assert_true(result == nil or type(result) == "string",
- "_detect_direct should return nil or string, got: " .. type(tostring(result)))
+ assert_true(
+ result == nil or type(result) == "string",
+ "_detect_direct should return nil or string, got: " .. type(tostring(result))
+ )
end)
test("get_tty_path caches result", function()
@@ -100,15 +102,14 @@ test("_detect_socket_peer returns nil when no connected sockets", function()
-- Just verify it doesn't crash and returns nil or a string
tty.reset()
local result = tty._detect_socket_peer()
- assert_true(result == nil or type(result) == "string",
- "_detect_socket_peer should return nil or string")
+ assert_true(result == nil or type(result) == "string", "_detect_socket_peer should return nil or string")
end)
test("_get_socket_peer_pid returns nil for non-socket fd", function()
pcall(ffi.cdef, "int open(const char *path, int flags); int close(int fd);")
local tmpfile = os.tmpname()
local f = io.open(tmpfile, "w")
- f:write("test")
+ f:write "test"
f:close()
local fd = ffi.C.open(tmpfile, 0)
local peer = tty._get_socket_peer_pid(fd)
@@ -123,12 +124,11 @@ end)
if ffi.os == "OSX" then
test("macOS: proc_bsdinfo struct size is 136 bytes", function()
- assert_eq(ffi.sizeof("struct md_proc_bsdinfo"), 136,
- "proc_bsdinfo should be 136 bytes (validates struct layout)")
+ assert_eq(ffi.sizeof "struct md_proc_bsdinfo", 136, "proc_bsdinfo should be 136 bytes (validates struct layout)")
end)
test("macOS: proc_pidinfo succeeds for own pid", function()
- local info = ffi.new("struct md_proc_bsdinfo")
+ local info = ffi.new "struct md_proc_bsdinfo"
local pid = vim.fn.getpid()
local size = ffi.C.proc_pidinfo(pid, 3, 0, info, ffi.sizeof(info))
assert_true(size > 0, "proc_pidinfo should return positive size for own pid")
@@ -137,8 +137,10 @@ if ffi.os == "OSX" then
test("macOS: _get_pid_tty_darwin returns nil or string for own pid", function()
local result = tty._get_pid_tty_darwin(vim.fn.getpid())
- assert_true(result == nil or type(result) == "string",
- "_get_pid_tty_darwin should return nil (headless) or string (terminal)")
+ assert_true(
+ result == nil or type(result) == "string",
+ "_get_pid_tty_darwin should return nil (headless) or string (terminal)"
+ )
end)
test("macOS: devname returns string for valid dev", function()
@@ -167,13 +169,11 @@ if ffi.os == "Linux" then
test("Linux: _get_pid_tty_linux parses stat correctly", function()
local result = tty._get_pid_tty_linux(vim.fn.getpid())
-- In headless mode, tty_nr is likely 0, so result should be nil
- assert_true(result == nil or type(result) == "string",
- "_get_pid_tty_linux should return nil (no tty) or string")
+ assert_true(result == nil or type(result) == "string", "_get_pid_tty_linux should return nil (no tty) or string")
end)
test("Linux: ucred struct size is 12 bytes", function()
- assert_eq(ffi.sizeof("struct md_ucred"), 12,
- "ucred should be 12 bytes (pid + uid + gid)")
+ assert_eq(ffi.sizeof "struct md_ucred", 12, "ucred should be 12 bytes (pid + uid + gid)")
end)
end
@@ -182,6 +182,4 @@ end
-- ============================================================================
print(string.format("\n%d passed, %d failed", pass_count, fail_count))
-if fail_count > 0 then
- os.exit(1)
-end
+if fail_count > 0 then os.exit(1) end
diff --git a/tests/url_hover_test.lua b/tests/url_hover_test.lua
index f37a363..d97481c 100644
--- a/tests/url_hover_test.lua
+++ b/tests/url_hover_test.lua
@@ -60,7 +60,7 @@ end)
local function make_buf_with_url(line_text, url, start_col, end_col)
local buf = vim.api.nvim_create_buf(false, true)
- local ns = vim.api.nvim_create_namespace("url_hover_test")
+ local ns = vim.api.nvim_create_namespace "url_hover_test"
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { line_text })
vim.api.nvim_buf_set_extmark(buf, ns, 0, start_col, {
end_col = end_col,
@@ -97,7 +97,7 @@ end)
test("url_at_mouse: returns nil when extmark has no URL", function()
local buf = vim.api.nvim_create_buf(false, true)
- local ns = vim.api.nvim_create_namespace("url_hover_test2")
+ local ns = vim.api.nvim_create_namespace "url_hover_test2"
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "Some text" })
vim.api.nvim_buf_set_extmark(buf, ns, 0, 0, { end_col = 4, hl_group = "Comment" })
assert_eq(internal.url_at_mouse({ winid = 1, line = 1, column = 2 }, buf, ns), nil, "non-URL extmark ignored")
@@ -159,9 +159,14 @@ end)
test("attach: registers window for hover", function()
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "x" })
- local ns = vim.api.nvim_create_namespace("attach_test")
+ local ns = vim.api.nvim_create_namespace "attach_test"
local win = vim.api.nvim_open_win(buf, false, {
- relative = "editor", width = 5, height = 1, row = 0, col = 0, style = "minimal",
+ relative = "editor",
+ width = 5,
+ height = 1,
+ row = 0,
+ col = 0,
+ style = "minimal",
})
UrlHover.attach(buf, ns, win)
assert_eq(internal.registered[win] ~= nil, true, "window registered")
@@ -170,12 +175,12 @@ test("attach: registers window for hover", function()
vim.api.nvim_win_close(win, true)
-- WinClosed autocmd should clear registration
- vim.wait(50, function() return internal.registered[win] == nil end)
+ vim.wait(50, function()
+ return internal.registered[win] == nil
+ end)
assert_eq(internal.registered[win], nil, "WinClosed cleared registration")
end)
-- Summary
print(string.format("\n%d passed, %d failed", pass_count, fail_count))
-if fail_count > 0 then
- os.exit(1)
-end
+if fail_count > 0 then os.exit(1) end
diff --git a/tests/visual_test_init.lua b/tests/visual_test_init.lua
index b5d0f9f..240de68 100644
--- a/tests/visual_test_init.lua
+++ b/tests/visual_test_init.lua
@@ -7,7 +7,7 @@ local plugin_root = vim.fn.getcwd()
vim.opt.runtimepath:prepend(plugin_root)
-- Load the plugin
-vim.cmd("runtime plugin/md-render.lua")
+vim.cmd "runtime plugin/md-render.lua"
-- Open the test markdown file
vim.cmd("edit " .. plugin_root .. "/tests/fixtures/visual_test.md")
@@ -27,7 +27,7 @@ vim.defer_fn(function()
vim.defer_fn(function()
local f = io.open(signal, "w")
if f then
- f:write("ready\n")
+ f:write "ready\n"
f:close()
end
end, 5000)