neovim/runtime/lua/_vim9script.lua
2024-04-21 17:08:07 +02:00

651 lines
15 KiB
Lua

-------------------------------------------------------------------------------
-- 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.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.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_exec2(table.concat(file, '\n'), { output = false })
end,
})
end
M.iter = function(expr)
if vim.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.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.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 various 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.uv.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