treewide: make the entire generated config lua based (#333)

* modules: switch to gerg's neovim-wrapper

* modules: use initViml instead of writing the file

* treewide: make the entire generated config lua based

* docs: remove mentions of configRC

* plugins/treesitter: remove vim.cmd hack

* treewide: move resolveDag to lib

* modules/wrapper(rc): fix typo

* treewide: migrate to pluginRC for correct DAG order

The "new" DAG order is as follows:
- (luaConfigPre)
- globalsScript
- basic
- theme
- pluginConfigs
- extraPluginConfigs
- mappings
- (luaConfigPost)

* plugins/theme: fix theme DAG place

* plugins/theme: fix fixed theme DAG place

* modules/wrapper(rc): add removed option module for configRC

* docs: add dag-entries chapter, add release note entry

* fix: formatting CI

* languages/nix: add missing `local`

* docs: fix page link

* docs: add mention of breaking changes at the start of the release notes

* plugins/neo-tree: convert to pluginRC

* modules/wrapper(rc): add back entryAnywhere

* modules/wrapper(rc): expose pluginRC

* apply raf patch

---------

Co-authored-by: NotAShelf <raf@notashelf.dev>
This commit is contained in:
diniamo 2024-07-20 10:30:48 +02:00 committed by GitHub
commit f9789432f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
84 changed files with 389 additions and 404 deletions

View file

@ -3,17 +3,16 @@
lib,
...
}: let
inherit (builtins) map mapAttrs toJSON filter;
inherit (builtins) map mapAttrs filter;
inherit (lib.options) mkOption;
inherit (lib.attrsets) filterAttrs getAttrs attrValues attrNames;
inherit (lib.strings) isString concatLines concatMapStringsSep;
inherit (lib.strings) concatLines concatMapStringsSep;
inherit (lib.misc) mapAttrsFlatten;
inherit (lib.trivial) showWarnings;
inherit (lib.types) str nullOr;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.dag) entryAnywhere entryAfter topoSort mkLuarcSection mkVimrcSection;
inherit (lib.nvim.lua) toLuaObject wrapLuaConfig;
inherit (lib.nvim.vim) valToVim;
inherit (lib.nvim.dag) entryAfter mkLuarcSection resolveDag entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.config) mkBool;
cfg = config.vim;
@ -82,11 +81,23 @@
maps);
in {
config = let
filterNonNull = mappings: filterAttrs (_name: value: value != null) mappings;
filterNonNull = attrs: filterAttrs (_: value: value != null) attrs;
globalsScript =
mapAttrsFlatten (name: value: "let g:${name}=${valToVim value}")
mapAttrsFlatten (name: value: "vim.g.${name} = ${toLuaObject value}")
(filterNonNull cfg.globals);
extraPluginConfigs = resolveDag {
name = "extra plugin configs";
dag = mapAttrs (_: value: entryAfter value.after value.setup) cfg.extraPlugins;
mapResult = result: concatLines (map mkLuarcSection result);
};
pluginConfigs = resolveDag {
name = "plugin configs";
dag = cfg.pluginRC;
mapResult = result: concatLines (map mkLuarcSection result);
};
toLuaBindings = mode: maps:
map (value: ''
vim.keymap.set(${toLuaObject mode}, ${toLuaObject value.key}, ${toLuaObject value.action}, ${toLuaObject value.config})
@ -105,96 +116,31 @@ in {
omap = toLuaBindings "o" config.vim.maps.operator;
icmap = toLuaBindings "ic" config.vim.maps.insertCommand;
resolveDag = {
name,
dag,
mapResult,
}: let
# When the value is a string, default it to dag.entryAnywhere
finalDag = mapAttrs (_: value:
if isString value
then entryAnywhere value
else value)
dag;
sortedDag = topoSort finalDag;
result =
if sortedDag ? result
then mapResult sortedDag.result
else abort ("Dependency cycle in ${name}: " + toJSON sortedDag);
in
result;
maps = [
nmap
imap
vmap
xmap
smap
cmap
omap
tmap
lmap
icmap
allmap
];
mappings = concatLines (map concatLines maps);
in {
vim = {
configRC = {
luaConfigRC = {
globalsScript = entryAnywhere (concatLines globalsScript);
# Call additional lua files with :luafile in Vimscript
# section of the configuration, only after
# the luaScript section has been evaluated
extraLuaFiles = let
callLuaFiles = map (file: "luafile ${file}") cfg.extraLuaFiles;
in
entryAfter ["globalScript"] (concatLines callLuaFiles);
# wrap the lua config in a lua block
# using the wrapLuaConfic function from the lib
luaScript = let
mapResult = result: (wrapLuaConfig {
luaBefore = "${cfg.luaConfigPre}";
luaConfig = concatLines (map mkLuarcSection result);
luaAfter = "${cfg.luaConfigPost}";
});
luaConfig = resolveDag {
name = "lua config script";
dag = cfg.luaConfigRC;
inherit mapResult;
};
in
entryAnywhere luaConfig;
extraPluginConfigs = let
mapResult = result: (wrapLuaConfig {
luaConfig = concatLines (map mkLuarcSection result);
});
extraPluginsDag = mapAttrs (_: {
after,
setup,
...
}:
entryAfter after setup)
cfg.extraPlugins;
pluginConfig = resolveDag {
name = "extra plugins config";
dag = extraPluginsDag;
inherit mapResult;
};
in
entryAfter ["luaScript"] pluginConfig;
# This is probably not the right way to set the config. I'm not sure how it should look like.
mappings = let
maps = [
nmap
imap
vmap
xmap
smap
cmap
omap
tmap
lmap
icmap
allmap
];
mapConfig = wrapLuaConfig {luaConfig = concatLines (map concatLines maps);};
in
entryAfter ["globalsScript"] mapConfig;
# basic, theme
pluginConfigs = entryAfter ["theme"] pluginConfigs;
extraPluginConfigs = entryAfter ["pluginConfigs"] extraPluginConfigs;
mappings = entryAfter ["extraPluginConfigs"] mappings;
};
builtConfigRC = let
builtLuaConfigRC = let
# Catch assertions and warnings
# and throw for each failed assertion. If no assertions are found, show warnings.
failedAssertions = map (x: x.message) (filter (x: !x.assertion) config.assertions);
@ -203,14 +149,18 @@ in {
then throw "\nFailed assertions:\n${concatMapStringsSep "\n" (x: "- ${x}") failedAssertions}"
else showWarnings config.warnings;
mapResult = result: concatMapStringsSep "\n" mkVimrcSection result;
vimConfig = resolveDag {
name = "vim config script";
dag = cfg.configRC;
inherit mapResult;
luaConfig = resolveDag {
name = "lua config script";
dag = cfg.luaConfigRC;
mapResult = result:
concatLines [
cfg.luaConfigPre
(concatMapStringsSep "\n" mkLuarcSection result)
cfg.luaConfigPost
];
};
in
baseSystemAssertWarn vimConfig;
baseSystemAssertWarn luaConfig;
};
};
}

View file

@ -3,13 +3,25 @@
lib,
...
}: let
inherit (lib.modules) mkRemovedOptionModule;
inherit (lib.options) mkOption mkEnableOption literalMD literalExpression;
inherit (lib.strings) optionalString;
inherit (lib.types) str oneOf attrs lines listOf either path bool;
inherit (lib.types) str attrs lines listOf either path bool;
inherit (lib.nvim.types) dagOf;
inherit (lib.nvim.lua) listToLuaTable;
cfg = config.vim;
in {
imports = [
(mkRemovedOptionModule ["vim" "configRC"] ''
Please migrate your configRC sections to Neovim's Lua format, and
add them to luaConfigRC.
See the v0.7 release notes for more information on how to migrate
your existing configurations.
'')
];
options.vim = {
enableLuaLoader = mkEnableOption ''
the experimental Lua module loader to speed up the start up process
@ -120,35 +132,20 @@ in {
description = ''
An attribute set containing global variable values
for storing vim variables as early as possible. If
populated, this soption will set vim variables in the
built configRC as the first item.
populated, this option will set vim variables in the
built luaConfigRC as the first item.
E.g. {foo = "bar"} will set `g:foo` to "bar" where
E.g. {foo = "bar"} will set `vim.g.foo` to "bar" where
the type of `bar` in the resulting vimscript will be
infered from the type of the value in the `{name = value}`
pair.
'';
};
configRC = mkOption {
type = oneOf [(dagOf lines) str];
pluginRC = mkOption {
type = either (dagOf lines) str;
default = {};
description = ''
Contents of vimrc, either as a string or a DAG.
If this option is passed as a DAG, it will be resolved
according to the DAG resolution rules (e.g. entryBefore
or entryAfter) as per the **nvf** extended library.
'';
example = literalMD ''
```vim
" Set the tab size to 4 spaces
set tabstop=4
set shiftwidth=4
set expandtab
```
'';
description = "The DAG used to configure plugins. If a string is passed, entryAnywhere is automatically applied.";
};
luaConfigPre = mkOption {
@ -211,7 +208,7 @@ in {
};
luaConfigRC = mkOption {
type = oneOf [(dagOf lines) str];
type = either (dagOf lines) str;
default = {};
description = ''
Lua configuration, either as a string or a DAG.
@ -245,10 +242,10 @@ in {
'';
};
builtConfigRC = mkOption {
builtLuaConfigRC = mkOption {
internal = true;
type = lines;
description = "The built config for neovim after resolving the DAG";
description = "The built lua config for neovim after resolving the DAG";
};
};
}