diff options
| -rw-r--r-- | .luacheckrc | 1 | ||||
| -rw-r--r-- | doc/lspconfig.txt | 12 | ||||
| -rw-r--r-- | lua/lspconfig/ui/lspinfo.lua | 54 | ||||
| -rw-r--r-- | lua/lspconfig/ui/windows.lua | 30 | ||||
| -rw-r--r-- | plugin/lspconfig.lua | 25 |
5 files changed, 94 insertions, 28 deletions
diff --git a/.luacheckrc b/.luacheckrc index a0e81d60..ac6af148 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -4,6 +4,7 @@ cache = true ignore = { + "122", -- Setting a read-only field of a global variable. "212", -- Unused argument, In the case of callback function, _arg_name is easier to understand than _, so this option is set to off. "631", -- max_line_length, vscode pkg URL is too long } diff --git a/doc/lspconfig.txt b/doc/lspconfig.txt index b5f2c4aa..0c999678 100644 --- a/doc/lspconfig.txt +++ b/doc/lspconfig.txt @@ -632,5 +632,17 @@ the built-in client to provide functionality tailored to specific language servers. ============================================================================== +Highlights *lspconfig-highlight* + +LspInfoTitle Client name +LspInfoList Server name list +LspInfoFiletype `filetypes` area +LspInfoTip Tip +LspInfoBorder Window border + To set the border use: > + require('lspconfig.ui.windows').default_options.border = 'single' +< Accepts the same values as the `border` option to |nvim_open_win()| + +============================================================================== vim:tw=78:ts=8:ft=help:norl: diff --git a/lua/lspconfig/ui/lspinfo.lua b/lua/lspconfig/ui/lspinfo.lua index e9066b7c..6b1c52d1 100644 --- a/lua/lspconfig/ui/lspinfo.lua +++ b/lua/lspconfig/ui/lspinfo.lua @@ -1,3 +1,4 @@ +local api = vim.api local configs = require 'lspconfig.configs' local windows = require 'lspconfig.ui.windows' local util = require 'lspconfig.util' @@ -52,7 +53,7 @@ local function make_config_info(config, bufnr) config_info.cmd_is_executable = 'NA' end - local buffer_dir = vim.api.nvim_buf_call(bufnr, function() + local buffer_dir = api.nvim_buf_call(bufnr, function() return vim.fn.expand '%:p:h' end) local root_dir = config.get_root_dir(buffer_dir) @@ -150,7 +151,12 @@ return function() local buf_clients = vim.lsp.buf_get_clients() local clients = vim.lsp.get_active_clients() local buffer_filetype = vim.bo.filetype - local original_bufnr = vim.api.nvim_get_current_buf() + local original_bufnr = api.nvim_get_current_buf() + + windows.default_options.wrap = true + windows.default_options.breakindent = true + windows.default_options.breakindentopt = 'shift:25' + windows.default_options.showbreak = 'NONE' local win_info = windows.percentage_range_window(0.8, 0.7) local bufnr, win_id = win_info.bufnr, win_info.win_id @@ -169,6 +175,9 @@ return function() end end + -- insert the tips at the top of window + table.insert(buf_lines, 'Use [q] or [Esc] to quit the window') + local header = { '', 'Language client log: ' .. (vim.lsp.get_log_path()), @@ -216,22 +225,39 @@ return function() local matching_config_header = { '', - 'Configured servers list: ' .. table.concat(vim.tbl_keys(configs), ', '), + 'Configured servers list: ' .. table.concat(util.available_servers(), ', '), } + vim.list_extend(buf_lines, matching_config_header) local fmt_buf_lines = indent_lines(buf_lines, ' ') 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') + api.nvim_buf_set_lines(bufnr, 0, -1, true, fmt_buf_lines) + api.nvim_buf_set_option(bufnr, 'modifiable', false) + api.nvim_buf_set_option(bufnr, 'filetype', 'lspinfo') - vim.api.nvim_buf_set_keymap(bufnr, 'n', '<esc>', '<cmd>bd<CR>', { noremap = true }) - vim.api.nvim_command( - string.format('autocmd BufHidden,BufLeave <buffer> ++once lua pcall(vim.api.nvim_win_close, %d, true)', win_id) - ) + local augroup = api.nvim_create_augroup('lspinfo', { clear = false }) + + local function close() + api.nvim_clear_autocmds { group = augroup, buffer = bufnr } + if api.nvim_buf_is_valid(bufnr) then + api.nvim_buf_delete(bufnr, { force = true }) + end + if api.nvim_win_is_valid(win_id) then + api.nvim_win_close(win_id, true) + end + end + + vim.keymap.set('n', '<ESC>', close, { buffer = bufnr, nowait = true }) + vim.keymap.set('n', 'q', close, { buffer = bufnr, nowait = true }) + api.nvim_create_autocmd({ 'BufDelete', 'BufLeave', 'BufHidden' }, { + once = true, + buffer = bufnr, + callback = close, + group = augroup, + }) vim.fn.matchadd( 'Error', @@ -246,12 +272,14 @@ return function() vim.cmd 'let m=matchadd("string", "true")' vim.cmd 'let m=matchadd("error", "false")' for _, config in pairs(configs) do - vim.fn.matchadd('Title', '\\%(Client\\|Config\\):.*\\zs' .. config.name .. '\\ze') - vim.fn.matchadd('Visual', 'list:.*\\zs' .. config.name .. '\\ze') + vim.fn.matchadd('LspInfoTitle', '\\%(Client\\|Config\\):.*\\zs' .. config.name .. '\\ze') + vim.fn.matchadd('LspInfoList', 'list:.*\\zs' .. config.name .. '\\ze') if config.filetypes then for _, ft in pairs(config.filetypes) do - vim.fn.matchadd('Type', '\\%(filetypes\\|filetype\\):.*\\zs' .. ft .. '\\ze') + vim.fn.matchadd('LspInfoFiletype', '\\%(filetypes\\|filetype\\):.*\\zs' .. ft .. '\\ze') end end end + + api.nvim_buf_add_highlight(bufnr, 0, 'LspInfoTip', 0, 0, -1) end diff --git a/lua/lspconfig/ui/windows.lua b/lua/lspconfig/ui/windows.lua index 8a39204d..c4149b4c 100644 --- a/lua/lspconfig/ui/windows.lua +++ b/lua/lspconfig/ui/windows.lua @@ -1,6 +1,8 @@ -- The following is extracted and modified from plenary.vnim by -- TJ Devries. It is not a stable API, and is expected to change -- +local api = vim.api + local function apply_defaults(original, defaults) if original == nil then original = {} @@ -19,13 +21,10 @@ end local win_float = {} -win_float.default_options = { - winblend = 15, - percentage = 0.9, -} +win_float.default_options = {} function win_float.default_opts(options) - options = apply_defaults(options, win_float.default_options) + options = apply_defaults(options, { percentage = 0.9 }) local width = math.floor(vim.o.columns * options.percentage) local height = math.floor(vim.o.lines * options.percentage) @@ -52,6 +51,8 @@ function win_float.default_opts(options) }, } + opts.border = options.border and options.border + return opts end @@ -85,6 +86,7 @@ function win_float.percentage_range_window(col_range, row_range, options) win_opts.height = math.ceil(vim.o.lines * height_percentage) win_opts.row = math.ceil(vim.o.lines * row_start_percentage) + win_opts.border = options.border or 'none' local width_percentage, col_start_percentage if type(col_range) == 'number' then @@ -102,11 +104,21 @@ 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) - local bufnr = options.bufnr or vim.api.nvim_create_buf(false, true) - local win_id = vim.api.nvim_open_win(bufnr, true, win_opts) - vim.api.nvim_win_set_buf(win_id, bufnr) + local bufnr = options.bufnr or api.nvim_create_buf(false, true) + local win_id = api.nvim_open_win(bufnr, true, win_opts) + api.nvim_win_set_option(win_id, 'winhl', 'FloatBorder:LspInfoBorder') + + for k, v in pairs(win_float.default_options) do + if k ~= 'border' then + vim.opt_local[k] = v + end + end + + api.nvim_win_set_buf(win_id, bufnr) - vim.cmd 'setlocal nocursorcolumn ts=2 sw=2' + api.nvim_win_set_option(win_id, 'cursorcolumn', false) + api.nvim_buf_set_option(bufnr, 'tabstop', 2) + api.nvim_buf_set_option(bufnr, 'shiftwidth', 2) return { bufnr = bufnr, diff --git a/plugin/lspconfig.lua b/plugin/lspconfig.lua index 5d4a8c92..05f42199 100644 --- a/plugin/lspconfig.lua +++ b/plugin/lspconfig.lua @@ -1,3 +1,5 @@ +local api = vim.api + if vim.g.lspconfig ~= nil then return end @@ -22,7 +24,7 @@ end local lsp_complete_configured_servers = function(arg) return completion_sort(vim.tbl_filter(function(s) return s:sub(1, #arg) == arg - end, vim.tbl_keys(require 'lspconfig.configs'))) + end, require('lspconfig.util').available_servers())) end local lsp_get_active_client_ids = function(arg) @@ -46,15 +48,25 @@ local get_clients_from_cmd_args = function(arg) return vim.tbl_values(result) end +for group, hi in pairs { + LspInfoBorder = { link = 'Label', default = true }, + LspInfoList = { link = 'Function', default = true }, + LspInfoTip = { link = 'Comment', default = true }, + LspInfoTitle = { link = 'Title', default = true }, + LspInfoFiletype = { link = 'Type', default = true }, +} do + api.nvim_set_hl(0, group, hi) +end + -- Called from plugin/lspconfig.vim because it requires knowing that the last -- script in scriptnames to be executed is lspconfig. -vim.api.nvim_create_user_command('LspInfo', function() +api.nvim_create_user_command('LspInfo', function() require 'lspconfig.ui.lspinfo'() end, { desc = 'Displays attached, active, and configured language servers', }) -vim.api.nvim_create_user_command('LspStart', function(info) +api.nvim_create_user_command('LspStart', function(info) local server_name = string.len(info.args) > 0 and info.args or nil if server_name then local config = require('lspconfig.configs')[server_name] @@ -73,7 +85,8 @@ end, { nargs = '?', complete = lsp_complete_configured_servers, }) -vim.api.nvim_create_user_command('LspRestart', function(info) + +api.nvim_create_user_command('LspRestart', function(info) for _, client in ipairs(get_clients_from_cmd_args(info.args)) do client.stop() vim.defer_fn(function() @@ -86,7 +99,7 @@ end, { complete = lsp_get_active_client_ids, }) -vim.api.nvim_create_user_command('LspStop', function(info) +api.nvim_create_user_command('LspStop', function(info) local current_buf = vim.api.nvim_get_current_buf() for _, client in ipairs(get_clients_from_cmd_args(info.args)) do local filetypes = client.config.filetypes @@ -100,7 +113,7 @@ end, { complete = lsp_get_active_client_ids, }) -vim.api.nvim_create_user_command('LspLog', function() +api.nvim_create_user_command('LspLog', function() vim.cmd(string.format('tabnew %s', vim.lsp.get_log_path())) end, { desc = 'Opens the Nvim LSP client log.', |
