diff options
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/_editor.lua | 69 | ||||
-rw-r--r-- | runtime/lua/vim/diagnostic.lua | 3 | ||||
-rw-r--r-- | runtime/lua/vim/filetype.lua | 24 | ||||
-rw-r--r-- | runtime/lua/vim/lsp.lua | 112 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 1 |
6 files changed, 135 insertions, 76 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index c4cc151bca..094fb2f909 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -288,6 +288,9 @@ end --- Execute Vim script commands. --- +--- Note that `vim.cmd` can be indexed with a command name to return a callable function to the +--- command. +--- --- Example: --- <pre> --- vim.cmd('echo 42') @@ -297,7 +300,23 @@ end --- autocmd FileType c setlocal cindent --- augroup END --- ]]) ---- vim.cmd({ cmd = 'echo', args = { '"foo"' } }) +--- +--- -- Ex command :echo "foo" +--- -- Note string literals need to be double quoted. +--- vim.cmd('echo "foo"') +--- vim.cmd { cmd = 'echo', args = { '"foo"' } } +--- vim.cmd.echo({ args = { '"foo"' } }) +--- vim.cmd.echo('"foo"') +--- +--- -- Ex command :write! myfile.txt +--- vim.cmd('write! myfile.txt') +--- vim.cmd { cmd = 'write', args = { "myfile.txt" }, bang = true } +--- vim.cmd.write { args = { "myfile.txt" }, bang = true } +--- vim.cmd.write {"myfile.txt", bang = true }) +--- +--- -- Ex command :colorscheme blue +--- vim.cmd('colorscheme blue') +--- vim.cmd.colorscheme('blue') --- </pre> --- ---@param command string|table Command(s) to execute. @@ -307,14 +326,47 @@ end --- If a table, executes a single command. In this case, it is an alias --- to |nvim_cmd()| where `opts` is empty. ---@see |ex-cmd-index| -function vim.cmd(command) - if type(command) == 'table' then - return vim.api.nvim_cmd(command, {}) - else - return vim.api.nvim_exec(command, false) - end +function vim.cmd(command) -- luacheck: no unused + error(command) -- Stub for gen_vimdoc.py end +local VIM_CMD_ARG_MAX = 20 + +vim.cmd = setmetatable({}, { + __call = function(_, command) + if type(command) == 'table' then + return vim.api.nvim_cmd(command, {}) + else + return vim.api.nvim_exec(command, false) + end + end, + __index = function(t, command) + t[command] = function(...) + local opts + if select('#', ...) == 1 and type(select(1, ...)) == 'table' then + opts = select(1, ...) + + -- Move indexed positions in opts to opt.args + if opts[1] and not opts.args then + opts.args = {} + for i = 1, VIM_CMD_ARG_MAX do + if not opts[i] then + break + end + opts.args[i] = opts[i] + opts[i] = nil + end + end + else + opts = { args = { ... } } + end + opts.cmd = command + return vim.api.nvim_cmd(opts, {}) + end + return t[command] + end, +}) + -- These are the vim.env/v/g/o/bo/wo variable magic accessors. do local validate = vim.validate @@ -614,7 +666,7 @@ function vim._expand_pat(pat, env) local function insert_keys(obj) for k, _ in pairs(obj) do if type(k) == 'string' and string.sub(k, 1, string.len(match_part)) == match_part then - table.insert(keys, k) + keys[k] = true end end end @@ -630,6 +682,7 @@ function vim._expand_pat(pat, env) insert_keys(vim._submodules) end + keys = vim.tbl_keys(keys) table.sort(keys) return keys, #prefix_match_pat diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 40991673f3..ae20b5c517 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -372,14 +372,15 @@ local function schedule_display(namespace, bufnr, args) bufs_waiting_to_update[bufnr][namespace] = args local key = make_augroup_key(namespace, bufnr) - local group = vim.api.nvim_create_augroup(key, { clear = true }) if not registered_autocmds[key] then + local group = vim.api.nvim_create_augroup(key, { clear = true }) vim.api.nvim_create_autocmd(insert_leave_auto_cmds, { group = group, buffer = bufnr, callback = function() execute_scheduled_display(namespace, bufnr) end, + desc = 'vim.diagnostic: display diagnostics', }) registered_autocmds[key] = true end diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 70c8cd15eb..c2dcc2a2c8 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -2241,30 +2241,30 @@ end --- <pre> --- vim.filetype.add({ --- extension = { ---- foo = "fooscript", +--- foo = 'fooscript', --- bar = function(path, bufnr) --- if some_condition() then ---- return "barscript", function(bufnr) +--- return 'barscript', function(bufnr) --- -- Set a buffer variable --- vim.b[bufnr].barscript_version = 2 --- end --- end ---- return "bar" +--- return 'bar' --- end, --- }, --- filename = { ---- [".foorc"] = "toml", ---- ["/etc/foo/config"] = "toml", +--- ['.foorc'] = 'toml', +--- ['/etc/foo/config'] = 'toml', --- }, --- pattern = { ---- [".*/etc/foo/.*"] = "fooscript", +--- ['.*/etc/foo/.*'] = 'fooscript', --- -- Using an optional priority ---- [".*/etc/foo/.*%.conf"] = { "dosini", { priority = 10 } }, ---- ["README.(%a+)$"] = function(path, bufnr, ext) ---- if ext == "md" then ---- return "markdown" ---- elseif ext == "rst" then ---- return "rst" +--- ['.*/etc/foo/.*%.conf'] = { 'dosini', { priority = 10 } }, +--- ['README.(%a+)$'] = function(path, bufnr, ext) +--- if ext == 'md' then +--- return 'markdown' +--- elseif ext == 'rst' then +--- return 'rst' --- end --- end, --- }, diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 7c95ecef92..61586ca44f 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1234,12 +1234,12 @@ function lsp.start_client(config) ) end, function(request_id) client.requests[request_id] = nil - nvim_command('doautocmd <nomodeline> User LspRequest') + nvim_exec_autocmds('User', { pattern = 'LspRequest', modeline = false }) end) if success then client.requests[request_id] = { type = 'pending', bufnr = bufnr, method = method } - nvim_command('doautocmd <nomodeline> User LspRequest') + nvim_exec_autocmds('User', { pattern = 'LspRequest', modeline = false }) end return success, request_id @@ -1308,7 +1308,7 @@ function lsp.start_client(config) local request = client.requests[id] if request and request.type == 'pending' then request.type = 'cancel' - nvim_command('doautocmd <nomodeline> User LspRequest') + nvim_exec_autocmds('User', { pattern = 'LspRequest', modeline = false }) end return rpc.notify('$/cancelRequest', { id = id }) end @@ -1398,8 +1398,9 @@ do end end --- Buffer lifecycle handler for textDocument/didSave -function lsp._text_document_did_save_handler(bufnr) +---@private +---Buffer lifecycle handler for textDocument/didSave +local function text_document_did_save_handler(bufnr) bufnr = resolve_bufnr(bufnr) local uri = vim.uri_from_bufnr(bufnr) local text = once(buf_get_full_text) @@ -1445,13 +1446,15 @@ function lsp.buf_attach_client(bufnr, client_id) all_buffer_active_clients[bufnr] = buffer_client_ids local uri = vim.uri_from_bufnr(bufnr) - local buf_did_save_autocommand = [=[ - augroup lsp_c_%d_b_%d_did_save - au! - au BufWritePost <buffer=%d> lua vim.lsp._text_document_did_save_handler(0) - augroup END - ]=] - api.nvim_exec(string.format(buf_did_save_autocommand, client_id, bufnr, bufnr), false) + local augroup = ('lsp_c_%d_b_%d_did_save'):format(client_id, bufnr) + api.nvim_create_autocmd('BufWritePost', { + group = api.nvim_create_augroup(augroup, { clear = true }), + buffer = bufnr, + desc = 'vim.lsp: textDocument/didSave handler', + callback = function(ctx) + text_document_did_save_handler(ctx.buf) + end, + }) -- First time, so attach and set up stuff. api.nvim_buf_attach(bufnr, false, { on_lines = text_document_did_change_handler, @@ -1634,60 +1637,61 @@ function lsp.get_active_clients(filter) return clients end -function lsp._vim_exit_handler() - log.info('exit_handler', active_clients) - for _, client in pairs(uninitialized_clients) do - client.stop(true) - end - -- TODO handle v:dying differently? - if tbl_isempty(active_clients) then - return - end - for _, client in pairs(active_clients) do - client.stop() - end +api.nvim_create_autocmd('VimLeavePre', { + desc = 'vim.lsp: exit handler', + callback = function() + log.info('exit_handler', active_clients) + for _, client in pairs(uninitialized_clients) do + client.stop(true) + end + -- TODO handle v:dying differently? + if tbl_isempty(active_clients) then + return + end + for _, client in pairs(active_clients) do + client.stop() + end - local timeouts = {} - local max_timeout = 0 - local send_kill = false + local timeouts = {} + local max_timeout = 0 + local send_kill = false - for client_id, client in pairs(active_clients) do - local timeout = if_nil(client.config.flags.exit_timeout, 500) - if timeout then - send_kill = true - timeouts[client_id] = timeout - max_timeout = math.max(timeout, max_timeout) + for client_id, client in pairs(active_clients) do + local timeout = if_nil(client.config.flags.exit_timeout, 500) + if timeout then + send_kill = true + timeouts[client_id] = timeout + max_timeout = math.max(timeout, max_timeout) + end end - end - local poll_time = 50 + local poll_time = 50 - ---@private - local function check_clients_closed() - for client_id, timeout in pairs(timeouts) do - timeouts[client_id] = timeout - poll_time - end + ---@private + local function check_clients_closed() + for client_id, timeout in pairs(timeouts) do + timeouts[client_id] = timeout - poll_time + end - for client_id, _ in pairs(active_clients) do - if timeouts[client_id] ~= nil and timeouts[client_id] > 0 then - return false + for client_id, _ in pairs(active_clients) do + if timeouts[client_id] ~= nil and timeouts[client_id] > 0 then + return false + end end + return true end - return true - end - if send_kill then - if not vim.wait(max_timeout, check_clients_closed, poll_time) then - for client_id, client in pairs(active_clients) do - if timeouts[client_id] ~= nil then - client.stop(true) + if send_kill then + if not vim.wait(max_timeout, check_clients_closed, poll_time) then + for client_id, client in pairs(active_clients) do + if timeouts[client_id] ~= nil then + client.stop(true) + end end end end - end -end - -nvim_command('autocmd VimLeavePre * lua vim.lsp._vim_exit_handler()') + end, +}) --- Sends an async request for all active clients attached to the --- buffer. diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 68e1f59aaf..3b869d8f5c 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -61,7 +61,7 @@ local function progress_handler(_, result, ctx, _) client.messages.progress[token].done = true end - api.nvim_command('doautocmd <nomodeline> User LspProgressUpdate') + api.nvim_exec_autocmds('User', { pattern = 'LspProgressUpdate', modeline = false }) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#progress diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 89b2301aa7..70f5010256 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1395,6 +1395,7 @@ local function close_preview_autocmd(events, winnr, bufnrs) if #events > 0 then api.nvim_create_autocmd(events, { + group = augroup, buffer = bufnrs[2], callback = function() close_preview_window(winnr) |