hephaestus/heph.nvim/lua/heph/conceal.lua

66 lines
2.5 KiB
Lua
Raw Normal View History

--- Conceal `[[NODEID|Name]]` links down to a styled "Name" hyperlink in node
--- buffers (tech-spec §8.4). The node id is structural noise to a reader, so we
--- hide the `[[id|` prefix and the `]]` suffix with conceal extmarks, leaving
--- the label visible and highlighted. `conceallevel=2` + an empty
--- `concealcursor` reveal the raw `[[id|Name]]` on the line the cursor is on, so
--- it stays directly editable. A bare `[[id]]` (briefly, before save→reload
--- canonicalises it) just hides its brackets.
local M = {}
local ns = vim.api.nvim_create_namespace("heph_link_conceal")
--- Recompute conceal extmarks for every `[[…]]` span in `buf`.
function M.refresh(buf)
if not vim.api.nvim_buf_is_valid(buf) then
return
end
vim.api.nvim_buf_clear_namespace(buf, ns, 0, -1)
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
for lnum, line in ipairs(lines) do
local row = lnum - 1
local from = 1
while true do
local s = line:find("[[", from, true) -- 1-based byte of first `[`
if not s then
break
end
local e = line:find("]]", s + 2, true) -- 1-based byte of `]]`
if not e then
break
end
local inner = line:sub(s + 2, e - 1)
local pipe = inner:find("|", 1, true)
-- Byte columns are 0-based for extmarks; end_col is exclusive.
local open_end -- exclusive end of the hidden prefix (`[[` or `[[id|`)
if pipe then
open_end = (s + 1 + pipe) -- 0-based col just past the `|`
else
open_end = s + 1 -- 0-based col just past `[[`
end
-- Hide the prefix, highlight the visible label, hide the closing `]]`.
vim.api.nvim_buf_set_extmark(buf, ns, row, s - 1, { end_col = open_end, conceal = "" })
vim.api.nvim_buf_set_extmark(buf, ns, row, open_end, { end_col = e - 1, hl_group = "HephLink" })
vim.api.nvim_buf_set_extmark(buf, ns, row, e - 1, { end_col = e + 1, conceal = "" })
from = e + 2
end
end
end
--- Enable link conceal for the current window + `buf`: define the highlight,
--- set the window conceal options, refresh now, and refresh on edits.
function M.attach(buf)
vim.api.nvim_set_hl(0, "HephLink", { link = "Underlined", default = true })
vim.wo.conceallevel = 2
vim.wo.concealcursor = "" -- reveal the raw link on the cursor's line
M.refresh(buf)
vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI" }, {
buffer = buf,
callback = function()
M.refresh(buf)
end,
desc = "heph: refresh [[link]] conceal",
})
end
return M