initial commit
This commit is contained in:
commit
13177e2c36
11 changed files with 554 additions and 0 deletions
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
# editors
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
# direnv
|
||||
.direnv
|
||||
.envrc
|
||||
# nix
|
||||
/result
|
||||
# custom
|
||||
test-cfg
|
31
default.nix
Normal file
31
default.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{ config ? { }
|
||||
, pkgs ? import <nixpkgs> { }
|
||||
, nix2lua ? import <nix2lua>
|
||||
}:
|
||||
|
||||
|
||||
let
|
||||
inherit (pkgs.lib) evalModules filter concatMapStringsSep showWarnings;
|
||||
|
||||
allModules = import ./module-list.nix { inherit pkgs; };
|
||||
|
||||
rawModule = evalModules {
|
||||
modules = [ config ] ++ allModules;
|
||||
specialArgs = {
|
||||
inherit pkgs;
|
||||
nix2lua = nix2lua.lib;
|
||||
};
|
||||
};
|
||||
|
||||
failedAssertions = map (x: x.message) (filter (x: !x.assertion) rawModule.config.assertions);
|
||||
|
||||
module =
|
||||
if failedAssertions != [ ]
|
||||
then throw "\nFailed assertions:\n${concatMapStringsSep "\n" (x: "- ${x}") failedAssertions}"
|
||||
else showWarnings rawModule.config.warnings rawModule;
|
||||
in
|
||||
{
|
||||
inherit (module.config.build) neovim;
|
||||
inherit (module) config options;
|
||||
inherit pkgs;
|
||||
}
|
18
module-list.nix
Normal file
18
module-list.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ pkgs }:
|
||||
|
||||
[
|
||||
./modules/build/neovim.nix
|
||||
|
||||
./modules/vim/opts.nix
|
||||
./modules/vim/keymap.nix
|
||||
|
||||
./modules/filetype.nix
|
||||
./modules/input.nix
|
||||
./modules/plugin.nix
|
||||
|
||||
./modules/plugins/theme/catppuccin.nix
|
||||
./modules/plugins/navigation/telescope.nix
|
||||
|
||||
##################################################
|
||||
(pkgs.path + "/nixos/modules/misc/assertions.nix")
|
||||
]
|
70
modules/build/neovim.nix
Normal file
70
modules/build/neovim.nix
Normal file
|
@ -0,0 +1,70 @@
|
|||
{ config, lib, pkgs, nix2lua, ... }:
|
||||
|
||||
let
|
||||
inherit (builtins) filter attrValues;
|
||||
|
||||
cfg = config.build.neovim;
|
||||
in
|
||||
{
|
||||
options.build.neovim = with lib; with types; {
|
||||
luaConfig = mkOption {
|
||||
type = lines;
|
||||
readOnly = true;
|
||||
internal = true;
|
||||
description = ''
|
||||
Neovim editor lua configuration.
|
||||
'';
|
||||
};
|
||||
plugins = mkOption {
|
||||
type = listOf package;
|
||||
readOnly = true;
|
||||
internal = true;
|
||||
};
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
readOnly = true;
|
||||
internal = true;
|
||||
description = ''
|
||||
Neovim editor derivation with plugins and configurations.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config.build.neovim = {
|
||||
luaConfig = with nix2lua; toLua (spaceBetween (lib.flatten [
|
||||
# Global Opts
|
||||
(lib.flip lib.mapAttrsToList config.vim.g (k: set "vim.g.${k}"))
|
||||
# Opts
|
||||
(lib.flip lib.mapAttrsToList config.vim.opt (k: set "vim.opt.${k}"))
|
||||
# Keymaps
|
||||
(lib.flip map config.vim.keymap.set ({ mode, lhs, rhs, ... } @ vars:
|
||||
call "vim.keymap.set" [ mode lhs rhs (removeAttrs vars [ "mode" "lhs" "rhs" ]) ]
|
||||
))
|
||||
# Plugins
|
||||
(map (v: v.genConfig) (filter (v: !v.isDependency) (attrValues config.plugin)))
|
||||
# Cmd
|
||||
(lib.optional (config.vim.cmd != "") (call "vim.cmd" config.vim.cmd))
|
||||
]));
|
||||
|
||||
plugins = lib.mapAttrsToList (k: v: v.package) config.plugin;
|
||||
|
||||
package = pkgs.wrapNeovim pkgs.neovim-unwrapped {
|
||||
viAlias = false;
|
||||
vimAlias = false;
|
||||
|
||||
withPython3 = false;
|
||||
withNodeJs = false;
|
||||
withRuby = false;
|
||||
|
||||
configure = {
|
||||
customRC = ''
|
||||
lua << EOF
|
||||
${cfg.luaConfig}
|
||||
EOF
|
||||
'';
|
||||
|
||||
packages.myVimPackages = { start = cfg.plugins; };
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
67
modules/filetype.nix
Normal file
67
modules/filetype.nix
Normal file
|
@ -0,0 +1,67 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
let cfg = config.filetype; in
|
||||
{
|
||||
options.filetype = with lib; with types; {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Vim can detect the type of file that is edited. This is done by checking the
|
||||
file name and sometimes by inspecting the contents of the file for specific
|
||||
text.
|
||||
|
||||
`:help filetypes`
|
||||
`:help filetype-off`
|
||||
`:help filetype-overview`
|
||||
'';
|
||||
};
|
||||
|
||||
plugin = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable loading the plugin files for specific file types
|
||||
|
||||
`:help :filetype-plugin-on`
|
||||
`:help :filetype-plugin-off`
|
||||
'';
|
||||
};
|
||||
|
||||
indent = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable loading the indent file for specific file types
|
||||
|
||||
`:help :filetype-indent-on`
|
||||
`:help :filetype-indent-off`
|
||||
'';
|
||||
};
|
||||
|
||||
ignore = mkOption {
|
||||
type = uniq (listOf str);
|
||||
default = [ "Z" "gz" "bz2" "zip" "tgz" ];
|
||||
description = ''
|
||||
To avoid that certain files are being inspected, the g:ft_ignore_pat variable
|
||||
is used. The default value is set like this:
|
||||
|
||||
`:help filetype-ignore`
|
||||
'';
|
||||
};
|
||||
extraIgnore = mkOption {
|
||||
type = uniq (listOf str);
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
vim.namedCmd.filetype = lib.concatLines
|
||||
(lib.flip lib.mapAttrsToList { inherit (cfg) enable plugin indent; }
|
||||
(k: v: ''filetype ${if k == "enable" then "" else k} ${if v then "on" else "off"}'')
|
||||
);
|
||||
|
||||
vim.g.ft_ignore_pat = "\\\\.(${lib.concatStringsSep "|" (cfg.ignore ++ cfg.extraIgnore)})$";
|
||||
};
|
||||
|
||||
}
|
34
modules/input.nix
Normal file
34
modules/input.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.input;
|
||||
|
||||
disableKeymaps = mode: lhss: lib.flip map lhss (lhs: { inherit mode lhs; rhs = "<nop>"; });
|
||||
in
|
||||
{
|
||||
options.input = with lib; with types; {
|
||||
exMode.enable = (mkEnableOption "Ex mode") // { default = true; };
|
||||
arrowKeys = {
|
||||
disableInMode = mkOption {
|
||||
type = oneOf [ str (uniq (listOf str)) ];
|
||||
default = [ "n" "v" ];
|
||||
};
|
||||
};
|
||||
pageButtons = {
|
||||
disableInMode = mkOption {
|
||||
type = oneOf [ str (uniq (listOf str)) ];
|
||||
default = [ "n" "v" "i" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config.vim.keymap.set =
|
||||
# Disable the annoying and useless ex-mode
|
||||
lib.optionals (!cfg.exMode.enable) (disableKeymaps "n" [ "Q" "gQ" ])
|
||||
# Disable arrow keys
|
||||
++ lib.optionals (cfg.arrowKeys.disableInMode != [ ])
|
||||
(disableKeymaps cfg.arrowKeys.disableInMode [ "<Up>" "<Down>" "<Left>" "<Right>" ])
|
||||
# Disable PageUp / PageDown
|
||||
++ lib.optionals (cfg.pageButtons.disableInMode != [ ])
|
||||
(disableKeymaps cfg.pageButtons.disableInMode [ "<PageUp>" "<PageDown>" ]);
|
||||
}
|
80
modules/plugin.nix
Normal file
80
modules/plugin.nix
Normal file
|
@ -0,0 +1,80 @@
|
|||
{ lib, pkgs, nix2lua, ... }:
|
||||
|
||||
|
||||
let
|
||||
pluginOpts = ({ name, config, ... }: {
|
||||
options = with lib; with types; {
|
||||
name = mkOption {
|
||||
type = str;
|
||||
};
|
||||
varName = mkOption {
|
||||
type = str;
|
||||
# TODO: add validation
|
||||
};
|
||||
package = mkPackageOption pkgs.vimPlugins name { };
|
||||
|
||||
isDependency = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
beforeSetup = mkOption {
|
||||
type = listOf attrs;
|
||||
default = [ ];
|
||||
};
|
||||
setupFnName = mkOption {
|
||||
type = str;
|
||||
default = "setup";
|
||||
};
|
||||
setupSettings = mkOption {
|
||||
type = nullOr attrs;
|
||||
default = null;
|
||||
};
|
||||
afterSetup = mkOption {
|
||||
type = listOf attrs;
|
||||
default = [ ];
|
||||
};
|
||||
extra = mkOption {
|
||||
type = listOf attrs;
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
genConfig = mkOption {
|
||||
type = listOf attrs;
|
||||
readOnly = true;
|
||||
internal = true;
|
||||
};
|
||||
|
||||
luaConfig = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
name = lib.mkDefault name;
|
||||
varName = lib.mkDefault (builtins.replaceStrings [ "-" "/" ] [ "_" "_" ] config.name);
|
||||
|
||||
genConfig = with nix2lua; lib.mkIf (!config.isDependency) (lib.flatten [
|
||||
(local (set config.varName (require config.name)))
|
||||
config.beforeSetup
|
||||
(lib.optional (config.setupSettings != null)
|
||||
(pipe1 (var config.varName) (call config.setupFnName config.setupSettings))
|
||||
)
|
||||
config.afterSetup
|
||||
config.extra
|
||||
]);
|
||||
|
||||
luaConfig = with nix2lua; toLua (spaceBetween config.genConfig);
|
||||
};
|
||||
});
|
||||
|
||||
in
|
||||
{
|
||||
options.plugin = with lib; with types; mkOption {
|
||||
type = attrsOf (submodule pluginOpts);
|
||||
default = { };
|
||||
};
|
||||
|
||||
}
|
35
modules/plugins/navigation/telescope.nix
Normal file
35
modules/plugins/navigation/telescope.nix
Normal file
|
@ -0,0 +1,35 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.plugins.navigation.telescope; in
|
||||
{
|
||||
options.plugins.navigation.telescope = with lib; {
|
||||
enable = mkEnableOption "telescope";
|
||||
|
||||
package = mkPackageOption pkgs.vimPlugins "telescope-nvim" { };
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
default = { };
|
||||
description = ''
|
||||
See: https://github.com/nvim-telescope/telescope.nvim?tab=readme-ov-file#customization
|
||||
'';
|
||||
example = {
|
||||
pickers = {
|
||||
find_files = {
|
||||
theme = "dropdown";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
plugin.plenary-nvim = lib.mkDefault { isDependency = true; };
|
||||
|
||||
plugin.telescope-nvim = {
|
||||
name = "telescope";
|
||||
package = cfg.package;
|
||||
setupSettings = cfg.settings;
|
||||
};
|
||||
};
|
||||
}
|
34
modules/plugins/theme/catppuccin.nix
Normal file
34
modules/plugins/theme/catppuccin.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.plugins.theme.catppuccin; in
|
||||
{
|
||||
options.plugins.theme.catppuccin = with lib; {
|
||||
enable = mkEnableOption "catppuccin";
|
||||
|
||||
package = mkPackageOption pkgs.vimPlugins "catppuccin-nvim" { };
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
default = { };
|
||||
description = ''
|
||||
See: https://github.com/catppuccin/nvim/?tab=readme-ov-file#configuration
|
||||
'';
|
||||
example = {
|
||||
flavour = "frappe";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
plugin.catppuccin-nvim = {
|
||||
name = "catppuccin";
|
||||
package = cfg.package;
|
||||
setupSettings = cfg.settings;
|
||||
};
|
||||
|
||||
vim.namedCmd.colorscheme = ''
|
||||
colorscheme catppuccin
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
141
modules/vim/keymap.nix
Normal file
141
modules/vim/keymap.nix
Normal file
|
@ -0,0 +1,141 @@
|
|||
{ lib, ... }:
|
||||
|
||||
let
|
||||
modeType = lib.types.enum [ "" "n" "!" "i" "c" "v" "x" "s" "o" "t" "l" ];
|
||||
|
||||
# TODO: maybe add more options and add descriptions from
|
||||
# :help vim.keymap.set
|
||||
# :help nvim_set_keymap
|
||||
setKeymapType = with lib; with types; submodule {
|
||||
options = {
|
||||
lhs = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
Left-hand side |{lhs}| of the mapping.
|
||||
'';
|
||||
};
|
||||
rhs = mkOption {
|
||||
type = oneOf [ str attrs ];
|
||||
description = ''
|
||||
Right-hand side |{rhs}| of the mapping, can be a Lua function.
|
||||
'';
|
||||
};
|
||||
mode = mkOption {
|
||||
type = oneOf [
|
||||
modeType
|
||||
(uniq (listOf modeType))
|
||||
];
|
||||
default = "";
|
||||
description = ''
|
||||
Mode | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang |
|
||||
Command +------+-----+-----+-----+-----+-----+------+------+
|
||||
"" | yes | - | - | yes | yes | yes | - | - |
|
||||
"n" | yes | - | - | - | - | - | - | - |
|
||||
"!" | - | yes | yes | - | - | - | - | - |
|
||||
"i" | - | yes | - | - | - | - | - | - |
|
||||
"c" | - | - | yes | - | - | - | - | - |
|
||||
"v" | - | - | - | yes | yes | - | - | - |
|
||||
"x" | - | - | - | yes | - | - | - | - |
|
||||
"s" | - | - | - | - | yes | - | - | - |
|
||||
"o" | - | - | - | - | - | yes | - | - |
|
||||
"t" | - | - | - | - | - | - | yes | - |
|
||||
"l" | - | yes | yes | - | - | - | - | yes |
|
||||
|
||||
`:help map-overview`
|
||||
'';
|
||||
};
|
||||
buffer = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
The mapping will be effective in the current buffer only.
|
||||
|
||||
`:help :map-buffer`
|
||||
'';
|
||||
};
|
||||
nowait = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
When defining a buffer-local mapping for "," there may be a global mapping
|
||||
that starts with ",". Then you need to type another character for Vim to know
|
||||
whether to use the "," mapping or the longer one. To avoid this add the
|
||||
<nowait> argument. Then the mapping will be used when it matches, Vim does
|
||||
not wait for more characters to be typed.
|
||||
|
||||
`:help :map-nowait`
|
||||
'';
|
||||
};
|
||||
silent = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
To define a mapping which will not be echoed on the command line.
|
||||
|
||||
`:help :map-silent`
|
||||
'';
|
||||
};
|
||||
script = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If the first argument to one of these commands is "<script>" and it is used to
|
||||
define a new mapping or abbreviation, the mapping will only remap characters
|
||||
in the {rhs} using mappings that were defined local to a script, starting with
|
||||
"<SID>". This can be used to avoid that mappings from outside a script
|
||||
interfere (e.g., when CTRL-V is remapped in mswin.vim), but do use other
|
||||
mappings defined in the script.
|
||||
|
||||
`:help :map-script`
|
||||
'';
|
||||
|
||||
};
|
||||
expr = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If the first argument to one of these commands is "<expr>" and it is used to
|
||||
define a new mapping or abbreviation, the argument is an expression. The
|
||||
expression is evaluated to obtain the {rhs} that is used.
|
||||
|
||||
`:help :map-expression`
|
||||
'';
|
||||
};
|
||||
unique = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
It is used to define a new mapping or abbreviation, the command will fail if
|
||||
the mapping or abbreviation already exists.
|
||||
|
||||
When defining a local mapping, there will also be a check if a global map
|
||||
already exists which is equal.
|
||||
|
||||
`:help :map-unique`
|
||||
'';
|
||||
};
|
||||
remap = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Make the mapping recursive.
|
||||
'';
|
||||
};
|
||||
desc = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Human-readable description.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.vim.keymap = with lib; with types; {
|
||||
set = mkOption {
|
||||
type = listOf setKeymapType;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
}
|
33
modules/vim/opts.nix
Normal file
33
modules/vim/opts.nix
Normal file
|
@ -0,0 +1,33 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
options.vim = with lib; with types; {
|
||||
g = mkOption {
|
||||
type = attrsOf (oneOf [ str bool number ]);
|
||||
};
|
||||
opt = mkOption {
|
||||
type = attrsOf anything;
|
||||
description = ''
|
||||
A special interface |vim.opt| exists for conveniently interacting with list-
|
||||
and map-style option from Lua: It allows accessing them as Lua tables and
|
||||
offers object-oriented method for adding and removing entries.
|
||||
|
||||
`:help vim.opt`
|
||||
'';
|
||||
};
|
||||
|
||||
# TODO: think more about vim.cmd
|
||||
namedCmd = mkOption {
|
||||
type = attrsOf str;
|
||||
default = { };
|
||||
};
|
||||
cmd = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
vim.cmd = lib.concatLines (lib.flip lib.mapAttrsToList config.vim.namedCmd (k: v: "\" ${k}\n${v}"));
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue