mirror of
https://github.com/NotAShelf/neovim-flake.git
synced 2024-12-23 23:29:48 +01:00
226 lines
6 KiB
Nix
226 lines
6 KiB
Nix
|
{
|
||
|
config,
|
||
|
lib,
|
||
|
pkgs,
|
||
|
...
|
||
|
}:
|
||
|
with lib;
|
||
|
with builtins; let
|
||
|
cfg = config.vim;
|
||
|
|
||
|
wrapLuaConfig = luaConfig: ''
|
||
|
lua << EOF
|
||
|
${luaConfig}
|
||
|
EOF
|
||
|
'';
|
||
|
|
||
|
mkMappingOption = it:
|
||
|
mkOption ({
|
||
|
default = {};
|
||
|
type = with types; attrsOf (nullOr str);
|
||
|
}
|
||
|
// it);
|
||
|
in {
|
||
|
options.vim = {
|
||
|
viAlias = mkOption {
|
||
|
description = "Enable vi alias";
|
||
|
type = types.bool;
|
||
|
default = true;
|
||
|
};
|
||
|
|
||
|
vimAlias = mkOption {
|
||
|
description = "Enable vim alias";
|
||
|
type = types.bool;
|
||
|
default = true;
|
||
|
};
|
||
|
|
||
|
configRC = mkOption {
|
||
|
description = "vimrc contents";
|
||
|
type = nvim.types.dagOf types.lines;
|
||
|
default = {};
|
||
|
};
|
||
|
|
||
|
luaConfigRC = mkOption {
|
||
|
description = "vim lua config";
|
||
|
type = nvim.types.dagOf types.lines;
|
||
|
default = {};
|
||
|
};
|
||
|
|
||
|
builtConfigRC = mkOption {
|
||
|
internal = true;
|
||
|
type = types.lines;
|
||
|
description = "The built config for neovim after resolving the DAG";
|
||
|
};
|
||
|
|
||
|
startPlugins = nvim.types.pluginsOpt {
|
||
|
default = [];
|
||
|
description = "List of plugins to startup.";
|
||
|
};
|
||
|
|
||
|
optPlugins = nvim.types.pluginsOpt {
|
||
|
default = [];
|
||
|
description = "List of plugins to optionally load";
|
||
|
};
|
||
|
|
||
|
globals = mkOption {
|
||
|
default = {};
|
||
|
description = "Set containing global variable values";
|
||
|
type = types.attrs;
|
||
|
};
|
||
|
|
||
|
nnoremap =
|
||
|
mkMappingOption {description = "Defines 'Normal mode' mappings";};
|
||
|
|
||
|
inoremap = mkMappingOption {
|
||
|
description = "Defines 'Insert and Replace mode' mappings";
|
||
|
};
|
||
|
|
||
|
vnoremap = mkMappingOption {
|
||
|
description = "Defines 'Visual and Select mode' mappings";
|
||
|
};
|
||
|
|
||
|
xnoremap =
|
||
|
mkMappingOption {description = "Defines 'Visual mode' mappings";};
|
||
|
|
||
|
snoremap =
|
||
|
mkMappingOption {description = "Defines 'Select mode' mappings";};
|
||
|
|
||
|
cnoremap =
|
||
|
mkMappingOption {description = "Defines 'Command-line mode' mappings";};
|
||
|
|
||
|
onoremap = mkMappingOption {
|
||
|
description = "Defines 'Operator pending mode' mappings";
|
||
|
};
|
||
|
|
||
|
tnoremap =
|
||
|
mkMappingOption {description = "Defines 'Terminal mode' mappings";};
|
||
|
|
||
|
nmap = mkMappingOption {description = "Defines 'Normal mode' mappings";};
|
||
|
|
||
|
imap = mkMappingOption {
|
||
|
description = "Defines 'Insert and Replace mode' mappings";
|
||
|
};
|
||
|
|
||
|
vmap = mkMappingOption {
|
||
|
description = "Defines 'Visual and Select mode' mappings";
|
||
|
};
|
||
|
|
||
|
xmap = mkMappingOption {description = "Defines 'Visual mode' mappings";};
|
||
|
|
||
|
smap = mkMappingOption {description = "Defines 'Select mode' mappings";};
|
||
|
|
||
|
cmap =
|
||
|
mkMappingOption {description = "Defines 'Command-line mode' mappings";};
|
||
|
|
||
|
omap = mkMappingOption {
|
||
|
description = "Defines 'Operator pending mode' mappings";
|
||
|
};
|
||
|
|
||
|
tmap =
|
||
|
mkMappingOption {description = "Defines 'Terminal mode' mappings";};
|
||
|
};
|
||
|
|
||
|
config = let
|
||
|
mkVimBool = val:
|
||
|
if val
|
||
|
then "1"
|
||
|
else "0";
|
||
|
valToVim = val:
|
||
|
if (isInt val)
|
||
|
then (builtins.toString val)
|
||
|
else
|
||
|
(
|
||
|
if (isBool val)
|
||
|
then (mkVimBool val)
|
||
|
else (toJSON val)
|
||
|
);
|
||
|
|
||
|
filterNonNull = mappings: filterAttrs (name: value: value != null) mappings;
|
||
|
globalsScript =
|
||
|
mapAttrsFlatten (name: value: "let g:${name}=${valToVim value}")
|
||
|
(filterNonNull cfg.globals);
|
||
|
|
||
|
matchCtrl = it: match "Ctrl-(.)(.*)" it;
|
||
|
mapKeyBinding = it: let
|
||
|
groups = matchCtrl it;
|
||
|
in
|
||
|
if groups == null
|
||
|
then it
|
||
|
else "<C-${toUpper (head groups)}>${head (tail groups)}";
|
||
|
mapVimBinding = prefix: mappings:
|
||
|
mapAttrsFlatten (name: value: "${prefix} ${mapKeyBinding name} ${value}")
|
||
|
(filterNonNull mappings);
|
||
|
|
||
|
nmap = mapVimBinding "nmap" config.vim.nmap;
|
||
|
imap = mapVimBinding "imap" config.vim.imap;
|
||
|
vmap = mapVimBinding "vmap" config.vim.vmap;
|
||
|
xmap = mapVimBinding "xmap" config.vim.xmap;
|
||
|
smap = mapVimBinding "smap" config.vim.smap;
|
||
|
cmap = mapVimBinding "cmap" config.vim.cmap;
|
||
|
omap = mapVimBinding "omap" config.vim.omap;
|
||
|
tmap = mapVimBinding "tmap" config.vim.tmap;
|
||
|
|
||
|
nnoremap = mapVimBinding "nnoremap" config.vim.nnoremap;
|
||
|
inoremap = mapVimBinding "inoremap" config.vim.inoremap;
|
||
|
vnoremap = mapVimBinding "vnoremap" config.vim.vnoremap;
|
||
|
xnoremap = mapVimBinding "xnoremap" config.vim.xnoremap;
|
||
|
snoremap = mapVimBinding "snoremap" config.vim.snoremap;
|
||
|
cnoremap = mapVimBinding "cnoremap" config.vim.cnoremap;
|
||
|
onoremap = mapVimBinding "onoremap" config.vim.onoremap;
|
||
|
tnoremap = mapVimBinding "tnoremap" config.vim.tnoremap;
|
||
|
|
||
|
resolveDag = {
|
||
|
name,
|
||
|
dag,
|
||
|
mapResult,
|
||
|
}: let
|
||
|
sortedDag = nvim.dag.topoSort dag;
|
||
|
result =
|
||
|
if sortedDag ? result
|
||
|
then mapResult sortedDag.result
|
||
|
else abort ("Dependency cycle in ${name}: " + toJSON sortedConfig);
|
||
|
in
|
||
|
result;
|
||
|
in {
|
||
|
vim = {
|
||
|
configRC = {
|
||
|
globalsScript = nvim.dag.entryAnywhere (concatStringsSep "\n" globalsScript);
|
||
|
|
||
|
luaScript = let
|
||
|
mkSection = r: ''
|
||
|
-- SECTION: ${r.name}
|
||
|
${r.data}
|
||
|
'';
|
||
|
mapResult = r: (wrapLuaConfig (concatStringsSep "\n" (map mkSection r)));
|
||
|
luaConfig = resolveDag {
|
||
|
name = "lua config script";
|
||
|
dag = cfg.luaConfigRC;
|
||
|
inherit mapResult;
|
||
|
};
|
||
|
in
|
||
|
nvim.dag.entryAfter ["globalsScript"] luaConfig;
|
||
|
|
||
|
mappings = let
|
||
|
maps = [nmap imap vmap xmap smap cmap omap tmap nnoremap inoremap vnoremap xnoremap snoremap cnoremap onoremap tnoremap];
|
||
|
mapConfig = concatStringsSep "\n" (map (v: concatStringsSep "\n" v) maps);
|
||
|
in
|
||
|
nvim.dag.entryAfter ["globalsScript"] mapConfig;
|
||
|
};
|
||
|
|
||
|
builtConfigRC = let
|
||
|
mkSection = r: ''
|
||
|
" SECTION: ${r.name}
|
||
|
${r.data}
|
||
|
'';
|
||
|
mapResult = r: (concatStringsSep "\n" (map mkSection r));
|
||
|
vimConfig = resolveDag {
|
||
|
name = "vim config script";
|
||
|
dag = cfg.configRC;
|
||
|
inherit mapResult;
|
||
|
};
|
||
|
in
|
||
|
vimConfig;
|
||
|
};
|
||
|
};
|
||
|
}
|