aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/_editor.lua69
-rw-r--r--runtime/lua/vim/diagnostic.lua3
-rw-r--r--runtime/lua/vim/filetype.lua24
-rw-r--r--runtime/lua/vim/lsp.lua112
-rw-r--r--runtime/lua/vim/lsp/handlers.lua2
-rw-r--r--runtime/lua/vim/lsp/util.lua1
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)