Skip to content

Commit

Permalink
perf: improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
qvalentin committed Aug 26, 2024
1 parent 98f4353 commit 76b231e
Showing 1 changed file with 102 additions and 44 deletions.
146 changes: 102 additions & 44 deletions lua/helm-ls/conceal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,133 @@ local lsp = vim.lsp
local api = vim.api
local ns_id = api.nvim_create_namespace("conceal_ns")

M.conceal_templates_with_hover = function()
-- Debounce timer
local debounce_timer = nil

-- Cache to store hover results
local hover_cache = {}

-- Function to check if the cursor is on the same line as the node
local function is_cursor_on_line(start_row)
local cursor_row = unpack(api.nvim_win_get_cursor(0))
return (cursor_row - 1) == start_row
end

-- Function to extract hover text from the LSP result
local function extract_hover_text(contents)
local markdown_lines = lsp.util.convert_input_to_markdown_lines(contents)
markdown_lines = lsp.util.trim_empty_lines(markdown_lines)

if vim.tbl_isempty(markdown_lines) then
return nil
end

return markdown_lines[3] or markdown_lines[2] or markdown_lines[1]
end

-- Function to pad hover text to match the length of the original text
local function pad_text(hover_text, original_length)
if #hover_text < original_length then
hover_text = hover_text .. string.rep(" ", original_length - #hover_text)
end
return hover_text
end

-- Helper function to request hover information from the LSP
local function request_hover(bufnr, line, col, callback)
lsp.buf_request(bufnr, "textDocument/hover", {
textDocument = lsp.util.make_text_document_params(),
position = { line = line, character = col },
}, callback)
end

-- Helper function to set an extmark with the hover result
local function set_extmark(bufnr, start_row, start_col, end_row, end_col, hover_text, original_text)
hover_text = pad_text(hover_text, #original_text)

-- Set conceal for the syntax element
api.nvim_buf_set_extmark(bufnr, ns_id, start_row, start_col, {
end_row = end_row,
end_col = end_col,
virt_text = { { hover_text, "Conceal" } },
virt_text_pos = "overlay",
hl_mode = "blend",
virt_text_hide = true,
})
end

-- Function to handle LSP hover requests and apply concealment
local function apply_concealment(bufnr, start_row, start_col, end_row, end_col, node)
local original_text = vim.treesitter.get_node_text(node, bufnr)
-- Use cached hover result if available
local hover_text = hover_cache[original_text]
if hover_text then
set_extmark(bufnr, start_row, start_col, end_row, end_col, hover_text, original_text)
else
request_hover(bufnr, end_row, end_col - 1, function(err, result, ctx, _)
if err or not result or not result.contents then
return
end

hover_text = extract_hover_text(result.contents)
hover_cache[original_text] = hover_text

set_extmark(bufnr, start_row, start_col, end_row, end_col, hover_text, original_text)
end)
end
end

-- Main function to conceal templates with hover
local conceal_templates_with_hover = function()
local bufnr = api.nvim_get_current_buf()
local parser = vim.treesitter.get_parser(bufnr, vim.bo.filetype)
local root = parser:parse()[1]:root()

-- Define the Tree-sitter query for the syntax you want to conceal
local query = vim.treesitter.query.parse(
vim.bo.filetype,
[[
((selector_expression) ["}}" "|" ]) @selector
]]
)

for _, match in query:iter_matches(root, bufnr, 0, -1) do
-- Get the range of visible lines in the current window
local start_line = vim.fn.line("w0") - 1 -- Convert to 0-based index
local end_line = vim.fn.line("w$") - 1 -- Convert to 0-based index

print("start_line: " .. start_line)
print("end_line: " .. end_line)

for _, match in query:iter_matches(root, bufnr, start_line, end_line) do
for id, node in pairs(match) do
local start_row, start_col, end_row, end_col = node:range()

local cursor_row = unpack(api.nvim_win_get_cursor(0))
if cursor_row - 1 == start_row then
if is_cursor_on_line(start_row) then
return
end

-- Request hover information from the LSP
lsp.buf_request(bufnr, "textDocument/hover", {
textDocument = lsp.util.make_text_document_params(),
position = { line = end_row, character = end_col - 1 },
}, function(err, result, ctx, _)
if err or not result or not result.contents then
return
end

local markdown_lines = lsp.util.convert_input_to_markdown_lines(result.contents)
markdown_lines = lsp.util.trim_empty_lines(markdown_lines)
if vim.tbl_isempty(markdown_lines) then
return
end

local original_text = vim.treesitter.get_node_text(node, bufnr)

local hover_text = markdown_lines[1] -- Using the first line of the hover result
if #markdown_lines >= 3 then
hover_text = markdown_lines[3] -- If there are more lines, use the third one
end

-- Pad the hover text with spaces if it's shorter than the original text
if #hover_text < #original_text then
hover_text = hover_text .. string.rep(" ", #original_text - #hover_text)
end

-- Set conceal for the syntax element
api.nvim_buf_set_extmark(bufnr, ns_id, start_row, start_col, {
end_row = end_row,
end_col = end_col,
virt_text = { { hover_text, "Conceal" } }, -- Replace node content with the hover result
virt_text_pos = "overlay", -- Overlay the text, replacing the original content
hl_mode = "blend", -- Blend with the existing text's highlight
virt_text_hide = true, -- Hide virt_text when selected
})
end)
apply_concealment(bufnr, start_row, start_col, end_row, end_col, node)
end
end
end

M.clear_extmark_if_cursor_on_line = function()
-- Debounced function call
local function debounce_conceal_templates_with_hover()
if debounce_timer then
debounce_timer:stop()
end
debounce_timer = vim.defer_fn(function()
conceal_templates_with_hover()
end, 500) -- 200ms debounce time
end

-- Function to clear extmarks on the cursor's current line
local clear_extmark_if_cursor_on_line = function()
local bufnr = api.nvim_get_current_buf()
local cursor_row = unpack(api.nvim_win_get_cursor(0))

-- Clear the extmark for the line where the cursor is located
api.nvim_buf_clear_namespace(bufnr, ns_id, cursor_row - 1, cursor_row)
end

M.conceal_templates_with_hover = conceal_templates_with_hover
M.clear_extmark_if_cursor_on_line = clear_extmark_if_cursor_on_line
return M

0 comments on commit 76b231e

Please sign in to comment.