diff options
| author | Michael Lingelbach <m.j.lbach@gmail.com> | 2021-01-09 01:25:51 -0800 |
|---|---|---|
| committer | Michael Lingelbach <m.j.lbach@gmail.com> | 2021-01-11 14:49:09 -0800 |
| commit | 8c63f6c919e9e89bce7758e5f93f4e0df4f50269 (patch) | |
| tree | c83b9f6a147b37d346212010e3a08cb88b75a585 /lua | |
| parent | Merge pull request #655 from ckipp01/metals (diff) | |
| download | nvim-lspconfig-8c63f6c919e9e89bce7758e5f93f4e0df4f50269.tar nvim-lspconfig-8c63f6c919e9e89bce7758e5f93f4e0df4f50269.tar.gz nvim-lspconfig-8c63f6c919e9e89bce7758e5f93f4e0df4f50269.tar.bz2 nvim-lspconfig-8c63f6c919e9e89bce7758e5f93f4e0df4f50269.tar.lz nvim-lspconfig-8c63f6c919e9e89bce7758e5f93f4e0df4f50269.tar.xz nvim-lspconfig-8c63f6c919e9e89bce7758e5f93f4e0df4f50269.tar.zst nvim-lspconfig-8c63f6c919e9e89bce7758e5f93f4e0df4f50269.zip | |
Commands: add LspInfo
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/lspconfig.lua | 98 | ||||
| -rw-r--r-- | lua/lspconfig/_lspui.lua | 107 |
2 files changed, 205 insertions, 0 deletions
diff --git a/lua/lspconfig.lua b/lua/lspconfig.lua index 9b9dbcf4..d8444160 100644 --- a/lua/lspconfig.lua +++ b/lua/lspconfig.lua @@ -1,4 +1,5 @@ local configs = require 'lspconfig/configs' +local lspui = require 'lspconfig/_lspui' local M = { util = require 'lspconfig/util'; @@ -18,6 +19,103 @@ end -- script in scriptnames to be executed is lspconfig. function M._root._setup() M._root.commands = { + LspInfo = { + function() + -- These options need to be cached before switching to the floating + -- buffer. + local buf_clients = vim.lsp.buf_get_clients() + local clients = vim.lsp.get_active_clients() + local buffer_filetype = vim.bo.filetype + local buffer_dir = vim.fn.expand('%:p:h') + + local win_info = lspui.percentage_range_window(0.8, 0.7) + local bufnr, win_id = win_info.bufnr, win_info.win_id + + local buf_lines = {} + local header = { + "Available servers:", + "\t"..table.concat(vim.tbl_keys(configs), ', '), + "", + "Clients attached to this buffer: "..tostring(#buf_clients) + } + vim.list_extend(buf_lines, header) + + for _, client in ipairs(buf_clients) do + local client_info = { + "", + "Client: "..tostring(client.id), + "\tname: "..client.name, + "\troot: "..client.workspaceFolders[1].name, + "\tfiletypes: "..table.concat(client.config.filetypes, ', '), + "\tcmd: "..table.concat(client.config.cmd, ', '), + } + vim.list_extend(buf_lines, client_info) + end + + local active_section_header = { + "", + "Total active clients: "..tostring(#clients), + } + vim.list_extend(buf_lines, active_section_header) + for _, client in ipairs(clients) do + local client_info = { + "", + "Client: "..tostring(client.id), + "\tname: "..client.name, + "\troot: "..client.workspaceFolders[1].name, + "\tfiletypes: "..table.concat(client.config.filetypes, ', '), + "\tcmd: "..table.concat(client.config.cmd, ', '), + } + vim.list_extend(buf_lines, client_info) + end + local matching_config_header = { + "", + "Clients that match the current buffer filetype:", + } + local cmd_not_found_msg = "False. Please check your path and ensure the server is installed" + vim.list_extend(buf_lines, matching_config_header) + for _, config in pairs(configs) do + --TODO(mjlbach): This is why the command is slow. + -- We should change config initialization so this is cached (generally) + local config_table = config.make_config(buffer_dir) + + local cmd_is_executable, cmd + if config_table.cmd then + cmd = table.concat(config_table.cmd, " ") + if vim.fn.executable(config_table.cmd[1]) == 1 then + cmd_is_executable = "True" + else + cmd_is_executable = cmd_not_found_msg + end + else + cmd = "cmd not defined" + cmd_is_executable = cmd + end + + for _, filetype_match in ipairs(config_table.filetypes) do + if buffer_filetype == filetype_match then + local matching_config_info = { + "", + "Config: "..config.name, + "\tcmd: "..cmd, + "\tcmd is executable: ".. cmd_is_executable, + "\tidentified root: "..(config_table.root_dir or "None"), + "\tcustom handlers: "..table.concat(vim.tbl_keys(config_table.handlers), ", "), + } + vim.list_extend(buf_lines, matching_config_info) + end + end + end + buf_lines = vim.lsp.util._trim_and_pad(buf_lines, { pad_left = 2, pad_top = 1}) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, buf_lines ) + vim.fn.matchadd("Title", table.concat(vim.tbl_keys(configs), '\\|')) + vim.fn.matchadd("Error", "cmd not defined\\|"..cmd_not_found_msg) + vim.api.nvim_buf_set_keymap(bufnr, 'n', '<esc>', '<cmd>bd<CR>', { noremap = true}) + vim.lsp.util.close_preview_autocmd({"BufHidden", "BufLeave"}, win_id) + end; + "-nargs=?"; + description = '`:LspInfo` Displays info on currently configured and currently active servers'; + }; LspInstall = { function() print("deprecated, see https://github.com/neovim/neovim/wiki/Following-HEAD") diff --git a/lua/lspconfig/_lspui.lua b/lua/lspconfig/_lspui.lua new file mode 100644 index 00000000..609a4c49 --- /dev/null +++ b/lua/lspconfig/_lspui.lua @@ -0,0 +1,107 @@ +-- The following is extracted and modified from plenary.vnim by +-- TJ Devries. It is not a stable API, and is expected to change +-- +local function apply_defaults(original, defaults) + if original == nil then + original = {} + end + + original = vim.deepcopy(original) + + for k, v in pairs(defaults) do + if original[k] == nil then + original[k] = v + end + end + + return original +end + +local win_float = {} + +win_float.default_options = { + winblend = 15, + percentage = 0.9, +} + +function win_float.default_opts(options) + options = apply_defaults(options, win_float.default_options) + + local width = math.floor(vim.o.columns * options.percentage) + local height = math.floor(vim.o.lines * options.percentage) + + local top = math.floor(((vim.o.lines - height) / 2) - 1) + local left = math.floor((vim.o.columns - width) / 2) + + local opts = { + relative = 'editor', + row = top, + col = left, + width = width, + height = height, + style = 'minimal' + } + + return opts +end +--- Create window that takes up certain percentags of the current screen. +--- +--- Works regardless of current buffers, tabs, splits, etc. +--@param col_range number | Table: +-- If number, then center the window taking up this percentage of the screen. +-- If table, first index should be start, second_index should be end +--@param row_range number | Table: +-- If number, then center the window taking up this percentage of the screen. +-- If table, first index should be start, second_index should be end +function win_float.percentage_range_window(col_range, row_range, options) + options = apply_defaults(options, win_float.default_options) + + local win_opts = win_float.default_opts(options) + win_opts.relative = "editor" + + local height_percentage, row_start_percentage + if type(row_range) == 'number' then + assert(row_range <= 1) + assert(row_range > 0) + height_percentage = row_range + row_start_percentage = (1 - height_percentage) / 2 + elseif type(row_range) == 'table' then + height_percentage = row_range[2] - row_range[1] + row_start_percentage = row_range[1] + else + error(string.format("Invalid type for 'row_range': %p", row_range)) + end + + win_opts.height = math.ceil(vim.o.lines * height_percentage) + win_opts.row = math.ceil(vim.o.lines * row_start_percentage) + + local width_percentage, col_start_percentage + if type(col_range) == 'number' then + assert(col_range <= 1) + assert(col_range > 0) + width_percentage = col_range + col_start_percentage = (1 - width_percentage) / 2 + elseif type(col_range) == 'table' then + width_percentage = col_range[2] - col_range[1] + col_start_percentage = col_range[1] + else + error(string.format("Invalid type for 'col_range': %p", col_range)) + end + + win_opts.col = math.floor(vim.o.columns * col_start_percentage) + win_opts.width = math.floor(vim.o.columns * width_percentage) + + local bufnr = options.bufnr or vim.fn.nvim_create_buf(false, true) + local win_id = vim.fn.nvim_open_win(bufnr, true, win_opts) + vim.api.nvim_win_set_buf(win_id, bufnr) + + vim.cmd('setlocal nocursorcolumn') + vim.fn.nvim_win_set_option(win_id, 'winblend', options.winblend) + + return { + bufnr = bufnr, + win_id = win_id, + } +end + +return win_float |
