shared.lua 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. -- Functions shared by Nvim and its test-suite.
  2. --
  3. -- These are "pure" lua functions not depending of the state of the editor.
  4. -- Thus they should always be available whenever nvim-related lua code is run,
  5. -- regardless if it is code in the editor itself, or in worker threads/processes,
  6. -- or the test suite. (Eventually the test suite will be run in a worker process,
  7. -- so this wouldn't be a separate case to consider)
  8. local vim = vim or {}
  9. --- Returns a deep copy of the given object. Non-table objects are copied as
  10. --- in a typical Lua assignment, whereas table objects are copied recursively.
  11. --- Functions are naively copied, so functions in the copied table point to the
  12. --- same functions as those in the input table. Userdata and threads are not
  13. --- copied and will throw an error.
  14. ---
  15. ---@param orig table Table to copy
  16. ---@return table Table of copied keys and (nested) values.
  17. function vim.deepcopy(orig) end -- luacheck: no unused
  18. vim.deepcopy = (function()
  19. local function _id(v)
  20. return v
  21. end
  22. local deepcopy_funcs = {
  23. table = function(orig, cache)
  24. if cache[orig] then
  25. return cache[orig]
  26. end
  27. local copy = {}
  28. cache[orig] = copy
  29. local mt = getmetatable(orig)
  30. for k, v in pairs(orig) do
  31. copy[vim.deepcopy(k, cache)] = vim.deepcopy(v, cache)
  32. end
  33. return setmetatable(copy, mt)
  34. end,
  35. number = _id,
  36. string = _id,
  37. ['nil'] = _id,
  38. boolean = _id,
  39. ['function'] = _id,
  40. }
  41. return function(orig, cache)
  42. local f = deepcopy_funcs[type(orig)]
  43. if f then
  44. return f(orig, cache or {})
  45. else
  46. error('Cannot deepcopy object of type ' .. type(orig))
  47. end
  48. end
  49. end)()
  50. --- Splits a string at each instance of a separator.
  51. ---
  52. ---@see |vim.split()|
  53. ---@see https://www.lua.org/pil/20.2.html
  54. ---@see http://lua-users.org/wiki/StringLibraryTutorial
  55. ---
  56. ---@param s string String to split
  57. ---@param sep string Separator or pattern
  58. ---@param plain boolean If `true` use `sep` literally (passed to string.find)
  59. ---@return function Iterator over the split components
  60. function vim.gsplit(s, sep, plain)
  61. vim.validate({ s = { s, 's' }, sep = { sep, 's' }, plain = { plain, 'b', true } })
  62. local start = 1
  63. local done = false
  64. local function _pass(i, j, ...)
  65. if i then
  66. assert(j + 1 > start, 'Infinite loop detected')
  67. local seg = s:sub(start, i - 1)
  68. start = j + 1
  69. return seg, ...
  70. else
  71. done = true
  72. return s:sub(start)
  73. end
  74. end
  75. return function()
  76. if done or (s == '' and sep == '') then
  77. return
  78. end
  79. if sep == '' then
  80. if start == #s then
  81. done = true
  82. end
  83. return _pass(start + 1, start)
  84. end
  85. return _pass(s:find(sep, start, plain))
  86. end
  87. end
  88. --- Splits a string at each instance of a separator.
  89. ---
  90. --- Examples:
  91. --- <pre>
  92. --- split(":aa::b:", ":") => {'','aa','','b',''}
  93. --- split("axaby", "ab?") => {'','x','y'}
  94. --- split("x*yz*o", "*", {plain=true}) => {'x','yz','o'}
  95. --- split("|x|y|z|", "|", {trimempty=true}) => {'x', 'y', 'z'}
  96. --- </pre>
  97. ---
  98. ---@see |vim.gsplit()|
  99. ---
  100. ---@param s string String to split
  101. ---@param sep string Separator or pattern
  102. ---@param kwargs table Keyword arguments:
  103. --- - plain: (boolean) If `true` use `sep` literally (passed to string.find)
  104. --- - trimempty: (boolean) If `true` remove empty items from the front
  105. --- and back of the list
  106. ---@return table List of split components
  107. function vim.split(s, sep, kwargs)
  108. local plain
  109. local trimempty = false
  110. if type(kwargs) == 'boolean' then
  111. -- Support old signature for backward compatibility
  112. plain = kwargs
  113. else
  114. vim.validate({ kwargs = { kwargs, 't', true } })
  115. kwargs = kwargs or {}
  116. plain = kwargs.plain
  117. trimempty = kwargs.trimempty
  118. end
  119. local t = {}
  120. local skip = trimempty
  121. for c in vim.gsplit(s, sep, plain) do
  122. if c ~= '' then
  123. skip = false
  124. end
  125. if not skip then
  126. table.insert(t, c)
  127. end
  128. end
  129. if trimempty then
  130. for i = #t, 1, -1 do
  131. if t[i] ~= '' then
  132. break
  133. end
  134. table.remove(t, i)
  135. end
  136. end
  137. return t
  138. end
  139. --- Return a list of all keys used in a table.
  140. --- However, the order of the return table of keys is not guaranteed.
  141. ---
  142. ---@see From https://github.com/premake/premake-core/blob/master/src/base/table.lua
  143. ---
  144. ---@param t table Table
  145. ---@return table List of keys
  146. function vim.tbl_keys(t)
  147. assert(type(t) == 'table', string.format('Expected table, got %s', type(t)))
  148. local keys = {}
  149. for k, _ in pairs(t) do
  150. table.insert(keys, k)
  151. end
  152. return keys
  153. end
  154. --- Return a list of all values used in a table.
  155. --- However, the order of the return table of values is not guaranteed.
  156. ---
  157. ---@param t table Table
  158. ---@return table List of values
  159. function vim.tbl_values(t)
  160. assert(type(t) == 'table', string.format('Expected table, got %s', type(t)))
  161. local values = {}
  162. for _, v in pairs(t) do
  163. table.insert(values, v)
  164. end
  165. return values
  166. end
  167. --- Apply a function to all values of a table.
  168. ---
  169. ---@param func function|table Function or callable table
  170. ---@param t table Table
  171. ---@return table Table of transformed values
  172. function vim.tbl_map(func, t)
  173. vim.validate({ func = { func, 'c' }, t = { t, 't' } })
  174. local rettab = {}
  175. for k, v in pairs(t) do
  176. rettab[k] = func(v)
  177. end
  178. return rettab
  179. end
  180. --- Filter a table using a predicate function
  181. ---
  182. ---@param func function|table Function or callable table
  183. ---@param t table Table
  184. ---@return table Table of filtered values
  185. function vim.tbl_filter(func, t)
  186. vim.validate({ func = { func, 'c' }, t = { t, 't' } })
  187. local rettab = {}
  188. for _, entry in pairs(t) do
  189. if func(entry) then
  190. table.insert(rettab, entry)
  191. end
  192. end
  193. return rettab
  194. end
  195. --- Checks if a list-like (vector) table contains `value`.
  196. ---
  197. ---@param t table Table to check
  198. ---@param value any Value to compare
  199. ---@return boolean `true` if `t` contains `value`
  200. function vim.tbl_contains(t, value)
  201. vim.validate({ t = { t, 't' } })
  202. for _, v in ipairs(t) do
  203. if v == value then
  204. return true
  205. end
  206. end
  207. return false
  208. end
  209. --- Checks if a table is empty.
  210. ---
  211. ---@see https://github.com/premake/premake-core/blob/master/src/base/table.lua
  212. ---
  213. ---@param t table Table to check
  214. ---@return boolean `true` if `t` is empty
  215. function vim.tbl_isempty(t)
  216. assert(type(t) == 'table', string.format('Expected table, got %s', type(t)))
  217. return next(t) == nil
  218. end
  219. --- We only merge empty tables or tables that are not a list
  220. ---@private
  221. local function can_merge(v)
  222. return type(v) == 'table' and (vim.tbl_isempty(v) or not vim.tbl_islist(v))
  223. end
  224. local function tbl_extend(behavior, deep_extend, ...)
  225. if behavior ~= 'error' and behavior ~= 'keep' and behavior ~= 'force' then
  226. error('invalid "behavior": ' .. tostring(behavior))
  227. end
  228. if select('#', ...) < 2 then
  229. error(
  230. 'wrong number of arguments (given '
  231. .. tostring(1 + select('#', ...))
  232. .. ', expected at least 3)'
  233. )
  234. end
  235. local ret = {}
  236. if vim._empty_dict_mt ~= nil and getmetatable(select(1, ...)) == vim._empty_dict_mt then
  237. ret = vim.empty_dict()
  238. end
  239. for i = 1, select('#', ...) do
  240. local tbl = select(i, ...)
  241. vim.validate({ ['after the second argument'] = { tbl, 't' } })
  242. if tbl then
  243. for k, v in pairs(tbl) do
  244. if deep_extend and can_merge(v) and can_merge(ret[k]) then
  245. ret[k] = tbl_extend(behavior, true, ret[k], v)
  246. elseif behavior ~= 'force' and ret[k] ~= nil then
  247. if behavior == 'error' then
  248. error('key found in more than one map: ' .. k)
  249. end -- Else behavior is "keep".
  250. else
  251. ret[k] = v
  252. end
  253. end
  254. end
  255. end
  256. return ret
  257. end
  258. --- Merges two or more map-like tables.
  259. ---
  260. ---@see |extend()|
  261. ---
  262. ---@param behavior string Decides what to do if a key is found in more than one map:
  263. --- - "error": raise an error
  264. --- - "keep": use value from the leftmost map
  265. --- - "force": use value from the rightmost map
  266. ---@param ... table Two or more map-like tables
  267. ---@return table Merged table
  268. function vim.tbl_extend(behavior, ...)
  269. return tbl_extend(behavior, false, ...)
  270. end
  271. --- Merges recursively two or more map-like tables.
  272. ---
  273. ---@see |vim.tbl_extend()|
  274. ---
  275. ---@param behavior string Decides what to do if a key is found in more than one map:
  276. --- - "error": raise an error
  277. --- - "keep": use value from the leftmost map
  278. --- - "force": use value from the rightmost map
  279. ---@param ... table Two or more map-like tables
  280. ---@return table Merged table
  281. function vim.tbl_deep_extend(behavior, ...)
  282. return tbl_extend(behavior, true, ...)
  283. end
  284. --- Deep compare values for equality
  285. ---
  286. --- Tables are compared recursively unless they both provide the `eq` metamethod.
  287. --- All other types are compared using the equality `==` operator.
  288. ---@param a any First value
  289. ---@param b any Second value
  290. ---@return boolean `true` if values are equals, else `false`
  291. function vim.deep_equal(a, b)
  292. if a == b then
  293. return true
  294. end
  295. if type(a) ~= type(b) then
  296. return false
  297. end
  298. if type(a) == 'table' then
  299. for k, v in pairs(a) do
  300. if not vim.deep_equal(v, b[k]) then
  301. return false
  302. end
  303. end
  304. for k, _ in pairs(b) do
  305. if a[k] == nil then
  306. return false
  307. end
  308. end
  309. return true
  310. end
  311. return false
  312. end
  313. --- Add the reverse lookup values to an existing table.
  314. --- For example:
  315. --- ``tbl_add_reverse_lookup { A = 1 } == { [1] = 'A', A = 1 }``
  316. ---
  317. --- Note that this *modifies* the input.
  318. ---@param o table Table to add the reverse to
  319. ---@return table o
  320. function vim.tbl_add_reverse_lookup(o)
  321. local keys = vim.tbl_keys(o)
  322. for _, k in ipairs(keys) do
  323. local v = o[k]
  324. if o[v] then
  325. error(
  326. string.format(
  327. 'The reverse lookup found an existing value for %q while processing key %q',
  328. tostring(v),
  329. tostring(k)
  330. )
  331. )
  332. end
  333. o[v] = k
  334. end
  335. return o
  336. end
  337. --- Index into a table (first argument) via string keys passed as subsequent arguments.
  338. --- Return `nil` if the key does not exist.
  339. ---
  340. --- Examples:
  341. --- <pre>
  342. --- vim.tbl_get({ key = { nested_key = true }}, 'key', 'nested_key') == true
  343. --- vim.tbl_get({ key = {}}, 'key', 'nested_key') == nil
  344. --- </pre>
  345. ---
  346. ---@param o table Table to index
  347. ---@param ... string Optional strings (0 or more, variadic) via which to index the table
  348. ---
  349. ---@return any Nested value indexed by key (if it exists), else nil
  350. function vim.tbl_get(o, ...)
  351. local keys = { ... }
  352. if #keys == 0 then
  353. return
  354. end
  355. for i, k in ipairs(keys) do
  356. if type(o[k]) ~= 'table' and next(keys, i) then
  357. return nil
  358. end
  359. o = o[k]
  360. if o == nil then
  361. return
  362. end
  363. end
  364. return o
  365. end
  366. --- Extends a list-like table with the values of another list-like table.
  367. ---
  368. --- NOTE: This mutates dst!
  369. ---
  370. ---@see |vim.tbl_extend()|
  371. ---
  372. ---@param dst table List which will be modified and appended to
  373. ---@param src table List from which values will be inserted
  374. ---@param start number Start index on src. Defaults to 1
  375. ---@param finish number Final index on src. Defaults to `#src`
  376. ---@return table dst
  377. function vim.list_extend(dst, src, start, finish)
  378. vim.validate({
  379. dst = { dst, 't' },
  380. src = { src, 't' },
  381. start = { start, 'n', true },
  382. finish = { finish, 'n', true },
  383. })
  384. for i = start or 1, finish or #src do
  385. table.insert(dst, src[i])
  386. end
  387. return dst
  388. end
  389. --- Creates a copy of a list-like table such that any nested tables are
  390. --- "unrolled" and appended to the result.
  391. ---
  392. ---@see From https://github.com/premake/premake-core/blob/master/src/base/table.lua
  393. ---
  394. ---@param t table List-like table
  395. ---@return table Flattened copy of the given list-like table
  396. function vim.tbl_flatten(t)
  397. local result = {}
  398. local function _tbl_flatten(_t)
  399. local n = #_t
  400. for i = 1, n do
  401. local v = _t[i]
  402. if type(v) == 'table' then
  403. _tbl_flatten(v)
  404. elseif v then
  405. table.insert(result, v)
  406. end
  407. end
  408. end
  409. _tbl_flatten(t)
  410. return result
  411. end
  412. --- Tests if a Lua table can be treated as an array.
  413. ---
  414. --- Empty table `{}` is assumed to be an array, unless it was created by
  415. --- |vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
  416. --- for example from |rpcrequest()| or |vim.fn|.
  417. ---
  418. ---@param t table Table
  419. ---@return boolean `true` if array-like table, else `false`
  420. function vim.tbl_islist(t)
  421. if type(t) ~= 'table' then
  422. return false
  423. end
  424. local count = 0
  425. for k, _ in pairs(t) do
  426. if type(k) == 'number' then
  427. count = count + 1
  428. else
  429. return false
  430. end
  431. end
  432. if count > 0 then
  433. return true
  434. else
  435. -- TODO(bfredl): in the future, we will always be inside nvim
  436. -- then this check can be deleted.
  437. if vim._empty_dict_mt == nil then
  438. return nil
  439. end
  440. return getmetatable(t) ~= vim._empty_dict_mt
  441. end
  442. end
  443. --- Counts the number of non-nil values in table `t`.
  444. ---
  445. --- <pre>
  446. --- vim.tbl_count({ a=1, b=2 }) => 2
  447. --- vim.tbl_count({ 1, 2 }) => 2
  448. --- </pre>
  449. ---
  450. ---@see https://github.com/Tieske/Penlight/blob/master/lua/pl/tablex.lua
  451. ---@param t table Table
  452. ---@return number Number of non-nil values in table
  453. function vim.tbl_count(t)
  454. vim.validate({ t = { t, 't' } })
  455. local count = 0
  456. for _ in pairs(t) do
  457. count = count + 1
  458. end
  459. return count
  460. end
  461. --- Creates a copy of a table containing only elements from start to end (inclusive)
  462. ---
  463. ---@param list table Table
  464. ---@param start number Start range of slice
  465. ---@param finish number End range of slice
  466. ---@return table Copy of table sliced from start to finish (inclusive)
  467. function vim.list_slice(list, start, finish)
  468. local new_list = {}
  469. for i = start or 1, finish or #list do
  470. new_list[#new_list + 1] = list[i]
  471. end
  472. return new_list
  473. end
  474. --- Trim whitespace (Lua pattern "%s") from both sides of a string.
  475. ---
  476. ---@see https://www.lua.org/pil/20.2.html
  477. ---@param s string String to trim
  478. ---@return string String with whitespace removed from its beginning and end
  479. function vim.trim(s)
  480. vim.validate({ s = { s, 's' } })
  481. return s:match('^%s*(.*%S)') or ''
  482. end
  483. --- Escapes magic chars in |lua-patterns|.
  484. ---
  485. ---@see https://github.com/rxi/lume
  486. ---@param s string String to escape
  487. ---@return string %-escaped pattern string
  488. function vim.pesc(s)
  489. vim.validate({ s = { s, 's' } })
  490. return s:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', '%%%1')
  491. end
  492. --- Tests if `s` starts with `prefix`.
  493. ---
  494. ---@param s string String
  495. ---@param prefix string Prefix to match
  496. ---@return boolean `true` if `prefix` is a prefix of `s`
  497. function vim.startswith(s, prefix)
  498. vim.validate({ s = { s, 's' }, prefix = { prefix, 's' } })
  499. return s:sub(1, #prefix) == prefix
  500. end
  501. --- Tests if `s` ends with `suffix`.
  502. ---
  503. ---@param s string String
  504. ---@param suffix string Suffix to match
  505. ---@return boolean `true` if `suffix` is a suffix of `s`
  506. function vim.endswith(s, suffix)
  507. vim.validate({ s = { s, 's' }, suffix = { suffix, 's' } })
  508. return #suffix == 0 or s:sub(-#suffix) == suffix
  509. end
  510. --- Validates a parameter specification (types and values).
  511. ---
  512. --- Usage example:
  513. --- <pre>
  514. --- function user.new(name, age, hobbies)
  515. --- vim.validate{
  516. --- name={name, 'string'},
  517. --- age={age, 'number'},
  518. --- hobbies={hobbies, 'table'},
  519. --- }
  520. --- ...
  521. --- end
  522. --- </pre>
  523. ---
  524. --- Examples with explicit argument values (can be run directly):
  525. --- <pre>
  526. --- vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}}
  527. --- => NOP (success)
  528. ---
  529. --- vim.validate{arg1={1, 'table'}}
  530. --- => error('arg1: expected table, got number')
  531. ---
  532. --- vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}}
  533. --- => error('arg1: expected even number, got 3')
  534. --- </pre>
  535. ---
  536. --- If multiple types are valid they can be given as a list.
  537. --- <pre>
  538. --- vim.validate{arg1={{'foo'}, {'table', 'string'}}, arg2={'foo', {'table', 'string'}}}
  539. --- => NOP (success)
  540. ---
  541. --- vim.validate{arg1={1, {'string', table'}}}
  542. --- => error('arg1: expected string|table, got number')
  543. ---
  544. --- </pre>
  545. ---
  546. ---@param opt table Names of parameters to validate. Each key is a parameter
  547. --- name; each value is a tuple in one of these forms:
  548. --- 1. (arg_value, type_name, optional)
  549. --- - arg_value: argument value
  550. --- - type_name: string|table type name, one of: ("table", "t", "string",
  551. --- "s", "number", "n", "boolean", "b", "function", "f", "nil",
  552. --- "thread", "userdata") or list of them.
  553. --- - optional: (optional) boolean, if true, `nil` is valid
  554. --- 2. (arg_value, fn, msg)
  555. --- - arg_value: argument value
  556. --- - fn: any function accepting one argument, returns true if and
  557. --- only if the argument is valid. Can optionally return an additional
  558. --- informative error message as the second returned value.
  559. --- - msg: (optional) error string if validation fails
  560. function vim.validate(opt) end -- luacheck: no unused
  561. do
  562. local type_names = {
  563. ['table'] = 'table',
  564. t = 'table',
  565. ['string'] = 'string',
  566. s = 'string',
  567. ['number'] = 'number',
  568. n = 'number',
  569. ['boolean'] = 'boolean',
  570. b = 'boolean',
  571. ['function'] = 'function',
  572. f = 'function',
  573. ['callable'] = 'callable',
  574. c = 'callable',
  575. ['nil'] = 'nil',
  576. ['thread'] = 'thread',
  577. ['userdata'] = 'userdata',
  578. }
  579. local function _is_type(val, t)
  580. return type(val) == t or (t == 'callable' and vim.is_callable(val))
  581. end
  582. ---@private
  583. local function is_valid(opt)
  584. if type(opt) ~= 'table' then
  585. return false, string.format('opt: expected table, got %s', type(opt))
  586. end
  587. for param_name, spec in pairs(opt) do
  588. if type(spec) ~= 'table' then
  589. return false, string.format('opt[%s]: expected table, got %s', param_name, type(spec))
  590. end
  591. local val = spec[1] -- Argument value
  592. local types = spec[2] -- Type name, or callable
  593. local optional = (true == spec[3])
  594. if type(types) == 'string' then
  595. types = { types }
  596. end
  597. if vim.is_callable(types) then
  598. -- Check user-provided validation function
  599. local valid, optional_message = types(val)
  600. if not valid then
  601. local error_message =
  602. string.format('%s: expected %s, got %s', param_name, (spec[3] or '?'), tostring(val))
  603. if optional_message ~= nil then
  604. error_message = error_message .. string.format('. Info: %s', optional_message)
  605. end
  606. return false, error_message
  607. end
  608. elseif type(types) == 'table' then
  609. local success = false
  610. for i, t in ipairs(types) do
  611. local t_name = type_names[t]
  612. if not t_name then
  613. return false, string.format('invalid type name: %s', t)
  614. end
  615. types[i] = t_name
  616. if (optional and val == nil) or _is_type(val, t_name) then
  617. success = true
  618. break
  619. end
  620. end
  621. if not success then
  622. return false,
  623. string.format(
  624. '%s: expected %s, got %s',
  625. param_name,
  626. table.concat(types, '|'),
  627. type(val)
  628. )
  629. end
  630. else
  631. return false, string.format('invalid type name: %s', tostring(types))
  632. end
  633. end
  634. return true, nil
  635. end
  636. function vim.validate(opt)
  637. local ok, err_msg = is_valid(opt)
  638. if not ok then
  639. error(err_msg, 2)
  640. end
  641. end
  642. end
  643. --- Returns true if object `f` can be called as a function.
  644. ---
  645. ---@param f any Any object
  646. ---@return boolean `true` if `f` is callable, else `false`
  647. function vim.is_callable(f)
  648. if type(f) == 'function' then
  649. return true
  650. end
  651. local m = getmetatable(f)
  652. if m == nil then
  653. return false
  654. end
  655. return type(m.__call) == 'function'
  656. end
  657. --- Creates a table whose members are automatically created when accessed, if they don't already
  658. --- exist.
  659. ---
  660. --- They mimic defaultdict in python.
  661. ---
  662. --- If {create} is `nil`, this will create a defaulttable whose constructor function is
  663. --- this function, effectively allowing to create nested tables on the fly:
  664. ---
  665. --- <pre>
  666. --- local a = vim.defaulttable()
  667. --- a.b.c = 1
  668. --- </pre>
  669. ---
  670. ---@param create function|nil The function called to create a missing value.
  671. ---@return table Empty table with metamethod
  672. function vim.defaulttable(create)
  673. create = create or vim.defaulttable
  674. return setmetatable({}, {
  675. __index = function(tbl, key)
  676. rawset(tbl, key, create())
  677. return rawget(tbl, key)
  678. end,
  679. })
  680. end
  681. return vim
  682. -- vim:sw=2 ts=2 et