diff options
author | Christian Clason <c.clason@uni-graz.at> | 2023-04-14 10:39:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-14 10:39:57 +0200 |
commit | 4d04feb6629cb049cb2a13ba35f0c8d3c6b67ff4 (patch) | |
tree | 17dadca32fa46116a9c576fc651a61bc5da8ece4 /runtime/lua/vim | |
parent | 72a327cad20fa2dbb214177cc48c533543d5b9e8 (diff) | |
download | rneovim-4d04feb6629cb049cb2a13ba35f0c8d3c6b67ff4.tar.gz rneovim-4d04feb6629cb049cb2a13ba35f0c8d3c6b67ff4.tar.bz2 rneovim-4d04feb6629cb049cb2a13ba35f0c8d3c6b67ff4.zip |
feat(lua): vim.tbl_contains supports general tables and predicates (#23040)
* feat(lua): vim.tbl_contains supports general tables and predicates
Problem: `vim.tbl_contains` only works for list-like tables (integer
keys without gaps) and primitive values (in particular, not for nested
tables).
Solution: Rename `vim.tbl_contains` to `vim.list_contains` and add new
`vim.tbl_contains` that works for general tables and optionally allows
`value` to be a predicate function that is checked for every key.
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/loader.lua | 4 | ||||
-rw-r--r-- | runtime/lua/vim/lsp.lua | 4 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/_snippet.lua | 4 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/codelens.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/shared.lua | 45 |
6 files changed, 51 insertions, 10 deletions
diff --git a/runtime/lua/vim/loader.lua b/runtime/lua/vim/loader.lua index 7f953adc21..66627fe4e7 100644 --- a/runtime/lua/vim/loader.lua +++ b/runtime/lua/vim/loader.lua @@ -449,7 +449,7 @@ function Loader.lsmod(path) if topname then Loader._indexed[path][topname] = { modpath = modpath, modname = topname } Loader._topmods[topname] = Loader._topmods[topname] or {} - if not vim.tbl_contains(Loader._topmods[topname], path) then + if not vim.list_contains(Loader._topmods[topname], path) then table.insert(Loader._topmods[topname], path) end end @@ -523,7 +523,7 @@ function M._inspect(opts) { ms(Loader._stats[stat].time / Loader._stats[stat].total) .. '\n', 'Bold' }, }) for k, v in pairs(Loader._stats[stat]) do - if not vim.tbl_contains({ 'time', 'total' }, k) then + if not vim.list_contains({ 'time', 'total' }, k) then chunks[#chunks + 1] = { '* ' .. k .. ':' .. string.rep(' ', 9 - #k) } chunks[#chunks + 1] = { tostring(v) .. '\n', 'Number' } end diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 3db3545786..5c78bd7580 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -171,7 +171,7 @@ local function for_each_buffer_client(bufnr, fn, restrict_client_ids) if restrict_client_ids and #restrict_client_ids > 0 then local filtered_client_ids = {} for client_id in pairs(client_ids) do - if vim.tbl_contains(restrict_client_ids, client_id) then + if vim.list_contains(restrict_client_ids, client_id) then filtered_client_ids[client_id] = true end end @@ -2186,7 +2186,7 @@ function lsp.formatexpr(opts) opts = opts or {} local timeout_ms = opts.timeout_ms or 500 - if vim.tbl_contains({ 'i', 'R', 'ic', 'ix' }, vim.fn.mode()) then + if vim.list_contains({ 'i', 'R', 'ic', 'ix' }, vim.fn.mode()) then -- `formatexpr` is also called when exceeding `textwidth` in insert mode -- fall back to internal formatting return 1 diff --git a/runtime/lua/vim/lsp/_snippet.lua b/runtime/lua/vim/lsp/_snippet.lua index 797d8960d5..e7ada5415f 100644 --- a/runtime/lua/vim/lsp/_snippet.lua +++ b/runtime/lua/vim/lsp/_snippet.lua @@ -17,14 +17,14 @@ P.take_until = function(targets, specials) table.insert(raw, '\\') new_pos = new_pos + 1 c = string.sub(input, new_pos, new_pos) - if not vim.tbl_contains(targets, c) and not vim.tbl_contains(specials, c) then + if not vim.list_contains(targets, c) and not vim.list_contains(specials, c) then table.insert(esc, '\\') end table.insert(raw, c) table.insert(esc, c) new_pos = new_pos + 1 else - if vim.tbl_contains(targets, c) then + if vim.list_contains(targets, c) then break end table.insert(raw, c) diff --git a/runtime/lua/vim/lsp/codelens.lua b/runtime/lua/vim/lsp/codelens.lua index 81cac6a511..005a0047fa 100644 --- a/runtime/lua/vim/lsp/codelens.lua +++ b/runtime/lua/vim/lsp/codelens.lua @@ -42,7 +42,7 @@ local function execute_lens(lens, bufnr, client_id) -- Need to use the client that returned the lens → must not use buf_request local command_provider = client.server_capabilities.executeCommandProvider local commands = type(command_provider) == 'table' and command_provider.commands or {} - if not vim.tbl_contains(commands, command.command) then + if not vim.list_contains(commands, command.command) then vim.notify( string.format( 'Language server does not support command `%s`. This command may require a client extension.', diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index dca258e4b9..31af2afb0b 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1476,7 +1476,7 @@ end local function close_preview_window(winnr, bufnrs) vim.schedule(function() -- exit if we are in one of ignored buffers - if bufnrs and vim.tbl_contains(bufnrs, api.nvim_get_current_buf()) then + if bufnrs and vim.list_contains(bufnrs, api.nvim_get_current_buf()) then return end diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index 9245adae3a..7ecb56eb92 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -252,12 +252,53 @@ function vim.tbl_filter(func, t) return rettab end ---- Checks if a list-like (vector) table contains `value`. +--- Checks if a table contains a given value, specified either directly or via +--- a predicate that is checked for each value. +--- +--- Example: +--- <pre>lua +--- vim.tbl_contains({ 'a', { 'b', 'c' } }, function(v) +--- return vim.deep_equal(v, { 'b', 'c' }) +--- end, { predicate = true }) +--- -- true +--- </pre> +--- +---@see |vim.list_contains()| for checking values in list-like tables --- ---@param t table Table to check +---@param value any Value to compare or predicate function reference +---@param opts (table|nil) Keyword arguments |kwargs|: +--- - predicate: (boolean) `value` is a function reference to be checked (default false) +---@return boolean `true` if `t` contains `value` +function vim.tbl_contains(t, value, opts) + vim.validate({ t = { t, 't' }, opts = { opts, 't', true } }) + + local pred + if opts and opts.predicate then + vim.validate({ value = { value, 'c' } }) + pred = value + else + pred = function(v) + return v == value + end + end + + for _, v in pairs(t) do + if pred(v) then + return true + end + end + return false +end + +--- Checks if a list-like table (integer keys without gaps) contains `value`. +--- +---@see |vim.tbl_contains()| for checking values in general tables +--- +---@param t table Table to check (must be list-like, not validated) ---@param value any Value to compare ---@return boolean `true` if `t` contains `value` -function vim.tbl_contains(t, value) +function vim.list_contains(t, value) vim.validate({ t = { t, 't' } }) for _, v in ipairs(t) do |