-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: fix non displayed diagnostic when in last line, fix arrow highlight
- Loading branch information
1 parent
abe21bf
commit 06d4249
Showing
4 changed files
with
243 additions
and
255 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
local M = {} | ||
|
||
local extmarks = require('tiny-inline-diagnostic.extmarks') | ||
local utils = require('tiny-inline-diagnostic.utils') | ||
|
||
|
||
--- Function to calculates the maximum width from a list of chunks. | ||
--- @param chunks table: A table representing the chunks of a diagnostic message. | ||
--- @return number: The maximum width among all chunks. | ||
function M.get_max_width_from_chunks(chunks) | ||
local max_chunk_line_length = 0 | ||
|
||
for i = 1, #chunks do | ||
if #chunks[i] > max_chunk_line_length then | ||
max_chunk_line_length = #chunks[i] | ||
end | ||
end | ||
|
||
return max_chunk_line_length | ||
end | ||
|
||
--- Function to generates a header for a diagnostic message chunk. | ||
--- @param message string: The diagnostic message. | ||
--- @param num_chunks number: The total number of chunks the message is split into. | ||
--- @param opts table: The options table, which includes signs for the diagnostic message. | ||
--- @param diag_hi string: The highlight group for the diagnostic message. | ||
--- @param diag_inv_hi string: The highlight group for the diagnostic signs. | ||
--- @return table: A table representing the virtual text array for the diagnostic message header. | ||
function M.get_header_from_chunk( | ||
message, | ||
index_diag, | ||
num_chunks, | ||
need_to_be_under, | ||
opts, | ||
diag_hi, | ||
diag_inv_hi | ||
) | ||
local virt_texts = {} | ||
|
||
virt_texts = { | ||
{ opts.signs.left, diag_inv_hi }, | ||
{ opts.signs.diag, diag_hi } | ||
} | ||
|
||
if not need_to_be_under and index_diag > 1 then | ||
table.insert(virt_texts, 1, { string.rep(" ", #opts.signs.arrow - 2), diag_inv_hi }) | ||
end | ||
|
||
-- if need_to_be_under then | ||
-- virt_texts = { | ||
-- { string.rep(" ", #opts.signs.arrow - 1) .. " ", diag_inv_hi }, | ||
-- { opts.signs.diag, diag_hi }, | ||
-- } | ||
-- end | ||
|
||
local text_after_message = " " | ||
|
||
if num_chunks == 1 then | ||
vim.list_extend(virt_texts, { | ||
{ " " .. message .. " ", diag_hi }, | ||
{ opts.signs.right, diag_inv_hi }, | ||
}) | ||
else | ||
vim.list_extend(virt_texts, { | ||
{ " " .. message .. text_after_message, diag_hi }, | ||
{ string.rep(" ", #opts.signs.right), diag_inv_hi }, | ||
}) | ||
end | ||
|
||
return virt_texts | ||
end | ||
|
||
--- Function to generates the body for a diagnostic message chunk. | ||
--- @param chunk string: The chunk of the diagnostic message. | ||
--- @param opts table: The options table, which includes signs for the diagnostic message. | ||
--- @param need_to_be_under boolean: A flag indicating whether the arrow needs to point upwards. | ||
--- @param diag_hi string: The highlight group for the diagnostic message. | ||
--- @param diag_inv_hi string: The highlight group for the diagnostic signs. | ||
--- @param is_last boolean: A flag indicating whether the chunk is the last one. | ||
--- @return table: A table representing the virtual text array for the diagnostic message body. | ||
function M.get_body_from_chunk( | ||
chunk, | ||
opts, | ||
need_to_be_under, | ||
diag_hi, | ||
diag_inv_hi, | ||
is_last | ||
) | ||
local vertical_sign = opts.signs.vertical | ||
|
||
if is_last then | ||
vertical_sign = opts.signs.vertical_end | ||
end | ||
|
||
local chunk_virtual_texts = { | ||
{ vertical_sign, diag_hi }, | ||
{ " " .. chunk, diag_hi }, | ||
{ " ", diag_hi }, | ||
} | ||
|
||
if not need_to_be_under then | ||
table.insert(chunk_virtual_texts, 1, { string.rep(" ", #opts.signs.arrow - 1), diag_inv_hi }) | ||
else | ||
table.insert(chunk_virtual_texts, 1, { " ", diag_inv_hi }) | ||
end | ||
|
||
if is_last then | ||
vim.list_extend(chunk_virtual_texts, { | ||
{ opts.signs.right, diag_inv_hi }, | ||
}) | ||
end | ||
|
||
return chunk_virtual_texts | ||
end | ||
|
||
function M.get_arrow_from_chunk( | ||
offset, | ||
cursorpos, | ||
opts, | ||
need_to_be_under | ||
) | ||
local arrow = opts.signs.arrow | ||
local chunck = {} | ||
|
||
if need_to_be_under then | ||
arrow = opts.signs.up_arrow | ||
chunck = { | ||
{ " ", "None" }, | ||
{ arrow, "TinyInlineDiagnosticVirtualTextArrow" }, | ||
} | ||
else | ||
chunck = { arrow, "TinyInlineDiagnosticVirtualTextArrow" } | ||
end | ||
|
||
return chunck | ||
end | ||
|
||
--- Function to splits a diagnostic message into chunks for overflow handling. | ||
--- @param message string: The diagnostic message. | ||
--- @param offset number: The offset from the start of the line to the diagnostic position. | ||
--- @param need_to_be_under boolean: A flag indicating whether the diagnostic message needs to be displayed under the line. | ||
--- @param line_length number: The length of the line where the diagnostic message is. | ||
--- @param win_width number: The width of the window where the diagnostic message is displayed. | ||
--- @param opts table: The options table, which includes signs for the diagnostic message and the softwrap option. | ||
--- @return table, boolean: A table representing the chunks of the diagnostic message, and a boolean indicating whether the message needs to be displayed under the line. | ||
function M.get_message_chunks_for_overflow( | ||
message, | ||
offset, | ||
need_to_be_under, | ||
win_width, | ||
opts | ||
) | ||
local signs_total_text_len = #opts.signs.arrow + #opts.signs.right + #opts.signs.left + #opts.signs.diag + 4 | ||
|
||
local distance = win_width - offset - signs_total_text_len | ||
|
||
if distance < opts.options.softwrap then | ||
need_to_be_under = true | ||
distance = win_width - signs_total_text_len | ||
end | ||
|
||
local message_chunk = {} | ||
message_chunk = utils.wrap_text(message, distance) | ||
|
||
return message_chunk, need_to_be_under | ||
end | ||
|
||
function M.get_chunks(opts, diag, plugin_offset, curline, buf) | ||
local win_width = vim.api.nvim_win_get_width(0) | ||
local line_length = #vim.api.nvim_get_current_line() | ||
local offset = 0 | ||
local need_to_be_under = false | ||
local win_option_wrap_enabled = vim.api.nvim_get_option_value("wrap", { win = 0 }) | ||
|
||
local chunks = { diag.message } | ||
|
||
local other_extmarks_offset = extmarks.handle_other_extmarks( | ||
opts, | ||
buf, | ||
curline, | ||
line_length | ||
) | ||
|
||
if win_option_wrap_enabled then | ||
if line_length > win_width - opts.options.softwrap then | ||
need_to_be_under = true | ||
end | ||
end | ||
|
||
if opts.options.break_line.enabled == true then | ||
chunks = {} | ||
chunks = utils.wrap_text(diag.message, opts.options.break_line.after) | ||
elseif opts.options.overflow.mode == "wrap" then | ||
if need_to_be_under then | ||
offset = 0 | ||
else | ||
offset = line_length | ||
end | ||
|
||
chunks, need_to_be_under = M.get_message_chunks_for_overflow( | ||
diag.message, | ||
offset + plugin_offset + other_extmarks_offset, | ||
need_to_be_under, | ||
win_width, opts | ||
) | ||
elseif opts.options.overflow.position == "none" then | ||
chunks = { " " .. diag.message } | ||
end | ||
|
||
|
||
return chunks, { | ||
offset = offset, | ||
offset_win_col = other_extmarks_offset + plugin_offset, | ||
need_to_be_under = need_to_be_under | ||
} | ||
end | ||
|
||
return M |
Oops, something went wrong.