diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua new file mode 100644 index 0000000000..9c49d93596 --- /dev/null +++ b/runtime/lua/vim/shared.lua @@ -0,0 +1,39 @@ +--- Shared functions +-- - Used by Nvim and tests +-- - Can run in vanilla Lua (do not require a running instance of Nvim) + + +--- Merge map-like tables. +-- +--@see |extend()| +-- +-- behavior: Decides what to do if a key is found in more than one map: +-- "error": raise an error +-- "keep": skip +-- "force": set the item again +local function tbl_extend(behavior, ...) + if (behavior ~= 'error' and behavior ~= 'keep' and behavior ~= 'force') then + error('invalid "behavior": '..tostring(behavior)) + end + local ret = {} + for i = 1, select('#', ...) do + local tbl = select(i, ...) + if tbl then + for k, v in pairs(tbl) do + if behavior ~= 'force' and ret[k] ~= nil then + if behavior == 'error' then + error('key found in more than one map: '..k) + end -- Else behavior is "keep". + else + ret[k] = v + end + end + end + end + return ret +end + +local module = { + tbl_extend = tbl_extend, +} +return module diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index b0d0bfc74b..1a7aec6cc6 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -1,3 +1,39 @@ +-- Nvim-Lua stdlib: the `vim` module (:help lua-stdlib) +-- +-- Lua code lives in one of three places: +-- 1. The runtime (`runtime/lua/vim/`). For "nice to have" features, e.g. +-- the `inspect` and `lpeg` modules. +-- 2. The `vim.shared` module: code shared between Nvim and its test-suite. +-- 3. Compiled-into Nvim itself (`src/nvim/lua/`). +-- +-- Guideline: "If in doubt, put it in the runtime". +-- +-- Most functions should live directly on `vim.`, not sub-modules. The only +-- "forbidden" names are those claimed by legacy `if_lua`: +-- $ vim +-- :lua for k,v in pairs(vim) do print(k) end +-- buffer +-- open +-- window +-- lastline +-- firstline +-- type +-- line +-- eval +-- dict +-- beep +-- list +-- command +-- +-- Reference (#6580): +-- - https://github.com/luafun/luafun +-- - https://github.com/rxi/lume +-- - http://leafo.net/lapis/reference/utilities.html +-- - https://github.com/torch/paths +-- - https://github.com/bakpakin/Fennel (pretty print, repl) +-- - https://github.com/howl-editor/howl/tree/master/lib/howl/util + + -- Internal-only until comments in #8107 are addressed. -- Returns: -- {errcode}, {output} @@ -187,10 +223,14 @@ deepcopy = function(orig) return deepcopy_funcs[type(orig)](orig) end -local function __index(table, key) - if key == "inspect" then - table.inspect = require("vim.inspect") - return table.inspect +local function __index(t, key) + if key == 'inspect' then + t.inspect = require('vim.inspect') + return t.inspect + elseif require('vim.shared')[key] ~= nil then + -- Expose all `vim.shared` functions on the `vim` module. + t[key] = require('vim.shared')[key] + return t[key] end end diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 00acd12247..ae11455b3e 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -846,7 +846,7 @@ local module = { window = window, winmeths = winmeths, } -module = global_helpers.map_extend('error', module, global_helpers) +module = global_helpers.tbl_extend('error', module, global_helpers) return function(after_each) if after_each then diff --git a/test/helpers.lua b/test/helpers.lua index 966b7b408f..e987fa69db 100644 --- a/test/helpers.lua +++ b/test/helpers.lua @@ -1,4 +1,5 @@ require('vim.compat') +local shared = require('vim.shared') local assert = require('luassert') local luv = require('luv') local lfs = require('lfs') @@ -435,34 +436,6 @@ local function concat_tables(...) return ret end --- Concat map-like tables. --- --- behavior: Decides what to do if a key is found in more than one map: --- "error": raise an error --- "keep": skip --- "force": set the item again -local function map_extend(behavior, ...) - if (behavior ~= 'error' and behavior ~= 'keep' and behavior ~= 'force') then - error('invalid "behavior": '..tostring(behavior)) - end - local ret = {} - for i = 1, select('#', ...) do - local tbl = select(i, ...) - if tbl then - for k, v in pairs(tbl) do - if behavior ~= 'force' and ret[k] ~= nil then - if behavior == 'error' then - error('key found in more than one map: '..k) - end -- Else behavior is "keep". - else - ret[k] = v - end - end - end - end - return ret -end - local function dedent(str, leave_indent) -- find minimum common indent across lines local indent = nil @@ -801,7 +774,6 @@ local module = { intchar2lua = intchar2lua, isCI = isCI, map = map, - map_extend = map_extend, matches = matches, mergedicts_copy = mergedicts_copy, near = near, @@ -816,6 +788,7 @@ local module = { shallowcopy = shallowcopy, sleep = sleep, table_contains = table_contains, + tbl_extend = shared.tbl_extend, table_flatten = table_flatten, tmpname = tmpname, uname = uname, @@ -823,6 +796,6 @@ local module = { which = which, write_file = write_file, } -module = map_extend('error', module, Paths) +module = shared.tbl_extend('error', module, Paths) return module diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua index c42eddf7f3..e634b7296e 100644 --- a/test/unit/helpers.lua +++ b/test/unit/helpers.lua @@ -865,7 +865,7 @@ local module = { ptr2key = ptr2key, debug_log = debug_log, } -module = global_helpers.map_extend('error', module, global_helpers) +module = global_helpers.tbl_extend('error', module, global_helpers) return function() return module end