aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/shared.lua
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:23:01 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:23:01 +0000
commit142d9041391780ac15b89886a54015fdc5c73995 (patch)
tree0f6b5cac1a60810a03f52826c9e67c9e2780b033 /runtime/lua/vim/shared.lua
parentad86b5db74922285699ab2a1dbb2ff20e6268a33 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-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.lua97
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>