Skip to content

Commit 3119a11

Browse files
authored
fix(conceal): fix for wrapped lines (#21)
* fix: improve template concealment on wrapped lines (#20) - Use 'inline' virtual text with 'conceal' when 'conceallevel > 0' - Fallback to 'overlay' with padding when 'conceallevel == 0' - Add note to README regarding 'conceallevel' recommendation * fix: prevent duplication of concealed virtual text - Clear namespace for visible range before applying concealment - Use stable IDs for extmarks based on position - Ensure full range concealment when using inline virtual text * fix: format
1 parent d6f3a8d commit 3119a11

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The plugin is in early development.
1111
- Highlight the current block (`if`, `with`, `range`, etc.)
1212
- Jump between the start and end of a block with `%`
1313
- experimental: Overwrite templates with their current values using virtual text (See [Demos](#demos))
14+
- Note: Setting `vim.opt.conceallevel = 2` is recommended for correct handling of wrapped lines.
1415
- experimental: Show hints highlighting the effect of `nindent` and `indent` functions (See [Demos](#demos))
1516

1617
## Keymaps
@@ -52,6 +53,7 @@ Default config:
5253
{
5354
conceal_templates = {
5455
-- enable the replacement of templates with virtual text of their current values
56+
-- note: for better wrapping support, set `vim.opt.conceallevel = 2`
5557
enabled = true, -- this might change to false in the future
5658
},
5759
indent_hints = {

lua/helm-ls/conceal.lua

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,34 @@ end
4242

4343
-- Helper function to set an extmark with the hover result
4444
local function set_extmark(bufnr, start_row, start_col, end_row, end_col, hover_text, original_text)
45-
hover_text = pad_text(hover_text, #original_text)
46-
47-
-- Set conceal for the syntax element
48-
api.nvim_buf_set_extmark(bufnr, ns_id, start_row, start_col, {
49-
end_row = end_row,
50-
end_col = end_col,
51-
virt_text = { { hover_text, "Conceal" } },
52-
virt_text_pos = "overlay",
53-
hl_mode = "blend",
54-
virt_text_hide = true,
55-
})
45+
local conceallevel = vim.opt_local.conceallevel:get()
46+
-- Use a stable ID based on position to avoid duplicates
47+
local id = start_row * 10000 + start_col + 1
48+
49+
if conceallevel > 0 then
50+
-- Set conceal for the syntax element (new approach, handles wrapping)
51+
api.nvim_buf_set_extmark(bufnr, ns_id, start_row, start_col, {
52+
id = id,
53+
end_row = end_row,
54+
end_col = end_col,
55+
virt_text = { { hover_text, "Conceal" } },
56+
virt_text_pos = "inline",
57+
conceal = "",
58+
})
59+
else
60+
-- Fallback for conceallevel = 0 (original approach, has issues with wrapping)
61+
hover_text = pad_text(hover_text, #original_text)
62+
63+
api.nvim_buf_set_extmark(bufnr, ns_id, start_row, start_col, {
64+
id = id,
65+
end_row = end_row,
66+
end_col = end_col,
67+
virt_text = { { hover_text, "Conceal" } },
68+
virt_text_pos = "overlay",
69+
hl_mode = "blend",
70+
virt_text_hide = true,
71+
})
72+
end
5673
end
5774

5875
-- Function to handle LSP hover requests and apply concealment
@@ -76,7 +93,11 @@ local function apply_concealment(bufnr, start_row, start_col, end_row, end_col,
7693

7794
hover_cache[original_text] = hover_text
7895

79-
set_extmark(bufnr, start_row, start_col, end_row, end_col, hover_text, original_text)
96+
-- Re-verify we are still on the same buffer/context if needed,
97+
-- but for now, applying if buffer is still active
98+
if api.nvim_buf_is_valid(bufnr) then
99+
set_extmark(bufnr, start_row, start_col, end_row, end_col, hover_text, original_text)
100+
end
80101
end)
81102
end
82103
end
@@ -101,20 +122,24 @@ local conceal_templates_with_hover = function()
101122
local start_line = vim.fn.line("w0") - 1
102123
local end_line = vim.fn.line("w$") - 1
103124

125+
-- Clear existing extmarks in the visible range to avoid duplication
126+
-- and handle deleted/moved templates
127+
api.nvim_buf_clear_namespace(bufnr, ns_id, start_line, end_line + 1)
128+
104129
for _, match in query:iter_matches(root, bufnr, start_line, end_line, { all = true }) do
105130
for _, nodes in pairs(match) do
106131
local start_row, start_col = nodes[1]:range()
107132
local _, _, end_row, end_col = nodes[#nodes]:range()
108133

109134
if util.is_cursor_on_line(start_row) then
110-
return
135+
goto continue
111136
end
112137

113138
apply_concealment(bufnr, start_row, start_col, end_row, end_col, nodes[1])
139+
::continue::
114140
end
115141
end
116142
end
117-
118143
-- Function to clear extmarks on the cursor's current line
119144
local clear_extmark_if_cursor_on_line = function()
120145
local bufnr = api.nvim_get_current_buf()
@@ -128,6 +153,7 @@ local function update_conceal_templates()
128153
if vim.tbl_isempty(clients) then
129154
return
130155
end
156+
131157
conceal_templates_with_hover()
132158
clear_extmark_if_cursor_on_line()
133159
end

0 commit comments

Comments
 (0)