nvim: move lua compiler to a separate flake

This commit is contained in:
chayleaf 2023-03-18 02:50:38 +07:00
parent 7c1bcf409e
commit 75b50759ae
8 changed files with 58 additions and 596 deletions

View file

@ -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: [

View file

@ -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))

View file

@ -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

View file

@ -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;
}

View file

@ -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"
} }
}, },

View file

@ -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

View file

@ -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
]; ];