nvim: move lua compiler to a separate flake
This commit is contained in:
parent
7c1bcf409e
commit
75b50759ae
|
@ -1,6 +1,6 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
{
|
{
|
||||||
imports = [ ../options.nix ];
|
imports = [ ./options.nix ];
|
||||||
/*
|
/*
|
||||||
VIM config backup:
|
VIM config backup:
|
||||||
syntax on
|
syntax on
|
||||||
|
@ -14,310 +14,13 @@
|
||||||
|
|
||||||
# welcome to my cursed DSL
|
# welcome to my cursed DSL
|
||||||
programs.neovim = let
|
programs.neovim = let
|
||||||
# add a single ident level to code
|
notlua = config.notlua;
|
||||||
identLines = lines: builtins.concatStringsSep "\n" (map (x: " ${x}") lines);
|
notlua-nvim = notlua.neovim { inherit (config.programs.neovim) plugins extraLuaPackages; };
|
||||||
ident = code: identLines (lib.splitString "\n" code);
|
inherit (notlua.keywords) CALL RAW PROP SET LET DEFUN IF APPLY OR EQ RETURN ELSE ATTR MCALL LETREC;
|
||||||
|
inherit (notlua.utils) compile;
|
||||||
# convert list into pairs
|
inherit (notlua-nvim.stdlib) vim string require print;
|
||||||
pairsv = ret: list: key: if list == [] then {
|
inherit (notlua-nvim.keywords) REQ REQ' REQLET;
|
||||||
list = ret;
|
in let
|
||||||
leftover = key;
|
|
||||||
} else pairsk (ret ++ [[key (builtins.head list)]]) (builtins.tail list);
|
|
||||||
pairsk = ret: list: if list == [] then {
|
|
||||||
list = ret;
|
|
||||||
leftover = null;
|
|
||||||
} else pairsv ret (builtins.tail list) (builtins.head list);
|
|
||||||
|
|
||||||
# list end
|
|
||||||
end = list: builtins.elemAt list (builtins.length list - 1);
|
|
||||||
# pop list end
|
|
||||||
pop = list: lib.take (builtins.length list - 1) list;
|
|
||||||
|
|
||||||
luaType = val:
|
|
||||||
if builtins.isAttrs val && val?__kind then (
|
|
||||||
if val?_type then val._type
|
|
||||||
# can't know the type of arbitrary expressions!
|
|
||||||
else null
|
|
||||||
) else if builtins.isList val || builtins.isAttrs val then "table"
|
|
||||||
else if builtins.isPath val || builtins.isString val then "string"
|
|
||||||
else if builtins.isInt val || builtins.isFloat val then "number"
|
|
||||||
else if builtins.isNull val then "nil"
|
|
||||||
else if builtins.isFunction val then let info = getInfo val; in (
|
|
||||||
if info != null && info?_expr then luaType info._expr
|
|
||||||
else if info != null && info?_stmt then luaType info._stmt
|
|
||||||
else "function"
|
|
||||||
) else if builtins.isBool val then "boolean"
|
|
||||||
else null;
|
|
||||||
|
|
||||||
# vararg system
|
|
||||||
getInfo = func: if builtins.isFunction func && builtins.functionArgs func == {} then (
|
|
||||||
let ret = builtins.tryEval (func {__GET_INFO = true;}); in if ret.success then ret.value else null
|
|
||||||
) else null;
|
|
||||||
isGetInfo = arg: arg == { __GET_INFO = true; };
|
|
||||||
argsSink = key: args: finally: arg:
|
|
||||||
if isGetInfo arg then
|
|
||||||
{${key} = finally args;}
|
|
||||||
else if builtins.isAttrs arg && arg?__kind && arg.__kind == "unroll" then
|
|
||||||
{${key} = finally (args ++ arg.list);}
|
|
||||||
else
|
|
||||||
argsSink key (args ++ [arg]) finally;
|
|
||||||
|
|
||||||
# The following functions may take state: moduleName and scope
|
|
||||||
# scope is how many variables are currently in scope
|
|
||||||
# the count is used for generating new variable names
|
|
||||||
|
|
||||||
pushScope = n: { moduleName, scope }: { inherit moduleName; scope = scope + n; };
|
|
||||||
pushScope1 = pushScope 1;
|
|
||||||
|
|
||||||
# wrap an expression in parentheses if necessary
|
|
||||||
# probably not the best heuristics, but good enough to make the output readable
|
|
||||||
wrapSafe = s: (builtins.match "^[-\"a-zA-Z0-9_.()]*$" s) != null;
|
|
||||||
wrapExpr = s: if wrapSafe s then s else "(${s})";
|
|
||||||
|
|
||||||
# Same, but for table keys
|
|
||||||
keySafe = s: (builtins.match "^[a-zA-Z_][_a-zA-Z0-9]*$" s) != null;
|
|
||||||
wrapKey = scope: s: if keySafe s then s else "[${compileExpr scope s}]";
|
|
||||||
|
|
||||||
applyVars' = origScope: count: prefix: let self = (scope: func: argc:
|
|
||||||
let info = getInfo func; in
|
|
||||||
if info != null && info?_expr then self scope info._expr argc
|
|
||||||
else if info != null && info?_stmt then self scope info._stmt argc
|
|
||||||
else if count != null && scope == (origScope + count) then { result = func; }
|
|
||||||
else if count == null && !builtins.isFunction func then { result = func; inherit argc; }
|
|
||||||
else self (scope + 1) (let
|
|
||||||
args = builtins.functionArgs func;
|
|
||||||
name = "${prefix}${builtins.toString scope}"; in
|
|
||||||
if args == {} then func (RAW name)
|
|
||||||
else func (builtins.mapAttrs (k: v: RAW "${name}.${k}") args)) (argc + 1)
|
|
||||||
); in self;
|
|
||||||
applyVars = count: prefix: scope: func: applyVars' scope count prefix scope func 0;
|
|
||||||
|
|
||||||
compileFunc = state@{moduleName, scope}: id: expr:
|
|
||||||
let
|
|
||||||
res = applyVars null "${moduleName}_${id}_arg" scope expr;
|
|
||||||
argc = res.argc;
|
|
||||||
func = res.result;
|
|
||||||
header = if id == "" then "function" else "local function ${id}";
|
|
||||||
in ''
|
|
||||||
${header}(${builtins.concatStringsSep ", " (builtins.genList (n: "${moduleName}_${id}_arg${builtins.toString (scope + n)}") argc)})
|
|
||||||
${ident (compileStmt (pushScope argc state) func)}
|
|
||||||
end'';
|
|
||||||
|
|
||||||
compileExpr = state: func: (
|
|
||||||
if builtins.isString func then
|
|
||||||
if lib.hasInfix "\n" func then ''
|
|
||||||
[[
|
|
||||||
${ident func}
|
|
||||||
]]'' else "\"${lib.escape ["\\" "\""] func}\""
|
|
||||||
else if builtins.isInt func then builtins.toString func
|
|
||||||
else if builtins.isFloat func then builtins.toString func
|
|
||||||
else if builtins.isBool func then (if func then "true" else "false")
|
|
||||||
else if builtins.isNull func then "nil"
|
|
||||||
else if builtins.isPath func then compileExpr state (builtins.toString func)
|
|
||||||
else if builtins.isFunction func then let
|
|
||||||
info = getInfo func; in
|
|
||||||
if info != null && info?_name then
|
|
||||||
info._name
|
|
||||||
else if info != null && info?_expr then
|
|
||||||
compileExpr state info._expr
|
|
||||||
else if info != null && info?_stmt then
|
|
||||||
assert false; null
|
|
||||||
else (compileFunc state "" func)
|
|
||||||
else if builtins.isList func then ''
|
|
||||||
{
|
|
||||||
${ident (builtins.concatStringsSep "\n" (map (x: (compileExpr state x) + ";" ) func))}
|
|
||||||
}''
|
|
||||||
else if builtins.isAttrs func && func?_expr then compileExpr state func._expr
|
|
||||||
else if builtins.isAttrs func && !(func?__kind) then ''
|
|
||||||
{
|
|
||||||
${ident (builtins.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${wrapKey state k} = ${compileExpr state v};") func))}
|
|
||||||
}''
|
|
||||||
else if func.__kind == "var" then
|
|
||||||
"${func._name}"
|
|
||||||
else if func.__kind == "op2" then
|
|
||||||
builtins.concatStringsSep " ${func.op} " (map (x: wrapExpr (compileExpr state x)) func.args)
|
|
||||||
else if func.__kind == "defun" then
|
|
||||||
(compileFunc state (if func?id then func.id else "") func.func)
|
|
||||||
else if func.__kind == "prop" then
|
|
||||||
assert lib.assertMsg (luaType func.expr == null || luaType func.expr == "table") "Unable to get property ${func.name} of a ${luaType func.expr}!";
|
|
||||||
"${wrapExpr (compileExpr state func.expr)}.${func.name}"
|
|
||||||
else if func.__kind == "call" then
|
|
||||||
let args = func._args; in
|
|
||||||
assert lib.assertMsg
|
|
||||||
((!(func._func?_minArity) || (builtins.length args) >= func._func._minArity) && (!(func._func?_maxArity) || (builtins.length args) <= func._func._maxArity))
|
|
||||||
"error: wrong function arity for ${compileExpr state func._func}! expected at least ${builtins.toString func._func._minArity}; found ${builtins.toString (builtins.length args)}";
|
|
||||||
"${wrapExpr (compileExpr state func._func)}(${builtins.concatStringsSep ", " (map (compileExpr state) args)})"
|
|
||||||
else if func.__kind == "mcall" then
|
|
||||||
"${wrapExpr (compileExpr state func.val)}:${func.name}(${builtins.concatStringsSep ", " (map (compileExpr state) func.args)})"
|
|
||||||
else if func.__kind == "tableAttr" then
|
|
||||||
assert lib.assertMsg (luaType func.table == null || luaType func.table == "table") "Unable to get table value ${compileExpr state func.key} of a ${luaType func.table} ${compileExpr state func.table}!";
|
|
||||||
"${wrapExpr (compileExpr state func.table)}[${compileExpr state func.key}]"
|
|
||||||
else assert lib.assertMsg false "Invalid kind ${func.__kind}"; null
|
|
||||||
);
|
|
||||||
|
|
||||||
compileStmt = state@{moduleName,scope}: func: (
|
|
||||||
if builtins.isList func then builtins.concatStringsSep "\n" (map (compileStmt state) func)
|
|
||||||
else if builtins.isAttrs func && func?_stmt then compileStmt state func._stmt
|
|
||||||
else if builtins.isAttrs func && (func?__kind) then (
|
|
||||||
if func.__kind == "assign" then
|
|
||||||
assert lib.assertMsg
|
|
||||||
(luaType func.expr == null || luaType func.val == null || luaType func.val == func.expr._type)
|
|
||||||
"error: setting ${compileExpr state func.expr} to wrong type. It should be ${luaType func.expr} but is ${luaType func.val}";
|
|
||||||
"${compileExpr state func.expr} = ${compileExpr state func.val}"
|
|
||||||
else if func.__kind == "bind" then
|
|
||||||
"local ${func.name} = ${compileExpr state func.val}"
|
|
||||||
else if func.__kind == "let" then ''
|
|
||||||
${builtins.concatStringsSep "\n" (lib.imap0 (n: val:
|
|
||||||
"local ${moduleName}_var${builtins.toString (scope + n)} = ${
|
|
||||||
compileExpr state val
|
|
||||||
}") func.vals)}
|
|
||||||
${
|
|
||||||
let res = applyVars (builtins.length func.vals) "${moduleName}_var" scope func.func; in
|
|
||||||
compileStmt (pushScope (builtins.length func.vals) state) res.result
|
|
||||||
}''
|
|
||||||
else if func.__kind == "letrec" then let argc = builtins.length func.vals; in ''
|
|
||||||
${builtins.concatStringsSep "\n" (lib.imap0 (n: val:
|
|
||||||
"local ${moduleName}_var${builtins.toString (scope + n)} = ${
|
|
||||||
let res = applyVars argc "${moduleName}_var" scope val; in
|
|
||||||
compileExpr (pushScope argc state) res.result
|
|
||||||
}") func.vals)}
|
|
||||||
${
|
|
||||||
let res = applyVars argc "${moduleName}_var" scope func.func; in
|
|
||||||
compileStmt (pushScope (builtins.length func.vals) state) res.result
|
|
||||||
}''
|
|
||||||
else if func.__kind == "for" then let
|
|
||||||
res = applyVars null "${moduleName}_var" scope func.body;
|
|
||||||
varNames = builtins.genList (n: "${moduleName}_var${builtins.toString (scope + n)}") res.argc;
|
|
||||||
in ''
|
|
||||||
for ${builtins.concatStringsSep "," varNames} in ${compileExpr scope func.expr} do
|
|
||||||
${
|
|
||||||
ident (compileStmt (pushScope1 state) res.result)
|
|
||||||
}
|
|
||||||
end''
|
|
||||||
else if func.__kind == "return" then
|
|
||||||
"return ${compileExpr state func.expr}"
|
|
||||||
else if func.__kind == "if" then
|
|
||||||
(lib.removeSuffix "else" ((builtins.concatStringsSep "" (map
|
|
||||||
(cond: ''
|
|
||||||
if ${compileExpr state (builtins.elemAt cond 0)} then
|
|
||||||
${ident (compileStmt state (builtins.elemAt cond 1))}
|
|
||||||
else'')
|
|
||||||
func.conds))
|
|
||||||
+ (if func.fallback != null then "\n${ident (compileStmt state func.fallback)}\n" else ""))) + "end"
|
|
||||||
else compileExpr state func
|
|
||||||
) else if builtins.isFunction func then (let
|
|
||||||
info = getInfo func; in
|
|
||||||
if info != null && info?_stmt then compileStmt state info._stmt
|
|
||||||
else compileExpr state func
|
|
||||||
) else compileExpr state func
|
|
||||||
);
|
|
||||||
|
|
||||||
# compile a module
|
|
||||||
compile = moduleName: input: (compileStmt { inherit moduleName; scope = 1; } input) + "\n";
|
|
||||||
|
|
||||||
# pass some raw code to lua directly
|
|
||||||
VAR = name: { __kind = "var"; _name = name; };
|
|
||||||
RAW = VAR;
|
|
||||||
|
|
||||||
# Access a property
|
|
||||||
# Corresponding lua code: table.property
|
|
||||||
# expr -> identifier -> expr
|
|
||||||
PROP = expr: name: { __kind = "prop"; inherit expr name; };
|
|
||||||
|
|
||||||
# Escape a list so it can be passed to vararg functions
|
|
||||||
UNROLL = list: { __kind = "unroll"; inherit list; };
|
|
||||||
|
|
||||||
# Apply a list of arguments to a function/operator (probably more useful than the above)
|
|
||||||
APPLY = func: list: func (UNROLL list);
|
|
||||||
|
|
||||||
# Call a function
|
|
||||||
# Useful if you need to call a zero argument function, or if you need to handle some weird metatable stuff
|
|
||||||
# corresponding lua code: someFunc()
|
|
||||||
# expr -> arg1 -> ... -> argN -> expr
|
|
||||||
CALL = func: argsSink "_expr" [] (args: { __kind = "call"; _func = func; _args = args; });
|
|
||||||
|
|
||||||
# Call a method
|
|
||||||
# corresponding lua code: someTable:someFunc()
|
|
||||||
# expr -> identifier -> arg1 -> ... -> argN -> expr
|
|
||||||
MCALL = val: name: argsSink "_expr" [] (args: { __kind = "mcall"; inherit val name args; });
|
|
||||||
|
|
||||||
# corresponding lua code: =
|
|
||||||
# expr -> expr -> stmt
|
|
||||||
SET = expr: val: { __kind = "assign"; inherit expr val; };
|
|
||||||
|
|
||||||
# opName -> [exprs] -> expr | opName -> expr1 -> ... -> exprN -> expr
|
|
||||||
OP2 = op: argsSink "_expr" [] (args: { __kind = "op2"; inherit op args; });
|
|
||||||
|
|
||||||
# The following all have the signature
|
|
||||||
# expr1 -> ... -> exprN -> expr
|
|
||||||
EQ = OP2 "==";
|
|
||||||
# GT = OP2 ">";
|
|
||||||
# GE = OP2 ">=";
|
|
||||||
# NE = OP2 "~=";
|
|
||||||
# AND = OP2 "and";
|
|
||||||
OR = OP2 "or";
|
|
||||||
|
|
||||||
# Corresponding lua code: for ... in ...
|
|
||||||
# argc -> expr -> (expr1 -> ... -> exprN -> stmts) -> stmts
|
|
||||||
# FORIN = expr: body: { __kind = "for"; inherit expr body; };
|
|
||||||
|
|
||||||
# Issues a return statement
|
|
||||||
# Corresponding lua code: return
|
|
||||||
# expr -> stmt
|
|
||||||
RETURN = expr: { __kind = "return"; inherit expr; };
|
|
||||||
|
|
||||||
# Creates a zero argument function with user-provided statements
|
|
||||||
# stmts -> expr
|
|
||||||
DEFUN = func: { __kind = "defun"; inherit func; };
|
|
||||||
|
|
||||||
# Corresponding lua code: if then (else?)
|
|
||||||
# [[cond expr]] -> fallbackExpr? -> stmts
|
|
||||||
IFELSE' = conds: fallback: { __kind = "if"; inherit fallback; conds = if builtins.isList (builtins.elemAt conds 0) then conds else [conds]; };
|
|
||||||
|
|
||||||
# Corresponding lua code: if then (else?)
|
|
||||||
# (expr -> stmts ->)* (fallback expr ->)? stmts
|
|
||||||
IF = argsSink "_stmt" [] (args:
|
|
||||||
let pairs = pairsk [] args; in
|
|
||||||
if pairs.leftover == null && builtins.length pairs.list > 1 && builtins.elemAt (end pairs.list) 0 == ELSE
|
|
||||||
then IFELSE' (pop pairs.list) (builtins.elemAt (end pairs.list) 1)
|
|
||||||
else IFELSE' pairs.list pairs.leftover
|
|
||||||
);
|
|
||||||
|
|
||||||
# Signifies the fallback branch in IF. May only be the last branch.
|
|
||||||
# Note that you may also omit it and just include the last branch without a preceding condition.
|
|
||||||
ELSE = true;
|
|
||||||
|
|
||||||
# Corresponding lua code: table[key]
|
|
||||||
# table -> key -> expr
|
|
||||||
ATTR = table: key: { __kind = "tableAttr"; inherit table key; };
|
|
||||||
|
|
||||||
# Directly creates a local varible with your chosen name
|
|
||||||
# But why would you use this???
|
|
||||||
# bind' = name: val: { __kind = "bind"; inherit name val; };
|
|
||||||
|
|
||||||
# Creates variables and passes them to the function
|
|
||||||
# Corresponding lua code: local ... = ...
|
|
||||||
# expr1 -> (expr -> stmt) -> stmt | [expr] -> (expr1 -> ... -> exprN -> stmt) -> stmt
|
|
||||||
LET = vals: func: if builtins.isList vals then { __kind = "let"; inherit vals func; } else LET [ vals ] func;
|
|
||||||
|
|
||||||
# Creates variables and passes them to the function as well as variable binding code
|
|
||||||
# Corresponding lua code: local ... = ...
|
|
||||||
# (expr1 -> expr) -> (expr1 -> stmt) -> stmt | [(expr1 -> ... -> exprN -> expr)] -> (expr1 -> ... -> exprN -> stmt) -> stmt
|
|
||||||
LETREC = vals: func: if builtins.isList vals then { __kind = "letrec"; inherit vals func; } else LETREC [ vals ] func;
|
|
||||||
|
|
||||||
# "type definitions" for neovim
|
|
||||||
defs = pkgs.callPackage ./vim-opts.nix { inherit RAW CALL isGetInfo compileExpr; inherit (config.programs.neovim) plugins; };
|
|
||||||
|
|
||||||
reqbindGen = names: func:
|
|
||||||
if names == [] then func
|
|
||||||
else result: reqbindGen (builtins.tail names) (func (defs._reqbind (builtins.head names) result._name));
|
|
||||||
|
|
||||||
# bind a value to a require
|
|
||||||
REQBIND = name: func:
|
|
||||||
if builtins.isList name
|
|
||||||
then LET (map defs.require name) (reqbindGen name func)
|
|
||||||
else LET [ (defs.require name) ] (result: func (defs._reqbind name result._name));
|
|
||||||
in with defs; let
|
|
||||||
vimcmd = name: CALL (RAW "vim.cmd.${name}");
|
vimcmd = name: CALL (RAW "vim.cmd.${name}");
|
||||||
vimg = name: PROP vim.g name;
|
vimg = name: PROP vim.g name;
|
||||||
keymapSetSingle = opts@{
|
keymapSetSingle = opts@{
|
||||||
|
@ -475,7 +178,7 @@
|
||||||
{ plugin = ps.nvim-web-devicons;
|
{ plugin = ps.nvim-web-devicons;
|
||||||
config = compile "nvim_web_devicons" ((REQ "nvim-web-devicons").setup {}); }
|
config = compile "nvim_web_devicons" ((REQ "nvim-web-devicons").setup {}); }
|
||||||
{ plugin = ps.nvim-tree-lua;
|
{ plugin = ps.nvim-tree-lua;
|
||||||
config = compile "nvim_tree_lua" (REQBIND ["nvim-tree" "nvim-tree.api"] (nvim-tree: nvim-tree-api: [
|
config = compile "nvim_tree_lua" (REQLET "nvim-tree" "nvim-tree.api" (nvim-tree: nvim-tree-api: [
|
||||||
(SET (vimg "loaded_netrw") 1)
|
(SET (vimg "loaded_netrw") 1)
|
||||||
(SET (vimg "loaded_netrwPlugin") 1)
|
(SET (vimg "loaded_netrwPlugin") 1)
|
||||||
(SET vim.o.termguicolors true)
|
(SET vim.o.termguicolors true)
|
||||||
|
@ -501,7 +204,7 @@
|
||||||
[ "╰" name ]
|
[ "╰" name ]
|
||||||
[ "│" name ]
|
[ "│" name ]
|
||||||
]);
|
]);
|
||||||
in compile "nvim_cmp" (REQBIND [ "cmp" "lspkind" ] (cmp: lspkind:
|
in compile "nvim_cmp" (REQLET "cmp" "lspkind" (cmp: lspkind:
|
||||||
# call is required because cmp.setup is a table
|
# call is required because cmp.setup is a table
|
||||||
(CALL cmp.setup {
|
(CALL cmp.setup {
|
||||||
snippet = {
|
snippet = {
|
||||||
|
@ -567,7 +270,7 @@
|
||||||
ps.cmp_luasnip
|
ps.cmp_luasnip
|
||||||
ps.cmp-nvim-lsp
|
ps.cmp-nvim-lsp
|
||||||
{ plugin = ps.nvim-autopairs;
|
{ plugin = ps.nvim-autopairs;
|
||||||
config = compile "nvim_autopairs" (REQBIND ["nvim-autopairs.completion.cmp" "nvim-autopairs"] (cmp-autopairs: nvim-autopairs: [
|
config = compile "nvim_autopairs" (REQLET "nvim-autopairs.completion.cmp" "nvim-autopairs" (cmp-autopairs: nvim-autopairs: [
|
||||||
(nvim-autopairs.setup {
|
(nvim-autopairs.setup {
|
||||||
disable_filetype = [ "TelescopePrompt" "vim" ];
|
disable_filetype = [ "TelescopePrompt" "vim" ];
|
||||||
})
|
})
|
||||||
|
@ -616,7 +319,7 @@
|
||||||
desc = "Add buffer diagnostics to the location list.";
|
desc = "Add buffer diagnostics to the location list.";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
(LET [
|
(LET
|
||||||
# LET on_attach
|
# LET on_attach
|
||||||
(client: bufnr: [
|
(client: bufnr: [
|
||||||
# Enable completion triggered by <c-x><c-o>
|
# Enable completion triggered by <c-x><c-o>
|
||||||
|
@ -678,7 +381,7 @@
|
||||||
((REQ "cmp_nvim_lsp").default_capabilities {})
|
((REQ "cmp_nvim_lsp").default_capabilities {})
|
||||||
(CALL vim.lsp.protocol.make_client_capabilities))
|
(CALL vim.lsp.protocol.make_client_capabilities))
|
||||||
# BEGIN
|
# BEGIN
|
||||||
] (on_attach: rust_settings: capabilities: [
|
(on_attach: rust_settings: capabilities: [
|
||||||
(LETREC
|
(LETREC
|
||||||
# LETREC on_attach_rust
|
# LETREC on_attach_rust
|
||||||
(on_attach_rust: client: bufnr: [
|
(on_attach_rust: client: bufnr: [
|
|
@ -1,155 +0,0 @@
|
||||||
local seen = {}
|
|
||||||
|
|
||||||
local result = {}
|
|
||||||
|
|
||||||
local function dump2(t, path, res)
|
|
||||||
seen[t] = path
|
|
||||||
if path ~= "" then
|
|
||||||
path = path.."."
|
|
||||||
end
|
|
||||||
for k,v in pairs(t) do
|
|
||||||
k = tostring(k)
|
|
||||||
if path ~= "" or k ~= "package" then
|
|
||||||
if type(v) == "table" then
|
|
||||||
if seen[v] then
|
|
||||||
if not res[k] then
|
|
||||||
res[k] = { __kind = "rec", path = seen[v] }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if not res[k] then
|
|
||||||
res[k] = {}
|
|
||||||
end
|
|
||||||
res[k].__kind = "var"
|
|
||||||
res[k]._type = "table"
|
|
||||||
res[k]._name = path..k
|
|
||||||
dump2(v, path..k, res[k])
|
|
||||||
end
|
|
||||||
elseif type(v) == "function" then
|
|
||||||
local info = debug.getinfo(v)
|
|
||||||
res[k] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..k,
|
|
||||||
_type = "function",
|
|
||||||
_minArity = info.nparams
|
|
||||||
}
|
|
||||||
if not info.isvararg then
|
|
||||||
res[k]["maxArity"] = info.nparams
|
|
||||||
end
|
|
||||||
else
|
|
||||||
res[k] = {
|
|
||||||
__kind = "var", _name = path..k, _type = type(v)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dumpf(t, path, res)
|
|
||||||
for k,v in pairs(t.funcs) do
|
|
||||||
if type(v.args) == "table" then
|
|
||||||
-- 1 value: min bound
|
|
||||||
-- 2 values: min and max bound
|
|
||||||
if #v.args == 1 then
|
|
||||||
res[k] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..k,
|
|
||||||
_type = "function",
|
|
||||||
_minArity = v.args[1]
|
|
||||||
}
|
|
||||||
elseif #v.args == 2 then
|
|
||||||
res[k] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..k,
|
|
||||||
_type = "function",
|
|
||||||
_minArity = v.args[1],
|
|
||||||
_maxArity = v.args[2]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
print("ERROR")
|
|
||||||
end
|
|
||||||
elseif type(v.args) == "number" then
|
|
||||||
-- exact arg count
|
|
||||||
res[k] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..k,
|
|
||||||
_type = "function",
|
|
||||||
_minArity = v.args,
|
|
||||||
_maxArity = v.args
|
|
||||||
}
|
|
||||||
else
|
|
||||||
-- zero args
|
|
||||||
res[k] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..k,
|
|
||||||
_type = "function",
|
|
||||||
_minArity = 0,
|
|
||||||
_maxArity = 0
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dumpo(t, path, opt, res)
|
|
||||||
local types = {
|
|
||||||
bool = "boolean",
|
|
||||||
string = "string",
|
|
||||||
number = "number",
|
|
||||||
}
|
|
||||||
local key_value_options = {
|
|
||||||
fillchars = true,
|
|
||||||
listchars = true,
|
|
||||||
winhighlight = true,
|
|
||||||
}
|
|
||||||
for k,v in pairs(t.options) do
|
|
||||||
if opt and key_value_options[v.full_name] then
|
|
||||||
-- kv map
|
|
||||||
res[v.full_name] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..v.full_name,
|
|
||||||
_type = "table"
|
|
||||||
}
|
|
||||||
if type(v.abbreviation) == "string" then
|
|
||||||
res[path..v.full_name] = { __kind = "rec", path = path..v.full_name, }
|
|
||||||
end
|
|
||||||
elseif opt and v.list then
|
|
||||||
-- list
|
|
||||||
res[v.full_name] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..v.full_name,
|
|
||||||
_type = "table"
|
|
||||||
}
|
|
||||||
if type(v.abbreviation) == "string" then
|
|
||||||
res[v.abbreviation] = { __kind = "rec", path = path..v.full_name, }
|
|
||||||
end
|
|
||||||
elseif not opt then
|
|
||||||
res[v.full_name] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..v.full_name,
|
|
||||||
_type = types[v.type],
|
|
||||||
}
|
|
||||||
if type(v.abbreviation) == "string" then
|
|
||||||
res[v.abbreviation] = { __kind = "rec", path = path..v.full_name, }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local json = require "json"
|
|
||||||
|
|
||||||
--- DUMPING BUILTINS
|
|
||||||
result["vim"] = { __kind = "var", _type = "table", _name = "vim" }
|
|
||||||
for k in pairs(vim._submodules) do
|
|
||||||
result["vim"][k] = { __kind = "var", _type = "table", _name = "vim."..k }
|
|
||||||
dump2(vim[k], "vim."..k, result["vim"][k])
|
|
||||||
end
|
|
||||||
dump2(package.loaded["vim.shared"], "vim", result["vim"])
|
|
||||||
-- for main thread only?
|
|
||||||
dump2(package.loaded["vim._editor"], "vim", result["vim"])
|
|
||||||
dump2(_G, "", result)
|
|
||||||
-- eval.lua from https://github.com/neovim/neovim/blob/674e23f19c509381e2476a3990e21272e362e3a4/src/nvim/eval.lua
|
|
||||||
dumpf(require("eval"), "vim.fn.", result["vim"]["fn"])
|
|
||||||
-- https://github.com/neovim/neovim/blob/674e23f19c509381e2476a3990e21272e362e3a4/src/nvim/options.lua
|
|
||||||
dumpo(require("options"), "vim.o.", false, result["vim"]["o"])
|
|
||||||
dumpo(require("options"), "vim.opt.", true, result["vim"]["opt"])
|
|
||||||
print(json.encode(result))
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
local seen = {}
|
|
||||||
|
|
||||||
local result = {}
|
|
||||||
|
|
||||||
local function mark(t)
|
|
||||||
seen[t] = true
|
|
||||||
for k,v in pairs(t) do
|
|
||||||
if type(v) == "table" and not seen[v] then
|
|
||||||
mark(v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dump2(t, path, res)
|
|
||||||
seen[t] = path
|
|
||||||
if path ~= "" then
|
|
||||||
path = path.."."
|
|
||||||
end
|
|
||||||
for k,v in pairs(t) do
|
|
||||||
k = tostring(k)
|
|
||||||
if path ~= "" or k ~= "package" then
|
|
||||||
if type(v) == "table" then
|
|
||||||
if seen[v] then
|
|
||||||
if not res[k] and seen[v] ~= true then
|
|
||||||
res[k] = { __kind = "rec", path = seen[v] }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if not res[k] then
|
|
||||||
res[k] = {}
|
|
||||||
end
|
|
||||||
res[k].__kind = "var"
|
|
||||||
res[k]._type = "table"
|
|
||||||
res[k]._name = path..k
|
|
||||||
dump2(v, path..k, res[k])
|
|
||||||
end
|
|
||||||
elseif type(v) == "function" then
|
|
||||||
local info = debug.getinfo(v)
|
|
||||||
res[k] = {
|
|
||||||
__kind = "var",
|
|
||||||
_name = path..k,
|
|
||||||
_type = "function",
|
|
||||||
_minArity = info.nparams
|
|
||||||
}
|
|
||||||
if not info.isvararg then
|
|
||||||
res[k]["maxArity"] = info.nparams
|
|
||||||
end
|
|
||||||
else
|
|
||||||
res[k] = {
|
|
||||||
__kind = "var", _name = path..k, _type = type(v)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local json = require "cjson"
|
|
||||||
|
|
||||||
-- mark globals before requiring package
|
|
||||||
mark(_G)
|
|
||||||
|
|
||||||
local package = @package@
|
|
||||||
|
|
||||||
result = { __kind = "var", _type = "table", _name = "" }
|
|
||||||
dump2(package, "", result)
|
|
||||||
|
|
||||||
print(json.encode(result))
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,61 +0,0 @@
|
||||||
{ stdenvNoCC
|
|
||||||
, lib
|
|
||||||
, neovim-unwrapped
|
|
||||||
, neovimUtils
|
|
||||||
, lua51Packages
|
|
||||||
, wrapNeovimUnstable
|
|
||||||
, CALL
|
|
||||||
, isGetInfo
|
|
||||||
, substituteAll
|
|
||||||
, plugins
|
|
||||||
, compileExpr
|
|
||||||
# , extraLuaPackages ? []
|
|
||||||
, ... }:
|
|
||||||
|
|
||||||
# TODO: bfs instead of dfs in var dumps
|
|
||||||
|
|
||||||
let
|
|
||||||
update = self: prefix: lib.mapAttrs (k: v: let
|
|
||||||
v' = update self prefix v;
|
|
||||||
in (if builtins.isAttrs v && v?__kind then (
|
|
||||||
if v.__kind == "rec" then
|
|
||||||
lib.attrByPath (lib.splitString "." v.path) null self
|
|
||||||
else if v.__kind == "var" && v._type == "function" then
|
|
||||||
(args:
|
|
||||||
if isGetInfo args then v'
|
|
||||||
else CALL v' args)
|
|
||||||
else v'
|
|
||||||
) else if builtins.isAttrs v then v'
|
|
||||||
else if prefix != "" && k == "_name" then
|
|
||||||
(if v == "" then prefix else "${prefix}.${v}")
|
|
||||||
else v));
|
|
||||||
data = builtins.fromJSON (builtins.readFile ./vim-defs.json);
|
|
||||||
result = update result "" data;
|
|
||||||
config = neovimUtils.makeNeovimConfig {
|
|
||||||
extraLuaPackages = p: [ p.cjson ];
|
|
||||||
# inherit extraLuaPackages;
|
|
||||||
plugins = map (plugin: if plugin?plugin then {plugin=plugin.plugin;} else {inherit plugin;}) plugins;
|
|
||||||
};
|
|
||||||
neovim = wrapNeovimUnstable neovim-unwrapped config;
|
|
||||||
getReqAttrs = name: builtins.fromJSON (builtins.readFile (stdenvNoCC.mkDerivation {
|
|
||||||
phases = [ "installPhase" ];
|
|
||||||
name = "neovim-types-${name}.json";
|
|
||||||
dumpPlugin = substituteAll {
|
|
||||||
src = ./dump_plugin.lua;
|
|
||||||
package = name;
|
|
||||||
};
|
|
||||||
nativeBuildInputs = [ neovim ];
|
|
||||||
installPhase = ''
|
|
||||||
export HOME="$TMPDIR"
|
|
||||||
nvim --headless -S $dumpPlugin -i NONE -u NONE -n -c 'echo""|qall!' 2>$out
|
|
||||||
'';
|
|
||||||
}));
|
|
||||||
req = name: let res = update res name (getReqAttrs name); in res;
|
|
||||||
REQ = name: req "require(\"${name}\")";
|
|
||||||
# the code must not use external state! this can't be checked
|
|
||||||
# this could (?) be fixed with REQBIND', but I don't need it
|
|
||||||
REQ' = code: req (compileExpr { moduleName = "req"; scope = 1; } code);
|
|
||||||
_reqbind = name: varname: let s = "require(\"${name}\")"; res = update res "${varname}" (getReqAttrs s); in res;
|
|
||||||
in result // {
|
|
||||||
inherit REQ REQ' _reqbind;
|
|
||||||
}
|
|
|
@ -1,5 +1,20 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1678901627,
|
||||||
|
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
@ -54,6 +69,28 @@
|
||||||
"type": "indirect"
|
"type": "indirect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"notlua": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1679082335,
|
||||||
|
"narHash": "sha256-x6InD4OI2ACS2j53g0j/ogUFn4q7ZkbhDHd+H/CDWZ4=",
|
||||||
|
"owner": "chayleaf",
|
||||||
|
"repo": "notlua",
|
||||||
|
"rev": "3e1f540ea069861d5f0973a340aabc02e88e9f6c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "chayleaf",
|
||||||
|
"ref": "master",
|
||||||
|
"repo": "notlua",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nur": {
|
"nur": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1678002043,
|
"lastModified": 1678002043,
|
||||||
|
@ -74,6 +111,7 @@
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"nix-gaming": "nix-gaming",
|
"nix-gaming": "nix-gaming",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
"notlua": "notlua",
|
||||||
"nur": "nur"
|
"nur": "nur"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,9 +13,13 @@
|
||||||
url = "github:fufexan/nix-gaming";
|
url = "github:fufexan/nix-gaming";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
notlua = {
|
||||||
|
url = "github:chayleaf/notlua/master";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, home-manager, nur, nix-gaming }:
|
outputs = { self, nixpkgs, home-manager, nur, nix-gaming, notlua }:
|
||||||
let
|
let
|
||||||
# IRL-related private config
|
# IRL-related private config
|
||||||
priv = if builtins.pathExists ./private.nix then (import ./private.nix) else {};
|
priv = if builtins.pathExists ./private.nix then (import ./private.nix) else {};
|
||||||
|
@ -25,6 +29,7 @@
|
||||||
"user@nixmsi" = home-manager.lib.homeManagerConfiguration {
|
"user@nixmsi" = home-manager.lib.homeManagerConfiguration {
|
||||||
pkgs = nixpkgs.legacyPackages."x86_64-linux";
|
pkgs = nixpkgs.legacyPackages."x86_64-linux";
|
||||||
modules = [
|
modules = [
|
||||||
|
notlua.nixosModules.x86_64-linux.default
|
||||||
nur.nixosModules.nur
|
nur.nixosModules.nur
|
||||||
{ nixpkgs.overlays = [
|
{ nixpkgs.overlays = [
|
||||||
nix-gaming.overlays.default
|
nix-gaming.overlays.default
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
../common/general.nix
|
../common/general.nix
|
||||||
../common/firefox
|
../common/firefox
|
||||||
../common/i3-sway.nix
|
../common/i3-sway.nix
|
||||||
../common/nvim
|
../common/nvim.nix
|
||||||
../common/helix.nix
|
../common/helix.nix
|
||||||
../common/kakoune.nix
|
../common/kakoune.nix
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue