340 lines
8.7 KiB
Nix
340 lines
8.7 KiB
Nix
attrs@{ lib, korora, ... }:
|
|
let
|
|
e = import ./korora-lua.nix attrs;
|
|
k = korora;
|
|
h = e.helpers;
|
|
struct =
|
|
name: props: verify:
|
|
(k.struct name props).override {
|
|
total = false;
|
|
unknown = false;
|
|
verify = h.mkVerify verify;
|
|
};
|
|
|
|
lazyType = name: mkType: k.typedef' name (v: (mkType true).verify v);
|
|
|
|
types = {
|
|
# {{{ Helper types
|
|
oneOrMany =
|
|
type:
|
|
k.union [
|
|
type
|
|
(k.listOf type)
|
|
];
|
|
luaValue = k.any;
|
|
strictLuaLiteral =
|
|
(k.struct "lua literal" {
|
|
value = k.string;
|
|
__luaEncoderTag = k.enum "lua literal tag" [ "lua" ];
|
|
}).override
|
|
{ unknown = true; };
|
|
derivation = k.typedef "derivation" lib.isDerivation;
|
|
path = k.typedef "path" lib.isPath;
|
|
functionCheckedWith =
|
|
arg: type:
|
|
k.typedef' "${h.toPretty arg} -> ${type.name}" (
|
|
f:
|
|
if lib.isFunction f then
|
|
type.verify (f arg)
|
|
else
|
|
"Expected function, but got ${h.toPretty f} instead"
|
|
);
|
|
lazy = types.functionCheckedWith "";
|
|
luaEagerOrLazy =
|
|
type:
|
|
k.union [
|
|
type
|
|
(types.lazy type)
|
|
];
|
|
luaLiteral = types.luaEagerOrLazy types.strictLuaLiteral;
|
|
# }}}
|
|
# {{{ Lazy key
|
|
lazyKey = struct "lazy key" {
|
|
mapping = k.string;
|
|
action = k.union [
|
|
types.luaLiteral
|
|
k.string
|
|
];
|
|
mode = k.string;
|
|
desc = k.string;
|
|
expr = k.bool;
|
|
ft = types.oneOrMany k.string;
|
|
} [ (h.propExists "mapping") ];
|
|
# }}}
|
|
# {{{ Lazy module
|
|
lazyModule = lazyType "actually lazy lazy module" (
|
|
_:
|
|
struct "lazy module"
|
|
{
|
|
package = k.string;
|
|
dir = k.union [
|
|
k.string
|
|
types.derivation
|
|
types.path
|
|
];
|
|
version = k.string;
|
|
tag = k.string;
|
|
name = k.string;
|
|
main = k.string;
|
|
lazy = k.bool;
|
|
dependencies = struct "lazy dependencies" {
|
|
lua = k.listOf (
|
|
k.union [
|
|
k.string
|
|
types.lazyModule
|
|
]
|
|
);
|
|
nix = k.listOf types.derivation;
|
|
} [ ];
|
|
cond = types.oneOrMany types.luaLiteral;
|
|
init = types.luaEagerOrLazy (
|
|
k.union [
|
|
types.strictLuaLiteral
|
|
types.strictTempestConfig
|
|
]
|
|
);
|
|
config = k.union [
|
|
k.bool
|
|
(types.luaEagerOrLazy (
|
|
k.union [
|
|
types.strictLuaLiteral
|
|
types.strictTempestConfig
|
|
]
|
|
))
|
|
];
|
|
event = types.oneOrMany k.string;
|
|
cmd = types.oneOrMany k.string;
|
|
ft = types.oneOrMany k.string;
|
|
keys = types.oneOrMany (
|
|
k.union [
|
|
k.string
|
|
types.lazyKey
|
|
]
|
|
);
|
|
passthrough = types.luaValue;
|
|
opts = types.luaValue;
|
|
}
|
|
[
|
|
(h.propOnlyOne [
|
|
"dir"
|
|
"package"
|
|
])
|
|
(h.propImplies "tag" "package")
|
|
(h.propImplies "version" "package")
|
|
]
|
|
);
|
|
# }}}
|
|
# {{{ Tempest key
|
|
tempestKey =
|
|
struct "tempest key"
|
|
{
|
|
mapping = k.string;
|
|
action = types.luaValue;
|
|
mode = k.string;
|
|
desc = k.string;
|
|
expr = k.bool;
|
|
silent = k.bool;
|
|
ft = types.oneOrMany k.string;
|
|
buffer = k.union [
|
|
k.bool
|
|
k.number
|
|
types.luaLiteral
|
|
];
|
|
}
|
|
[
|
|
(h.propExists "mapping")
|
|
(h.propExists "action")
|
|
];
|
|
# }}}
|
|
# {{{ Tempest autocmd
|
|
tempestAutocmd =
|
|
struct "tempest autocommand"
|
|
{
|
|
event = types.oneOrMany k.string;
|
|
pattern = types.oneOrMany k.string;
|
|
group = k.string;
|
|
action = k.union [
|
|
types.tempestConfig
|
|
types.luaLiteral
|
|
];
|
|
}
|
|
[
|
|
(h.propExists "event")
|
|
(h.propExists "group")
|
|
(h.propExists "action")
|
|
];
|
|
# }}}
|
|
# {{{ Tempest config
|
|
strictTempestConfig = struct "tempest config" {
|
|
vim = types.luaValue;
|
|
callback = k.union [
|
|
types.luaLiteral
|
|
types.tempestConfig
|
|
];
|
|
setup = k.attrsOf types.luaValue;
|
|
keys = types.luaEagerOrLazy (types.oneOrMany types.tempestKey);
|
|
autocmds = types.luaEagerOrLazy (types.oneOrMany types.tempestAutocmd);
|
|
mkContext = types.luaValue;
|
|
cond = types.oneOrMany types.luaValue;
|
|
} [ ];
|
|
|
|
tempestConfig = lazyType "lazy tempest config" (_: types.strictTempestConfig);
|
|
# }}}
|
|
# {{{ Neovim env
|
|
neovimEnv = k.enum "neovim env" [
|
|
"neovide"
|
|
"firenvim"
|
|
"vscode"
|
|
];
|
|
# }}}
|
|
# {{{ Neovim config
|
|
neovimConfig = struct "neovim configuration" {
|
|
pre = k.attrsOf types.tempestConfig;
|
|
lazy = k.attrsOf types.lazyModule;
|
|
post = k.attrsOf types.tempestConfig;
|
|
} [ ];
|
|
# }}}
|
|
};
|
|
|
|
mkLib =
|
|
{ tempestModule }:
|
|
assert h.hasType k.string tempestModule;
|
|
rec {
|
|
inherit (e) encode;
|
|
inherit (h) lua;
|
|
|
|
# {{{ Common generation helpers
|
|
importFrom =
|
|
path: tag:
|
|
assert lib.isPath path;
|
|
assert h.hasType k.string tag;
|
|
lua "dofile(${encode (toString path)}).${tag}";
|
|
foldedList =
|
|
value:
|
|
assert h.hasType k.attrs value;
|
|
{
|
|
inherit value;
|
|
__luaEncoderTag = "foldedList";
|
|
};
|
|
thunk = code: _: lua code;
|
|
return = code: lua "return ${encode code}";
|
|
|
|
vim = lua "vim";
|
|
print = lua "print";
|
|
require = lua "require";
|
|
tempest = lua "D.tempest";
|
|
|
|
do = actions: lua (lib.concatStringsSep "\n" (lib.forEach actions encode));
|
|
args = values: lua (lib.concatStringsSep ", " (lib.forEach values encode));
|
|
none = lua "";
|
|
|
|
tempestConfigure =
|
|
given: context:
|
|
lua ''
|
|
D.tempest.configure(
|
|
${encode given},
|
|
${context}
|
|
)
|
|
'';
|
|
tempestBufnr =
|
|
given:
|
|
lua ''
|
|
function(_, bufnr)
|
|
return D.tempest.configure(
|
|
${encode given},
|
|
{ bufnr = bufnr}
|
|
)
|
|
end
|
|
'';
|
|
keymap = mode: mapping: action: desc: {
|
|
inherit
|
|
mode
|
|
mapping
|
|
action
|
|
desc
|
|
;
|
|
};
|
|
nmap = mapping: action: desc: { inherit mapping action desc; };
|
|
unmap = mapping: {
|
|
inherit mapping;
|
|
action = "<nop>";
|
|
};
|
|
blacklist =
|
|
given:
|
|
assert h.hasType (types.oneOrMany types.neovimEnv) given;
|
|
# lua
|
|
lua ''
|
|
D.tempest.blacklist(${encode given})
|
|
'';
|
|
whitelist =
|
|
given:
|
|
assert h.hasType (types.oneOrMany types.neovimEnv) given;
|
|
# lua
|
|
lua ''
|
|
D.tempest.whitelist(${encode given})
|
|
'';
|
|
# :p => expands path
|
|
# :h => returns the head of the path
|
|
notmp = lua ''vim.fn.expand("%:p:h") ~= "/tmp"'';
|
|
# }}}
|
|
# {{{ Main config generation entrypoint
|
|
generateConfig =
|
|
rawConfig:
|
|
assert h.hasType types.neovimConfig rawConfig;
|
|
let
|
|
config = {
|
|
lazy = { };
|
|
pre = { };
|
|
post = { };
|
|
} // rawConfig;
|
|
collectNixDeps =
|
|
lazyModule:
|
|
if lazyModule ? dependencies then
|
|
let
|
|
nix = lazyModule.dependencies.nix or [ ];
|
|
other = lib.pipe (lazyModule.dependencies.lua or [ ]) [
|
|
(lib.lists.map collectNixDeps)
|
|
lib.lists.flatten
|
|
];
|
|
in
|
|
nix ++ other
|
|
else
|
|
[ ];
|
|
dependencies = lib.pipe config.lazy [
|
|
(lib.mapAttrsToList (_: collectNixDeps))
|
|
lib.lists.flatten
|
|
];
|
|
processedLazyModules = lib.mapAttrs (
|
|
name: module:
|
|
{ inherit name; } // module // { dependencies = (module.dependencies or { }).lua or null; }
|
|
) config.lazy;
|
|
|
|
luaConfig = ''
|
|
local M = {}
|
|
local D = {
|
|
tempest = require(${encode tempestModule}),
|
|
}
|
|
|
|
-- {{{ Pre-plugin config
|
|
M.pre = ${encode (foldedList config.pre)}
|
|
-- }}}
|
|
-- {{{ Lazy modules
|
|
M.lazy = ${encode (foldedList processedLazyModules)}
|
|
D.tempest.prepareLazySpec(M.lazy)
|
|
-- }}}
|
|
-- {{{ Post-plugin config
|
|
M.post = ${encode (foldedList config.post)}
|
|
-- }}}
|
|
|
|
return M
|
|
'';
|
|
in
|
|
{
|
|
inherit dependencies;
|
|
lua = luaConfig;
|
|
};
|
|
# }}}
|
|
};
|
|
in
|
|
mkLib
|