commit 027486a55df60343e0f59a7f2ad69f70fd6bef6f
parent dbb62eeac74b762a2f352ef03442cec9fd1a922d
Author: Thomas Vigouroux <thomas.vigouroux@protonmail.com>
Date: Thu, 25 Aug 2022 13:38:43 +0200
feat(lsp): enhance status update
Diffstat:
2 files changed, 128 insertions(+), 25 deletions(-)
diff --git a/lua/lsp_config.lua b/lua/lsp_config.lua
@@ -8,36 +8,18 @@ vim.diagnostic.config {
vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, { border = 'rounded' })
vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with(vim.lsp.handlers.hover, { border = 'rounded' })
-local ignore_messages = {
- ltex = true,
-}
-
-local function progress_handle(infos)
- local new_messages = vim.lsp.util.get_progress_messages()
- for _, msg in ipairs(new_messages) do
- if not ignore_messages[msg.name] then
- if msg.message and not msg.done then
- vim.notify(string.format("[%s] %s ... %s", msg.name, msg.title, msg.message))
- elseif msg.done then
- vim.notify(string.format("[%s] %s ... DONE", msg.name, msg.title))
- end
- end
- end
- return false
-end
-
-vim.api.nvim_create_autocmd({ "User" }, {
- pattern = "LspProgressUpdate",
- callback = progress_handle
-})
+require"lsp_status"
local function on_attach(client, bufnr)
- local function set_keymap(lhs, func)
+ local function set_keymap(lhs, func, ...)
+ local args = { ... }
vim.keymap.set("n", lhs, "", {
remap = false,
silent = true,
buffer = bufnr,
- callback = func
+ callback = function()
+ func(unpack(args))
+ end
})
end
@@ -58,7 +40,7 @@ local function on_attach(client, bufnr)
set_keymap('[d', vim.diagnostic.goto_prev)
set_keymap(']d', vim.diagnostic.goto_next)
set_keymap('<Leader>q', vim.diagnostic.setqflist)
- set_keymap('<Leader>=', function() vim.lsp.buf.format { async = true } end)
+ set_keymap('<Leader>=', vim.lsp.buf.format, { async = true })
set_keymap('gR', require "telescope.builtin".lsp_references)
set_keymap('<Leader>s', require "telescope.builtin".lsp_dynamic_workspace_symbols)
diff --git a/lua/lsp_status.lua b/lua/lsp_status.lua
@@ -0,0 +1,121 @@
+local ns = vim.api.nvim_create_namespace "lsp-status"
+
+local ignore_messages = {
+ ltex = true,
+}
+
+local status = {
+ buf_nr = nil,
+ win_nr = nil,
+ active = {}
+}
+
+local status_width = 50
+
+function status.create_win()
+ if not status.win_nr then
+ vim.notify "Create"
+ status.buf_nr = vim.api.nvim_create_buf(false, true);
+ status.win_nr = vim.api.nvim_open_win(status.buf_nr, false, {
+ focusable = false,
+ style = "minimal",
+ border = "none",
+ noautocmd = true,
+ relative = "editor",
+ anchor = "NE",
+ width = status_width,
+ height = 3,
+ row = 0,
+ col = vim.o.columns,
+ })
+ end
+end
+
+function status.maybe_delete_win(force)
+ if force or vim.tbl_isempty(status.active) then
+ vim.api.nvim_win_close(status.win_nr, true)
+ status.win_nr = nil
+ end
+end
+
+local function adjust_width(src, width)
+ if #src > width then
+ return string.sub(src, 1, width - 3) .. "..."
+ else
+ local acc = src
+ while #acc < width do
+ acc = " " .. acc
+ end
+
+ return acc
+ end
+end
+
+local function format(msg, width)
+ if msg.message then
+ local tmp = string.format("%s (%s)", msg.title, msg.message)
+ if #tmp > width then
+ return adjust_width(msg.title, width)
+ else
+ return adjust_width(tmp, width)
+ end
+ else
+ return adjust_width(msg.title, width)
+ end
+end
+
+function status.redraw()
+ status.create_win()
+
+ if not vim.tbl_isempty(status.active) then
+ local lines = {}
+ local title_lines = {}
+
+ -- For each lsp, print the message
+ for name, msg in pairs(status.active) do
+ table.insert(lines, format(msg, status_width))
+ table.insert(lines, adjust_width(name, status_width))
+
+ title_lines[#lines] = true
+ end
+
+ vim.api.nvim_buf_set_lines(status.buf_nr, 0, -1, false, lines)
+
+ -- Then highlight the lines
+ for i = 1, vim.api.nvim_buf_line_count(status.buf_nr) do
+ local hl_name
+ if title_lines[i] then
+ hl_name = "Title"
+ else
+ hl_name = "NonText"
+ end
+ vim.api.nvim_buf_add_highlight(status.buf_nr, ns, hl_name, i - 1, 0, -1)
+ end
+ else
+ status.maybe_delete_win()
+ end
+end
+
+function status.handle(msg)
+ if msg.done then
+ status.active[msg.name] = nil
+ else
+ status.active[msg.name] = msg
+ end
+ vim.schedule(status.redraw)
+end
+
+local function progress_handle()
+ local new_messages = vim.lsp.util.get_progress_messages()
+ for _, msg in ipairs(new_messages) do
+ if not ignore_messages[msg.name] and msg.progress then
+ status.handle(msg)
+ end
+ end
+ return false
+end
+
+vim.api.nvim_create_autocmd({ "User" }, {
+ pattern = "LspProgressUpdate",
+ callback = progress_handle
+})