aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/_vim9script.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/_vim9script.lua')
-rw-r--r--runtime/lua/_vim9script.lua650
1 files changed, 650 insertions, 0 deletions
diff --git a/runtime/lua/_vim9script.lua b/runtime/lua/_vim9script.lua
new file mode 100644
index 0000000000..363d061451
--- /dev/null
+++ b/runtime/lua/_vim9script.lua
@@ -0,0 +1,650 @@
+-------------------------------------------------------------------------------
+-- This file is auto generated by vim9jit. Do not edit by hand.
+-- All content is in the source repository.
+-- Bugs should be reported to: github.com/tjdevries/vim9jit
+--
+-- In addition, this file is considered "private" by neovim. You should
+-- not expect any of the APIs, functions, etc to be stable. They are subject
+-- to change at any time.
+-------------------------------------------------------------------------------
+
+local vim9 = (function()
+ local M = {}
+
+ M.ternary = function(cond, if_true, if_false)
+ if cond then
+ if type(if_true) == 'function' then
+ return if_true()
+ else
+ return if_true
+ end
+ else
+ if type(if_false) == 'function' then
+ return if_false()
+ else
+ return if_false
+ end
+ end
+ end
+
+ M.fn_ref = function(module, name, copied, ...)
+ for _, val in ipairs({ ... }) do
+ table.insert(copied, val)
+ end
+
+ local funcref = name
+ if type(funcref) == 'function' then
+ return funcref(unpack(copied))
+ elseif type(funcref) == 'string' then
+ if vim.fn.exists('*' .. funcref) == 1 then
+ return vim.fn[funcref](unpack(copied))
+ end
+
+ if module[funcref] then
+ module[funcref](unpack(copied))
+ end
+
+ error('unknown function: ' .. funcref)
+ else
+ error(string.format('unable to call funcref: %s', funcref))
+ end
+ end
+
+ M.fn_mut = function(name, args, info)
+ local result = vim.fn._Vim9ScriptFn(name, args)
+ for idx, val in pairs(result[2]) do
+ M.replace(args[idx], val)
+ end
+
+ -- Substitute returning the reference to the
+ -- returned value
+ if info.replace then
+ return args[info.replace + 1]
+ end
+
+ return result[1]
+ end
+
+ M.replace = function(orig, new)
+ if type(orig) == 'table' and type(new) == 'table' then
+ for k in pairs(orig) do
+ orig[k] = nil
+ end
+
+ for k, v in pairs(new) do
+ orig[k] = v
+ end
+
+ return orig
+ end
+
+ return new
+ end
+
+ M.index = function(obj, idx)
+ if vim.tbl_islist(obj) then
+ if idx < 0 then
+ return obj[#obj + idx + 1]
+ else
+ return obj[idx + 1]
+ end
+ elseif type(obj) == 'table' then
+ return obj[idx]
+ elseif type(obj) == 'string' then
+ return string.sub(obj, idx + 1, idx + 1)
+ end
+
+ error('invalid type for indexing: ' .. vim.inspect(obj))
+ end
+
+ M.index_expr = function(idx)
+ if type(idx) == 'string' then
+ return idx
+ elseif type(idx) == 'number' then
+ return idx + 1
+ else
+ error(string.format('not yet handled: %s', vim.inspect(idx)))
+ end
+ end
+
+ M.slice = function(obj, start, finish)
+ if start == nil then
+ start = 0
+ end
+
+ if start < 0 then
+ start = #obj + start
+ end
+ assert(type(start) == 'number')
+
+ if finish == nil then
+ finish = #obj
+ end
+
+ if finish < 0 then
+ finish = #obj + finish
+ end
+ assert(type(finish) == 'number')
+
+ local slicer
+ if vim.tbl_islist(obj) then
+ slicer = vim.list_slice
+ elseif type(obj) == 'string' then
+ slicer = string.sub
+ else
+ error('invalid type for slicing: ' .. vim.inspect(obj))
+ end
+
+ return slicer(obj, start + 1, finish + 1)
+ end
+
+ -- Currently unused, but this could be used to embed vim9jit within a
+ -- running nvim application and transpile "on the fly" as files are
+ -- sourced. There would still need to be some work done to make that
+ -- work correctly with imports and what not, but overall it could
+ -- work well for calling ":source X" from within a vimscript/vim9script
+ -- function
+ M.make_source_cmd = function()
+ local group = vim.api.nvim_create_augroup('vim9script-source', {})
+ vim.api.nvim_create_autocmd('SourceCmd', {
+ pattern = '*.vim',
+ group = group,
+ callback = function(a)
+ local file = vim.fn.readfile(a.file)
+ for _, line in ipairs(file) do
+ -- TODO: Or starts with def <something>
+ -- You can use def in legacy vim files
+ if vim.startswith(line, 'vim9script') then
+ -- TODO: Use the rust lib to actually
+ -- generate the corresponding lua code and then
+ -- execute that (instead of sourcing it directly)
+ return
+ end
+ end
+
+ vim.api.nvim_exec(table.concat(file, '\n'), false)
+ end,
+ })
+ end
+
+ M.iter = function(expr)
+ if vim.tbl_islist(expr) then
+ return ipairs(expr)
+ else
+ return pairs(expr)
+ end
+ end
+
+ M.ITER_DEFAULT = 0
+ M.ITER_CONTINUE = 1
+ M.ITER_BREAK = 2
+ M.ITER_RETURN = 3
+
+ return M
+end)()
+
+vim.cmd([[
+function! _Vim9ScriptFn(name, args) abort
+ try
+ let ret = function(a:name, a:args)()
+ catch
+ echo "Failed..."
+ echo a:name
+ echo a:args
+
+ throw v:errmsg
+ endtry
+
+ return [ret, a:args]
+endfunction
+]])
+
+vim9['autoload'] = (function()
+ return function(path)
+ return loadfile(path)()
+ end
+end)()
+vim9['bool'] = (function()
+ return function(...)
+ return vim9.convert.to_vim_bool(...)
+ end
+end)()
+vim9['convert'] = (function()
+ local M = {}
+
+ M.decl_bool = function(val)
+ if type(val) == 'boolean' then
+ return val
+ elseif type(val) == 'number' then
+ if val == 0 then
+ return false
+ elseif val == 1 then
+ return true
+ else
+ error(string.format('bad number passed to bool declaration: %s', val))
+ end
+ end
+
+ error(string.format('invalid bool declaration: %s', vim.inspect(val)))
+ end
+
+ M.decl_dict = function(val)
+ if type(val) == 'nil' then
+ return vim.empty_dict()
+ elseif type(val) == 'table' then
+ if vim.tbl_isempty(val) then
+ return vim.empty_dict()
+ elseif vim.tbl_islist(val) then
+ error(string.format('Cannot pass list to dictionary? %s', vim.inspect(val)))
+ else
+ return val
+ end
+ end
+
+ error(string.format('invalid dict declaration: %s', vim.inspect(val)))
+ end
+
+ M.to_vim_bool = function(val)
+ if type(val) == 'boolean' then
+ return val
+ elseif type(val) == 'number' then
+ return val ~= 0
+ elseif type(val) == 'string' then
+ return string.len(val) ~= 0
+ elseif type(val) == 'table' then
+ return not vim.tbl_isempty(val)
+ elseif val == nil then
+ return false
+ end
+
+ error('unhandled type: ' .. vim.inspect(val))
+ end
+
+ return M
+end)()
+vim9['fn'] = (function()
+ local M = {}
+
+ M.insert = function(list, item, idx)
+ if idx == nil then
+ idx = 1
+ end
+
+ table.insert(list, idx + 1, item)
+
+ return list
+ end
+
+ M.extend = function(left, right, expr3)
+ if expr3 ~= nil then
+ error("haven't written this code yet")
+ end
+
+ if vim.tbl_islist(right) then
+ vim.list_extend(left, right)
+ return left
+ else
+ -- local result = vim.tbl_extend(left, right)
+ for k, v in pairs(right) do
+ left[k] = v
+ end
+
+ return left
+ end
+ end
+
+ M.add = function(list, item)
+ table.insert(list, item)
+ return list
+ end
+
+ M.has_key = function(obj, key)
+ return not not obj[key]
+ end
+
+ M.prop_type_add = function(...)
+ local args = { ... }
+ print('[prop_type_add]', vim.inspect(args))
+ end
+
+ do
+ local has_overrides = {
+ -- We do have vim9script ;) that's this plugin
+ ['vim9script'] = true,
+
+ -- Include some vim patches that are sometimes required by variuos vim9script plugins
+ -- that we implement via vim9jit
+ [ [[patch-8.2.2261]] ] = true,
+ [ [[patch-8.2.4257]] ] = true,
+ }
+
+ M.has = function(patch)
+ if has_overrides[patch] then
+ return true
+ end
+
+ return vim.fn.has(patch)
+ end
+ end
+
+ --[=[
+Currently missing patch, can be removed in the future.
+
+readdirex({directory} [, {expr} [, {dict}]]) *readdirex()*
+ Extended version of |readdir()|.
+ Return a list of Dictionaries with file and directory
+ information in {directory}.
+ This is useful if you want to get the attributes of file and
+ directory at the same time as getting a list of a directory.
+ This is much faster than calling |readdir()| then calling
+ |getfperm()|, |getfsize()|, |getftime()| and |getftype()| for
+ each file and directory especially on MS-Windows.
+ The list will by default be sorted by name (case sensitive),
+ the sorting can be changed by using the optional {dict}
+ argument, see |readdir()|.
+
+ The Dictionary for file and directory information has the
+ following items:
+ group Group name of the entry. (Only on Unix)
+ name Name of the entry.
+ perm Permissions of the entry. See |getfperm()|.
+ size Size of the entry. See |getfsize()|.
+ time Timestamp of the entry. See |getftime()|.
+ type Type of the entry.
+ On Unix, almost same as |getftype()| except:
+ Symlink to a dir "linkd"
+ Other symlink "link"
+ On MS-Windows:
+ Normal file "file"
+ Directory "dir"
+ Junction "junction"
+ Symlink to a dir "linkd"
+ Other symlink "link"
+ Other reparse point "reparse"
+ user User name of the entry's owner. (Only on Unix)
+ On Unix, if the entry is a symlink, the Dictionary includes
+ the information of the target (except the "type" item).
+ On MS-Windows, it includes the information of the symlink
+ itself because of performance reasons.
+--]=]
+ M.readdirex = function(dir)
+ local files = vim.fn.readdir(dir)
+ local direx = {}
+ for _, f in ipairs(files) do
+ table.insert(direx, {
+ name = f,
+ type = vim.fn.getftype(f),
+ })
+ end
+
+ return direx
+ end
+
+ M.mapnew = function(tbl, expr)
+ return vim.fn.map(tbl, expr)
+ end
+
+ M.typename = function(val)
+ local ty = type(val)
+ if ty == 'string' then
+ return 'string'
+ elseif ty == 'boolean' then
+ return 'bool'
+ elseif ty == 'number' then
+ return 'number'
+ else
+ error(string.format('typename: %s', val))
+ end
+ end
+
+ -- Popup menu stuff: Could be rolled into other plugin later
+ -- but currently is here for testing purposes (and implements
+ -- some very simple compat layers at the moment)
+ do
+ local pos_map = {
+ topleft = 'NW',
+ topright = 'NE',
+ botleft = 'SW',
+ botright = 'SE',
+ }
+
+ M.popup_menu = function(_, options)
+ -- print "OPTIONS:"
+
+ local buf = vim.api.nvim_create_buf(false, true)
+ local win = vim.api.nvim_open_win(buf, true, {
+ relative = 'editor',
+ style = 'minimal',
+ anchor = pos_map[options.pos],
+ height = options.maxheight or options.minheight,
+ width = options.maxwidth or options.minwidth,
+ row = options.line,
+ col = options.col,
+ })
+
+ if options.filter then
+ local loop
+ loop = function()
+ vim.cmd([[redraw!]])
+ local ok, ch = pcall(vim.fn.getcharstr)
+ if not ok then
+ return
+ end -- interrupted
+
+ if ch == '<C-C>' then
+ return
+ end
+
+ if not require('vim9script').bool(options.filter(nil, ch)) then
+ vim.cmd.normal(ch)
+ end
+
+ vim.schedule(loop)
+ end
+
+ vim.schedule(loop)
+ end
+
+ return win
+ end
+
+ M.popup_settext = function(id, text)
+ if type(text) == 'string' then
+ -- text = vim.split(text, "\n")
+ error("Haven't handled string yet")
+ end
+
+ local lines = {}
+ for _, obj in ipairs(text) do
+ table.insert(lines, obj.text)
+ end
+
+ vim.api.nvim_buf_set_lines(vim.api.nvim_win_get_buf(id), 0, -1, false, lines)
+ end
+
+ M.popup_filter_menu = function()
+ print('ok, just pretend we filtered the menu')
+ end
+
+ M.popup_setoptions = function(id, _)
+ print('setting options...', id)
+ end
+ end
+
+ M = setmetatable(M, {
+ __index = vim.fn,
+ })
+
+ return M
+end)()
+vim9['heredoc'] = (function()
+ local M = {}
+
+ M.trim = function(lines)
+ local min_whitespace = 9999
+ for _, line in ipairs(lines) do
+ local _, finish = string.find(line, '^%s*')
+ min_whitespace = math.min(min_whitespace, finish)
+ end
+
+ local trimmed_lines = {}
+ for _, line in ipairs(lines) do
+ table.insert(trimmed_lines, string.sub(line, min_whitespace + 1))
+ end
+
+ return trimmed_lines
+ end
+
+ return M
+end)()
+vim9['import'] = (function()
+ local imported = {}
+ imported.autoload = setmetatable({}, {
+ __index = function(_, name)
+ local luaname = 'autoload/' .. string.gsub(name, '%.vim$', '.lua')
+ local runtime_file = vim.api.nvim_get_runtime_file(luaname, false)[1]
+ if not runtime_file then
+ error('unable to find autoload file:' .. name)
+ end
+
+ return imported.absolute[vim.fn.fnamemodify(runtime_file, ':p')]
+ end,
+ })
+
+ imported.absolute = setmetatable({}, {
+ __index = function(self, name)
+ if vim.loop.fs_stat(name) then
+ local result = loadfile(name)()
+ rawset(self, name, result)
+
+ return result
+ end
+
+ error(string.format('unabled to find absolute file: %s', name))
+ end,
+ })
+
+ return function(info)
+ local name = info.name
+
+ if info.autoload then
+ return imported.autoload[info.name]
+ end
+
+ local debug_info = debug.getinfo(2, 'S')
+ local sourcing_path = vim.fn.fnamemodify(string.sub(debug_info.source, 2), ':p')
+
+ -- Relative paths
+ if vim.startswith(name, '../') or vim.startswith(name, './') then
+ local luaname = string.gsub(name, '%.vim$', '.lua')
+ local directory = vim.fn.fnamemodify(sourcing_path, ':h')
+ local search = directory .. '/' .. luaname
+ return imported.absolute[search]
+ end
+
+ if vim.startswith(name, '/') then
+ error('absolute path')
+ -- local luaname = string.gsub(name, "%.vim", ".lua")
+ -- local runtime_file = vim.api.nvim_get_runtime_file(luaname, false)[1]
+ -- if runtime_file then
+ -- runtime_file = vim.fn.fnamemodify(runtime_file, ":p")
+ -- return loadfile(runtime_file)()
+ -- end
+ end
+
+ error('Unhandled case' .. vim.inspect(info) .. vim.inspect(debug_info))
+ end
+end)()
+vim9['ops'] = (function()
+ local lib = vim9
+
+ local M = {}
+
+ M['And'] = function(left, right)
+ return lib.bool(left) and lib.bool(right)
+ end
+
+ M['Or'] = function(left, right)
+ return lib.bool(left) or lib.bool(right)
+ end
+
+ M['Plus'] = function(left, right)
+ return left + right
+ end
+
+ M['Multiply'] = function(left, right)
+ return left * right
+ end
+
+ M['Divide'] = function(left, right)
+ return left / right
+ end
+
+ M['StringConcat'] = function(left, right)
+ return left .. right
+ end
+
+ M['EqualTo'] = function(left, right)
+ return left == right
+ end
+
+ M['NotEqualTo'] = function(left, right)
+ return not M['EqualTo'](left, right)
+ end
+
+ M['LessThan'] = function(left, right)
+ return left < right
+ end
+
+ M['LessThanOrEqual'] = function(left, right)
+ return left <= right
+ end
+
+ M['GreaterThan'] = function(left, right)
+ return left > right
+ end
+
+ M['GreaterThanOrEqual'] = function(left, right)
+ return left >= right
+ end
+
+ M['RegexpMatches'] = function(left, right)
+ return not not vim.regex(right):match_str(left)
+ end
+
+ M['RegexpMatchesIns'] = function(left, right)
+ return not not vim.regex('\\c' .. right):match_str(left)
+ end
+
+ M['NotRegexpMatches'] = function(left, right)
+ return not M['RegexpMatches'](left, right)
+ end
+
+ M['Modulo'] = function(left, right)
+ return left % right
+ end
+
+ M['Minus'] = function(left, right)
+ -- TODO: This is not right :)
+ return left - right
+ end
+
+ return M
+end)()
+vim9['prefix'] = (function()
+ local lib = vim9
+
+ local M = {}
+
+ M['Minus'] = function(right)
+ return -right
+ end
+
+ M['Bang'] = function(right)
+ return not lib.bool(right)
+ end
+
+ return M
+end)()
+
+return vim9