diff options
| author | kylo252 <59826753+kylo252@users.noreply.github.com> | 2021-08-25 13:34:16 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-25 04:34:16 -0700 |
| commit | d6e78ef013a57761226df5b842d52912f15011dd (patch) | |
| tree | e7794a840e69dd30631619a2df8fe0cb85889b98 /lua/lspconfig/ui | |
| parent | [docgen] Update CONFIG.md (diff) | |
| download | nvim-lspconfig-d6e78ef013a57761226df5b842d52912f15011dd.tar nvim-lspconfig-d6e78ef013a57761226df5b842d52912f15011dd.tar.gz nvim-lspconfig-d6e78ef013a57761226df5b842d52912f15011dd.tar.bz2 nvim-lspconfig-d6e78ef013a57761226df5b842d52912f15011dd.tar.lz nvim-lspconfig-d6e78ef013a57761226df5b842d52912f15011dd.tar.xz nvim-lspconfig-d6e78ef013a57761226df5b842d52912f15011dd.tar.zst nvim-lspconfig-d6e78ef013a57761226df5b842d52912f15011dd.zip | |
feat(ui): lspinfo: better layout #1184)
Diffstat (limited to 'lua/lspconfig/ui')
| -rw-r--r-- | lua/lspconfig/ui/lspinfo.lua | 273 | ||||
| -rw-r--r-- | lua/lspconfig/ui/windows.lua | 14 |
2 files changed, 174 insertions, 113 deletions
diff --git a/lua/lspconfig/ui/lspinfo.lua b/lua/lspconfig/ui/lspinfo.lua index 90839291..6cbf94f2 100644 --- a/lua/lspconfig/ui/lspinfo.lua +++ b/lua/lspconfig/ui/lspinfo.lua @@ -1,5 +1,117 @@ local configs = require 'lspconfig/configs' local windows = require 'lspconfig/ui/windows' +local util = require 'lspconfig/util' + +local indent = ' ' +local cmd_not_found_msg = 'False. Please check your path and ensure the server is installed' + +local function trim_whitespace(cmd) + local trimmed_cmd = {} + for _, str in pairs(cmd) do + table.insert(trimmed_cmd, str:match '^%s*(.*)') + end + return trimmed_cmd +end + +local function indent_lines(lines, offset) + return vim.tbl_map(function(val) + return offset .. val + end, lines) +end + +local function remove_newlines(cmd) + cmd = trim_whitespace(cmd) + cmd = table.concat(cmd, ' ') + cmd = vim.split(cmd, '\n') + cmd = trim_whitespace(cmd) + cmd = table.concat(cmd, ' ') + return cmd +end + +local function autostart_to_str(autostart) + local autostart_status = 'true' + if autostart == false then + autostart_status = 'false' + end + return autostart_status +end + +local function make_config_info(config) + local config_info = {} + config_info.name = config.name + if config.cmd then + config_info.cmd = remove_newlines(config.cmd) + if vim.fn.executable(config.cmd[1]) == 1 then + config_info.cmd_is_executable = 'true' + else + config_info.cmd_is_executable = cmd_not_found_msg + end + config_info.cmd = config.cmd[1] + config_info.cmd_args = '[' .. table.concat(vim.list_slice(config.cmd, 2, #config.cmd), ', ') .. ']' + else + config_info.cmd = 'cmd not defined' + config_info.cmd_is_executable = 'NA' + config_info.cmd_args = 'NA' + end + local buffer_dir = vim.fn.expand '%:p:h' + config_info.root_dir = config.get_root_dir(buffer_dir) or 'NA' + config_info.autostart = autostart_to_str(config._autostart) + config_info.handlers = table.concat(vim.tbl_keys(config.handlers), ', ') + config_info.filetypes = '[' .. table.concat(config.filetypes or {}, ', ') .. ']' + + local lines = { + '', + 'Config: ' .. config_info.name, + '\tfiletypes: ' .. config_info.filetypes, + '\troot directory: ' .. config_info.root_dir, + '\tcommand: ' .. config_info.cmd, + '\targ[s]: ' .. config_info.cmd_args, + '\tcmd is executable: ' .. config_info.cmd_is_executable, + '\tautostart: ' .. config_info.autostart, + '\tcustom handlers: ' .. config_info.handlers, + } + return lines +end + +local function get_other_matching_providers(filetype) + local active_clients_list = util.get_active_client_by_ft(filetype) + local other_matching_configs = {} + for _, config in pairs(configs) do + if not vim.tbl_contains(active_clients_list, config.name) then + table.insert(other_matching_configs, config) + end + end + return other_matching_configs +end + +local function make_client_info(client) + local client_info = {} + + client_info.cmd = client.config.cmd[1] + client_info.cmd_args = '[' .. table.concat(vim.list_slice(client.config.cmd, 2, #client.config.cmd), ', ') .. ']' + client_info.root_dir = client.workspaceFolders[1].name + client_info.filetypes = table.concat(client.config.filetypes or {}, ', ') + client_info.autostart = autostart_to_str(client._autostart) + + local lines = { + '', + 'Client: ' .. client.name .. ' (id: ' .. tostring(client.id) .. ' pid: ' .. tostring(client.rpc.pid) .. ')', + '\tfiletypes: ' .. client_info.filetypes, + '\tautostart: ' .. client_info.autostart, + '\troot directory: ' .. client_info.root_dir, + '\tcommand: ' .. client_info.cmd, + '\targ[s]: ' .. client_info.cmd_args, + } + if client.config.lspinfo then + local server_specific_info = client.config.lspinfo(client.config) + server_specific_info = vim.tbl_map(function(val) + return indent .. '\t' .. val + end, server_specific_info) + lines = vim.list_extend(lines, server_specific_info) + end + + return lines +end return function() -- These options need to be cached before switching to the floating @@ -7,7 +119,6 @@ return function() 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 = windows.percentage_range_window(0.8, 0.7) local bufnr, win_id = win_info.bufnr, win_info.win_id @@ -20,8 +131,13 @@ return function() end local header = { + '', + '', + 'Language Server Protocol (LSP) info', + '', + 'Detected filetype: ' .. buffer_filetype, + 'Default LSP log: ' .. (vim.lsp.get_log_path()), 'Configured servers: ' .. table.concat(vim.tbl_keys(configs), ', '), - 'Neovim logs at: ' .. (vim.lsp.get_log_path()), '', tostring(#vim.tbl_keys(buf_clients)) .. ' client(s) attached to this buffer: ' .. table.concat( buf_client_names, @@ -30,63 +146,6 @@ return function() } vim.list_extend(buf_lines, header) - local function trim_whitespace(cmd) - local trimmed_cmd = {} - for _, str in pairs(cmd) do - table.insert(trimmed_cmd, str:match '^%s*(.*)') - end - return trimmed_cmd - end - - local function remove_newlines(cmd) - cmd = trim_whitespace(cmd) - cmd = table.concat(cmd, ' ') - cmd = vim.split(cmd, '\n') - cmd = trim_whitespace(cmd) - cmd = table.concat(cmd, ' ') - return cmd - end - - local function autostart_to_str(autostart) - local autostart_status = 'True' - if autostart == false then - autostart_status = 'Disabled' - end - return autostart_status - end - local indent = ' ' - local function make_client_info(client) - local lines = { - '', - indent - .. 'Client: ' - .. client.name - .. ' (id: ' - .. tostring(client.id) - .. ' pid: ' - .. tostring(client.rpc.pid) - .. ')', - indent .. '\troot: ' .. client.workspaceFolders[1].name, - indent .. '\tfiletypes: ' .. table.concat(client.config.filetypes or {}, ', '), - indent .. '\tcmd: ' .. remove_newlines(client.config.cmd), - indent .. '\tautostart: ' .. autostart_to_str(client._autostart), - } - if client.config.lspinfo then - local server_specific_info = client.config.lspinfo(client.config) - server_specific_info = vim.tbl_map(function(val) - return indent .. '\t' .. val - end, server_specific_info) - lines = vim.list_extend(lines, server_specific_info) - end - - return lines - end - - for _, client in pairs(buf_clients) do - local client_info = make_client_info(client) - vim.list_extend(buf_lines, client_info) - end - local active_section_header = { '', tostring(#clients) .. ' active client(s): ', @@ -96,60 +155,70 @@ return function() local client_info = make_client_info(client) vim.list_extend(buf_lines, client_info) end + local matching_config_header = { '', - 'Clients that match the filetype ' .. buffer_filetype .. ':', + '', + 'Other clients that match the filetype ' .. 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 - local cmd_is_executable, cmd - if config.cmd then - cmd = remove_newlines(config.cmd) - if vim.fn.executable(config.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 - if config.filetypes then - for _, filetype_match in pairs(config.filetypes) do - if buffer_filetype == filetype_match then - local matching_config_info = { - indent .. '', - indent .. 'Config: ' .. config.name, - indent .. '\tcmd: ' .. cmd, - indent .. '\tcmd is executable: ' .. cmd_is_executable, - indent .. '\tidentified root: ' .. (config.get_root_dir(buffer_dir) or 'None'), - indent .. '\tautostart: ' .. autostart_to_str(config._autostart), - indent .. '\tcustom handlers: ' .. table.concat(vim.tbl_keys(config.handlers), ', '), - } - vim.list_extend(buf_lines, matching_config_info) + + local all_matching_configs_attached_header = { + '', + 'All the clients that can be configured for the current buffer filetype are currently active.', + '', + } + + local other_matching_configs = get_other_matching_providers(buffer_filetype) + + if vim.tbl_isempty(other_matching_configs) then + vim.list_extend(buf_lines, all_matching_configs_attached_header) + else + vim.list_extend(buf_lines, matching_config_header) + for _, config in pairs(other_matching_configs) do + if config.filetypes then + for _, filetype_match in pairs(config.filetypes) do + if filetype_match == buffer_filetype then + vim.list_extend(buf_lines, make_config_info(config)) + end end + else + local matching_config_info = { + '', + 'Config: ' .. config.name, + '\tfiletype: ' .. 'No filetypes defined, please define filetypes in setup().', + } + vim.list_extend(buf_lines, matching_config_info) end - else - local matching_config_info = { - '', - 'Config: ' .. config.name, - '\tfiletype: ' .. 'No filetypes defined, please define filetypes in setup().', - } - vim.list_extend(buf_lines, matching_config_info) end end - buf_lines = vim.lsp.util._trim(buf_lines, {}) - vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, buf_lines) + + local fmt_buf_lines = indent_lines(buf_lines, indent .. indent) + + fmt_buf_lines = vim.lsp.util._trim(fmt_buf_lines, {}) + + vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, fmt_buf_lines) vim.api.nvim_buf_set_option(bufnr, 'modifiable', false) vim.api.nvim_buf_set_option(bufnr, 'filetype', 'lspinfo') - local configs_pattern = '\\%(' .. table.concat(vim.tbl_keys(configs), '\\|') .. '\\)' - vim.cmd('syntax match Title /\\%(Client\\|Config\\):.*\\zs' .. configs_pattern .. '/') - vim.cmd('syntax match Identifier /filetypes:.*\\zs\\<' .. buffer_filetype .. '\\>/') + + vim.api.nvim_buf_set_keymap(bufnr, 'n', '<esc>', '<cmd>bd<CR>', { noremap = true }) + vim.lsp.util.close_preview_autocmd({ 'BufHidden', 'BufLeave' }, win_id) + vim.fn.matchadd( 'Error', 'No filetypes defined, please define filetypes in setup().\\|' .. '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) + local configs_pattern = '\\%(' .. table.concat(vim.tbl_keys(configs), '\\|') .. '\\)' + + vim.cmd [[highlight LspInfoIdentifier gui=bold]] + vim.cmd [[highlight link LspInfoFileTypes Type]] + vim.cmd [[highlight link LspInfoHeader Identifier]] + vim.cmd [[let m=matchadd("LspInfoHeader", "Language Server Protocol (LSP) info")]] + vim.cmd('let m=matchadd("LspInfoFileTypes", " ' .. buffer_filetype .. '$")') + vim.cmd 'let m=matchadd("string", "true")' + vim.cmd 'let m=matchadd("error", "false")' + for _, name in ipairs(buf_client_names) do + vim.cmd('let m=matchadd("LspInfoIdentifier", "' .. name .. '.*[ ,|\']")') + end + + vim.cmd('syntax match Title /\\%(Client\\|Config\\):.*\\zs' .. configs_pattern .. '/') end diff --git a/lua/lspconfig/ui/windows.lua b/lua/lspconfig/ui/windows.lua index 51c8fae9..a9bd820f 100644 --- a/lua/lspconfig/ui/windows.lua +++ b/lua/lspconfig/ui/windows.lua @@ -1,4 +1,4 @@ --- The following is extracted and modified from plenary.vnim by +-- The following is extracted and modified from popup.nvim by -- TJ Devries. It is not a stable API, and is expected to change -- local function apply_defaults(original, defaults) @@ -40,10 +40,12 @@ function win_float.default_opts(options) width = width, height = height, style = 'minimal', + border = 'rounded', } return opts end + --- Create window that takes up certain percentags of the current screen. --- --- Works regardless of current buffers, tabs, splits, etc. @@ -90,16 +92,6 @@ function win_float.percentage_range_window(col_range, row_range, options) win_opts.col = math.floor(vim.o.columns * col_start_percentage) win_opts.width = math.floor(vim.o.columns * width_percentage) - win_opts.border = { - { ' ', 'NormalFloat' }, - { ' ', 'NormalFloat' }, - { ' ', 'NormalFloat' }, - { ' ', 'NormalFloat' }, - { ' ', 'NormalFloat' }, - { ' ', 'NormalFloat' }, - { ' ', 'NormalFloat' }, - { ' ', 'NormalFloat' }, - } local bufnr = options.bufnr or vim.api.nvim_create_buf(false, true) local win_id = vim.api.nvim_open_win(bufnr, true, win_opts) |
