diff --git a/runtime/lua/editorconfig.lua b/runtime/lua/editorconfig.lua index 12a1548ee7..b743d01a94 100644 --- a/runtime/lua/editorconfig.lua +++ b/runtime/lua/editorconfig.lua @@ -130,7 +130,7 @@ function properties.indent_size(bufnr, val, opts) vim.bo[bufnr].shiftwidth = 0 vim.bo[bufnr].softtabstop = 0 else - local n = assert(tonumber(val), 'indent_size must be a number') + local n = assert(vim._tointeger(val), 'indent_size must be an integer') vim.bo[bufnr].shiftwidth = n vim.bo[bufnr].softtabstop = -1 if not opts.tab_width then @@ -141,17 +141,17 @@ end --- The display size of a single tab character. Sets the 'tabstop' option. function properties.tab_width(bufnr, val) - vim.bo[bufnr].tabstop = assert(tonumber(val), 'tab_width must be a number') + vim.bo[bufnr].tabstop = assert(vim._tointeger(val), 'tab_width must be an integer') end --- A number indicating the maximum length of a single --- line. Sets the 'textwidth' option. function properties.max_line_length(bufnr, val) - local n = tonumber(val) + local n = vim._tointeger(val) if n then vim.bo[bufnr].textwidth = n else - assert(val == 'off', 'max_line_length must be a number or "off"') + assert(val == 'off', 'max_line_length must be an integer or "off"') vim.bo[bufnr].textwidth = 0 end end diff --git a/runtime/lua/man.lua b/runtime/lua/man.lua index 1104e7f906..ef1e6e51eb 100644 --- a/runtime/lua/man.lua +++ b/runtime/lua/man.lua @@ -438,7 +438,7 @@ local function get_page(path, silent) if (vim.g.man_hardwrap or 1) ~= 1 then manwidth = 999 elseif vim.env.MANWIDTH then - vim.env.MANWIDTH = tonumber(vim.env.MANWIDTH) or 0 + vim.env.MANWIDTH = vim._tointeger(vim.env.MANWIDTH) or 0 manwidth = math.min(vim.env.MANWIDTH, api.nvim_win_get_width(0) - vim.o.wrapmargin) else manwidth = api.nvim_win_get_width(0) - vim.o.wrapmargin diff --git a/runtime/lua/nvim/tutor.lua b/runtime/lua/nvim/tutor.lua index 730469f3e6..53a417f366 100644 --- a/runtime/lua/nvim/tutor.lua +++ b/runtime/lua/nvim/tutor.lua @@ -57,7 +57,7 @@ function M.apply_marks() vim.b.tutor_extmarks = {} for expct, _ in pairs(vim.b.tutor_metadata.expect) do ---@diagnostic disable-next-line: assign-type-mismatch - local lnum = tonumber(expct) ---@type integer + local lnum = vim._ensure_integer(expct) vim.api.nvim_buf_set_extmark(0, tutor_hl_ns, lnum - 1, 0, { line_hl_group = 'tutorExpect', invalidate = true, diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index a709d4de63..6d46a26a11 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -228,9 +228,8 @@ local function cterm_to_hex(colorstr) if colorstr:sub(1, 1) == '#' then return colorstr end - assert(colorstr ~= '') - local color = tonumber(colorstr) --[[@as integer]] - assert(color and 0 <= color and color <= 255) + local color = vim._ensure_integer(colorstr) + assert(0 <= color and color <= 255) if cterm_color_cache[color] then return cterm_color_cache[color] end @@ -239,7 +238,7 @@ local function cterm_to_hex(colorstr) cterm_color_cache[color] = hex else notify("Couldn't get terminal colors, using fallback") - local t_Co = tonumber(vim.api.nvim_eval('&t_Co')) + local t_Co = vim._ensure_integer(vim.api.nvim_eval('&t_Co')) if t_Co <= 8 then cterm_color_cache = cterm_8_to_hex elseif t_Co == 88 then @@ -744,7 +743,7 @@ local function styletable_statuscolumn(state) signcolumn = 'auto' end if signcolumn ~= 'no' then - local max = tonumber(signcolumn:match('^%w-:(%d)')) --[[@as integer?]] or 1 + local max = vim._tointeger(signcolumn:match('^%w-:(%d)')) or 1 if signcolumn:match('^auto') then --- @type table local signcount = {} @@ -771,7 +770,7 @@ local function styletable_statuscolumn(state) local foldcolumn = state.opt.foldcolumn if foldcolumn ~= '0' then if foldcolumn:match('^auto') then - local max = tonumber(foldcolumn:match('^%w-:(%d)')) --[[@as integer?]] or 1 + local max = vim._tointeger(foldcolumn:match('^%w-:(%d)')) or 1 local maxfold = 0 vim._with({ buf = state.bufnr }, function() for row = state.start, state.end_ do @@ -783,7 +782,7 @@ local function styletable_statuscolumn(state) end) minwidth = minwidth + math.min(maxfold, max) else - minwidth = minwidth + tonumber(foldcolumn) --[[@as integer]] + minwidth = minwidth + vim._ensure_integer(foldcolumn) end end diff --git a/runtime/lua/vim/_core/defaults.lua b/runtime/lua/vim/_core/defaults.lua index f6b4f18e61..10611be194 100644 --- a/runtime/lua/vim/_core/defaults.lua +++ b/runtime/lua/vim/_core/defaults.lua @@ -794,12 +794,12 @@ do return nil end - local val = tonumber(c, 16) + local val = vim._tointeger(c, 16) if not val then return nil end - local max = assert(tonumber(string.rep('f', #c), 16)) + local max = vim._ensure_integer(string.rep('f', #c), 16) return val / max end @@ -1001,9 +1001,9 @@ do end if - tonumber(params[#params - 2]) == r - and tonumber(params[#params - 1]) == g - and tonumber(params[#params]) == b + vim._tointeger(params[#params - 2]) == r + and vim._tointeger(params[#params - 1]) == g + and vim._tointeger(params[#params]) == b then setoption('termguicolors', true) end diff --git a/runtime/lua/vim/_core/editor.lua b/runtime/lua/vim/_core/editor.lua index 680791c4d3..49adc6ff7e 100644 --- a/runtime/lua/vim/_core/editor.lua +++ b/runtime/lua/vim/_core/editor.lua @@ -1,3 +1,5 @@ +local tointeger = vim._tointeger + -- Nvim-Lua stdlib: the `vim` module (:help lua-stdlib) -- @@ -74,7 +76,7 @@ function vim._os_proc_info(pid) local ppid_string = assert(vim.system({ 'ps', '-p', pid, '-o', 'ppid=' }):wait().stdout) -- Remove trailing whitespace. name = vim.trim(name):gsub('^.*/', '') - local ppid = tonumber(ppid_string) or -1 + local ppid = tointeger(ppid_string) or -1 return { name = name, pid = pid, @@ -95,12 +97,9 @@ function vim._os_proc_children(ppid) elseif r.code ~= 0 then error('command failed: ' .. vim.fn.string(cmd)) end - local children = {} + local children = {} --- @type integer[] for s in r.stdout:gmatch('%S+') do - local i = tonumber(s) - if i ~= nil then - table.insert(children, i) - end + children[#children + 1] = tointeger(s) end return children end @@ -476,17 +475,17 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive) local c2 --- @type number if regtype:byte() == 22 then -- block selection: take width from regtype c1 = pos1[2] - c2 = c1 + tonumber(regtype:sub(2)) + c2 = c1 + vim._ensure_integer(regtype:sub(2)) -- and adjust for non-ASCII characters local bufline = vim.api.nvim_buf_get_lines(bufnr, l, l + 1, true)[1] local utflen = vim.str_utfindex(bufline, 'utf-32', #bufline) if c1 <= utflen then - c1 = assert(tonumber(vim.str_byteindex(bufline, 'utf-32', c1))) + c1 = vim.str_byteindex(bufline, 'utf-32', c1) else c1 = #bufline + 1 end if c2 <= utflen then - c2 = assert(tonumber(vim.str_byteindex(bufline, 'utf-32', c2))) + c2 = vim.str_byteindex(bufline, 'utf-32', c2) else c2 = #bufline + 1 end @@ -1264,7 +1263,7 @@ function vim.deprecate(name, alternative, version, plugin, backtrace) -- Example: if removal `version` is 0.12 (soft-deprecated since 0.10-dev), show warnings -- starting at 0.11, including 0.11-dev. local major, minor = version:match('(%d+)%.(%d+)') - major, minor = tonumber(major), tonumber(minor) + major, minor = tointeger(major), tointeger(minor) local nvim_major = 0 --- Current Nvim major version. -- We can't "subtract" from a major version, so: diff --git a/runtime/lua/vim/_core/options.lua b/runtime/lua/vim/_core/options.lua index e98b95f837..d826df5c00 100644 --- a/runtime/lua/vim/_core/options.lua +++ b/runtime/lua/vim/_core/options.lua @@ -692,7 +692,7 @@ local function create_option_accessor(scope) local option_mt local function make_option(name, value) - local info = assert(get_options_info(name), 'Not a valid option name: ' .. name) + local info = get_options_info(name) or error('Not a valid option name: ' .. name) if type(value) == 'table' and getmetatable(value) == option_mt then assert(name == value._name, "must be the same value, otherwise that's weird.") diff --git a/runtime/lua/vim/_core/shared.lua b/runtime/lua/vim/_core/shared.lua index da50338d01..b898f0e45b 100644 --- a/runtime/lua/vim/_core/shared.lua +++ b/runtime/lua/vim/_core/shared.lua @@ -1620,6 +1620,35 @@ function vim._ensure_list(x) return { x } end +--- Coerces {x} to an integer, like `tonumber()`, but rejects fractional values. +--- +--- Returns `nil` if {x} cannot be converted with `tonumber()`, or if the +--- resulting number is not integral. +--- +--- @param x any Value to convert. +--- @param base? integer Numeric base passed to `tonumber()`. +--- @return integer? integer Converted integer value, or `nil`. +function vim._tointeger(x, base) + --- @diagnostic disable-next-line:param-type-mismatch optional `base` is equivalent to `tonumber(x)` + local nx = tonumber(x, base) + if nx and nx == math.floor(nx) then + --- @cast nx integer + return nx + end +end + +--- Coerces {x} to an integer and errors if conversion fails. +--- +--- This is the throwing counterpart to |vim._tointeger()| and should be used +--- when non-integer input is a programming error. +--- +--- @param x any Value to convert. +--- @param base? integer Numeric base passed to `tonumber()`. +--- @return integer integer Converted integer value. +function vim._ensure_integer(x, base) + return vim._tointeger(x, base) or error(('Cannot convert %s to integer'):format(x)) +end + -- Use max 32-bit signed int value to avoid overflow on 32-bit systems. #31633 vim._maxint = 2 ^ 32 - 1 diff --git a/runtime/lua/vim/deprecated/health.lua b/runtime/lua/vim/deprecated/health.lua index eed889d90a..901a107d6f 100644 --- a/runtime/lua/vim/deprecated/health.lua +++ b/runtime/lua/vim/deprecated/health.lua @@ -14,7 +14,7 @@ function M.check() local version, backtraces, alternative = v[1], v[2], v[3] local major, minor = version:match('(%d+)%.(%d+)') - major, minor = tonumber(major), tonumber(minor) + major, minor = vim._ensure_integer(major), vim._ensure_integer(minor) local removal_version = string.format('nvim-%d.%d', major, minor) local will_be_removed = vim.fn.has(removal_version) == 1 and 'was removed' or 'will be removed' diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 81862988fc..2f6afcafb6 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -2857,7 +2857,7 @@ function M.match(str, pat, groups, severity_map, defaults) if field == 'severity' then diagnostic[field] = severity_map[match] elseif field == 'lnum' or field == 'end_lnum' or field == 'col' or field == 'end_col' then - diagnostic[field] = assert(tonumber(match)) - 1 + diagnostic[field] = vim._ensure_integer(match) - 1 elseif field then diagnostic[field] = match end diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index dc26790d14..7eadf8cb78 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -790,8 +790,7 @@ function M.abspath(path) -- Windows allows paths like C:foo/bar, these paths are relative to the current working directory -- of the drive specified in the path - local cwd = (iswin and prefix:match('^%w:$')) and uv.fs_realpath(prefix) or uv.cwd() - assert(cwd ~= nil) + local cwd = assert((iswin and prefix:match('^%w:$')) and uv.fs_realpath(prefix) or uv.cwd()) -- Convert cwd path separator to `/` cwd = cwd:gsub(os_sep, '/') diff --git a/runtime/lua/vim/func/_memoize.lua b/runtime/lua/vim/func/_memoize.lua index c46f878067..c79ca596db 100644 --- a/runtime/lua/vim/func/_memoize.lua +++ b/runtime/lua/vim/func/_memoize.lua @@ -24,11 +24,15 @@ local function resolve_hash(hash) if type(hash) == 'number' then hash = idx_hash(hash) elseif type(hash) == 'string' then - local c = hash == 'concat' or hash:match('^concat%-(%d+)') - if c then - hash = concat_hash(tonumber(c)) + if hash == 'concat' then + hash = concat_hash() else - error('invalid value for hash: ' .. hash) + local c = hash:match('^concat%-(%d+)') + if c then + hash = concat_hash(vim._ensure_integer(c)) + else + error('invalid value for hash: ' .. hash) + end end end --- @cast hash -integer diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua index 663d4872bd..e22e72c589 100644 --- a/runtime/lua/vim/health.lua +++ b/runtime/lua/vim/health.lua @@ -147,7 +147,7 @@ local function filepath_to_healthcheck(path) -- */health/init.lua name = vim.fs.dirname(vim.fs.dirname(subpath)) end - name = assert(name:gsub('/', '.')) --- @type string + name = assert(name:gsub('/', '.')) --[[@as string]] func = 'require("' .. name .. '.health").check()' filetype = 'l' diff --git a/runtime/lua/vim/health/health.lua b/runtime/lua/vim/health/health.lua index 42e7bdb067..b48f2306a2 100644 --- a/runtime/lua/vim/health/health.lua +++ b/runtime/lua/vim/health/health.lua @@ -295,10 +295,15 @@ local function check_tmux() if tmux_esc_time ~= 'error' then if tmux_esc_time == '' then health.error('`escape-time` is not set', suggestions) - elseif tonumber(tmux_esc_time) > 300 then - health.error('`escape-time` (' .. tmux_esc_time .. ') is higher than 300ms', suggestions) else - health.ok('escape-time: ' .. tmux_esc_time) + local tmux_esc_time_ms = vim._tointeger(tmux_esc_time) + if not tmux_esc_time_ms then + health.error('`escape-time` (' .. tmux_esc_time .. ') is not an integer', suggestions) + elseif tmux_esc_time_ms > 300 then + health.error('`escape-time` (' .. tmux_esc_time .. ') is higher than 300ms', suggestions) + else + health.ok('escape-time: ' .. tmux_esc_time) + end end end diff --git a/runtime/lua/vim/loader.lua b/runtime/lua/vim/loader.lua index c5279990d1..6aa79a0244 100644 --- a/runtime/lua/vim/loader.lua +++ b/runtime/lua/vim/loader.lua @@ -174,13 +174,21 @@ local function read_cachefile(cname) --- @type integer[]|{[0]:integer} local header = vim.split(data:sub(1, zero - 1), ',') - if tonumber(header[1]) ~= VERSION then + local version = vim._tointeger(header[1]) + if version ~= VERSION then + return + end + + local size = vim._tointeger(header[2]) + local sec = vim._tointeger(header[3]) + local nsec = vim._tointeger(header[4]) + if not (size and sec and nsec) then return end local hash = { - size = tonumber(header[2]), - mtime = { sec = tonumber(header[3]), nsec = tonumber(header[4]) }, + size = size, + mtime = { sec = sec, nsec = nsec }, } local chunk = data:sub(zero + 1) diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 0764c28b44..aad7958aeb 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1136,7 +1136,7 @@ api.nvim_create_autocmd('VimLeavePre', { local max_timeout = 0 for _, client in pairs(active_clients) do - max_timeout = math.max(max_timeout, tonumber(client.exit_timeout) or 0) + max_timeout = math.max(max_timeout, vim._tointeger(client.exit_timeout) or 0) client:stop(client.exit_timeout) end diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua index 3d54b12656..e3c9feb46a 100644 --- a/runtime/lua/vim/lsp/_changetracking.lua +++ b/runtime/lua/vim/lsp/_changetracking.lua @@ -32,8 +32,8 @@ local M = {} --- @field lines string[] snapshot of buffer lines from last didChange --- @field lines_tmp string[] --- @field pending_changes table[] List of debounced changes in incremental sync mode ---- @field timer uv.uv_timer_t? uv_timer ---- @field last_flush nil|number uv.hrtime of the last flush/didChange-notification +--- @field timer? uv.uv_timer_t uv_timer +--- @field last_flush? number uv.hrtime of the last flush/didChange-notification --- @field needs_flush boolean true if buffer updates haven't been sent to clients/servers yet --- @field refs integer how many clients are using this group --- @@ -68,7 +68,7 @@ local function get_group(client) local change_capability = vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'change') local sync_kind = change_capability or protocol.TextDocumentSyncKind.None if not allow_inc_sync and change_capability == protocol.TextDocumentSyncKind.Incremental then - sync_kind = protocol.TextDocumentSyncKind.Full --[[@as integer]] + sync_kind = protocol.TextDocumentSyncKind.Full end return { sync_kind = sync_kind, diff --git a/runtime/lua/vim/lsp/_snippet_grammar.lua b/runtime/lua/vim/lsp/_snippet_grammar.lua index f06d6e9afd..7828b2a994 100644 --- a/runtime/lua/vim/lsp/_snippet_grammar.lua +++ b/runtime/lua/vim/lsp/_snippet_grammar.lua @@ -174,9 +174,7 @@ local G = P({ --- @param input string --- @return vim.snippet.Node function M.parse(input) - local snippet = G:match(input) - assert(snippet, 'snippet parsing failed') - return snippet --- @type vim.snippet.Node + return assert(G:match(input), 'snippet parsing failed') end return M diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 635c2cde76..d7d5b46ba6 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -713,10 +713,8 @@ end --- @see |vim.lsp.buf_request_all()| function Client:request(method, params, handler, bufnr) if not handler then - handler = assert( - self:_resolve_handler(method), - string.format('not found: %q request handler for client %q.', method, self.name) - ) + handler = self:_resolve_handler(method) + or error(('not found: %q request handler for client %q.'):format(method, self.name)) end -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state changetracking.flush(self, bufnr) diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index d70a61d0da..66880ae8d1 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -324,7 +324,13 @@ local function generate_kind(item) -- extract hex from RGB format local r, g, b = doc:match('rgb%((%d+)%s*,?%s*(%d+)%s*,?%s*(%d+)%)') - local hex = r and string.format('%02x%02x%02x', tonumber(r), tonumber(g), tonumber(b)) + local hex = r + and string.format( + '%02x%02x%02x', + vim._ensure_integer(r), + vim._ensure_integer(g), + vim._ensure_integer(b) + ) or doc:match('#?([%da-fA-F]+)') if not hex then @@ -696,7 +702,7 @@ function CompletionResolver:is_valid() return vim.api.nvim_buf_is_valid(self.bufnr) and vim.api.nvim_get_current_buf() == self.bufnr and vim.startswith(vim.api.nvim_get_mode().mode, 'i') - and tonumber(vim.fn.pumvisible()) == 1 + and vim.fn.pumvisible() ~= 0 and (vim.tbl_get(cmp_info, 'completed', 'word') or '') == self.word, cmp_info end @@ -916,7 +922,7 @@ local function trigger(bufnr, clients, ctx) reset_timer() Context:cancel_pending() - if tonumber(vim.fn.pumvisible()) == 1 and not Context.isIncomplete then + if vim.fn.pumvisible() ~= 0 and not Context.isIncomplete then return end @@ -1018,7 +1024,7 @@ end --- @param handle vim.lsp.completion.BufHandle local function on_insert_char_pre(handle) - if tonumber(vim.fn.pumvisible()) == 1 then + if vim.fn.pumvisible() ~= 0 then if Context.isIncomplete then reset_timer() @@ -1143,8 +1149,7 @@ local function enable_completions(client_id, bufnr, opts) end if not buf_handle.clients[client_id] then - local client = lsp.get_client_by_id(client_id) - assert(client, 'invalid client ID') + local client = assert(lsp.get_client_by_id(client_id), 'invalid client ID') -- Add the new client to the buffer's clients. buf_handle.clients[client_id] = client @@ -1245,7 +1250,6 @@ end --- - findstart=1: list of matches (actually just calls |complete()|) function M._omnifunc(findstart, base) lsp.log.debug('omnifunc.findstart', { findstart = findstart, base = base }) - assert(base) -- silence luals local bufnr = api.nvim_get_current_buf() local clients = lsp.get_clients({ bufnr = bufnr, method = 'textDocument/completion' }) local remaining = #clients diff --git a/runtime/lua/vim/lsp/document_color.lua b/runtime/lua/vim/lsp/document_color.lua index 0b9e1a415c..1c6e3d40d0 100644 --- a/runtime/lua/vim/lsp/document_color.lua +++ b/runtime/lua/vim/lsp/document_color.lua @@ -47,10 +47,9 @@ local function get_contrast_color(color) if not (r_s and g_s and b_s) then error('Invalid color format: ' .. color) end - local r, g, b = tonumber(r_s, 16), tonumber(g_s, 16), tonumber(b_s, 16) - if not (r and g and b) then - error('Invalid color format: ' .. color) - end + local r = vim._ensure_integer(r_s, 16) + local g = vim._ensure_integer(g_s, 16) + local b = vim._ensure_integer(b_s, 16) -- Source: https://www.w3.org/TR/WCAG21/#dfn-relative-luminance -- Using power 2.2 is a close approximation to full piecewise transform diff --git a/runtime/lua/vim/lsp/health.lua b/runtime/lua/vim/lsp/health.lua index 14502851a5..c868affa10 100644 --- a/runtime/lua/vim/lsp/health.lua +++ b/runtime/lua/vim/lsp/health.lua @@ -137,8 +137,7 @@ local function check_watcher() return end - local watchfunc = vim.lsp._watchfiles._watchfunc - assert(watchfunc) + local watchfunc = assert(vim.lsp._watchfiles._watchfunc) local watchfunc_name --- @type string if watchfunc == vim._watch.watch then watchfunc_name = 'libuv-watch' diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index a34a04bffd..d75b3ed18f 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -56,7 +56,10 @@ local function get_content_length(header) elseif state == 'value' then if c == 13 and header:byte(i + 1) == 10 then -- must end with \r\n local value = buf:get() - return assert(digit and tonumber(value), 'value of Content-Length is not number: ' .. value) + if digit then + return vim._ensure_integer(value) + end + error('value of Content-Length is not number: ' .. value) else buf:put(string.char(c)) end @@ -429,7 +432,7 @@ function Client:handle_body(body) ) then -- We sent a number, so we expect a number. - local result_id = assert(tonumber(decoded.id), 'response id must be a number') --[[@as integer]] + local result_id = vim._ensure_integer(decoded.id) -- Notify the user that a response was received for the request local notify_reply_callback = self.notify_reply_callbacks[result_id] diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index a0ac87afec..b58286b7b7 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -636,8 +636,7 @@ function M.rename(old_fname, new_fname, opts) local newdir = vim.fs.dirname(new_fname) vim.fn.mkdir(newdir, 'p') - local ok, err = os.rename(old_fname_full, new_fname) - assert(ok, err) + assert(os.rename(old_fname_full, new_fname)) local old_undofile = vim.fn.undofile(old_fname_full) if uv.fs_stat(old_undofile) ~= nil then @@ -1745,10 +1744,10 @@ function M.open_floating_preview(contents, syntax, opts) api.nvim_create_autocmd('WinClosed', { group = api.nvim_create_augroup('nvim.closing_floating_preview', { clear = true }), callback = function(args) - local winid = tonumber(args.match) - local ok, preview_bufnr = pcall(api.nvim_win_get_var, winid, 'lsp_floating_bufnr') + local winid = vim._tointeger(args.match) + local preview_bufnr = vim.w[winid].lsp_floating_bufnr if - ok + preview_bufnr and api.nvim_buf_is_valid(preview_bufnr) and winid == vim.b[preview_bufnr].lsp_floating_preview then diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua index 6d9b8dc9a1..a218a38d6a 100644 --- a/runtime/lua/vim/pack.lua +++ b/runtime/lua/vim/pack.lua @@ -1157,7 +1157,7 @@ local function show_confirm_buf(lines, on_finish) --- @type integer local cancel_au_id local function on_cancel(data) - if tonumber(data.match) ~= win_id then + if vim._tointeger(data.match) ~= win_id then return end pcall(api.nvim_del_autocmd, cancel_au_id) diff --git a/runtime/lua/vim/pack/_lsp.lua b/runtime/lua/vim/pack/_lsp.lua index f40d65ddea..7eedf9dfe5 100644 --- a/runtime/lua/vim/pack/_lsp.lua +++ b/runtime/lua/vim/pack/_lsp.lua @@ -20,7 +20,7 @@ function methods.shutdown(_, callback) end local get_confirm_bufnr = function(uri) - return tonumber(uri:match('^nvim%-pack://confirm#(%d+)$')) + return vim._tointeger(uri:match('^nvim%-pack://confirm#(%d+)$')) end local group_header_pattern = '^# (%S+)' diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua index 7bfc860111..391d3487d1 100644 --- a/runtime/lua/vim/treesitter/_query_linter.lua +++ b/runtime/lua/vim/treesitter/_query_linter.lua @@ -86,7 +86,8 @@ local function get_error_entry(err, node) local start_line, start_col = node:range() local line_offset, col_offset, msg = err:gmatch('.-:%d+: Query error at (%d+):(%d+)%. ([^:]+)')() ---@type string, string, string start_line, start_col = - start_line + tonumber(line_offset) - 1, start_col + tonumber(col_offset) - 1 + start_line + vim._ensure_integer(line_offset) - 1, + start_col + vim._ensure_integer(col_offset) - 1 local end_line, end_col = start_line, start_col if msg:match('^Invalid syntax') or msg:match('^Impossible') then -- Use the length of the underlined node diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua index b71f0db9a7..9521ce3dfd 100644 --- a/runtime/lua/vim/treesitter/highlighter.lua +++ b/runtime/lua/vim/treesitter/highlighter.lua @@ -429,7 +429,7 @@ local function on_range_impl( -- The "priority" attribute can be set at the pattern level or on a particular capture local priority = ( - tonumber(metadata.priority or metadata[capture] and metadata[capture].priority) + vim._tointeger(metadata.priority or metadata[capture] and metadata[capture].priority) or vim.hl.priorities.treesitter ) + spell_pri_offset diff --git a/runtime/lua/vim/uri.lua b/runtime/lua/vim/uri.lua index 8b6f1a61ee..0e954bcb7a 100644 --- a/runtime/lua/vim/uri.lua +++ b/runtime/lua/vim/uri.lua @@ -25,7 +25,7 @@ local PATTERNS = { ---@param hex string ---@return string local function hex_to_char(hex) - return schar(tonumber(hex, 16)) + return schar(vim._ensure_integer(hex, 16)) end ---@param char string @@ -101,7 +101,7 @@ end ---@param uri string ---@return string filename or unchanged URI for non-file URIs function M.uri_to_fname(uri) - local scheme = assert(uri:match(URI_SCHEME_PATTERN), 'URI must contain a scheme: ' .. uri) + local scheme = uri:match(URI_SCHEME_PATTERN) or error('URI must contain a scheme: ' .. uri) if scheme ~= 'file' then return uri end diff --git a/runtime/lua/vim/version.lua b/runtime/lua/vim/version.lua index a904255490..652d645325 100644 --- a/runtime/lua/vim/version.lua +++ b/runtime/lua/vim/version.lua @@ -86,8 +86,12 @@ local function cmp_prerel(prerel1, prerel2) if word1 == nil and word2 == nil then -- Done iterating. return 0 end - word1, n1, word2, n2 = - word1 or '', n1 and tonumber(n1) or 0, word2 or '', n2 and tonumber(n2) or 0 + + word1 = word1 or '' + n1 = vim._tointeger(n1) or 0 + word2 = word2 or '' + n2 = vim._tointeger(n2) or 0 + if word1 ~= word2 then return word1 < word2 and -1 or 1 end @@ -197,9 +201,9 @@ function M._version(version, strict) -- Adapted from https://github.com/folke/la or (major and minor and patch and major ~= '' and minor ~= '' and patch ~= '') then return setmetatable({ - major = tonumber(major), - minor = minor == '' and 0 or tonumber(minor), - patch = patch == '' and 0 or tonumber(patch), + major = vim._ensure_integer(major), + minor = minor == '' and 0 or vim._ensure_integer(minor), + patch = patch == '' and 0 or vim._ensure_integer(patch), prerelease = prerel ~= '' and prerel or nil, build = build ~= '' and build or nil, }, Version) @@ -286,7 +290,6 @@ function M.range(spec) -- Adapted from https://github.com/folke/lazy.nvim return setmetatable({ from = M.parse('0.0.0') }, range_mt) end - ---@type number? local hyphen = spec:find(' - ', 1, true) if hyphen then local a = spec:sub(1, hyphen - 1) @@ -379,15 +382,15 @@ function M.intersect(r1, r2) end end ----@param v string|vim.Version +---@param v string|vim.Version|number[] ---@return string -local function create_err_msg(v) +local function err_msg(v) if type(v) == 'string' then - return string.format('invalid version: "%s"', tostring(v)) + return ('invalid version: "%s"'):format(v) elseif type(v) == 'table' and v.major then - return string.format('invalid version: %s', vim.inspect(v)) + return ('invalid version: %s'):format(vim.inspect(v)) end - return string.format('invalid version: %s (%s)', tostring(v), type(v)) + return ('invalid version: %s (%s)'):format(tostring(v), type(v)) end --- Parses and compares two version objects (the result of |vim.version.parse()|, or @@ -413,8 +416,8 @@ end ---@param v2 vim.Version|number[]|string Version to compare with `v1`. ---@return integer -1 if `v1 < v2`, 0 if `v1 == v2`, 1 if `v1 > v2`. function M.cmp(v1, v2) - local v1_parsed = assert(M._version(v1), create_err_msg(v1)) - local v2_parsed = assert(M._version(v2), create_err_msg(v1)) + local v1_parsed = M._version(v1) or error(err_msg(v1)) + local v2_parsed = M._version(v2) or error(err_msg(v2)) if v1_parsed == v2_parsed then return 0 end @@ -492,7 +495,9 @@ end ---@param opts vim.version.parse.Opts? Options for parsing. ---@return vim.Version? # `Version` object or `nil` if input is invalid. function M.parse(version, opts) - assert(type(version) == 'string', create_err_msg(version)) + if type(version) ~= 'string' then + error(err_msg(version)) + end opts = opts or { strict = false } return M._version(version, opts.strict) end