aboutsummaryrefslogtreecommitdiff
path: root/init.lua
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2024-04-25 17:51:02 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2024-04-25 20:26:05 +0200
commit53c6d728d0f39e361a1922f77f45786616f69f1c (patch)
tree6310ca3db14a44d2e3b0b4bfc740a7e2c6c4c8a1 /init.lua
parent036a656fbdd2a21d09746a8dcfb7a71abab47b62 (diff)
downloadvis-lspc-53c6d728d0f39e361a1922f77f45786616f69f1c.tar.gz
vis-lspc-53c6d728d0f39e361a1922f77f45786616f69f1c.zip
support highlighting line numbers using vis:style_pos
Replace the hacky style_lineno code with the new vis:style_pos API probably included in upcoming vis v0.9.
Diffstat (limited to 'init.lua')
-rw-r--r--init.lua69
1 files changed, 48 insertions, 21 deletions
diff --git a/init.lua b/init.lua
index eaadc1b..1b048f5 100644
--- a/init.lua
+++ b/init.lua
@@ -597,9 +597,34 @@ local function vis_apply_workspaceEdit(_, _, workspaceEdit)
end
end
+-- translate file line number to the relative row the line is displayed in the view of a window
+-- returns an integer relative to the window if line is in view (starting at 1)
+-- returns nil otherwise
+local function file_lineno_to_viewport_lineno(win, file_lineno)
+ -- The line is not in the current viewport
+ if file_lineno < win.viewport.lines.start or file_lineno > win.viewport.lines.finish then
+ return nil
+ end
+
+ -- The line is in the viewport and there is no wrapped line
+ if win.viewport.lines.finish - win.viewport.lines.start == win.viewport.height then
+ return file_lineno - win.viewport.lines.start
+ else -- Determine the position in the viewport considering possible prior wrapped lines
+ local view_lineno = 0
+ for n = win.viewport.lines.start, file_lineno do
+ view_lineno = view_lineno + 1
+ -- Wrapped line this shifts our displayed line down
+ if #win.file.lines[n] > win.viewport.width then
+ view_lineno = view_lineno + #win.file.lines[n] // win.viewport.width
+ end
+ end
+ return view_lineno
+ end
+end
+
local function lspc_highlight_diagnostics(win, diagnostics, style)
if not style then
- style = lspc.diagnostic_style_id
+ style = lspc.diagnostic_style_id or win.STYLE_LEXER_MAX
end
local level_mapping = {
@@ -611,7 +636,7 @@ local function lspc_highlight_diagnostics(win, diagnostics, style)
for _, diagnostic in ipairs(diagnostics) do
local diagnostic_style = level_mapping[diagnostic.severity] or level_mapping[1]
- assert(win:style_define(lspc.diagnostic_style_id, diagnostic_style))
+ assert(win:style_define(style, diagnostic_style))
if lspc.highlight_diagnostics == 'range' then
local range = diagnostic.vis_range
@@ -625,24 +650,27 @@ local function lspc_highlight_diagnostics(win, diagnostics, style)
end
elseif lspc.highlight_diagnostics == 'line' then
- if not win.style_lineno then
- lspc_err('Vis build does not support style_lineno')
+ if not win.style_pos then
+ lspc_err('Vis build does not support style_pos')
return
end
- local start_line = diagnostic.range.start.line + 1
- local end_line = diagnostic.range['end'].line + 1
+ local start_line = diagnostic.range.start.line
+ local end_line = diagnostic.range['end'].line
for line = start_line, end_line, 1 do
- win:style_lineno(style, line)
+ local row = file_lineno_to_viewport_lineno(win, line)
+ if row then
+ -- Heuristic how many cells need to be styled
+ -- (at least one plus the decimal places of the line number).
+ for i = 0, #('' .. line) do
+ win:style_pos(style, i, row)
+ end
+ end
end
end
end
end
-local function lspc_clear_highlight_diagnostics(win, diagnostics)
- lspc_highlight_diagnostics(win, diagnostics, win.STYLE_DEFAULT)
-end
-
-- send a rpc message to a language server
local function ls_rpc(ls, req)
req.jsonrpc = '2.0'
@@ -1047,11 +1075,7 @@ local function lspc_handle_publish_diagnostics(ls, uri, diagnostics)
diagnostic.content = vis.win.file:content(diagnostic.vis_range)
end
- if file.diagnostics then
- lspc_clear_highlight_diagnostics(vis.win, file.diagnostics)
- end
file.diagnostics = diagnostics
-
lspc.log('remembered ' .. #diagnostics .. ' diagnostics for ' .. file_path)
else
lspc.log('Diagnostics for not opened file' .. file_path)
@@ -1620,20 +1644,20 @@ vis:command_register('lspc-show-diagnostics', function(argv, _, win)
end)
-- vis-lspc event hooks
-
vis.events.subscribe(vis.events.WIN_OPEN, function(win)
if lspc.autostart and win.syntax then
ls_start_server(win.syntax)
end
end)
-vis.events.subscribe(vis.events.WIN_HIGHLIGHT, function(win)
- local ls = lspc_get_usable_ls(win.syntax)
- if not ls then
+local function highlight_event()
+ local win = vis.win
+ if not win or not win.file then
return
end
- if not win.file then
+ local ls = lspc_get_usable_ls(win.syntax)
+ if not ls then
return
end
@@ -1641,7 +1665,10 @@ vis.events.subscribe(vis.events.WIN_HIGHLIGHT, function(win)
if open_file and open_file.diagnostics and lspc.highlight_diagnostics then
lspc_highlight_diagnostics(win, open_file.diagnostics)
end
-end)
+end
+
+vis.events.subscribe(vis.events.WIN_HIGHLIGHT, highlight_event)
+vis.events.subscribe(vis.events.UI_DRAW, highlight_event)
vis.events.subscribe(vis.events.FILE_OPEN, function(file)
local win = vis.win