From 7c428386d812b2298c30c3b4af41fa5d58234b37 Mon Sep 17 00:00:00 2001 From: Frank Zechert Date: Thu, 25 Jun 2026 02:44:53 +0200 Subject: [PATCH] added language server info output --- lua/lsp/init.lua | 202 ++++++++++++++++++++++++++++++++++++--------- lua/lsp/lua_ls.lua | 75 +++++++++++++++++ 2 files changed, 236 insertions(+), 41 deletions(-) create mode 100644 lua/lsp/lua_ls.lua diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index c8b3060..e79a7ae 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -33,48 +33,168 @@ vim.pack.add({ { src = "https://github.com/neovim/nvim-lspconfig" }, }) -vim.lsp.config("lua_ls", { - on_init = function(client) - if client.workspace_folders then - local path = client.workspace_folders[1].name - if - path ~= vim.fn.stdpath("config") - and ( - vim.uv.fs_stat(path .. "/.luarc.json") - or vim.uv.fs_stat(path .. "/.luarc.jsonc") - ) - then - -- Path is not neovim's config folder and - -- the file .luarc.json or .luarc.jsonc exists - -- in the directory -> exit function and skip custom - -- configuration of the client below - return +require("lsp.lua_ls") + +local function run_healthcheck(section) + local before = {} + for _, b in ipairs(vim.api.nvim_list_bufs()) do + before[b] = true + end + + vim.cmd("silent checkhealth " .. section) + + local after = vim.api.nvim_list_bufs() + local health_buf = nil + + for _, b in ipairs(after) do + if not before[b] then + health_buf = b + break + end + end + + if not health_buf then + return { "Could not capture :checkhealth vim.lsp output" } + end + + -- Read lines + local lines = vim.api.nvim_buf_get_lines(health_buf, 0, -1, false) + + -- Close the health window + for _, win in ipairs(vim.api.nvim_list_wins()) do + if vim.api.nvim_win_get_buf(win) == health_buf then + vim.api.nvim_win_close(win, true) + end + end + + return lines +end + +local function get_all_treesitter_languages() + local bufnr = 0 + local ok, parser = pcall(vim.treesitter.get_parser, bufnr) + if not ok or not parser then + return {} + end + + local langs = { parser:lang() } + for _, child in ipairs(parser:children()) do + table.insert(langs, child:lang()) + end + return langs +end + +local function get_treesitter_status() + local bufnr = 0 + local ok, parser = pcall(vim.treesitter.get_parser, bufnr) + + if not ok or not parser then + return { + "Treesitter:", + " active: no", + " parsers: none", + } + end + + local langs = get_all_treesitter_languages() + return { + "Treesitter:", + " active: yes", + " parsers: " .. table.concat(langs, ", "), + } +end + + +local function show_lsp_details() + local popup_buffer = vim.api.nvim_create_buf(false, true) + local lsp_clients = vim.lsp.get_clients({ bufnr = 0 }) + local lines = {} + + -- Treesitter status + table.insert(lines, "Treesitter Status") + table.insert(lines, "=================") + local ts = get_treesitter_status() + for _, l in ipairs(ts) do + table.insert(lines, l) + end + + table.insert(lines, "") + if #lsp_clients == 0 then + table.insert(lines, "No LSP clients attached.") + else + table.insert(lines, "Active LSP Clients:") + table.insert(lines, "===================") + for _, client in ipairs(lsp_clients) do + table.insert(lines, "") + table.insert(lines, "• " .. client.name) + + -- Root folders + local roots = {} + if client.workspace_folders then + for _, workspace_folder in ipairs(client.workspace_folders) do + table.insert(roots, workspace_folder.name or workspace_folder.uri or "") + end + end + + if #roots > 0 then + table.insert(lines, " Roots:") + for _, root in ipairs(roots) do + table.insert(lines, " - " ..root) + end + else + table.insert(lines, " Roots: none") + end + + -- Capabilities + table.insert(lines, " Capabilities:") + for capability, _ in pairs(client.server_capabilities or {}) do + table.insert(lines, " - " .. capability) end end + end - client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, { - runtime = { - -- neovim uses LuaJIT runtime - version = "LuaJIT", - -- find lua modules the same way neovim does - path = { - "lua/?.lua", - "lua/?/init.lua", - } - }, - -- make the server aware of neovim runtime files - workspace = { - checkThirdParty = false, - library = { - vim.env.VIMRUNTIME, - -- for LSP settings type annotations - vim.api.nvim_get_runtime_file("lua/lspconfig", false)[1], - } - } - }) - end, - settings = { - Lua = {} - } + table.insert(lines, "") + table.insert(lines, "Health Check (vim.lsp):") + table.insert(lines, "=======================") + local health_lines = run_healthcheck("vim.lsp") + for _, l in ipairs(health_lines) do + table.insert(lines, " " .. l) + end + + table.insert(lines, "") + table.insert(lines, "Health Check (vim.treesitter):") + table.insert(lines, "=======================") + local health_lines = run_healthcheck("vim.treesitter") + for _, l in ipairs(health_lines) do + table.insert(lines, " " .. l) + end + + + vim.api.nvim_buf_set_lines(popup_buffer, 0, -1, false, lines) + vim.api.nvim_set_option_value("modifiable", false, { buf = popup_buffer }) + vim.api.nvim_set_option_value("readonly", true, { buf = popup_buffer }) + local width = math.floor(vim.o.columns * 0.6) + local height = math.floor(vim.o.lines * 0.6) + local row = math.floor((vim.o.lines - height) / 2) + local col = math.floor((vim.o.columns - width) / 2) + + local window = vim.api.nvim_open_win(popup_buffer, true, { + relative = "editor", + style = "minimal", + border = vim.g.ui.popupborder, + row = row, + col = col, + width = width, + height = height, + }) + + vim.keymap.set("n", "q", function() + if vim.api.nvim_win_is_valid(window) then + vim.api.nvim_win_close(window, true) + end + end, { buffer = popup_buffer, nowait = true, desc = "Close Window" }) +end + +vim.keymap.set("n", "li", show_lsp_details, { + desc = "Show detailed LSP info in a float" }) -vim.lsp.enable({ "lua_ls" }) diff --git a/lua/lsp/lua_ls.lua b/lua/lsp/lua_ls.lua new file mode 100644 index 0000000..3948788 --- /dev/null +++ b/lua/lsp/lua_ls.lua @@ -0,0 +1,75 @@ +--[[ + + +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣾⣷⣦⣄⡀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⡀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⡀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠚⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠗⢀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣄⡉⠓⠦⣌⡙⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⢋⣡⠴⠚⢉⣠⣤⣀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⣶⣿⣿⣿⣿⣿⣷⣦⣄⡉⠓⠦⣌⡙⠻⢿⣿⣿⣿⣿⣿⣿⡿⠟⢋⣡⠴⠚⢉⣠⣴⣾⣿⣿⣿⣿⣿⣶⣤ +⠀⠀⠀⠀⠀⠀⠀⠀⠐⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⡉⠓⠦⣌⡙⠻⠟⢋⣡⠴⠚⢉⣠⣴⣾⣿⣿⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⠂ +⠀⠀⠀⠀⢀⣠⣴⣆⡈⠻⢿⣿⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⡉⠃⠘⢉⣠⣴⣾⣿⣿⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⣿⡿⠟⢁⣰⣦⣄⡀ +⠀⠀⠐⠾⣿⣿⣿⣿⣿⣷⣦⣌⡙⠻⢿⣿⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⣿⡿⠟⢋⣡⣴⣾⣿⣿⣿⣿⣿⠷⠂ +⠀⢸⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣌⡙⠻⢿⣿⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⣿⡿⠟⢋⣡⣴⣾⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⡇ +⠀⢸⣿⣿⣿⣿⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣌⡙⠻⢿⣿⣷⣦⣄⡉⠛⠿⠿⠛⢉⣠⣴⣾⣿⡿⠟⢋⣡⣴⣾⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⣿⣿⣿⣿⡇ +⠀⠀⠉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣌⡙⠻⢿⣿⣷⡆⢰⣾⣿⡿⠟⢋⣡⣴⣾⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⣿⣿⣿⣿⣿⠿⠛⠉ +⠀⠀⠀⠀⠀⠀⠉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣌⡙⠃⠘⢋⣡⣴⣾⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⣿⣿⣿⣿⣿⠿⠛⠉ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⣿⣿⣿⣿⣿⠿⠛⠉ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣄⡉⠛⠿⣿⣿⣿⣿⠿⠛⢉⣠⣴⣾⣿⣿⣿⣿⣿⠿⠛⠉ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⣿⣿⣿⣿⣿⣷⣦⣄⡉⢉⣠⣴⣾⣿⣿⣿⣿⣿⠿⠛⠉ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⣿⣿⣿⣿⡇⢸⣿⣿⣿⣿⠿⠛⠉ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⡇⢸⠿⠛⠉ + +__ _ _ +/ _|___ ___| |_ __ _ ___| | __ +| ||_ /____/ __| __/ _` |/ __| |/ / +| _/ /_____\__ \ || (_| | (__| < +|_|/___| |___/\__\__,_|\___|_|\_\ + +Neovim v0.12 configuration +(C) Frank Zechert 2026 +]] + +vim.lsp.config("lua_ls", { + on_init = function(client) + if client.workspace_folders then + local path = client.workspace_folders[1].name + if + path ~= vim.fn.stdpath("config") + and ( + vim.uv.fs_stat(path .. "/.luarc.json") + or vim.uv.fs_stat(path .. "/.luarc.jsonc") + ) + then + -- Path is not neovim's config folder, or has custom + -- lua language server configuration, skip custom client configuration + return + end + end + client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, { + runtime = { + -- neovim uses LuaJIT runtime + version = "LuaJIT", + -- find lua modules the same way neovim does + path = { + "lua/?.lua", + "lua/?/init.lua", + } + }, + -- make the server aware of neovim runtime files + workspace = { + checkThirdParty = false, + library = { + vim.env.VIMRUNTIME, + -- for LSP settings type annotations + vim.api.nvim_get_runtime_file("lua/lspconfig", false)[1], + } + } + }) + end, + settings = { + Lua = {} + } + }) + + vim.lsp.enable({ "lua_ls" })