home/nvim: add varargs; uppercase dsl keywords; some cleanup
This commit is contained in:
parent
4c463b22a4
commit
7c1bcf409e
|
@ -18,6 +18,57 @@
|
||||||
identLines = lines: builtins.concatStringsSep "\n" (map (x: " ${x}") lines);
|
identLines = lines: builtins.concatStringsSep "\n" (map (x: " ${x}") lines);
|
||||||
ident = code: identLines (lib.splitString "\n" code);
|
ident = code: identLines (lib.splitString "\n" code);
|
||||||
|
|
||||||
|
# convert list into pairs
|
||||||
|
pairsv = ret: list: key: if list == [] then {
|
||||||
|
list = ret;
|
||||||
|
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
|
# wrap an expression in parentheses if necessary
|
||||||
# probably not the best heuristics, but good enough to make the output readable
|
# probably not the best heuristics, but good enough to make the output readable
|
||||||
wrapSafe = s: (builtins.match "^[-\"a-zA-Z0-9_.()]*$" s) != null;
|
wrapSafe = s: (builtins.match "^[-\"a-zA-Z0-9_.()]*$" s) != null;
|
||||||
|
@ -27,32 +78,32 @@
|
||||||
keySafe = s: (builtins.match "^[a-zA-Z_][_a-zA-Z0-9]*$" s) != null;
|
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}]";
|
wrapKey = scope: s: if keySafe s then s else "[${compileExpr scope s}]";
|
||||||
|
|
||||||
# The following functions take state: sname and scope
|
applyVars' = origScope: count: prefix: let self = (scope: func: argc:
|
||||||
# sname is module name
|
let info = getInfo func; in
|
||||||
# scope is how many variables are currently in scope
|
if info != null && info?_expr then self scope info._expr argc
|
||||||
# the count is used for generating new variable names
|
else if info != null && info?_stmt then self scope info._stmt argc
|
||||||
|
else if count != null && scope == (origScope + count) then { result = func; }
|
||||||
compileFunc' = argn: sc@{sname,scope}: id: func:
|
else if count == null && !builtins.isFunction func then { result = func; inherit argc; }
|
||||||
(if builtins.isFunction func
|
else self (scope + 1) (let
|
||||||
then
|
|
||||||
(compileFunc'
|
|
||||||
(argn + 1)
|
|
||||||
sc
|
|
||||||
id
|
|
||||||
(func (let
|
|
||||||
args = builtins.functionArgs func;
|
args = builtins.functionArgs func;
|
||||||
rawVar = var "${sname}_${id}_arg${builtins.toString (scope + argn)}";
|
name = "${prefix}${builtins.toString scope}"; in
|
||||||
in if args == {}
|
if args == {} then func (RAW name)
|
||||||
then rawVar
|
else func (builtins.mapAttrs (k: v: RAW "${name}.${k}") args)) (argc + 1)
|
||||||
else builtins.mapAttrs (k: v: prop rawVar k) args
|
); in self;
|
||||||
)))
|
applyVars = count: prefix: scope: func: applyVars' scope count prefix scope func 0;
|
||||||
else ''
|
|
||||||
function ${id}(${builtins.concatStringsSep ", " (builtins.genList (n: "${sname}_${id}_arg${builtins.toString (scope + n)}") argn)})
|
|
||||||
${ident (compileStmt {inherit sname;scope = scope + argn;} func)}
|
|
||||||
end'');
|
|
||||||
compileFunc = compileFunc' 0;
|
|
||||||
|
|
||||||
compileExpr = sc: func: (
|
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 builtins.isString func then
|
||||||
if lib.hasInfix "\n" func then ''
|
if lib.hasInfix "\n" func then ''
|
||||||
[[
|
[[
|
||||||
|
@ -62,181 +113,183 @@
|
||||||
else if builtins.isFloat 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.isBool func then (if func then "true" else "false")
|
||||||
else if builtins.isNull func then "nil"
|
else if builtins.isNull func then "nil"
|
||||||
else if builtins.isPath func then compileExpr sc (builtins.toString func)
|
else if builtins.isPath func then compileExpr state (builtins.toString func)
|
||||||
else if builtins.isFunction func then let
|
else if builtins.isFunction func then let
|
||||||
info = if builtins.functionArgs func == {} then (func "GET_INFO") else null; in
|
info = getInfo func; in
|
||||||
if builtins.isAttrs info && info?_name
|
if info != null && info?_name then
|
||||||
then info._name
|
info._name
|
||||||
else (compileFunc sc "" func)
|
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 ''
|
else if builtins.isList func then ''
|
||||||
{
|
{
|
||||||
${ident (builtins.concatStringsSep "\n" (map (x: (compileExpr sc x) + ";" ) func))}
|
${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 ''
|
else if builtins.isAttrs func && !(func?__kind) then ''
|
||||||
{
|
{
|
||||||
${ident (builtins.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${wrapKey sc k} = ${compileExpr sc v};") func))}
|
${ident (builtins.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${wrapKey state k} = ${compileExpr state v};") func))}
|
||||||
}''
|
}''
|
||||||
else if func.__kind == "var" then
|
else if func.__kind == "var" then
|
||||||
"${func._name}"
|
"${func._name}"
|
||||||
else if func.__kind == "op2" then
|
else if func.__kind == "op2" then
|
||||||
builtins.concatStringsSep func.op (map (x: wrapExpr (compileExpr sc x)) func.args)
|
builtins.concatStringsSep " ${func.op} " (map (x: wrapExpr (compileExpr state x)) func.args)
|
||||||
else if func.__kind == "defun" then
|
else if func.__kind == "defun" then
|
||||||
(compileFunc sc (if func?id then func.id else "") func.func)
|
(compileFunc state (if func?id then func.id else "") func.func)
|
||||||
else if func.__kind == "prop" then
|
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}!";
|
assert lib.assertMsg (luaType func.expr == null || luaType func.expr == "table") "Unable to get property ${func.name} of a ${luaType func.expr}!";
|
||||||
"${wrapExpr (compileExpr sc func.expr)}.${func.name}"
|
"${wrapExpr (compileExpr state func.expr)}.${func.name}"
|
||||||
else if func.__kind == "call" then
|
else if func.__kind == "call" then
|
||||||
let args = if builtins.isList func._args then func._args else [func._args]; in
|
let args = func._args; in
|
||||||
assert lib.assertMsg
|
assert lib.assertMsg
|
||||||
((!(func._func?_minArity) || (builtins.length args) >= func._func._minArity) && (!(func._func?_maxArity) || (builtins.length args) <= func._func._maxArity))
|
((!(func._func?_minArity) || (builtins.length args) >= func._func._minArity) && (!(func._func?_maxArity) || (builtins.length args) <= func._func._maxArity))
|
||||||
"error: wrong function arity for ${compileExpr sc func._func}! expected at least ${builtins.toString func._func._minArity}; found ${builtins.toString (builtins.length args)}";
|
"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 sc func._func)}(${builtins.concatStringsSep ", " (map (compileExpr sc) args)})"
|
"${wrapExpr (compileExpr state func._func)}(${builtins.concatStringsSep ", " (map (compileExpr state) args)})"
|
||||||
else if func.__kind == "mcall" then
|
else if func.__kind == "mcall" then
|
||||||
"${wrapExpr (compileExpr sc func.val)}:${func.name}(${builtins.concatStringsSep ", " (map (compileExpr sc) (if builtins.isList func.args then func.args else [func.args]))})"
|
"${wrapExpr (compileExpr state func.val)}:${func.name}(${builtins.concatStringsSep ", " (map (compileExpr state) func.args)})"
|
||||||
else if func.__kind == "tableAttr" then
|
else if func.__kind == "tableAttr" then
|
||||||
assert lib.assertMsg (luaType func.table == null || luaType func.table == "table") "Unable to get table value ${compileExpr sc func.key} of a ${luaType func.table} ${compileExpr sc func.table}!";
|
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 sc func.table)}[${compileExpr sc func.key}]"
|
"${wrapExpr (compileExpr state func.table)}[${compileExpr state func.key}]"
|
||||||
else null
|
else assert lib.assertMsg false "Invalid kind ${func.__kind}"; null
|
||||||
);
|
);
|
||||||
|
|
||||||
luaType = val:
|
compileStmt = state@{moduleName,scope}: func: (
|
||||||
if builtins.isAttrs val && val?__kind then (
|
if builtins.isList func then builtins.concatStringsSep "\n" (map (compileStmt state) func)
|
||||||
if val?_type then val._type
|
else if builtins.isAttrs func && func?_stmt then compileStmt state func._stmt
|
||||||
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 "function"
|
|
||||||
else if builtins.isBool val then "boolean"
|
|
||||||
else null;
|
|
||||||
|
|
||||||
compileStmt = sc@{sname,scope}: func: (
|
|
||||||
if builtins.isList func then builtins.concatStringsSep "\n" (map (compileStmt sc) func)
|
|
||||||
else if builtins.isAttrs func && (func?__kind) then (
|
else if builtins.isAttrs func && (func?__kind) then (
|
||||||
if func.__kind == "assign" then
|
if func.__kind == "assign" then
|
||||||
assert lib.assertMsg
|
assert lib.assertMsg
|
||||||
(luaType func.expr == null || luaType func.val == null || luaType func.val == func.expr._type)
|
(luaType func.expr == null || luaType func.val == null || luaType func.val == func.expr._type)
|
||||||
"error: setting ${compileExpr sc func.expr} to wrong type. It should be ${luaType func.expr} but is ${luaType func.val}";
|
"error: setting ${compileExpr state func.expr} to wrong type. It should be ${luaType func.expr} but is ${luaType func.val}";
|
||||||
"${compileExpr sc func.expr} = ${compileExpr sc func.val}"
|
"${compileExpr state func.expr} = ${compileExpr state func.val}"
|
||||||
else if func.__kind == "bind" then
|
else if func.__kind == "bind" then
|
||||||
"local ${func.name} = ${compileExpr sc func.val}"
|
"local ${func.name} = ${compileExpr state func.val}"
|
||||||
else if func.__kind == "let" then ''
|
else if func.__kind == "let" then ''
|
||||||
${builtins.concatStringsSep "\n" (lib.imap0 (n: val:
|
${builtins.concatStringsSep "\n" (lib.imap0 (n: val:
|
||||||
"local ${sname}_var${builtins.toString (scope + n)} = ${
|
"local ${moduleName}_var${builtins.toString (scope + n)} = ${
|
||||||
compileExpr sc val
|
compileExpr state val
|
||||||
}") func.vals)}
|
}") func.vals)}
|
||||||
${let vals = func.vals; origScope = scope; apply = { scope, func }: if scope == (origScope + (builtins.length vals)) then func else apply {
|
${
|
||||||
scope = scope + 1;
|
let res = applyVars (builtins.length func.vals) "${moduleName}_var" scope func.func; in
|
||||||
func = func (raw "${sname}_var${builtins.toString scope}");
|
compileStmt (pushScope (builtins.length func.vals) state) res.result
|
||||||
}; in
|
|
||||||
compileStmt {inherit sname;scope = scope + (builtins.length func.vals);} (apply { inherit scope; inherit (func) func; })
|
|
||||||
}''
|
}''
|
||||||
else if func.__kind == "letrec" then ''
|
else if func.__kind == "letrec" then let argc = builtins.length func.vals; in ''
|
||||||
${builtins.concatStringsSep "\n" (lib.imap0 (n: val:
|
${builtins.concatStringsSep "\n" (lib.imap0 (n: val:
|
||||||
"local ${sname}_var${builtins.toString (scope + n)} = ${
|
"local ${moduleName}_var${builtins.toString (scope + n)} = ${
|
||||||
let vals = func.vals; origScope = scope; apply = { scope, func }: if scope == (origScope + (builtins.length vals)) then func else apply {
|
let res = applyVars argc "${moduleName}_var" scope val; in
|
||||||
scope = scope + 1;
|
compileExpr (pushScope argc state) res.result
|
||||||
func = func (raw "${sname}_var${builtins.toString scope}");
|
|
||||||
}; in
|
|
||||||
compileExpr {inherit sname;scope = scope + (builtins.length func.vals);} (apply { inherit scope; func = val; })
|
|
||||||
}") func.vals)}
|
}") func.vals)}
|
||||||
${let vals = func.vals; origScope = scope; apply = { scope, func }: if scope == (origScope + (builtins.length vals)) then func else apply {
|
${
|
||||||
scope = scope + 1;
|
let res = applyVars argc "${moduleName}_var" scope func.func; in
|
||||||
func = func (raw "${sname}_var${builtins.toString scope}");
|
compileStmt (pushScope (builtins.length func.vals) state) res.result
|
||||||
}; in
|
|
||||||
compileStmt {inherit sname;scope = scope + (builtins.length func.vals);} (apply { inherit scope; inherit (func) func; })
|
|
||||||
}''
|
}''
|
||||||
else if func.__kind == "for" then let
|
else if func.__kind == "for" then let
|
||||||
varNames = builtins.genList (n: "${sname}_var${builtins.toString (scope + n)}") func.n;
|
res = applyVars null "${moduleName}_var" scope func.body;
|
||||||
scope' = { inherit sname; scope = scope + 1; };
|
varNames = builtins.genList (n: "${moduleName}_var${builtins.toString (scope + n)}") res.argc;
|
||||||
in ''
|
in ''
|
||||||
for ${builtins.concatStringsSep "," varNames} in ${compileExpr scope' func.expr} do
|
for ${builtins.concatStringsSep "," varNames} in ${compileExpr scope func.expr} do
|
||||||
${
|
${
|
||||||
let argn = func.n; origScope = scope; apply = { scope, func }: if scope == (origScope + argn) then func else apply {
|
ident (compileStmt (pushScope1 state) res.result)
|
||||||
scope = scope + 1;
|
|
||||||
func = func (raw "${sname}_var${builtins.toString scope}");
|
|
||||||
}; in
|
|
||||||
ident (compileStmt scope' (apply { inherit scope; func = func.body; }))
|
|
||||||
}
|
}
|
||||||
end''
|
end''
|
||||||
else if func.__kind == "return" then
|
else if func.__kind == "return" then
|
||||||
"return ${compileExpr sc func.expr}"
|
"return ${compileExpr state func.expr}"
|
||||||
else if func.__kind == "if" then
|
else if func.__kind == "if" then
|
||||||
(lib.removeSuffix "else" ((builtins.concatStringsSep "" (map
|
(lib.removeSuffix "else" ((builtins.concatStringsSep "" (map
|
||||||
(cond: ''
|
(cond: ''
|
||||||
if ${compileExpr sc (builtins.elemAt cond 0)} then
|
if ${compileExpr state (builtins.elemAt cond 0)} then
|
||||||
${ident (compileStmt sc (builtins.elemAt cond 1))}
|
${ident (compileStmt state (builtins.elemAt cond 1))}
|
||||||
else'')
|
else'')
|
||||||
func.conds))
|
func.conds))
|
||||||
+ (if func.fallback != null then "\n${ident (compileStmt sc func.fallback)}\n" else ""))) + "end"
|
+ (if func.fallback != null then "\n${ident (compileStmt state func.fallback)}\n" else ""))) + "end"
|
||||||
else compileExpr sc func
|
else compileExpr state func
|
||||||
) else compileExpr sc 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 a module
|
||||||
compile = sname: input: (compileStmt {inherit sname;scope=1;} input) + "\n";
|
compile = moduleName: input: (compileStmt { inherit moduleName; scope = 1; } input) + "\n";
|
||||||
|
|
||||||
# pass some raw code to lua directly
|
# pass some raw code to lua directly
|
||||||
var = name: { __kind = "var"; _name = name; };
|
VAR = name: { __kind = "var"; _name = name; };
|
||||||
raw = var;
|
RAW = VAR;
|
||||||
|
|
||||||
# Access a property
|
# Access a property
|
||||||
# Corresponding lua code: table.property
|
# Corresponding lua code: table.property
|
||||||
# expr -> identifier -> expr
|
# expr -> identifier -> expr
|
||||||
prop = expr: name: { __kind = "prop"; inherit expr name; };
|
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
|
# 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()
|
# corresponding lua code: someFunc()
|
||||||
# expr -> [args] -> expr | expr -> arg1 -> expr
|
# expr -> arg1 -> ... -> argN -> expr
|
||||||
call = func: args: { __kind = "call"; _func = func; _args = args; };
|
CALL = func: argsSink "_expr" [] (args: { __kind = "call"; _func = func; _args = args; });
|
||||||
|
|
||||||
# Call a method
|
# Call a method
|
||||||
# corresponding lua code: someTable:someFunc()
|
# corresponding lua code: someTable:someFunc()
|
||||||
# expr -> identifier -> [args] -> expr | expr -> identifier -> arg1 -> expr
|
# expr -> identifier -> arg1 -> ... -> argN -> expr
|
||||||
mcall = val: name: args: { __kind = "mcall"; inherit val name args; };
|
MCALL = val: name: argsSink "_expr" [] (args: { __kind = "mcall"; inherit val name args; });
|
||||||
|
|
||||||
# corresponding lua code: =
|
# corresponding lua code: =
|
||||||
# expr -> expr -> stmt
|
# expr -> expr -> stmt
|
||||||
set = expr: val: { __kind = "assign"; inherit expr val; };
|
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; });
|
||||||
|
|
||||||
# opName -> expr1 -> expr2 -> expr | opName -> [exprs] -> expr
|
|
||||||
op2 = op: args:
|
|
||||||
if builtins.isList args then { __kind = "op2"; inherit op args; }
|
|
||||||
else (secondArg: { __kind = "op2"; inherit op; args = [ args secondArg ]; })
|
|
||||||
;
|
|
||||||
# The following all have the signature
|
# The following all have the signature
|
||||||
# expr1 -> expr2 -> expr2 | [exprs] -> expr
|
# expr1 -> ... -> exprN -> expr
|
||||||
eq = op2 "==";
|
EQ = OP2 "==";
|
||||||
# gt = op2 ">";
|
# GT = OP2 ">";
|
||||||
# ge = op2 ">=";
|
# GE = OP2 ">=";
|
||||||
# ne = op2 "~=";
|
# NE = OP2 "~=";
|
||||||
# and = op2 "and";
|
# AND = OP2 "and";
|
||||||
# or = op2 "or";
|
OR = OP2 "or";
|
||||||
|
|
||||||
# Corresponding lua code: for
|
# Corresponding lua code: for ... in ...
|
||||||
# argc -> expr -> (expr1 -> ... -> exprN -> stmts) -> stmts
|
# argc -> expr -> (expr1 -> ... -> exprN -> stmts) -> stmts
|
||||||
# forin = n: expr: body: { __kind = "for"; inherit n expr body; };
|
# FORIN = expr: body: { __kind = "for"; inherit expr body; };
|
||||||
|
|
||||||
# Issues a return statement
|
# Issues a return statement
|
||||||
# Corresponding lua code: return
|
# Corresponding lua code: return
|
||||||
# expr -> stmt
|
# expr -> stmt
|
||||||
return = expr: { __kind = "return"; inherit expr; };
|
RETURN = expr: { __kind = "return"; inherit expr; };
|
||||||
|
|
||||||
# Creates a zero argument function with user-provided statements
|
# Creates a zero argument function with user-provided statements
|
||||||
# stmts -> expr
|
# stmts -> expr
|
||||||
defun = func: { __kind = "defun"; inherit func; };
|
DEFUN = func: { __kind = "defun"; inherit func; };
|
||||||
|
|
||||||
# Corresponding lua code: if then else
|
# Corresponding lua code: if then (else?)
|
||||||
# [[cond expr]] -> fallbackExpr -> stmts
|
# [[cond expr]] -> fallbackExpr? -> stmts
|
||||||
ifelse = conds: fallback: { __kind = "if"; inherit fallback; conds = if builtins.isList (builtins.elemAt conds 0) then conds else [conds]; };
|
IFELSE' = conds: fallback: { __kind = "if"; inherit fallback; conds = if builtins.isList (builtins.elemAt conds 0) then conds else [conds]; };
|
||||||
|
|
||||||
# Corresponding lua code: if then
|
# Corresponding lua code: if then (else?)
|
||||||
# [[cond expr]] -> > stmts
|
# (expr -> stmts ->)* (fallback expr ->)? stmts
|
||||||
# ifnoelse = conds: ifelse conds null;
|
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]
|
# Corresponding lua code: table[key]
|
||||||
# table -> key -> expr
|
# table -> key -> expr
|
||||||
tableAttr = table: key: { __kind = "tableAttr"; inherit table key; };
|
ATTR = table: key: { __kind = "tableAttr"; inherit table key; };
|
||||||
|
|
||||||
# Directly creates a local varible with your chosen name
|
# Directly creates a local varible with your chosen name
|
||||||
# But why would you use this???
|
# But why would you use this???
|
||||||
|
@ -244,23 +297,29 @@
|
||||||
|
|
||||||
# Creates variables and passes them to the function
|
# Creates variables and passes them to the function
|
||||||
# Corresponding lua code: local ... = ...
|
# Corresponding lua code: local ... = ...
|
||||||
# [expr] -> (expr1 -> ... -> exprN -> stmt) -> stmt
|
# expr1 -> (expr -> stmt) -> stmt | [expr] -> (expr1 -> ... -> exprN -> stmt) -> stmt
|
||||||
bind = vals: func: if builtins.isList vals then { __kind = "let"; inherit vals func; } else bind [ vals ] func;
|
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
|
# Creates variables and passes them to the function as well as variable binding code
|
||||||
# Corresponding lua code: local ... = ...
|
# Corresponding lua code: local ... = ...
|
||||||
# [(expr1 -> ... -> exprN -> expr)] -> (expr1 -> ... -> exprN -> stmt) -> stmt
|
# (expr1 -> expr) -> (expr1 -> stmt) -> stmt | [(expr1 -> ... -> exprN -> expr)] -> (expr1 -> ... -> exprN -> stmt) -> stmt
|
||||||
bindrec = vals: func: if builtins.isList vals then { __kind = "letrec"; inherit vals func; } else bindrec [ vals ] func;
|
LETREC = vals: func: if builtins.isList vals then { __kind = "letrec"; inherit vals func; } else LETREC [ vals ] func;
|
||||||
|
|
||||||
# "type definitions" for neovim
|
# "type definitions" for neovim
|
||||||
defs = pkgs.callPackage ./vim-opts.nix { inherit raw call; plugins = config.programs.neovim.plugins; };
|
defs = pkgs.callPackage ./vim-opts.nix { inherit RAW CALL isGetInfo compileExpr; inherit (config.programs.neovim) plugins; };
|
||||||
reqbind = name: func: bind [ (defs.require name) ] (result: func (defs._reqbind name result._name));
|
|
||||||
|
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
|
in with defs; let
|
||||||
# require = name: call (var "require") [ name ];
|
vimcmd = name: CALL (RAW "vim.cmd.${name}");
|
||||||
# setup = plugin: opts: call (prop plugin "setup") [ opts ];
|
vimg = name: PROP vim.g name;
|
||||||
# vimfn = name: call (raw "vim.fn.${name}");
|
|
||||||
vimcmd = name: call (raw "vim.cmd.${name}");
|
|
||||||
vimg = name: prop vim.g name;
|
|
||||||
keymapSetSingle = opts@{
|
keymapSetSingle = opts@{
|
||||||
mode,
|
mode,
|
||||||
lhs,
|
lhs,
|
||||||
|
@ -274,7 +333,7 @@
|
||||||
k != "keys" && k != "mode" && k != "lhs" && k != "rhs" && k != "desc"
|
k != "keys" && k != "mode" && k != "lhs" && k != "rhs" && k != "desc"
|
||||||
# defaults to false
|
# defaults to false
|
||||||
&& ((k != "silent" && k != "noremap") || (builtins.isBool v && v))) opts'';
|
&& ((k != "silent" && k != "noremap") || (builtins.isBool v && v))) opts'';
|
||||||
in vim.keymap.set [ mode lhs rhs opts' ];
|
in vim.keymap.set mode lhs rhs opts';
|
||||||
keymapSetMulti = opts@{
|
keymapSetMulti = opts@{
|
||||||
keys,
|
keys,
|
||||||
mode,
|
mode,
|
||||||
|
@ -290,16 +349,16 @@
|
||||||
in (lib.mapAttrsToList (k: {rhs, desc}: keymapSetSingle (opts' // {
|
in (lib.mapAttrsToList (k: {rhs, desc}: keymapSetSingle (opts' // {
|
||||||
lhs = k; inherit rhs;
|
lhs = k; inherit rhs;
|
||||||
})) keys) ++ [
|
})) keys) ++ [
|
||||||
(which-key.register [(lib.mapAttrs (k: v: [v.rhs v.desc]) keys) opts'])
|
(which-key.register (lib.mapAttrs (k: v: [v.rhs v.desc]) keys) opts')
|
||||||
];
|
];
|
||||||
keymapSetNs = args: keymapSetMulti (args // { mode = "n"; });
|
keymapSetNs = args: keymapSetMulti (args // { mode = "n"; });
|
||||||
kmSetNs = keys: keymapSetNs { inherit keys; };
|
kmSetNs = keys: keymapSetNs { inherit keys; };
|
||||||
keymapSetVs = args: keymapSetMulti (args // { mode = "v"; });
|
keymapSetVs = args: keymapSetMulti (args // { mode = "v"; });
|
||||||
kmSetVs = keys: keymapSetVs { inherit keys; };
|
kmSetVs = keys: keymapSetVs { inherit keys; };
|
||||||
|
|
||||||
which-key = req "which-key";
|
which-key = REQ "which-key";
|
||||||
luasnip = req "luasnip";
|
luasnip = REQ "luasnip";
|
||||||
cmp = req "cmp";
|
cmp = REQ "cmp";
|
||||||
in {
|
in {
|
||||||
enable = true;
|
enable = true;
|
||||||
defaultEditor = true;
|
defaultEditor = true;
|
||||||
|
@ -330,42 +389,51 @@
|
||||||
vimdiffAlias = true;
|
vimdiffAlias = true;
|
||||||
|
|
||||||
extraLuaConfig = (compile "main" [
|
extraLuaConfig = (compile "main" [
|
||||||
(set (vimg "vimsyn_embed") "l")
|
(SET (vimg "vimsyn_embed") "l")
|
||||||
(bind (vim.api.nvim_create_augroup [ "nvimrc" { clear = true; } ]) (group:
|
(LET (vim.api.nvim_create_augroup "nvimrc" { clear = true; }) (group:
|
||||||
map (au: let au' = lib.filterAttrs (k: v: k != "event") au;
|
lib.mapAttrsToList (k: v: vim.api.nvim_create_autocmd k { inherit group; callback = v; }) {
|
||||||
in vim.api.nvim_create_autocmd [ au.event ({
|
BufReadPre = DEFUN (SET vim.o.foldmethod "syntax");
|
||||||
inherit group;
|
BufEnter = { buf, ... }:
|
||||||
} // au') ]
|
(LET (vim.filetype.match { inherit buf; }) (filetype: [
|
||||||
) [
|
(IF (APPLY OR (map (EQ filetype) [ "gitcommit" "markdown" ])) (LET vim.o.colorcolumn (old_colorcolumn: [
|
||||||
{ event = "FileType";
|
(SET vim.o.colorcolumn "73")
|
||||||
pattern = ["markdown" "gitcommit"];
|
(vim.api.nvim_create_autocmd "BufLeave" {
|
||||||
# must be a string
|
callback = DEFUN [
|
||||||
callback = defun (set vim.o.colorcolumn "73"); }
|
(SET vim.o.colorcolumn old_colorcolumn)
|
||||||
{ event = "FileType";
|
# return true = delete autocommand
|
||||||
pattern = ["markdown"];
|
(RETURN true)
|
||||||
# must be a number...
|
];
|
||||||
callback = defun (set vim.o.textwidth 72); }
|
})
|
||||||
{ event = "BufReadPre";
|
])))
|
||||||
callback = defun (set vim.o.foldmethod "syntax"); }
|
(IF (EQ filetype "markdown") (LET vim.o.textwidth (old_textwidth: [
|
||||||
{ event = "BufWinEnter";
|
(SET vim.o.textwidth 72)
|
||||||
callback = { buf, ... }:
|
(vim.api.nvim_create_autocmd "BufLeave" {
|
||||||
(bind (vim.filetype.match { inherit buf; }) (filetype: [
|
callback = DEFUN [
|
||||||
(vimcmd "folddoc" [ "foldopen!" ])
|
(SET vim.o.textwidth old_textwidth)
|
||||||
(ifelse [(eq filetype "gitcommit") [
|
(RETURN true)
|
||||||
(call vim.cmd {
|
];
|
||||||
|
})
|
||||||
|
])))
|
||||||
|
]));
|
||||||
|
BufWinEnter = { buf, ... }:
|
||||||
|
(LET (vim.filetype.match { inherit buf; }) (filetype: [
|
||||||
|
(vimcmd "folddoc" "foldopen!")
|
||||||
|
(IF (EQ filetype "gitcommit")
|
||||||
|
(CALL vim.cmd {
|
||||||
cmd = "normal";
|
cmd = "normal";
|
||||||
bang = true;
|
bang = true;
|
||||||
args = [ "gg" ];
|
args = [ "gg" ];
|
||||||
})
|
})
|
||||||
]]
|
ELSE
|
||||||
(call vim.cmd {
|
(CALL vim.cmd {
|
||||||
cmd = "normal";
|
cmd = "normal";
|
||||||
bang = true;
|
bang = true;
|
||||||
args = [ "g`\"" ];
|
args = [ "g`\"" ];
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
])); }
|
]));
|
||||||
])) # END
|
}
|
||||||
|
))
|
||||||
]);
|
]);
|
||||||
plugins = let ps = pkgs.vimPlugins; in map (x: if x?config && x?plugin then { type = "lua"; } // x else x) [
|
plugins = let ps = pkgs.vimPlugins; in map (x: if x?config && x?plugin then { type = "lua"; } // x else x) [
|
||||||
ps.vim-svelte
|
ps.vim-svelte
|
||||||
|
@ -382,7 +450,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = compile "vscode_nvim" [
|
config = compile "vscode_nvim" [
|
||||||
((req "vscode").setup {
|
((REQ "vscode").setup {
|
||||||
transparent = true;
|
transparent = true;
|
||||||
color_overrides = {
|
color_overrides = {
|
||||||
vscGray = "#745b5f";
|
vscGray = "#745b5f";
|
||||||
|
@ -400,25 +468,25 @@
|
||||||
vscPink = "#cf83c4";
|
vscPink = "#cf83c4";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
(vim.api.nvim_set_hl [ 0 "NormalFloat" {
|
(vim.api.nvim_set_hl 0 "NormalFloat" {
|
||||||
bg = "NONE";
|
bg = "NONE";
|
||||||
}])
|
})
|
||||||
]; }
|
]; }
|
||||||
{ 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" [
|
config = compile "nvim_tree_lua" (REQBIND ["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)
|
||||||
((req "nvim-tree").setup {}) # :help nvim-tree-setup
|
(nvim-tree.setup {}) # :help nvim-tree-setup
|
||||||
(kmSetNs {
|
(kmSetNs {
|
||||||
"<C-N>" = {
|
"<C-N>" = {
|
||||||
rhs = (req "nvim-tree.api").tree.toggle;
|
rhs = nvim-tree-api.tree.toggle;
|
||||||
desc = "Toggle NvimTree";
|
desc = "Toggle NvimTree";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
]; }
|
])); }
|
||||||
ps.vim-sleuth
|
ps.vim-sleuth
|
||||||
ps.luasnip
|
ps.luasnip
|
||||||
{ plugin = ps.nvim-cmp;
|
{ plugin = ps.nvim-cmp;
|
||||||
|
@ -433,11 +501,11 @@
|
||||||
[ "╰" name ]
|
[ "╰" name ]
|
||||||
[ "│" name ]
|
[ "│" name ]
|
||||||
]);
|
]);
|
||||||
in compile "nvim_cmp" (reqbind "cmp" (cmp:
|
in compile "nvim_cmp" (REQBIND [ "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 = {
|
||||||
expand = { body, ... }: luasnip.lsp_expand [ body {} ];
|
expand = { body, ... }: luasnip.lsp_expand body {};
|
||||||
};
|
};
|
||||||
view = { };
|
view = { };
|
||||||
window = {
|
window = {
|
||||||
|
@ -450,80 +518,67 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
formatting = {
|
formatting = {
|
||||||
format = _: vim_item: let kind = prop vim_item "kind"; in [
|
format = _: vim_item: let kind = PROP vim_item "kind"; in [
|
||||||
(set
|
(SET kind (string.format "%s %s" (ATTR lspkind kind) kind))
|
||||||
kind
|
(RETURN vim_item)
|
||||||
(string.format [
|
|
||||||
"%s %s"
|
|
||||||
(tableAttr (req "lspkind") kind)
|
|
||||||
kind
|
|
||||||
]))
|
|
||||||
(return vim_item)
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
mapping = {
|
mapping = {
|
||||||
"<C-p>" = cmp.mapping.select_prev_item [{}];
|
"<C-p>" = cmp.mapping.select_prev_item {};
|
||||||
"<C-n>" = cmp.mapping.select_next_item [{}];
|
"<C-n>" = cmp.mapping.select_next_item {};
|
||||||
"<C-space>" = cmp.mapping.complete [{}];
|
"<C-space>" = cmp.mapping.complete {};
|
||||||
"<C-e>" = cmp.mapping.close [{}];
|
"<C-e>" = cmp.mapping.close {};
|
||||||
"<cr>" = cmp.mapping.confirm {
|
"<cr>" = cmp.mapping.confirm {
|
||||||
behavior = cmp.ConfirmBehavior.Replace;
|
behavior = cmp.ConfirmBehavior.Replace;
|
||||||
select = false;
|
select = false;
|
||||||
};
|
};
|
||||||
"<tab>" = call cmp.mapping [(fallback:
|
"<tab>" = CALL cmp.mapping (fallback:
|
||||||
(ifelse [[(cmp.visible [])
|
(IF
|
||||||
(cmp.select_next_item [])]
|
(CALL cmp.visible)
|
||||||
/*elseif*/ [(luasnip.expand_or_jumpable [])
|
(CALL cmp.select_next_item)
|
||||||
(vim.api.nvim_feedkeys [
|
(CALL luasnip.expand_or_jumpable)
|
||||||
(vim.api.nvim_replace_termcodes [ "<Plug>luasnip-expand-or-jump" true true true ])
|
(vim.api.nvim_feedkeys
|
||||||
|
(vim.api.nvim_replace_termcodes "<Plug>luasnip-expand-or-jump" true true true)
|
||||||
""
|
""
|
||||||
false
|
false)
|
||||||
])
|
ELSE
|
||||||
]] # else
|
(CALL fallback)))
|
||||||
(call fallback [])
|
[ "i" "s" ];
|
||||||
))
|
"<S-tab>" = CALL cmp.mapping (fallback:
|
||||||
[ "i" "s" ]
|
(IF
|
||||||
];
|
(CALL cmp.visible)
|
||||||
"<S-tab>" = call cmp.mapping [(fallback:
|
(CALL cmp.select_prev_item)
|
||||||
(ifelse [[(cmp.visible [])
|
(luasnip.jumpable (-1))
|
||||||
(cmp.select_prev_item [])]
|
(vim.api.nvim_feedkeys
|
||||||
/*elseif*/ [(luasnip.jumpable [ (-1) ])
|
(vim.api.nvim_replace_termcodes "<Plug>luasnip-jump-prev" true true true)
|
||||||
(vim.api.nvim_feedkeys [
|
|
||||||
(vim.api.nvim_replace_termcodes [ "<Plug>luasnip-jump-prev" true true true ])
|
|
||||||
""
|
""
|
||||||
false
|
false)
|
||||||
])
|
ELSE
|
||||||
]] # else
|
(CALL fallback)))
|
||||||
(call fallback [])
|
[ "i" "s" ];
|
||||||
))
|
|
||||||
[ "i" "s" ]
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
sources = cmp.config.sources [[
|
sources = cmp.config.sources [
|
||||||
{ name = "nvim_lsp"; }
|
{ name = "nvim_lsp"; }
|
||||||
{ name = "luasnip"; }
|
{ name = "luasnip"; }
|
||||||
]];
|
];
|
||||||
})
|
})
|
||||||
)); }
|
)); }
|
||||||
ps.lspkind-nvim
|
ps.lspkind-nvim
|
||||||
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" (cmp_autopairs: [
|
config = compile "nvim_autopairs" (REQBIND ["nvim-autopairs.completion.cmp" "nvim-autopairs"] (cmp-autopairs: nvim-autopairs: [
|
||||||
((req "nvim-autopairs").setup {
|
(nvim-autopairs.setup {
|
||||||
disable_filetype = [ "TelescopePrompt" "vim" ];
|
disable_filetype = [ "TelescopePrompt" "vim" ];
|
||||||
})
|
})
|
||||||
(mcall cmp.event "on" [
|
(MCALL cmp.event "on" "confirm_done" (cmp-autopairs.on_confirm_done {}))
|
||||||
"confirm_done"
|
|
||||||
(cmp_autopairs.on_confirm_done [{}])
|
|
||||||
])
|
|
||||||
])); }
|
])); }
|
||||||
{ plugin = ps.comment-nvim;
|
{ plugin = ps.comment-nvim;
|
||||||
config = compile "comment_nvim" [
|
config = compile "comment_nvim" [
|
||||||
((req "Comment").setup {})
|
((REQ "Comment").setup {})
|
||||||
(kmSetNs {
|
(kmSetNs {
|
||||||
"<space>/" = {
|
"<space>/" = {
|
||||||
rhs = prop (req "Comment.api").toggle "linewise.current";
|
rhs = PROP (REQ "Comment.api").toggle "linewise.current";
|
||||||
desc = "Comment current line";
|
desc = "Comment current line";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
@ -535,7 +590,13 @@
|
||||||
})
|
})
|
||||||
]; }
|
]; }
|
||||||
{ plugin = ps.nvim-lspconfig;
|
{ plugin = ps.nvim-lspconfig;
|
||||||
config = compile "nvim_lspconfig" (let setupLsp = lsp: builtins.seq (req "lspconfig.server_configurations.${lsp}") (call (prop (req "lspconfig") "${lsp}.setup")); in [
|
config = compile "nvim_lspconfig" (
|
||||||
|
let lsp = name: builtins.seq
|
||||||
|
# ensure an lsp exists (otherwise lspconfig will still create an empty config for some reason)
|
||||||
|
(REQ "lspconfig.server_configurations.${name}")
|
||||||
|
# metatables, son! they harden in response to physical trauma
|
||||||
|
(REQ' (PROP (require "lspconfig") name));
|
||||||
|
in [
|
||||||
# See `:help vim.diagnostic.*` for documentation on any of the below functions
|
# See `:help vim.diagnostic.*` for documentation on any of the below functions
|
||||||
(kmSetNs {
|
(kmSetNs {
|
||||||
"<space>e" = {
|
"<space>e" = {
|
||||||
|
@ -555,11 +616,11 @@
|
||||||
desc = "Add buffer diagnostics to the location list.";
|
desc = "Add buffer diagnostics to the location list.";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
(bind [
|
(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>
|
||||||
(vim.api.nvim_buf_set_option [ bufnr "omnifunc" "v:lua.vim.lsp.omnifunc" ])
|
(vim.api.nvim_buf_set_option bufnr "omnifunc" "v:lua.vim.lsp.omnifunc")
|
||||||
# Mappings.
|
# Mappings.
|
||||||
# See `:help vim.lsp.*` for documentation on any of the below functions
|
# See `:help vim.lsp.*` for documentation on any of the below functions
|
||||||
(kmSetNs {
|
(kmSetNs {
|
||||||
|
@ -585,9 +646,7 @@
|
||||||
rhs = vim.lsp.buf.remove_workspace_folder;
|
rhs = vim.lsp.buf.remove_workspace_folder;
|
||||||
desc = "Remove a folder from the workspace folders."; };
|
desc = "Remove a folder from the workspace folders."; };
|
||||||
"<space>wl" = {
|
"<space>wl" = {
|
||||||
rhs = (defun (print [
|
rhs = DEFUN (print (CALL vim.inspect (CALL vim.lsp.buf.list_workspace_folders)));
|
||||||
(call vim.inspect [(vim.lsp.buf.list_workspace_folders [])])
|
|
||||||
]));
|
|
||||||
desc = "List workspace folders."; };
|
desc = "List workspace folders."; };
|
||||||
"<space>D" = {
|
"<space>D" = {
|
||||||
rhs = vim.lsp.buf.type_definition;
|
rhs = vim.lsp.buf.type_definition;
|
||||||
|
@ -602,10 +661,10 @@
|
||||||
rhs = vim.lsp.buf.references;
|
rhs = vim.lsp.buf.references;
|
||||||
desc = "Lists all the references to the symbol under the cursor in the quickfix window."; };
|
desc = "Lists all the references to the symbol under the cursor in the quickfix window."; };
|
||||||
"<space>f" = {
|
"<space>f" = {
|
||||||
rhs = (defun (vim.lsp.buf.format {async = true;}));
|
rhs = (DEFUN (vim.lsp.buf.format {async = true;}));
|
||||||
desc = "Formats a buffer."; };
|
desc = "Formats a buffer."; };
|
||||||
})
|
})
|
||||||
]))
|
])
|
||||||
# LET rust_settings
|
# LET rust_settings
|
||||||
{ rust-analyzer = {
|
{ rust-analyzer = {
|
||||||
assist.emitMustUse = true;
|
assist.emitMustUse = true;
|
||||||
|
@ -614,36 +673,36 @@
|
||||||
procMacro.enable = true;
|
procMacro.enable = true;
|
||||||
}; }
|
}; }
|
||||||
# LET capabilities
|
# LET capabilities
|
||||||
(vim.tbl_extend [
|
(vim.tbl_extend
|
||||||
"keep"
|
"keep"
|
||||||
((req "cmp_nvim_lsp").default_capabilities [{}])
|
((REQ "cmp_nvim_lsp").default_capabilities {})
|
||||||
(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: [
|
||||||
(bindrec
|
(LETREC
|
||||||
# LETREC on_attach_rust
|
# LETREC on_attach_rust
|
||||||
(on_attach_rust: client: bufnr: [
|
(on_attach_rust: client: bufnr: [
|
||||||
(vim.api.nvim_create_user_command ["RustAndroid" (opts: [
|
(vim.api.nvim_create_user_command "RustAndroid" (opts: [
|
||||||
(vim.lsp.set_log_level "debug")
|
(vim.lsp.set_log_level "debug")
|
||||||
(setupLsp "rust_analyzer" {
|
((lsp "rust_analyzer").setup {
|
||||||
on_attach = on_attach_rust;
|
on_attach = on_attach_rust;
|
||||||
inherit capabilities;
|
inherit capabilities;
|
||||||
settings = vim.tbl_deep_extend [
|
settings = vim.tbl_deep_extend
|
||||||
"keep"
|
"keep"
|
||||||
config.rustAnalyzerAndroidSettings
|
config.rustAnalyzerAndroidSettings
|
||||||
rust_settings
|
rust_settings;
|
||||||
];
|
|
||||||
})
|
})
|
||||||
]) {}])
|
]) {})
|
||||||
(call on_attach [client bufnr])
|
(CALL on_attach client bufnr)
|
||||||
])
|
])
|
||||||
# BEGIN
|
# BEGIN
|
||||||
(let lsp' = { name, settings ? {} }: setupLsp name {
|
(let setupLsp' = { name, settings ? {} }: (lsp name).setup {
|
||||||
inherit on_attach capabilities settings;
|
inherit on_attach capabilities settings;
|
||||||
}; lsp = args: lsp' (if builtins.isString args then { name = args; } else args); in (on_attach_rust: [
|
};
|
||||||
|
setupLsp = args: setupLsp' (if builtins.isString args then { name = args; } else args);
|
||||||
|
in (on_attach_rust: [
|
||||||
# (vim.lsp.set_log_level "debug")
|
# (vim.lsp.set_log_level "debug")
|
||||||
(map lsp [
|
(map setupLsp [
|
||||||
# see https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
|
# see https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
|
||||||
"bashls"
|
"bashls"
|
||||||
"clangd"
|
"clangd"
|
||||||
|
@ -660,7 +719,7 @@
|
||||||
"taplo"
|
"taplo"
|
||||||
"marksman"
|
"marksman"
|
||||||
])
|
])
|
||||||
(setupLsp "rust_analyzer" {
|
((lsp "rust_analyzer").setup {
|
||||||
on_attach = on_attach_rust;
|
on_attach = on_attach_rust;
|
||||||
settings = rust_settings;
|
settings = rust_settings;
|
||||||
inherit capabilities;
|
inherit capabilities;
|
||||||
|
@ -670,8 +729,8 @@
|
||||||
]); }
|
]); }
|
||||||
{ plugin = ps.which-key-nvim;
|
{ plugin = ps.which-key-nvim;
|
||||||
config = compile "which_key_nvim" [
|
config = compile "which_key_nvim" [
|
||||||
(set vim.o.timeout true)
|
(SET vim.o.timeout true)
|
||||||
(set vim.o.timeoutlen 500)
|
(SET vim.o.timeoutlen 500)
|
||||||
(which-key.setup {})
|
(which-key.setup {})
|
||||||
]; }
|
]; }
|
||||||
];
|
];
|
||||||
|
|
|
@ -58,10 +58,10 @@ local json = require "cjson"
|
||||||
-- mark globals before requiring package
|
-- mark globals before requiring package
|
||||||
mark(_G)
|
mark(_G)
|
||||||
|
|
||||||
local package = "@package@"
|
local package = @package@
|
||||||
|
|
||||||
result = { __kind = "var", _type = "table", _name = "" }
|
result = { __kind = "var", _type = "table", _name = "" }
|
||||||
dump2(require(package), "", result)
|
dump2(package, "", result)
|
||||||
|
|
||||||
print(json.encode(result))
|
print(json.encode(result))
|
||||||
|
|
||||||
|
|
|
@ -4,19 +4,26 @@
|
||||||
, neovimUtils
|
, neovimUtils
|
||||||
, lua51Packages
|
, lua51Packages
|
||||||
, wrapNeovimUnstable
|
, wrapNeovimUnstable
|
||||||
, call
|
, CALL
|
||||||
|
, isGetInfo
|
||||||
, substituteAll
|
, substituteAll
|
||||||
, plugins
|
, plugins
|
||||||
|
, compileExpr
|
||||||
# , extraLuaPackages ? []
|
# , extraLuaPackages ? []
|
||||||
, ... }:
|
, ... }:
|
||||||
|
|
||||||
let update = self: prefix: lib.mapAttrs (k: v: let
|
# TODO: bfs instead of dfs in var dumps
|
||||||
|
|
||||||
|
let
|
||||||
|
update = self: prefix: lib.mapAttrs (k: v: let
|
||||||
v' = update self prefix v;
|
v' = update self prefix v;
|
||||||
in (if builtins.isAttrs v && v?__kind then (
|
in (if builtins.isAttrs v && v?__kind then (
|
||||||
if v.__kind == "rec" then
|
if v.__kind == "rec" then
|
||||||
lib.attrByPath (lib.splitString "." v.path) self
|
lib.attrByPath (lib.splitString "." v.path) null self
|
||||||
else if v.__kind == "var" && v._type == "function" then
|
else if v.__kind == "var" && v._type == "function" then
|
||||||
(args: if args == "GET_INFO" then v' else call v' args)
|
(args:
|
||||||
|
if isGetInfo args then v'
|
||||||
|
else CALL v' args)
|
||||||
else v'
|
else v'
|
||||||
) else if builtins.isAttrs v then v'
|
) else if builtins.isAttrs v then v'
|
||||||
else if prefix != "" && k == "_name" then
|
else if prefix != "" && k == "_name" then
|
||||||
|
@ -32,7 +39,7 @@ config = neovimUtils.makeNeovimConfig {
|
||||||
neovim = wrapNeovimUnstable neovim-unwrapped config;
|
neovim = wrapNeovimUnstable neovim-unwrapped config;
|
||||||
getReqAttrs = name: builtins.fromJSON (builtins.readFile (stdenvNoCC.mkDerivation {
|
getReqAttrs = name: builtins.fromJSON (builtins.readFile (stdenvNoCC.mkDerivation {
|
||||||
phases = [ "installPhase" ];
|
phases = [ "installPhase" ];
|
||||||
name = "neovim-require-${name}.json";
|
name = "neovim-types-${name}.json";
|
||||||
dumpPlugin = substituteAll {
|
dumpPlugin = substituteAll {
|
||||||
src = ./dump_plugin.lua;
|
src = ./dump_plugin.lua;
|
||||||
package = name;
|
package = name;
|
||||||
|
@ -43,8 +50,12 @@ getReqAttrs = name: builtins.fromJSON (builtins.readFile (stdenvNoCC.mkDerivatio
|
||||||
nvim --headless -S $dumpPlugin -i NONE -u NONE -n -c 'echo""|qall!' 2>$out
|
nvim --headless -S $dumpPlugin -i NONE -u NONE -n -c 'echo""|qall!' 2>$out
|
||||||
'';
|
'';
|
||||||
}));
|
}));
|
||||||
req = name: let result = update result "require(\"${name}\")" (getReqAttrs name); in result;
|
req = name: let res = update res name (getReqAttrs name); in res;
|
||||||
_reqbind = name: varname: let result = update result "${varname}" (getReqAttrs name); in result;
|
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 // {
|
in result // {
|
||||||
inherit req _reqbind;
|
inherit REQ REQ' _reqbind;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue