aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2025-02-05 23:09:29 +0000
committerJosh Rahm <joshuarahm@gmail.com>2025-02-05 23:09:29 +0000
commitd5f194ce780c95821a855aca3c19426576d28ae0 (patch)
treed45f461b19f9118ad2bb1f440a7a08973ad18832 /runtime/lua
parentc5d770d311841ea5230426cc4c868e8db27300a8 (diff)
parent44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff)
downloadrneovim-rahm.tar.gz
rneovim-rahm.tar.bz2
rneovim-rahm.zip
Merge remote-tracking branch 'upstream/master' into mix_20240309HEADrahm
Diffstat (limited to 'runtime/lua')
-rw-r--r--runtime/lua/_vim9script.lua2
-rw-r--r--runtime/lua/coxpcall.lua19
-rw-r--r--runtime/lua/editorconfig.lua6
-rw-r--r--runtime/lua/man.lua701
-rw-r--r--runtime/lua/tohtml.lua10
-rw-r--r--runtime/lua/vim/_defaults.lua75
-rw-r--r--runtime/lua/vim/_editor.lua28
-rw-r--r--runtime/lua/vim/_inspector.lua27
-rw-r--r--runtime/lua/vim/_meta/api.lua206
-rw-r--r--runtime/lua/vim/_meta/api_keysets.lua102
-rw-r--r--runtime/lua/vim/_meta/api_keysets_extra.lua66
-rw-r--r--runtime/lua/vim/_meta/builtin.lua5
-rw-r--r--runtime/lua/vim/_meta/json.lua15
-rw-r--r--runtime/lua/vim/_meta/options.lua209
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua315
-rw-r--r--runtime/lua/vim/_meta/vvars.lua34
-rw-r--r--runtime/lua/vim/_meta/vvars_extra.lua77
-rw-r--r--runtime/lua/vim/_options.lua13
-rw-r--r--runtime/lua/vim/_system.lua129
-rw-r--r--runtime/lua/vim/diagnostic.lua517
-rw-r--r--runtime/lua/vim/filetype.lua68
-rw-r--r--runtime/lua/vim/filetype/detect.lua61
-rw-r--r--runtime/lua/vim/fs.lua158
-rw-r--r--runtime/lua/vim/func.lua14
-rw-r--r--runtime/lua/vim/func/_memoize.lua56
-rw-r--r--runtime/lua/vim/glob.lua1
-rw-r--r--runtime/lua/vim/health.lua65
-rw-r--r--runtime/lua/vim/health/health.lua13
-rw-r--r--runtime/lua/vim/hl.lua45
-rw-r--r--runtime/lua/vim/inspect.lua1
-rw-r--r--runtime/lua/vim/loader.lua71
-rw-r--r--runtime/lua/vim/lsp.lua692
-rw-r--r--runtime/lua/vim/lsp/_changetracking.lua18
-rw-r--r--runtime/lua/vim/lsp/_folding_range.lua373
-rw-r--r--runtime/lua/vim/lsp/_meta.lua4
-rw-r--r--runtime/lua/vim/lsp/_snippet_grammar.lua1
-rw-r--r--runtime/lua/vim/lsp/_tagfunc.lua18
-rw-r--r--runtime/lua/vim/lsp/_transport.lua182
-rw-r--r--runtime/lua/vim/lsp/_watchfiles.lua3
-rw-r--r--runtime/lua/vim/lsp/buf.lua98
-rw-r--r--runtime/lua/vim/lsp/client.lua411
-rw-r--r--runtime/lua/vim/lsp/codelens.lua14
-rw-r--r--runtime/lua/vim/lsp/completion.lua43
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua29
-rw-r--r--runtime/lua/vim/lsp/handlers.lua20
-rw-r--r--runtime/lua/vim/lsp/health.lua77
-rw-r--r--runtime/lua/vim/lsp/inlay_hint.lua29
-rw-r--r--runtime/lua/vim/lsp/protocol.lua15
-rw-r--r--runtime/lua/vim/lsp/rpc.lua290
-rw-r--r--runtime/lua/vim/lsp/semantic_tokens.lua35
-rw-r--r--runtime/lua/vim/lsp/sync.lua52
-rw-r--r--runtime/lua/vim/lsp/util.lua222
-rw-r--r--runtime/lua/vim/provider/health.lua34
-rw-r--r--runtime/lua/vim/re.lua1
-rw-r--r--runtime/lua/vim/shared.lua74
-rw-r--r--runtime/lua/vim/snippet.lua4
-rw-r--r--runtime/lua/vim/text.lua24
-rw-r--r--runtime/lua/vim/treesitter.lua57
-rw-r--r--runtime/lua/vim/treesitter/_fold.lua325
-rw-r--r--runtime/lua/vim/treesitter/_meta/misc.lua8
-rw-r--r--runtime/lua/vim/treesitter/_meta/tsnode.lua16
-rw-r--r--runtime/lua/vim/treesitter/_query_linter.lua6
-rw-r--r--runtime/lua/vim/treesitter/dev.lua25
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua30
-rw-r--r--runtime/lua/vim/treesitter/language.lua7
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua356
-rw-r--r--runtime/lua/vim/treesitter/query.lua418
-rw-r--r--runtime/lua/vim/uri.lua7
-rw-r--r--runtime/lua/vim/version.lua3
-rw-r--r--runtime/lua/vim/vimhelp.lua2
70 files changed, 4654 insertions, 2478 deletions
diff --git a/runtime/lua/_vim9script.lua b/runtime/lua/_vim9script.lua
index 23c078cb87..29bafc53b2 100644
--- a/runtime/lua/_vim9script.lua
+++ b/runtime/lua/_vim9script.lua
@@ -145,7 +145,7 @@ local vim9 = (function()
-- work well for calling ":source X" from within a vimscript/vim9script
-- function
M.make_source_cmd = function()
- local group = vim.api.nvim_create_augroup('vim9script-source', {})
+ local group = vim.api.nvim_create_augroup('nvim.vim9script_source', {})
vim.api.nvim_create_autocmd('SourceCmd', {
pattern = '*.vim',
group = group,
diff --git a/runtime/lua/coxpcall.lua b/runtime/lua/coxpcall.lua
index 6b179f1ef0..43e321eac3 100644
--- a/runtime/lua/coxpcall.lua
+++ b/runtime/lua/coxpcall.lua
@@ -1,6 +1,10 @@
-------------------------------------------------------------------------------
+-- (Not needed for LuaJIT or Lua 5.2+)
+--
-- Coroutine safe xpcall and pcall versions
--
+-- https://keplerproject.github.io/coxpcall/
+--
-- Encapsulates the protected calls with a coroutine based loop, so errors can
-- be dealed without the usual Lua 5.x pcall/xpcall issues with coroutines
-- yielding inside the call to pcall or xpcall.
@@ -27,22 +31,23 @@ end
-- No need to do anything if pcall and xpcall are already safe.
if isCoroutineSafe(pcall) and isCoroutineSafe(xpcall) then
- copcall = pcall
- coxpcall = xpcall
+ _G.copcall = pcall
+ _G.coxpcall = xpcall
return { pcall = pcall, xpcall = xpcall, running = coroutine.running }
end
-------------------------------------------------------------------------------
-- Implements xpcall with coroutines
-------------------------------------------------------------------------------
-local performResume, handleReturnValue
+local performResume
local oldpcall, oldxpcall = pcall, xpcall
local pack = table.pack or function(...) return {n = select("#", ...), ...} end
local unpack = table.unpack or unpack
local running = coroutine.running
+--- @type table<thread,thread>
local coromap = setmetatable({}, { __mode = "k" })
-function handleReturnValue(err, co, status, ...)
+local function handleReturnValue(err, co, status, ...)
if not status then
return false, err(debug.traceback(co, (...)), ...)
end
@@ -57,11 +62,12 @@ function performResume(err, co, ...)
return handleReturnValue(err, co, coroutine.resume(co, ...))
end
+--- @diagnostic disable-next-line: unused-vararg
local function id(trace, ...)
return trace
end
-function coxpcall(f, err, ...)
+function _G.coxpcall(f, err, ...)
local current = running()
if not current then
if err == id then
@@ -84,6 +90,7 @@ function coxpcall(f, err, ...)
end
end
+--- @param coro? thread
local function corunning(coro)
if coro ~= nil then
assert(type(coro)=="thread", "Bad argument; expected thread, got: "..type(coro))
@@ -101,7 +108,7 @@ end
-- Implements pcall with coroutines
-------------------------------------------------------------------------------
-function copcall(f, ...)
+function _G.copcall(f, ...)
return coxpcall(f, id, ...)
end
diff --git a/runtime/lua/editorconfig.lua b/runtime/lua/editorconfig.lua
index e65d267a70..2093c4eb5c 100644
--- a/runtime/lua/editorconfig.lua
+++ b/runtime/lua/editorconfig.lua
@@ -151,7 +151,7 @@ function properties.trim_trailing_whitespace(bufnr, val)
)
if val == 'true' then
vim.api.nvim_create_autocmd('BufWritePre', {
- group = 'editorconfig',
+ group = 'nvim.editorconfig',
buffer = bufnr,
callback = function()
local view = vim.fn.winsaveview()
@@ -163,7 +163,7 @@ function properties.trim_trailing_whitespace(bufnr, val)
else
vim.api.nvim_clear_autocmds({
event = 'BufWritePre',
- group = 'editorconfig',
+ group = 'nvim.editorconfig',
buffer = bufnr,
})
end
@@ -180,7 +180,7 @@ function properties.insert_final_newline(bufnr, val)
local endofline = val == 'true'
if vim.bo[bufnr].endofline ~= endofline then
vim.api.nvim_create_autocmd('BufWritePre', {
- group = 'editorconfig',
+ group = 'nvim.editorconfig',
buffer = bufnr,
once = true,
callback = function()
diff --git a/runtime/lua/man.lua b/runtime/lua/man.lua
index 114c94f9e5..96cfdf523d 100644
--- a/runtime/lua/man.lua
+++ b/runtime/lua/man.lua
@@ -1,93 +1,84 @@
local api, fn = vim.api, vim.fn
-local FIND_ARG = '-w'
-local localfile_arg = true -- Always use -l if possible. #6683
-
----@type table[]
-local buf_hls = {}
-
local M = {}
-local function man_error(msg)
- M.errormsg = 'man.lua: ' .. vim.inspect(msg)
- error(M.errormsg)
-end
-
--- Run a system command and timeout after 30 seconds.
----@param cmd string[]
----@param silent boolean?
----@param env? table<string,string|number>
----@return string
+--- Run a system command and timeout after 10 seconds.
+--- @param cmd string[]
+--- @param silent boolean?
+--- @param env? table<string,string|number>
+--- @return string
local function system(cmd, silent, env)
local r = vim.system(cmd, { env = env, timeout = 10000 }):wait()
- if r.code ~= 0 and not silent then
- local cmd_str = table.concat(cmd, ' ')
- man_error(string.format("command error '%s': %s", cmd_str, r.stderr))
+ if not silent then
+ if r.code ~= 0 then
+ local cmd_str = table.concat(cmd, ' ')
+ error(string.format("command error '%s': %s", cmd_str, r.stderr))
+ end
+ assert(r.stdout ~= '')
end
return assert(r.stdout)
end
----@param line string
----@param linenr integer
-local function highlight_line(line, linenr)
- ---@type string[]
+--- @enum Man.Attribute
+local Attrs = {
+ None = 0,
+ Bold = 1,
+ Underline = 2,
+ Italic = 3,
+}
+
+--- @param line string
+--- @param row integer
+--- @param hls {attr:Man.Attribute,row:integer,start:integer,final:integer}[]
+--- @return string
+local function render_line(line, row, hls)
+ --- @type string[]
local chars = {}
local prev_char = ''
local overstrike, escape, osc8 = false, false, false
- ---@type table<integer,{attr:integer,start:integer,final:integer}>
- local hls = {} -- Store highlight groups as { attr, start, final }
-
- local NONE, BOLD, UNDERLINE, ITALIC = 0, 1, 2, 3
- local hl_groups = { [BOLD] = 'manBold', [UNDERLINE] = 'manUnderline', [ITALIC] = 'manItalic' }
- local attr = NONE
+ local attr = Attrs.None
local byte = 0 -- byte offset
- local function end_attr_hl(attr_)
- for i, hl in ipairs(hls) do
- if hl.attr == attr_ and hl.final == -1 then
- hl.final = byte
- hls[i] = hl
- end
- end
- end
+ local hls_start = #hls + 1
+ --- @param code integer
local function add_attr_hl(code)
local continue_hl = true
if code == 0 then
- attr = NONE
+ attr = Attrs.None
continue_hl = false
elseif code == 1 then
- attr = BOLD
+ attr = Attrs.Bold
elseif code == 22 then
- attr = BOLD
+ attr = Attrs.Bold
continue_hl = false
elseif code == 3 then
- attr = ITALIC
+ attr = Attrs.Italic
elseif code == 23 then
- attr = ITALIC
+ attr = Attrs.Italic
continue_hl = false
elseif code == 4 then
- attr = UNDERLINE
+ attr = Attrs.Underline
elseif code == 24 then
- attr = UNDERLINE
+ attr = Attrs.Underline
continue_hl = false
else
- attr = NONE
+ attr = Attrs.None
return
end
if continue_hl then
- hls[#hls + 1] = { attr = attr, start = byte, final = -1 }
+ hls[#hls + 1] = { attr = attr, row = row, start = byte, final = -1 }
else
- if attr == NONE then
- for a, _ in pairs(hl_groups) do
- end_attr_hl(a)
+ for _, a in pairs(attr == Attrs.None and Attrs or { attr }) do
+ for i = hls_start, #hls do
+ if hls[i].attr == a and hls[i].final == -1 then
+ hls[i].final = byte
+ end
end
- else
- end_attr_hl(attr)
end
end
end
@@ -100,11 +91,11 @@ local function highlight_line(line, linenr)
if overstrike then
local last_hl = hls[#hls]
if char == prev_char then
- if char == '_' and attr == ITALIC and last_hl and last_hl.final == byte then
+ if char == '_' and attr == Attrs.Italic and last_hl and last_hl.final == byte then
-- This underscore is in the middle of an italic word
- attr = ITALIC
+ attr = Attrs.Italic
else
- attr = BOLD
+ attr = Attrs.Bold
end
elseif prev_char == '_' then
-- Even though underline is strictly what this should be. <bs>_ was used by nroff to
@@ -113,26 +104,26 @@ local function highlight_line(line, linenr)
-- See:
-- - https://unix.stackexchange.com/questions/274658/purpose-of-ascii-text-with-overstriking-file-format/274795#274795
-- - https://cmd.inp.nsk.su/old/cmd2/manuals/unix/UNIX_Unleashed/ch08.htm
- -- attr = UNDERLINE
- attr = ITALIC
+ -- attr = Attrs.Underline
+ attr = Attrs.Italic
elseif prev_char == '+' and char == 'o' then
-- bullet (overstrike text '+^Ho')
- attr = BOLD
+ attr = Attrs.Bold
char = '·'
elseif prev_char == '·' and char == 'o' then
-- bullet (additional handling for '+^H+^Ho^Ho')
- attr = BOLD
+ attr = Attrs.Bold
char = '·'
else
-- use plain char
- attr = NONE
+ attr = Attrs.None
end
-- Grow the previous highlight group if possible
if last_hl and last_hl.attr == attr and last_hl.final == byte then
last_hl.final = byte + #char
else
- hls[#hls + 1] = { attr = attr, start = byte, final = byte + #char }
+ hls[#hls + 1] = { attr = attr, row = row, start = byte, final = byte + #char }
end
overstrike = false
@@ -151,14 +142,15 @@ local function highlight_line(line, linenr)
-- We only want to match against SGR sequences, which consist of ESC
-- followed by '[', then a series of parameter and intermediate bytes in
-- the range 0x20 - 0x3f, then 'm'. (See ECMA-48, sections 5.4 & 8.3.117)
- ---@type string?
+ --- @type string?
local sgr = prev_char:match('^%[([\032-\063]*)m$')
-- Ignore escape sequences with : characters, as specified by ITU's T.416
-- Open Document Architecture and interchange format.
- if sgr and not string.find(sgr, ':') then
- local match ---@type string?
+ if sgr and not sgr:find(':') then
+ local match --- @type string?
while sgr and #sgr > 0 do
-- Match against SGR parameters, which may be separated by ';'
+ --- @type string?, string?
match, sgr = sgr:match('^(%d*);?(.*)')
add_attr_hl(match + 0) -- coerce to number
end
@@ -184,55 +176,43 @@ local function highlight_line(line, linenr)
end
end
- for _, hl in ipairs(hls) do
- if hl.attr ~= NONE then
- buf_hls[#buf_hls + 1] = {
- 0,
- -1,
- hl_groups[hl.attr],
- linenr - 1,
- hl.start,
- hl.final,
- }
- end
- end
-
return table.concat(chars, '')
end
+local HlGroups = {
+ [Attrs.Bold] = 'manBold',
+ [Attrs.Underline] = 'manUnderline',
+ [Attrs.Italic] = 'manItalic',
+}
+
local function highlight_man_page()
local mod = vim.bo.modifiable
vim.bo.modifiable = true
local lines = api.nvim_buf_get_lines(0, 0, -1, false)
+
+ --- @type {attr:Man.Attribute,row:integer,start:integer,final:integer}[]
+ local hls = {}
+
for i, line in ipairs(lines) do
- lines[i] = highlight_line(line, i)
+ lines[i] = render_line(line, i - 1, hls)
end
+
api.nvim_buf_set_lines(0, 0, -1, false, lines)
- for _, args in ipairs(buf_hls) do
- api.nvim_buf_add_highlight(unpack(args))
+ for _, hl in ipairs(hls) do
+ if hl.attr ~= Attrs.None then
+ --- @diagnostic disable-next-line: deprecated
+ api.nvim_buf_add_highlight(0, -1, HlGroups[hl.attr], hl.row, hl.start, hl.final)
+ end
end
- buf_hls = {}
vim.bo.modifiable = mod
end
--- replace spaces in a man page name with underscores
--- intended for PostgreSQL, which has man pages like 'CREATE_TABLE(7)';
--- while editing SQL source code, it's nice to visually select 'CREATE TABLE'
--- and hit 'K', which requires this transformation
----@param str string
----@return string
-local function spaces_to_underscores(str)
- local res = str:gsub('%s', '_')
- return res
-end
-
----@param sect string|nil
----@param name string|nil
----@param silent boolean
-local function get_path(sect, name, silent)
+--- @param name? string
+--- @param sect? string
+local function get_path(name, sect)
name = name or ''
sect = sect or ''
-- Some man implementations (OpenBSD) return all available paths from the
@@ -253,14 +233,14 @@ local function get_path(sect, name, silent)
--
-- Finally, we can avoid relying on -S or -s here since they are very
-- inconsistently supported. Instead, call -w with a section and a name.
- local cmd ---@type string[]
+ local cmd --- @type string[]
if sect == '' then
- cmd = { 'man', FIND_ARG, name }
+ cmd = { 'man', '-w', name }
else
- cmd = { 'man', FIND_ARG, sect, name }
+ cmd = { 'man', '-w', sect, name }
end
- local lines = system(cmd, silent)
+ local lines = system(cmd, true)
local results = vim.split(lines, '\n', { trimempty = true })
if #results == 0 then
@@ -276,87 +256,73 @@ local function get_path(sect, name, silent)
end
-- find any that match the specified name
- ---@param v string
+ --- @param v string
local namematches = vim.tbl_filter(function(v)
local tail = fn.fnamemodify(v, ':t')
- return string.find(tail, name, 1, true)
+ return tail:find(name, 1, true) ~= nil
end, results) or {}
local sectmatches = {}
if #namematches > 0 and sect ~= '' then
- ---@param v string
+ --- @param v string
sectmatches = vim.tbl_filter(function(v)
return fn.fnamemodify(v, ':e') == sect
end, namematches)
end
- return fn.substitute(sectmatches[1] or namematches[1] or results[1], [[\n\+$]], '', '')
+ return (sectmatches[1] or namematches[1] or results[1]):gsub('\n+$', '')
end
----@param text string
----@param pat_or_re string
-local function matchstr(text, pat_or_re)
- local re = type(pat_or_re) == 'string' and vim.regex(pat_or_re) or pat_or_re
-
- ---@type integer, integer
- local s, e = re:match_str(text)
-
- if s == nil then
- return
+--- Attempt to extract the name and sect out of 'name(sect)'
+--- otherwise just return the largest string of valid characters in ref
+--- @param ref string
+--- @return string? name
+--- @return string? sect
+--- @return string? err
+local function parse_ref(ref)
+ if ref == '' or ref:sub(1, 1) == '-' then
+ return nil, nil, ('invalid manpage reference "%s"'):format(ref)
end
- return text:sub(vim.str_utfindex(text, 'utf-32', s) + 1, vim.str_utfindex(text, 'utf-32', e))
-end
+ -- match "<name>(<sect>)"
+ -- note: name can contain spaces
+ local name, sect = ref:match('([^()]+)%(([^()]+)%)')
+ if name then
+ -- see ':Man 3X curses' on why tolower.
+ -- TODO(nhooyr) Not sure if this is portable across OSs
+ -- but I have not seen a single uppercase section.
+ return name, sect:lower()
+ end
--- attempt to extract the name and sect out of 'name(sect)'
--- otherwise just return the largest string of valid characters in ref
----@param ref string
----@return string, string
-local function extract_sect_and_name_ref(ref)
- ref = ref or ''
- if ref:sub(1, 1) == '-' then -- try ':Man -pandoc' with this disabled.
- man_error("manpage name cannot start with '-'")
- end
- local ref1 = ref:match('[^()]+%([^()]+%)')
- if not ref1 then
- local name = ref:match('[^()]+')
- if not name then
- man_error('manpage reference cannot contain only parentheses: ' .. ref)
- end
- return '', name
- end
- local parts = vim.split(ref1, '(', { plain = true })
- -- see ':Man 3X curses' on why tolower.
- -- TODO(nhooyr) Not sure if this is portable across OSs
- -- but I have not seen a single uppercase section.
- local sect = vim.split(parts[2] or '', ')', { plain = true })[1]:lower()
- local name = parts[1]
- return sect, name
+ name = ref:match('[^()]+')
+ if not name then
+ return nil, nil, ('invalid manpage reference "%s"'):format(ref)
+ end
+ return name
end
--- find_path attempts to find the path to a manpage
--- based on the passed section and name.
---
--- 1. If manpage could not be found with the given sect and name,
--- then try all the sections in b:man_default_sects.
--- 2. If it still could not be found, then we try again without a section.
--- 3. If still not found but $MANSECT is set, then we try again with $MANSECT
--- unset.
--- 4. If a path still wasn't found, return nil.
----@param sect string?
----@param name string
-function M.find_path(sect, name)
+--- Attempts to find the path to a manpage based on the passed section and name.
+---
+--- 1. If manpage could not be found with the given sect and name,
+--- then try all the sections in b:man_default_sects.
+--- 2. If it still could not be found, then we try again without a section.
+--- 3. If still not found but $MANSECT is set, then we try again with $MANSECT
+--- unset.
+--- 4. If a path still wasn't found, return nil.
+--- @param name string?
+--- @param sect string?
+--- @return string? path
+function M._find_path(name, sect)
if sect and sect ~= '' then
- local ret = get_path(sect, name, true)
+ local ret = get_path(name, sect)
if ret then
return ret
end
end
if vim.b.man_default_sects ~= nil then
- local sects = vim.split(vim.b.man_default_sects, ',', { plain = true, trimempty = true })
- for _, sec in ipairs(sects) do
- local ret = get_path(sec, name, true)
+ for sec in vim.gsplit(vim.b.man_default_sects, ',', { trimempty = true }) do
+ local ret = get_path(name, sec)
if ret then
return ret
end
@@ -364,17 +330,18 @@ function M.find_path(sect, name)
end
-- if none of the above worked, we will try with no section
- local res_empty_sect = get_path('', name, true)
- if res_empty_sect then
- return res_empty_sect
+ local ret = get_path(name)
+ if ret then
+ return ret
end
-- if that still didn't work, we will check for $MANSECT and try again with it
-- unset
if vim.env.MANSECT then
+ --- @type string
local mansect = vim.env.MANSECT
vim.env.MANSECT = nil
- local res = get_path('', name, tr