_vim9script.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. -------------------------------------------------------------------------------
  2. -- This file is auto generated by vim9jit. Do not edit by hand.
  3. -- All content is in the source repository.
  4. -- Bugs should be reported to: github.com/tjdevries/vim9jit
  5. --
  6. -- In addition, this file is considered "private" by neovim. You should
  7. -- not expect any of the APIs, functions, etc to be stable. They are subject
  8. -- to change at any time.
  9. -------------------------------------------------------------------------------
  10. local vim9 = (function()
  11. local M = {}
  12. M.ternary = function(cond, if_true, if_false)
  13. if cond then
  14. if type(if_true) == 'function' then
  15. return if_true()
  16. else
  17. return if_true
  18. end
  19. else
  20. if type(if_false) == 'function' then
  21. return if_false()
  22. else
  23. return if_false
  24. end
  25. end
  26. end
  27. M.fn_ref = function(module, name, copied, ...)
  28. for _, val in ipairs({ ... }) do
  29. table.insert(copied, val)
  30. end
  31. local funcref = name
  32. if type(funcref) == 'function' then
  33. return funcref(unpack(copied))
  34. elseif type(funcref) == 'string' then
  35. if vim.fn.exists('*' .. funcref) == 1 then
  36. return vim.fn[funcref](unpack(copied))
  37. end
  38. if module[funcref] then
  39. module[funcref](unpack(copied))
  40. end
  41. error('unknown function: ' .. funcref)
  42. else
  43. error(string.format('unable to call funcref: %s', funcref))
  44. end
  45. end
  46. M.fn_mut = function(name, args, info)
  47. local result = vim.fn._Vim9ScriptFn(name, args)
  48. for idx, val in pairs(result[2]) do
  49. M.replace(args[idx], val)
  50. end
  51. -- Substitute returning the reference to the
  52. -- returned value
  53. if info.replace then
  54. return args[info.replace + 1]
  55. end
  56. return result[1]
  57. end
  58. M.replace = function(orig, new)
  59. if type(orig) == 'table' and type(new) == 'table' then
  60. for k in pairs(orig) do
  61. orig[k] = nil
  62. end
  63. for k, v in pairs(new) do
  64. orig[k] = v
  65. end
  66. return orig
  67. end
  68. return new
  69. end
  70. M.index = function(obj, idx)
  71. if vim.islist(obj) then
  72. if idx < 0 then
  73. return obj[#obj + idx + 1]
  74. else
  75. return obj[idx + 1]
  76. end
  77. elseif type(obj) == 'table' then
  78. return obj[idx]
  79. elseif type(obj) == 'string' then
  80. return string.sub(obj, idx + 1, idx + 1)
  81. end
  82. error('invalid type for indexing: ' .. vim.inspect(obj))
  83. end
  84. M.index_expr = function(idx)
  85. if type(idx) == 'string' then
  86. return idx
  87. elseif type(idx) == 'number' then
  88. return idx + 1
  89. else
  90. error(string.format('not yet handled: %s', vim.inspect(idx)))
  91. end
  92. end
  93. M.slice = function(obj, start, finish)
  94. if start == nil then
  95. start = 0
  96. end
  97. if start < 0 then
  98. start = #obj + start
  99. end
  100. assert(type(start) == 'number')
  101. if finish == nil then
  102. finish = #obj
  103. end
  104. if finish < 0 then
  105. finish = #obj + finish
  106. end
  107. assert(type(finish) == 'number')
  108. local slicer
  109. if vim.islist(obj) then
  110. slicer = vim.list_slice
  111. elseif type(obj) == 'string' then
  112. slicer = string.sub
  113. else
  114. error('invalid type for slicing: ' .. vim.inspect(obj))
  115. end
  116. return slicer(obj, start + 1, finish + 1)
  117. end
  118. -- Currently unused, but this could be used to embed vim9jit within a
  119. -- running nvim application and transpile "on the fly" as files are
  120. -- sourced. There would still need to be some work done to make that
  121. -- work correctly with imports and what not, but overall it could
  122. -- work well for calling ":source X" from within a vimscript/vim9script
  123. -- function
  124. M.make_source_cmd = function()
  125. local group = vim.api.nvim_create_augroup('vim9script-source', {})
  126. vim.api.nvim_create_autocmd('SourceCmd', {
  127. pattern = '*.vim',
  128. group = group,
  129. callback = function(a)
  130. local file = vim.fn.readfile(a.file)
  131. for _, line in ipairs(file) do
  132. -- TODO: Or starts with def <something>
  133. -- You can use def in legacy vim files
  134. if vim.startswith(line, 'vim9script') then
  135. -- TODO: Use the rust lib to actually
  136. -- generate the corresponding lua code and then
  137. -- execute that (instead of sourcing it directly)
  138. return
  139. end
  140. end
  141. vim.api.nvim_exec2(table.concat(file, '\n'), { output = false })
  142. end,
  143. })
  144. end
  145. M.iter = function(expr)
  146. if vim.islist(expr) then
  147. return ipairs(expr)
  148. else
  149. return pairs(expr)
  150. end
  151. end
  152. M.ITER_DEFAULT = 0
  153. M.ITER_CONTINUE = 1
  154. M.ITER_BREAK = 2
  155. M.ITER_RETURN = 3
  156. return M
  157. end)()
  158. vim.cmd([[
  159. function! _Vim9ScriptFn(name, args) abort
  160. try
  161. let ret = function(a:name, a:args)()
  162. catch
  163. echo "Failed..."
  164. echo a:name
  165. echo a:args
  166. throw v:errmsg
  167. endtry
  168. return [ret, a:args]
  169. endfunction
  170. ]])
  171. vim9['autoload'] = (function()
  172. return function(path)
  173. return loadfile(path)()
  174. end
  175. end)()
  176. vim9['bool'] = (function()
  177. return function(...)
  178. return vim9.convert.to_vim_bool(...)
  179. end
  180. end)()
  181. vim9['convert'] = (function()
  182. local M = {}
  183. M.decl_bool = function(val)
  184. if type(val) == 'boolean' then
  185. return val
  186. elseif type(val) == 'number' then
  187. if val == 0 then
  188. return false
  189. elseif val == 1 then
  190. return true
  191. else
  192. error(string.format('bad number passed to bool declaration: %s', val))
  193. end
  194. end
  195. error(string.format('invalid bool declaration: %s', vim.inspect(val)))
  196. end
  197. M.decl_dict = function(val)
  198. if type(val) == 'nil' then
  199. return vim.empty_dict()
  200. elseif type(val) == 'table' then
  201. if vim.tbl_isempty(val) then
  202. return vim.empty_dict()
  203. elseif vim.islist(val) then
  204. error(string.format('Cannot pass list to dictionary? %s', vim.inspect(val)))
  205. else
  206. return val
  207. end
  208. end
  209. error(string.format('invalid dict declaration: %s', vim.inspect(val)))
  210. end
  211. M.to_vim_bool = function(val)
  212. if type(val) == 'boolean' then
  213. return val
  214. elseif type(val) == 'number' then
  215. return val ~= 0
  216. elseif type(val) == 'string' then
  217. return string.len(val) ~= 0
  218. elseif type(val) == 'table' then
  219. return not vim.tbl_isempty(val)
  220. elseif val == nil then
  221. return false
  222. end
  223. error('unhandled type: ' .. vim.inspect(val))
  224. end
  225. return M
  226. end)()
  227. vim9['fn'] = (function()
  228. local M = {}
  229. M.insert = function(list, item, idx)
  230. if idx == nil then
  231. idx = 1
  232. end
  233. table.insert(list, idx + 1, item)
  234. return list
  235. end
  236. M.extend = function(left, right, expr3)
  237. if expr3 ~= nil then
  238. error("haven't written this code yet")
  239. end
  240. if vim.islist(right) then
  241. vim.list_extend(left, right)
  242. return left
  243. else
  244. -- local result = vim.tbl_extend(left, right)
  245. for k, v in pairs(right) do
  246. left[k] = v
  247. end
  248. return left
  249. end
  250. end
  251. M.add = function(list, item)
  252. table.insert(list, item)
  253. return list
  254. end
  255. M.has_key = function(obj, key)
  256. return not not obj[key]
  257. end
  258. M.prop_type_add = function(...)
  259. local args = { ... }
  260. print('[prop_type_add]', vim.inspect(args))
  261. end
  262. do
  263. local has_overrides = {
  264. -- We do have vim9script ;) that's this plugin
  265. ['vim9script'] = true,
  266. -- Include some vim patches that are sometimes required by various vim9script plugins
  267. -- that we implement via vim9jit
  268. [ [[patch-8.2.2261]] ] = true,
  269. [ [[patch-8.2.4257]] ] = true,
  270. }
  271. M.has = function(patch)
  272. if has_overrides[patch] then
  273. return true
  274. end
  275. return vim.fn.has(patch)
  276. end
  277. end
  278. --[=[
  279. Currently missing patch, can be removed in the future.
  280. readdirex({directory} [, {expr} [, {dict}]]) *readdirex()*
  281. Extended version of |readdir()|.
  282. Return a list of Dictionaries with file and directory
  283. information in {directory}.
  284. This is useful if you want to get the attributes of file and
  285. directory at the same time as getting a list of a directory.
  286. This is much faster than calling |readdir()| then calling
  287. |getfperm()|, |getfsize()|, |getftime()| and |getftype()| for
  288. each file and directory especially on MS-Windows.
  289. The list will by default be sorted by name (case sensitive),
  290. the sorting can be changed by using the optional {dict}
  291. argument, see |readdir()|.
  292. The Dictionary for file and directory information has the
  293. following items:
  294. group Group name of the entry. (Only on Unix)
  295. name Name of the entry.
  296. perm Permissions of the entry. See |getfperm()|.
  297. size Size of the entry. See |getfsize()|.
  298. time Timestamp of the entry. See |getftime()|.
  299. type Type of the entry.
  300. On Unix, almost same as |getftype()| except:
  301. Symlink to a dir "linkd"
  302. Other symlink "link"
  303. On MS-Windows:
  304. Normal file "file"
  305. Directory "dir"
  306. Junction "junction"
  307. Symlink to a dir "linkd"
  308. Other symlink "link"
  309. Other reparse point "reparse"
  310. user User name of the entry's owner. (Only on Unix)
  311. On Unix, if the entry is a symlink, the Dictionary includes
  312. the information of the target (except the "type" item).
  313. On MS-Windows, it includes the information of the symlink
  314. itself because of performance reasons.
  315. --]=]
  316. M.readdirex = function(dir)
  317. local files = vim.fn.readdir(dir)
  318. local direx = {}
  319. for _, f in ipairs(files) do
  320. table.insert(direx, {
  321. name = f,
  322. type = vim.fn.getftype(f),
  323. })
  324. end
  325. return direx
  326. end
  327. M.mapnew = function(tbl, expr)
  328. return vim.fn.map(tbl, expr)
  329. end
  330. M.typename = function(val)
  331. local ty = type(val)
  332. if ty == 'string' then
  333. return 'string'
  334. elseif ty == 'boolean' then
  335. return 'bool'
  336. elseif ty == 'number' then
  337. return 'number'
  338. else
  339. error(string.format('typename: %s', val))
  340. end
  341. end
  342. -- Popup menu stuff: Could be rolled into other plugin later
  343. -- but currently is here for testing purposes (and implements
  344. -- some very simple compat layers at the moment)
  345. do
  346. local pos_map = {
  347. topleft = 'NW',
  348. topright = 'NE',
  349. botleft = 'SW',
  350. botright = 'SE',
  351. }
  352. M.popup_menu = function(_, options)
  353. -- print "OPTIONS:"
  354. local buf = vim.api.nvim_create_buf(false, true)
  355. local win = vim.api.nvim_open_win(buf, true, {
  356. relative = 'editor',
  357. style = 'minimal',
  358. anchor = pos_map[options.pos],
  359. height = options.maxheight or options.minheight,
  360. width = options.maxwidth or options.minwidth,
  361. row = options.line,
  362. col = options.col,
  363. })
  364. if options.filter then
  365. local loop
  366. loop = function()
  367. vim.cmd([[redraw!]])
  368. local ok, ch = pcall(vim.fn.getcharstr)
  369. if not ok then
  370. return
  371. end -- interrupted
  372. if ch == '<C-C>' then
  373. return
  374. end
  375. if not require('vim9script').bool(options.filter(nil, ch)) then
  376. vim.cmd.normal(ch)
  377. end
  378. vim.schedule(loop)
  379. end
  380. vim.schedule(loop)
  381. end
  382. return win
  383. end
  384. M.popup_settext = function(id, text)
  385. if type(text) == 'string' then
  386. -- text = vim.split(text, "\n")
  387. error("Haven't handled string yet")
  388. end
  389. local lines = {}
  390. for _, obj in ipairs(text) do
  391. table.insert(lines, obj.text)
  392. end
  393. vim.api.nvim_buf_set_lines(vim.api.nvim_win_get_buf(id), 0, -1, false, lines)
  394. end
  395. M.popup_filter_menu = function()
  396. print('ok, just pretend we filtered the menu')
  397. end
  398. M.popup_setoptions = function(id, _)
  399. print('setting options...', id)
  400. end
  401. end
  402. M = setmetatable(M, {
  403. __index = vim.fn,
  404. })
  405. return M
  406. end)()
  407. vim9['heredoc'] = (function()
  408. local M = {}
  409. M.trim = function(lines)
  410. local min_whitespace = 9999
  411. for _, line in ipairs(lines) do
  412. local _, finish = string.find(line, '^%s*')
  413. min_whitespace = math.min(min_whitespace, finish)
  414. end
  415. local trimmed_lines = {}
  416. for _, line in ipairs(lines) do
  417. table.insert(trimmed_lines, string.sub(line, min_whitespace + 1))
  418. end
  419. return trimmed_lines
  420. end
  421. return M
  422. end)()
  423. vim9['import'] = (function()
  424. local imported = {}
  425. imported.autoload = setmetatable({}, {
  426. __index = function(_, name)
  427. local luaname = 'autoload/' .. string.gsub(name, '%.vim$', '.lua')
  428. local runtime_file = vim.api.nvim_get_runtime_file(luaname, false)[1]
  429. if not runtime_file then
  430. error('unable to find autoload file:' .. name)
  431. end
  432. return imported.absolute[vim.fn.fnamemodify(runtime_file, ':p')]
  433. end,
  434. })
  435. imported.absolute = setmetatable({}, {
  436. __index = function(self, name)
  437. if vim.uv.fs_stat(name) then
  438. local result = loadfile(name)()
  439. rawset(self, name, result)
  440. return result
  441. end
  442. error(string.format('unabled to find absolute file: %s', name))
  443. end,
  444. })
  445. return function(info)
  446. local name = info.name
  447. if info.autoload then
  448. return imported.autoload[info.name]
  449. end
  450. local debug_info = debug.getinfo(2, 'S')
  451. local sourcing_path = vim.fn.fnamemodify(string.sub(debug_info.source, 2), ':p')
  452. -- Relative paths
  453. if vim.startswith(name, '../') or vim.startswith(name, './') then
  454. local luaname = string.gsub(name, '%.vim$', '.lua')
  455. local directory = vim.fn.fnamemodify(sourcing_path, ':h')
  456. local search = directory .. '/' .. luaname
  457. return imported.absolute[search]
  458. end
  459. if vim.startswith(name, '/') then
  460. error('absolute path')
  461. -- local luaname = string.gsub(name, "%.vim", ".lua")
  462. -- local runtime_file = vim.api.nvim_get_runtime_file(luaname, false)[1]
  463. -- if runtime_file then
  464. -- runtime_file = vim.fn.fnamemodify(runtime_file, ":p")
  465. -- return loadfile(runtime_file)()
  466. -- end
  467. end
  468. error('Unhandled case' .. vim.inspect(info) .. vim.inspect(debug_info))
  469. end
  470. end)()
  471. vim9['ops'] = (function()
  472. local lib = vim9
  473. local M = {}
  474. M['And'] = function(left, right)
  475. return lib.bool(left) and lib.bool(right)
  476. end
  477. M['Or'] = function(left, right)
  478. return lib.bool(left) or lib.bool(right)
  479. end
  480. M['Plus'] = function(left, right)
  481. return left + right
  482. end
  483. M['Multiply'] = function(left, right)
  484. return left * right
  485. end
  486. M['Divide'] = function(left, right)
  487. return left / right
  488. end
  489. M['StringConcat'] = function(left, right)
  490. return left .. right
  491. end
  492. M['EqualTo'] = function(left, right)
  493. return left == right
  494. end
  495. M['NotEqualTo'] = function(left, right)
  496. return not M['EqualTo'](left, right)
  497. end
  498. M['LessThan'] = function(left, right)
  499. return left < right
  500. end
  501. M['LessThanOrEqual'] = function(left, right)
  502. return left <= right
  503. end
  504. M['GreaterThan'] = function(left, right)
  505. return left > right
  506. end
  507. M['GreaterThanOrEqual'] = function(left, right)
  508. return left >= right
  509. end
  510. M['RegexpMatches'] = function(left, right)
  511. return not not vim.regex(right):match_str(left)
  512. end
  513. M['RegexpMatchesIns'] = function(left, right)
  514. return not not vim.regex('\\c' .. right):match_str(left)
  515. end
  516. M['NotRegexpMatches'] = function(left, right)
  517. return not M['RegexpMatches'](left, right)
  518. end
  519. M['Modulo'] = function(left, right)
  520. return left % right
  521. end
  522. M['Minus'] = function(left, right)
  523. -- TODO: This is not right :)
  524. return left - right
  525. end
  526. return M
  527. end)()
  528. vim9['prefix'] = (function()
  529. local lib = vim9
  530. local M = {}
  531. M['Minus'] = function(right)
  532. return -right
  533. end
  534. M['Bang'] = function(right)
  535. return not lib.bool(right)
  536. end
  537. return M
  538. end)()
  539. return vim9