diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:23:01 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:23:01 +0000 |
commit | 142d9041391780ac15b89886a54015fdc5c73995 (patch) | |
tree | 0f6b5cac1a60810a03f52826c9e67c9e2780b033 /runtime/lua/vim/shared.lua | |
parent | ad86b5db74922285699ab2a1dbb2ff20e6268a33 (diff) | |
parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
download | rneovim-142d9041391780ac15b89886a54015fdc5c73995.tar.gz rneovim-142d9041391780ac15b89886a54015fdc5c73995.tar.bz2 rneovim-142d9041391780ac15b89886a54015fdc5c73995.zip |
Merge remote-tracking branch 'upstream/master' into userreg
Diffstat (limited to 'runtime/lua/vim/shared.lua')
-rw-r--r-- | runtime/lua/vim/shared.lua | 97 |
1 files changed, 63 insertions, 34 deletions
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index f03d608e56..cc48e3f193 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -49,6 +49,9 @@ vim.deepcopy = (function() if f then return f(orig, cache or {}) else + if type(orig) == 'userdata' and orig == vim.NIL then + return vim.NIL + end error('Cannot deepcopy object of type ' .. type(orig)) end end @@ -57,12 +60,13 @@ end)() --- Splits a string at each instance of a separator. --- ---@see |vim.split()| +---@see |luaref-patterns| ---@see https://www.lua.org/pil/20.2.html ---@see http://lua-users.org/wiki/StringLibraryTutorial --- ---@param s string String to split ---@param sep string Separator or pattern ----@param plain boolean If `true` use `sep` literally (passed to string.find) +---@param plain (boolean|nil) If `true` use `sep` literally (passed to string.find) ---@return fun():string (function) Iterator over the split components function vim.gsplit(s, sep, plain) vim.validate({ s = { s, 's' }, sep = { sep, 's' }, plain = { plain, 'b', true } }) @@ -99,20 +103,18 @@ end --- Splits a string at each instance of a separator. --- --- Examples: ---- <pre> ---- split(":aa::b:", ":") => {'','aa','','b',''} ---- split("axaby", "ab?") => {'','x','y'} ---- split("x*yz*o", "*", {plain=true}) => {'x','yz','o'} ---- split("|x|y|z|", "|", {trimempty=true}) => {'x', 'y', 'z'} +--- <pre>lua +--- split(":aa::b:", ":") --> {'','aa','','b',''} +--- split("axaby", "ab?") --> {'','x','y'} +--- split("x*yz*o", "*", {plain=true}) --> {'x','yz','o'} +--- split("|x|y|z|", "|", {trimempty=true}) --> {'x', 'y', 'z'} --- </pre> --- ---@see |vim.gsplit()| --- ----@alias split_kwargs {plain: boolean, trimempty: boolean} | boolean | nil ---- ---@param s string String to split ---@param sep string Separator or pattern ----@param kwargs? {plain: boolean, trimempty: boolean} (table|nil) Keyword arguments: +---@param kwargs (table|nil) Keyword arguments: --- - plain: (boolean) If `true` use `sep` literally (passed to string.find) --- - trimempty: (boolean) If `true` remove empty items from the front --- and back of the list @@ -159,8 +161,8 @@ end --- ---@see From https://github.com/premake/premake-core/blob/master/src/base/table.lua --- ----@param t table<T, any> (table) Table ---@generic T: table +---@param t table<T, any> (table) Table ---@return T[] (list) List of keys function vim.tbl_keys(t) assert(type(t) == 'table', string.format('Expected table, got %s', type(t))) @@ -382,7 +384,7 @@ end --- Return `nil` if the key does not exist. --- --- Examples: ---- <pre> +--- <pre>lua --- vim.tbl_get({ key = { nested_key = true }}, 'key', 'nested_key') == true --- vim.tbl_get({ key = {}}, 'key', 'nested_key') == nil --- </pre> @@ -394,15 +396,14 @@ end function vim.tbl_get(o, ...) local keys = { ... } if #keys == 0 then - return + return nil end for i, k in ipairs(keys) do - if type(o[k]) ~= 'table' and next(keys, i) then - return nil - end o = o[k] if o == nil then - return + return nil + elseif type(o) ~= 'table' and next(keys, i) then + return nil end end return o @@ -417,8 +418,8 @@ end ---@generic T: table ---@param dst T List which will be modified and appended to ---@param src table List from which values will be inserted ----@param start? number Start index on src. Defaults to 1 ----@param finish? number Final index on src. Defaults to `#src` +---@param start (number|nil) Start index on src. Defaults to 1 +---@param finish (number|nil) Final index on src. Defaults to `#src` ---@return T dst function vim.list_extend(dst, src, start, finish) vim.validate({ @@ -457,6 +458,33 @@ function vim.tbl_flatten(t) return result end +--- Enumerate a table sorted by its keys. +--- +---@see Based on https://github.com/premake/premake-core/blob/master/src/base/table.lua +--- +---@param t table List-like table +---@return iterator over sorted keys and their values +function vim.spairs(t) + assert(type(t) == 'table', string.format('Expected table, got %s', type(t))) + + -- collect the keys + local keys = {} + for k in pairs(t) do + table.insert(keys, k) + end + table.sort(keys) + + -- Return the iterator function. + -- TODO(justinmk): Return "iterator function, table {t}, and nil", like pairs()? + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], t[keys[i]] + end + end +end + --- Tests if a Lua table can be treated as an array. --- --- Empty table `{}` is assumed to be an array, unless it was created by @@ -486,7 +514,7 @@ function vim.tbl_islist(t) -- TODO(bfredl): in the future, we will always be inside nvim -- then this check can be deleted. if vim._empty_dict_mt == nil then - return nil + return false end return getmetatable(t) ~= vim._empty_dict_mt end @@ -494,9 +522,9 @@ end --- Counts the number of non-nil values in table `t`. --- ---- <pre> ---- vim.tbl_count({ a=1, b=2 }) => 2 ---- vim.tbl_count({ 1, 2 }) => 2 +--- <pre>lua +--- vim.tbl_count({ a=1, b=2 }) --> 2 +--- vim.tbl_count({ 1, 2 }) --> 2 --- </pre> --- ---@see https://github.com/Tieske/Penlight/blob/master/lua/pl/tablex.lua @@ -516,8 +544,8 @@ end --- ---@generic T ---@param list T[] (list) Table ----@param start number Start range of slice ----@param finish number End range of slice +---@param start number|nil Start range of slice +---@param finish number|nil End range of slice ---@return T[] (list) Copy of table sliced from start to finish (inclusive) function vim.list_slice(list, start, finish) local new_list = {} @@ -529,6 +557,7 @@ end --- Trim whitespace (Lua pattern "%s") from both sides of a string. --- +---@see |luaref-patterns| ---@see https://www.lua.org/pil/20.2.html ---@param s string String to trim ---@return string String with whitespace removed from its beginning and end @@ -544,7 +573,7 @@ end ---@return string %-escaped pattern string function vim.pesc(s) vim.validate({ s = { s, 's' } }) - return s:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', '%%%1') + return (s:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', '%%%1')) end --- Tests if `s` starts with `prefix`. @@ -570,7 +599,7 @@ end --- Validates a parameter specification (types and values). --- --- Usage example: ---- <pre> +--- <pre>lua --- function user.new(name, age, hobbies) --- vim.validate{ --- name={name, 'string'}, @@ -582,24 +611,24 @@ end --- </pre> --- --- Examples with explicit argument values (can be run directly): ---- <pre> +--- <pre>lua --- vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}} ---- => NOP (success) +--- --> NOP (success) --- --- vim.validate{arg1={1, 'table'}} ---- => error('arg1: expected table, got number') +--- --> error('arg1: expected table, got number') --- --- vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}} ---- => error('arg1: expected even number, got 3') +--- --> error('arg1: expected even number, got 3') --- </pre> --- --- If multiple types are valid they can be given as a list. ---- <pre> +--- <pre>lua --- vim.validate{arg1={{'foo'}, {'table', 'string'}}, arg2={'foo', {'table', 'string'}}} ---- => NOP (success) +--- --> NOP (success) --- --- vim.validate{arg1={1, {'string', table'}}} ---- => error('arg1: expected string|table, got number') +--- --> error('arg1: expected string|table, got number') --- --- </pre> --- @@ -734,7 +763,7 @@ end --- If {create} is `nil`, this will create a defaulttable whose constructor function is --- this function, effectively allowing to create nested tables on the fly: --- ---- <pre> +--- <pre>lua --- local a = vim.defaulttable() --- a.b.c = 1 --- </pre> |