mirror of
https://github.com/NotAShelf/nvf.git
synced 2024-11-22 21:30:51 +00:00
treewide: begin restructuring the module tree
This commit is contained in:
parent
e1835f6c46
commit
7c730a78e5
254 changed files with 749 additions and 664 deletions
|
@ -1,15 +1,19 @@
|
|||
# Home Manager module
|
||||
packages: inputs: {
|
||||
pkgs,
|
||||
config,
|
||||
pkgs,
|
||||
lib ? pkgs.lib,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
}: let
|
||||
inherit (lib) maintainers;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.options) mkOption mkEnableOption literalExpression;
|
||||
inherit (lib.types) attrsOf anything;
|
||||
|
||||
cfg = config.programs.neovim-flake;
|
||||
inherit (import ../../configuration.nix inputs) neovimConfiguration;
|
||||
set = neovimConfiguration {
|
||||
|
||||
builtPackage = neovimConfiguration {
|
||||
inherit pkgs;
|
||||
modules = [cfg.settings];
|
||||
};
|
||||
|
@ -17,10 +21,10 @@ in {
|
|||
meta.maintainers = with maintainers; [NotAShelf];
|
||||
|
||||
options.programs.neovim-flake = {
|
||||
enable = mkEnableOption "A NeoVim IDE with a focus on configurability and extensibility.";
|
||||
enable = mkEnableOption "neovim-flake, the extensible neovim-wrapper";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrsOf types.anything;
|
||||
type = attrsOf anything;
|
||||
default = {};
|
||||
example = literalExpression ''
|
||||
{
|
||||
|
@ -44,6 +48,6 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [set.neovim];
|
||||
home.packages = [builtPackage];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{lib}: {
|
||||
types = import ./types {inherit lib;};
|
||||
|
||||
binds = import ./binds.nix {inherit lib;};
|
||||
dag = import ./dag.nix {inherit lib;};
|
||||
languages = import ./languages.nix {inherit lib;};
|
||||
|
|
|
@ -1,188 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (builtins) concatStringsSep;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.lists) optionals;
|
||||
inherit (lib.strings) optionalString;
|
||||
inherit (lib.nvim.dag) entryAfter;
|
||||
|
||||
cfg = config.vim;
|
||||
in {
|
||||
config = {
|
||||
vim.startPlugins = ["plenary-nvim"] ++ optionals (cfg.spellChecking.enableProgrammingWordList) ["vim-dirtytalk"];
|
||||
|
||||
vim.maps.normal =
|
||||
mkIf cfg.disableArrows {
|
||||
"<up>" = {
|
||||
action = "<nop>";
|
||||
|
||||
noremap = false;
|
||||
};
|
||||
"<down>" = {
|
||||
action = "<nop>";
|
||||
|
||||
noremap = false;
|
||||
};
|
||||
"<left>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
"<right>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
}
|
||||
// mkIf cfg.mapLeaderSpace {
|
||||
"<space>" = {
|
||||
action = "<nop>";
|
||||
};
|
||||
};
|
||||
|
||||
vim.maps.insert = mkIf cfg.disableArrows {
|
||||
"<up>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
"<down>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
"<left>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
"<right>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
};
|
||||
|
||||
vim.configRC.basic = entryAfter ["globalsScript"] ''
|
||||
" Settings that are set for everything
|
||||
set encoding=utf-8
|
||||
set mouse=${cfg.mouseSupport}
|
||||
set tabstop=${toString cfg.tabWidth}
|
||||
set shiftwidth=${toString cfg.tabWidth}
|
||||
set softtabstop=${toString cfg.tabWidth}
|
||||
set expandtab
|
||||
set cmdheight=${toString cfg.cmdHeight}
|
||||
set updatetime=${toString cfg.updateTime}
|
||||
set shortmess+=c
|
||||
set tm=${toString cfg.mapTimeout}
|
||||
set hidden
|
||||
set cursorlineopt=${toString cfg.cursorlineOpt}
|
||||
set scrolloff=${toString cfg.scrollOffset}
|
||||
|
||||
${optionalString cfg.debugMode.enable ''
|
||||
" Debug mode settings
|
||||
set verbose=${toString cfg.debugMode.level}
|
||||
set verbosefile=${cfg.debugMode.logFile}
|
||||
''}
|
||||
|
||||
${optionalString cfg.splitBelow ''
|
||||
set splitbelow
|
||||
''}
|
||||
|
||||
${optionalString cfg.splitRight ''
|
||||
set splitright
|
||||
''}
|
||||
|
||||
${optionalString cfg.showSignColumn ''
|
||||
set signcolumn=yes
|
||||
''}
|
||||
|
||||
${optionalString cfg.autoIndent ''
|
||||
set autoindent
|
||||
''}
|
||||
|
||||
${optionalString cfg.preventJunkFiles ''
|
||||
set noswapfile
|
||||
set nobackup
|
||||
set nowritebackup
|
||||
''}
|
||||
|
||||
${optionalString (cfg.bell == "none") ''
|
||||
set noerrorbells
|
||||
set novisualbell
|
||||
''}
|
||||
|
||||
${optionalString (cfg.bell == "on") ''
|
||||
set novisualbell
|
||||
''}
|
||||
|
||||
${optionalString (cfg.bell == "visual") ''
|
||||
set noerrorbells
|
||||
''}
|
||||
|
||||
${optionalString (cfg.lineNumberMode == "relative") ''
|
||||
set relativenumber
|
||||
''}
|
||||
|
||||
${optionalString (cfg.lineNumberMode == "number") ''
|
||||
set number
|
||||
''}
|
||||
|
||||
${optionalString (cfg.lineNumberMode == "relNumber") ''
|
||||
set number relativenumber
|
||||
''}
|
||||
|
||||
${optionalString cfg.useSystemClipboard ''
|
||||
set clipboard+=unnamedplus
|
||||
''}
|
||||
|
||||
${optionalString cfg.mapLeaderSpace ''
|
||||
let mapleader=" "
|
||||
let maplocalleader=" "
|
||||
''}
|
||||
|
||||
${optionalString cfg.syntaxHighlighting ''
|
||||
syntax on
|
||||
''}
|
||||
|
||||
${optionalString (!cfg.wordWrap) ''
|
||||
set nowrap
|
||||
''}
|
||||
|
||||
${optionalString cfg.hideSearchHighlight ''
|
||||
set nohlsearch
|
||||
set incsearch
|
||||
''}
|
||||
|
||||
${optionalString cfg.colourTerm ''
|
||||
set termguicolors
|
||||
set t_Co=256
|
||||
''}
|
||||
|
||||
${optionalString (!cfg.enableEditorconfig) ''
|
||||
let g:editorconfig = v:false
|
||||
''}
|
||||
|
||||
${optionalString cfg.spellChecking.enable ''
|
||||
set spell
|
||||
set spelllang=${concatStringsSep "," cfg.spellChecking.languages}${optionalString cfg.spellChecking.enableProgrammingWordList ",programming"}
|
||||
''}
|
||||
|
||||
${optionalString (cfg.leaderKey != null) ''
|
||||
let mapleader = "${toString cfg.leaderKey}"
|
||||
''}
|
||||
|
||||
${optionalString (cfg.searchCase == "ignore") ''
|
||||
set nosmartcase
|
||||
set ignorecase
|
||||
''}
|
||||
|
||||
${optionalString (cfg.searchCase == "smart") ''
|
||||
set smartcase
|
||||
set ignorecase
|
||||
''}
|
||||
|
||||
${optionalString (cfg.searchCase == "sensitive") ''
|
||||
set nosmartcase
|
||||
set noignorecase
|
||||
''}
|
||||
'';
|
||||
};
|
||||
}
|
322
modules/core/build/config.nix
Normal file
322
modules/core/build/config.nix
Normal file
|
@ -0,0 +1,322 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (builtins) attrValues attrNames map mapAttrs toJSON isString concatStringsSep filter;
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.attrsets) filterAttrs getAttrs;
|
||||
inherit (lib.strings) optionalString;
|
||||
inherit (lib.misc) mapAttrsFlatten;
|
||||
inherit (lib.trivial) showWarnings;
|
||||
inherit (lib.types) bool str oneOf attrsOf nullOr attrs submodule lines;
|
||||
inherit (lib.nvim.types) dagOf;
|
||||
inherit (lib.nvim.dag) entryAnywhere entryAfter topoSort;
|
||||
inherit (lib.generators) mkLuaInline;
|
||||
inherit (lib.nvim.lua) toLuaObject;
|
||||
inherit (lib.nvim.vim) valToVim;
|
||||
|
||||
cfg = config.vim;
|
||||
|
||||
wrapLuaConfig = luaConfig: ''
|
||||
lua << EOF
|
||||
${optionalString cfg.enableLuaLoader ''
|
||||
vim.loader.enable()
|
||||
''}
|
||||
${luaConfig}
|
||||
EOF
|
||||
'';
|
||||
|
||||
mkBool = value: description:
|
||||
mkOption {
|
||||
type = bool;
|
||||
default = value;
|
||||
inherit description;
|
||||
};
|
||||
|
||||
# Most of the keybindings code is highly inspired by pta2002/nixvim. Thank you!
|
||||
mapConfigOptions = {
|
||||
silent =
|
||||
mkBool false
|
||||
"Whether this mapping should be silent. Equivalent to adding <silent> to a map.";
|
||||
|
||||
nowait =
|
||||
mkBool false
|
||||
"Whether to wait for extra input on ambiguous mappings. Equivalent to adding <nowait> to a map.";
|
||||
|
||||
script =
|
||||
mkBool false
|
||||
"Equivalent to adding <script> to a map.";
|
||||
|
||||
expr =
|
||||
mkBool false
|
||||
"Means that the action is actually an expression. Equivalent to adding <expr> to a map.";
|
||||
|
||||
unique =
|
||||
mkBool false
|
||||
"Whether to fail if the map is already defined. Equivalent to adding <unique> to a map.";
|
||||
|
||||
noremap =
|
||||
mkBool true
|
||||
"Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default.";
|
||||
|
||||
desc = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "A description of this keybind, to be shown in which-key, if you have it enabled.";
|
||||
};
|
||||
};
|
||||
|
||||
genMaps = mode: maps: let
|
||||
/*
|
||||
Take a user-defined action (string or attrs) and return the following attribute set:
|
||||
{
|
||||
action = (string) the actual action to map to this key
|
||||
config = (attrs) the configuration options for this mapping (noremap, silent...)
|
||||
}
|
||||
*/
|
||||
normalizeAction = action: let
|
||||
# Extract the values of the config options that have been explicitly set by the user
|
||||
config =
|
||||
filterAttrs (_: v: v != null)
|
||||
(getAttrs (attrNames mapConfigOptions) action);
|
||||
in {
|
||||
config =
|
||||
if config == {}
|
||||
then {"__empty" = null;}
|
||||
else config;
|
||||
action =
|
||||
if action.lua
|
||||
then mkLuaInline action.action
|
||||
else action.action;
|
||||
};
|
||||
in
|
||||
attrValues (mapAttrs
|
||||
(key: action: let
|
||||
normalizedAction = normalizeAction action;
|
||||
in {
|
||||
inherit (normalizedAction) action config;
|
||||
inherit key;
|
||||
inherit mode;
|
||||
})
|
||||
maps);
|
||||
|
||||
mapOption = submodule {
|
||||
options =
|
||||
mapConfigOptions
|
||||
// {
|
||||
action = mkOption {
|
||||
type = str;
|
||||
description = "The action to execute.";
|
||||
};
|
||||
|
||||
lua = mkOption {
|
||||
type = bool;
|
||||
description = ''
|
||||
If true, `action` is considered to be lua code.
|
||||
Thus, it will not be wrapped in `""`.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mapOptions = mode:
|
||||
mkOption {
|
||||
description = "Mappings for ${mode} mode";
|
||||
type = attrsOf mapOption;
|
||||
default = {};
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
vim = {
|
||||
configRC = mkOption {
|
||||
description = "vimrc contents";
|
||||
type = oneOf [(dagOf lines) str];
|
||||
default = {};
|
||||
};
|
||||
|
||||
luaConfigRC = mkOption {
|
||||
description = "vim lua config";
|
||||
type = oneOf [(dagOf lines) str];
|
||||
default = {};
|
||||
};
|
||||
|
||||
builtConfigRC = mkOption {
|
||||
internal = true;
|
||||
type = lines;
|
||||
description = "The built config for neovim after resolving the DAG";
|
||||
};
|
||||
|
||||
globals = mkOption {
|
||||
default = {};
|
||||
description = "Set containing global variable values";
|
||||
type = attrs;
|
||||
};
|
||||
|
||||
maps = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
normal = mapOptions "normal";
|
||||
insert = mapOptions "insert";
|
||||
select = mapOptions "select";
|
||||
visual = mapOptions "visual and select";
|
||||
terminal = mapOptions "terminal";
|
||||
normalVisualOp = mapOptions "normal, visual, select and operator-pending (same as plain 'map')";
|
||||
|
||||
visualOnly = mapOptions "visual only";
|
||||
operator = mapOptions "operator-pending";
|
||||
insertCommand = mapOptions "insert and command-line";
|
||||
lang = mapOptions "insert, command-line and lang-arg";
|
||||
command = mapOptions "command-line";
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
description = ''
|
||||
Custom keybindings for any mode.
|
||||
|
||||
For plain maps (e.g. just 'map' or 'remap') use maps.normalVisualOp.
|
||||
'';
|
||||
|
||||
example = ''
|
||||
maps = {
|
||||
normal."<leader>m" = {
|
||||
silent = true;
|
||||
action = "<cmd>make<CR>";
|
||||
}; # Same as nnoremap <leader>m <silent> <cmd>make<CR>
|
||||
};
|
||||
'';
|
||||
};
|
||||
|
||||
enableLuaLoader = lib.options.mkEnableOption ''
|
||||
experimental Lua module loader to speed up the start up process
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
filterNonNull = mappings: filterAttrs (_name: value: value != null) mappings;
|
||||
globalsScript =
|
||||
mapAttrsFlatten (name: value: "let g:${name}=${valToVim value}")
|
||||
(filterNonNull cfg.globals);
|
||||
|
||||
toLuaBindings = mode: maps:
|
||||
map (value: ''
|
||||
vim.keymap.set(${toLuaObject mode}, ${toLuaObject value.key}, ${toLuaObject value.action}, ${toLuaObject value.config})
|
||||
'') (genMaps mode maps);
|
||||
|
||||
# I'm not sure if every one of these will work.
|
||||
allmap = toLuaBindings "" config.vim.maps.normalVisualOp;
|
||||
nmap = toLuaBindings "n" config.vim.maps.normal;
|
||||
vmap = toLuaBindings "v" config.vim.maps.visual;
|
||||
xmap = toLuaBindings "x" config.vim.maps.visualOnly;
|
||||
smap = toLuaBindings "s" config.vim.maps.select;
|
||||
imap = toLuaBindings "i" config.vim.maps.insert;
|
||||
cmap = toLuaBindings "c" config.vim.maps.command;
|
||||
tmap = toLuaBindings "t" config.vim.maps.terminal;
|
||||
lmap = toLuaBindings "l" config.vim.maps.lang;
|
||||
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;
|
||||
in {
|
||||
vim = {
|
||||
startPlugins = map (x: x.package) (attrValues cfg.extraPlugins);
|
||||
configRC = {
|
||||
globalsScript = 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
|
||||
entryAfter ["globalsScript"] luaConfig;
|
||||
|
||||
extraPluginConfigs = let
|
||||
mkSection = r: ''
|
||||
-- SECTION: ${r.name}
|
||||
${r.data}
|
||||
'';
|
||||
mapResult = r: (wrapLuaConfig (concatStringsSep "\n" (map mkSection r)));
|
||||
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 (concatStringsSep "\n" (map (v: concatStringsSep "\n" v) maps));
|
||||
in
|
||||
entryAfter ["globalsScript"] mapConfig;
|
||||
};
|
||||
|
||||
builtConfigRC = let
|
||||
failedAssertions = map (x: x.message) (filter (x: !x.assertion) config.assertions);
|
||||
|
||||
baseSystemAssertWarn =
|
||||
if failedAssertions != []
|
||||
then throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
|
||||
else showWarnings config.warnings;
|
||||
|
||||
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
|
||||
baseSystemAssertWarn vimConfig;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
_: {
|
||||
{
|
||||
imports = [
|
||||
./config.nix
|
||||
./module.nix
|
||||
./options.nix
|
||||
];
|
||||
}
|
87
modules/core/build/options.nix
Normal file
87
modules/core/build/options.nix
Normal file
|
@ -0,0 +1,87 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkEnableOption mkOption literalExpression;
|
||||
inherit (lib.types) path int package bool str listOf attrsOf;
|
||||
inherit (lib.nvim.types) pluginsOpt extraPluginType;
|
||||
in {
|
||||
options.vim = {
|
||||
package = mkOption {
|
||||
type = package;
|
||||
default = pkgs.neovim-unwrapped;
|
||||
description = ''
|
||||
The neovim package to use.
|
||||
|
||||
You will need to use an unwrapped package for this option to work as intended.
|
||||
'';
|
||||
};
|
||||
|
||||
debugMode = {
|
||||
enable = mkEnableOption "debug mode";
|
||||
level = mkOption {
|
||||
type = int;
|
||||
default = 20;
|
||||
description = "Set the debug level";
|
||||
};
|
||||
|
||||
logFile = mkOption {
|
||||
type = path;
|
||||
default = "/tmp/nvim.log";
|
||||
description = "Set the log file";
|
||||
};
|
||||
};
|
||||
|
||||
viAlias = mkOption {
|
||||
description = "Enable vi alias";
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
vimAlias = mkOption {
|
||||
description = "Enable vim alias";
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
startPlugins = pluginsOpt {
|
||||
default = [];
|
||||
description = "List of plugins to startup.";
|
||||
};
|
||||
|
||||
optPlugins = pluginsOpt {
|
||||
default = [];
|
||||
description = "List of plugins to optionally load";
|
||||
};
|
||||
|
||||
extraPlugins = mkOption {
|
||||
type = attrsOf extraPluginType;
|
||||
default = {};
|
||||
description = ''
|
||||
List of plugins and related config.
|
||||
Note that these are setup after builtin plugins.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
with pkgs.vimPlugins; {
|
||||
aerial = {
|
||||
package = aerial-nvim;
|
||||
setup = "require('aerial').setup {}";
|
||||
};
|
||||
harpoon = {
|
||||
package = harpoon;
|
||||
setup = "require('harpoon').setup {}";
|
||||
after = ["aerial"];
|
||||
};
|
||||
}'';
|
||||
};
|
||||
|
||||
luaPackages = mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
description = ''
|
||||
List of lua packages to install.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,394 +1,6 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (builtins) attrValues attrNames map mapAttrs toJSON isString concatStringsSep filter;
|
||||
inherit (lib.options) mkOption literalExpression mdDoc;
|
||||
inherit (lib.attrsets) filterAttrs getAttrs;
|
||||
inherit (lib.strings) optionalString;
|
||||
inherit (lib.misc) mapAttrsFlatten;
|
||||
inherit (lib.trivial) showWarnings;
|
||||
inherit (lib.types) bool str listOf oneOf attrsOf nullOr attrs submodule unspecified lines;
|
||||
inherit (lib.nvim.types) dagOf pluginsOpt extraPluginType;
|
||||
inherit (lib.nvim.dag) entryAnywhere entryAfter topoSort;
|
||||
inherit (lib.generators) mkLuaInline;
|
||||
inherit (lib.nvim.lua) toLuaObject;
|
||||
inherit (lib.nvim.vim) valToVim;
|
||||
|
||||
cfg = config.vim;
|
||||
|
||||
wrapLuaConfig = luaConfig: ''
|
||||
lua << EOF
|
||||
${optionalString cfg.enableLuaLoader ''
|
||||
vim.loader.enable()
|
||||
''}
|
||||
${luaConfig}
|
||||
EOF
|
||||
'';
|
||||
|
||||
mkBool = value: description:
|
||||
mkOption {
|
||||
type = bool;
|
||||
default = value;
|
||||
inherit description;
|
||||
};
|
||||
|
||||
# Most of the keybindings code is highly inspired by pta2002/nixvim. Thank you!
|
||||
mapConfigOptions = {
|
||||
silent =
|
||||
mkBool false
|
||||
"Whether this mapping should be silent. Equivalent to adding <silent> to a map.";
|
||||
|
||||
nowait =
|
||||
mkBool false
|
||||
"Whether to wait for extra input on ambiguous mappings. Equivalent to adding <nowait> to a map.";
|
||||
|
||||
script =
|
||||
mkBool false
|
||||
"Equivalent to adding <script> to a map.";
|
||||
|
||||
expr =
|
||||
mkBool false
|
||||
"Means that the action is actually an expression. Equivalent to adding <expr> to a map.";
|
||||
|
||||
unique =
|
||||
mkBool false
|
||||
"Whether to fail if the map is already defined. Equivalent to adding <unique> to a map.";
|
||||
|
||||
noremap =
|
||||
mkBool true
|
||||
"Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default.";
|
||||
|
||||
desc = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "A description of this keybind, to be shown in which-key, if you have it enabled.";
|
||||
};
|
||||
};
|
||||
|
||||
genMaps = mode: maps: let
|
||||
/*
|
||||
Take a user-defined action (string or attrs) and return the following attribute set:
|
||||
{
|
||||
action = (string) the actual action to map to this key
|
||||
config = (attrs) the configuration options for this mapping (noremap, silent...)
|
||||
}
|
||||
*/
|
||||
normalizeAction = action: let
|
||||
# Extract the values of the config options that have been explicitly set by the user
|
||||
config =
|
||||
filterAttrs (_: v: v != null)
|
||||
(getAttrs (attrNames mapConfigOptions) action);
|
||||
in {
|
||||
config =
|
||||
if config == {}
|
||||
then {"__empty" = null;}
|
||||
else config;
|
||||
action =
|
||||
if action.lua
|
||||
then mkLuaInline action.action
|
||||
else action.action;
|
||||
};
|
||||
in
|
||||
attrValues (mapAttrs
|
||||
(key: action: let
|
||||
normalizedAction = normalizeAction action;
|
||||
in {
|
||||
inherit (normalizedAction) action config;
|
||||
inherit key;
|
||||
inherit mode;
|
||||
})
|
||||
maps);
|
||||
|
||||
mapOption = submodule {
|
||||
options =
|
||||
mapConfigOptions
|
||||
// {
|
||||
action = mkOption {
|
||||
type = str;
|
||||
description = "The action to execute.";
|
||||
};
|
||||
|
||||
lua = mkOption {
|
||||
type = bool;
|
||||
description = ''
|
||||
If true, `action` is considered to be lua code.
|
||||
Thus, it will not be wrapped in `""`.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mapOptions = mode:
|
||||
mkOption {
|
||||
description = "Mappings for ${mode} mode";
|
||||
type = attrsOf mapOption;
|
||||
default = {};
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
assertions = mkOption {
|
||||
type = listOf unspecified;
|
||||
internal = true;
|
||||
default = [];
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
assertion = false;
|
||||
message = "you can't enable this for that reason";
|
||||
}
|
||||
]
|
||||
'';
|
||||
};
|
||||
|
||||
warnings = mkOption {
|
||||
internal = true;
|
||||
default = [];
|
||||
type = listOf str;
|
||||
example = ["The `foo' service is deprecated and will go away soon!"];
|
||||
description = mdDoc ''
|
||||
This option allows modules to show warnings to users during
|
||||
the evaluation of the system configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
vim = {
|
||||
viAlias = mkOption {
|
||||
description = "Enable vi alias";
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
vimAlias = mkOption {
|
||||
description = "Enable vim alias";
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
configRC = mkOption {
|
||||
description = "vimrc contents";
|
||||
type = oneOf [(dagOf lines) str];
|
||||
default = {};
|
||||
};
|
||||
|
||||
luaConfigRC = mkOption {
|
||||
description = "vim lua config";
|
||||
type = oneOf [(dagOf lines) str];
|
||||
default = {};
|
||||
};
|
||||
|
||||
builtConfigRC = mkOption {
|
||||
internal = true;
|
||||
type = lines;
|
||||
description = "The built config for neovim after resolving the DAG";
|
||||
};
|
||||
|
||||
startPlugins = pluginsOpt {
|
||||
default = [];
|
||||
description = "List of plugins to startup.";
|
||||
};
|
||||
|
||||
optPlugins = pluginsOpt {
|
||||
default = [];
|
||||
description = "List of plugins to optionally load";
|
||||
};
|
||||
|
||||
extraPlugins = mkOption {
|
||||
type = attrsOf extraPluginType;
|
||||
default = {};
|
||||
description = ''
|
||||
List of plugins and related config.
|
||||
Note that these are setup after builtin plugins.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
with pkgs.vimPlugins; {
|
||||
aerial = {
|
||||
package = aerial-nvim;
|
||||
setup = "require('aerial').setup {}";
|
||||
};
|
||||
harpoon = {
|
||||
package = harpoon;
|
||||
setup = "require('harpoon').setup {}";
|
||||
after = ["aerial"];
|
||||
};
|
||||
}'';
|
||||
};
|
||||
|
||||
luaPackages = mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
description = ''
|
||||
List of lua packages to install.
|
||||
'';
|
||||
};
|
||||
|
||||
globals = mkOption {
|
||||
default = {};
|
||||
description = "Set containing global variable values";
|
||||
type = attrs;
|
||||
};
|
||||
|
||||
maps = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
normal = mapOptions "normal";
|
||||
insert = mapOptions "insert";
|
||||
select = mapOptions "select";
|
||||
visual = mapOptions "visual and select";
|
||||
terminal = mapOptions "terminal";
|
||||
normalVisualOp = mapOptions "normal, visual, select and operator-pending (same as plain 'map')";
|
||||
|
||||
visualOnly = mapOptions "visual only";
|
||||
operator = mapOptions "operator-pending";
|
||||
insertCommand = mapOptions "insert and command-line";
|
||||
lang = mapOptions "insert, command-line and lang-arg";
|
||||
command = mapOptions "command-line";
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
description = ''
|
||||
Custom keybindings for any mode.
|
||||
|
||||
For plain maps (e.g. just 'map' or 'remap') use maps.normalVisualOp.
|
||||
'';
|
||||
|
||||
example = ''
|
||||
maps = {
|
||||
normal."<leader>m" = {
|
||||
silent = true;
|
||||
action = "<cmd>make<CR>";
|
||||
}; # Same as nnoremap <leader>m <silent> <cmd>make<CR>
|
||||
};
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
filterNonNull = mappings: filterAttrs (_name: value: value != null) mappings;
|
||||
globalsScript =
|
||||
mapAttrsFlatten (name: value: "let g:${name}=${valToVim value}")
|
||||
(filterNonNull cfg.globals);
|
||||
|
||||
toLuaBindings = mode: maps:
|
||||
map (value: ''
|
||||
vim.keymap.set(${toLuaObject mode}, ${toLuaObject value.key}, ${toLuaObject value.action}, ${toLuaObject value.config})
|
||||
'') (genMaps mode maps);
|
||||
|
||||
# I'm not sure if every one of these will work.
|
||||
allmap = toLuaBindings "" config.vim.maps.normalVisualOp;
|
||||
nmap = toLuaBindings "n" config.vim.maps.normal;
|
||||
vmap = toLuaBindings "v" config.vim.maps.visual;
|
||||
xmap = toLuaBindings "x" config.vim.maps.visualOnly;
|
||||
smap = toLuaBindings "s" config.vim.maps.select;
|
||||
imap = toLuaBindings "i" config.vim.maps.insert;
|
||||
cmap = toLuaBindings "c" config.vim.maps.command;
|
||||
tmap = toLuaBindings "t" config.vim.maps.terminal;
|
||||
lmap = toLuaBindings "l" config.vim.maps.lang;
|
||||
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;
|
||||
in {
|
||||
vim = {
|
||||
startPlugins = map (x: x.package) (attrValues cfg.extraPlugins);
|
||||
configRC = {
|
||||
globalsScript = 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
|
||||
entryAfter ["globalsScript"] luaConfig;
|
||||
|
||||
extraPluginConfigs = let
|
||||
mkSection = r: ''
|
||||
-- SECTION: ${r.name}
|
||||
${r.data}
|
||||
'';
|
||||
mapResult = r: (wrapLuaConfig (concatStringsSep "\n" (map mkSection r)));
|
||||
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
|
||||
imports = [
|
||||
./build
|
||||
./warnings
|
||||
];
|
||||
mapConfig = wrapLuaConfig (concatStringsSep "\n" (map (v: concatStringsSep "\n" v) maps));
|
||||
in
|
||||
entryAfter ["globalsScript"] mapConfig;
|
||||
};
|
||||
|
||||
builtConfigRC = let
|
||||
failedAssertions = map (x: x.message) (filter (x: !x.assertion) config.assertions);
|
||||
|
||||
baseSystemAssertWarn =
|
||||
if failedAssertions != []
|
||||
then throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
|
||||
else showWarnings config.warnings;
|
||||
|
||||
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
|
||||
baseSystemAssertWarn vimConfig;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
31
modules/core/warnings/default.nix
Normal file
31
modules/core/warnings/default.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{lib, ...}: let
|
||||
inherit (lib.options) mkOption literalExpression;
|
||||
inherit (lib.types) listOf str unspecified;
|
||||
in {
|
||||
options = {
|
||||
assertions = mkOption {
|
||||
type = listOf unspecified;
|
||||
internal = true;
|
||||
default = [];
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
assertion = false;
|
||||
message = "you can't enable this for that reason";
|
||||
}
|
||||
]
|
||||
'';
|
||||
};
|
||||
|
||||
warnings = mkOption {
|
||||
internal = true;
|
||||
default = [];
|
||||
type = listOf str;
|
||||
example = ["The `foo' service is deprecated and will go away soon!"];
|
||||
description = ''
|
||||
This option allows modules to show warnings to users during
|
||||
the evaluation of the system configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
|
@ -3,46 +3,59 @@
|
|||
lib,
|
||||
check ? true,
|
||||
}: let
|
||||
modules = [
|
||||
./completion
|
||||
./theme
|
||||
./core
|
||||
./basic
|
||||
./statusline
|
||||
./tabline
|
||||
./filetree
|
||||
./visuals
|
||||
./lsp
|
||||
./treesitter
|
||||
./autopairs
|
||||
./snippets
|
||||
./git
|
||||
./minimap
|
||||
./dashboard
|
||||
./utility
|
||||
./rich-presence
|
||||
./notes
|
||||
./terminal
|
||||
./ui
|
||||
./assistant
|
||||
./session
|
||||
./comments
|
||||
./projects
|
||||
./languages
|
||||
./debugger
|
||||
inherit (lib.modules) mkDefault;
|
||||
inherit (lib.lists) concatLists;
|
||||
|
||||
core = map (p: ./core + "/${p}") [
|
||||
"build"
|
||||
"warnings"
|
||||
];
|
||||
|
||||
neovim = map (p: ./neovim + "/${p}") [
|
||||
"basic"
|
||||
"mappings"
|
||||
];
|
||||
|
||||
plugins = map (p: ./plugins + "/${p}") [
|
||||
"assistant"
|
||||
"autopairs"
|
||||
"comments"
|
||||
"completion"
|
||||
"dashboard"
|
||||
"debugger"
|
||||
"filetree"
|
||||
"git"
|
||||
"languages"
|
||||
"lsp"
|
||||
"minimap"
|
||||
"notes"
|
||||
"projects"
|
||||
"rich-presence"
|
||||
"session"
|
||||
"snippets"
|
||||
"statusline"
|
||||
"tabline"
|
||||
"terminal"
|
||||
"theme"
|
||||
"treesitter"
|
||||
"ui"
|
||||
"utility"
|
||||
"visuals"
|
||||
];
|
||||
|
||||
allModules = concatLists [core neovim plugins];
|
||||
|
||||
pkgsModule = {config, ...}: {
|
||||
config = {
|
||||
_module = {
|
||||
inherit check;
|
||||
args = {
|
||||
baseModules = modules;
|
||||
pkgsPath = lib.mkDefault pkgs.path;
|
||||
pkgs = lib.mkDefault pkgs;
|
||||
baseModules = allModules;
|
||||
pkgsPath = mkDefault pkgs.path;
|
||||
pkgs = mkDefault pkgs;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
modules ++ [pkgsModule]
|
||||
allModules ++ [pkgsModule]
|
||||
|
|
|
@ -1,54 +1,22 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkEnableOption mkOption;
|
||||
inherit (lib.types) package path str bool int listOf enum nullOr;
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.strings) optionalString;
|
||||
inherit (lib.types) enum bool str int nullOr;
|
||||
inherit (lib.nvim.dag) entryAfter;
|
||||
|
||||
cfg = config.vim;
|
||||
in {
|
||||
options.vim = {
|
||||
package = mkOption {
|
||||
type = package;
|
||||
default = pkgs.neovim-unwrapped;
|
||||
description = ''
|
||||
The neovim package to use. You will need to use an unwrapped package for this option to work as intended.
|
||||
'';
|
||||
};
|
||||
|
||||
debugMode = {
|
||||
enable = mkEnableOption "debug mode";
|
||||
level = mkOption {
|
||||
type = int;
|
||||
default = 20;
|
||||
description = "Set the debug level";
|
||||
};
|
||||
|
||||
logFile = mkOption {
|
||||
type = path;
|
||||
default = "/tmp/nvim.log";
|
||||
description = "Set the log file";
|
||||
};
|
||||
};
|
||||
|
||||
enableLuaLoader = mkEnableOption "experimental Lua module loader to speed up the start up process";
|
||||
|
||||
leaderKey = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "The leader key to be used internally";
|
||||
};
|
||||
|
||||
spellChecking = {
|
||||
enable = mkEnableOption "neovim's built-in spellchecking";
|
||||
enableProgrammingWordList = mkEnableOption "vim-dirtytalk, a wordlist for programmers, that includes programming words";
|
||||
languages = mkOption {
|
||||
type = listOf str;
|
||||
description = "The languages to be used for spellchecking";
|
||||
default = ["en"];
|
||||
example = ["en" "de"];
|
||||
};
|
||||
};
|
||||
|
||||
colourTerm = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
|
@ -115,15 +83,20 @@ in {
|
|||
type = enum ["relative" "number" "relNumber" "none"];
|
||||
default = "relNumber";
|
||||
description = ''
|
||||
How line numbers are displayed. Available options are
|
||||
none, relative, number, relNumber
|
||||
How line numbers are displayed.
|
||||
|
||||
Available options are:
|
||||
* none
|
||||
* relative
|
||||
* number
|
||||
* relNumber
|
||||
'';
|
||||
};
|
||||
|
||||
preventJunkFiles = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Prevent swapfile, backupfile from being created";
|
||||
description = "Prevent swapfile and backupfile from being created";
|
||||
};
|
||||
|
||||
tabWidth = mkOption {
|
||||
|
@ -197,4 +170,124 @@ in {
|
|||
description = "Set the case sensitivity of search";
|
||||
};
|
||||
};
|
||||
|
||||
config.vim.configRC.basic = entryAfter ["globalsScript"] ''
|
||||
" Settings that are set for everything
|
||||
set encoding=utf-8
|
||||
set mouse=${cfg.mouseSupport}
|
||||
set tabstop=${toString cfg.tabWidth}
|
||||
set shiftwidth=${toString cfg.tabWidth}
|
||||
set softtabstop=${toString cfg.tabWidth}
|
||||
set expandtab
|
||||
set cmdheight=${toString cfg.cmdHeight}
|
||||
set updatetime=${toString cfg.updateTime}
|
||||
set shortmess+=c
|
||||
set tm=${toString cfg.mapTimeout}
|
||||
set hidden
|
||||
set cursorlineopt=${toString cfg.cursorlineOpt}
|
||||
set scrolloff=${toString cfg.scrollOffset}
|
||||
|
||||
${optionalString cfg.debugMode.enable ''
|
||||
" Debug mode settings
|
||||
set verbose=${toString cfg.debugMode.level}
|
||||
set verbosefile=${cfg.debugMode.logFile}
|
||||
''}
|
||||
|
||||
${optionalString cfg.splitBelow ''
|
||||
set splitbelow
|
||||
''}
|
||||
|
||||
${optionalString cfg.splitRight ''
|
||||
set splitright
|
||||
''}
|
||||
|
||||
${optionalString cfg.showSignColumn ''
|
||||
set signcolumn=yes
|
||||
''}
|
||||
|
||||
${optionalString cfg.autoIndent ''
|
||||
set autoindent
|
||||
''}
|
||||
|
||||
${optionalString cfg.preventJunkFiles ''
|
||||
set noswapfile
|
||||
set nobackup
|
||||
set nowritebackup
|
||||
''}
|
||||
|
||||
${optionalString (cfg.bell == "none") ''
|
||||
set noerrorbells
|
||||
set novisualbell
|
||||
''}
|
||||
|
||||
${optionalString (cfg.bell == "on") ''
|
||||
set novisualbell
|
||||
''}
|
||||
|
||||
${optionalString (cfg.bell == "visual") ''
|
||||
set noerrorbells
|
||||
''}
|
||||
|
||||
${optionalString (cfg.lineNumberMode == "relative") ''
|
||||
set relativenumber
|
||||
''}
|
||||
|
||||
${optionalString (cfg.lineNumberMode == "number") ''
|
||||
set number
|
||||
''}
|
||||
|
||||
${optionalString (cfg.lineNumberMode == "relNumber") ''
|
||||
set number relativenumber
|
||||
''}
|
||||
|
||||
${optionalString cfg.useSystemClipboard ''
|
||||
set clipboard+=unnamedplus
|
||||
''}
|
||||
|
||||
${optionalString cfg.mapLeaderSpace ''
|
||||
let mapleader=" "
|
||||
let maplocalleader=" "
|
||||
''}
|
||||
|
||||
${optionalString cfg.syntaxHighlighting ''
|
||||
syntax on
|
||||
''}
|
||||
|
||||
${optionalString (!cfg.wordWrap) ''
|
||||
set nowrap
|
||||
''}
|
||||
|
||||
${optionalString cfg.hideSearchHighlight ''
|
||||
set nohlsearch
|
||||
set incsearch
|
||||
''}
|
||||
|
||||
${optionalString cfg.colourTerm ''
|
||||
set termguicolors
|
||||
set t_Co=256
|
||||
''}
|
||||
|
||||
${optionalString (!cfg.enableEditorconfig) ''
|
||||
let g:editorconfig = v:false
|
||||
''}
|
||||
|
||||
${optionalString (cfg.leaderKey != null) ''
|
||||
let mapleader = "${toString cfg.leaderKey}"
|
||||
''}
|
||||
|
||||
${optionalString (cfg.searchCase == "ignore") ''
|
||||
set nosmartcase
|
||||
set ignorecase
|
||||
''}
|
||||
|
||||
${optionalString (cfg.searchCase == "smart") ''
|
||||
set smartcase
|
||||
set ignorecase
|
||||
''}
|
||||
|
||||
${optionalString (cfg.searchCase == "sensitive") ''
|
||||
set nosmartcase
|
||||
set noignorecase
|
||||
''}
|
||||
'';
|
||||
}
|
6
modules/neovim/basic/default.nix
Normal file
6
modules/neovim/basic/default.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
imports = [
|
||||
./configrc.nix
|
||||
./spellcheck.nix
|
||||
];
|
||||
}
|
38
modules/neovim/basic/spellcheck.nix
Normal file
38
modules/neovim/basic/spellcheck.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.options) mkEnableOption literalExpression mkOption;
|
||||
inherit (lib.strings) concatStringsSep optionalString;
|
||||
inherit (lib.lists) optionals;
|
||||
inherit (lib.types) listOf str;
|
||||
inherit (lib.nvim.dag) entryAfter;
|
||||
|
||||
cfg = config.vim.spellChecking;
|
||||
languages = cfg.languages ++ optionals cfg.enableProgrammingWordList ["programming"];
|
||||
in {
|
||||
options.vim.spellChecking = {
|
||||
enable = mkEnableOption "neovim's built-in spellchecking";
|
||||
enableProgrammingWordList = mkEnableOption "vim-dirtytalk, a wordlist for programmers, that includes programming words";
|
||||
languages = mkOption {
|
||||
type = listOf str;
|
||||
default = ["en"];
|
||||
example = literalExpression ["en" "de"];
|
||||
description = "The languages to be used for spellchecking";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
vim = {
|
||||
startPlugins = optionals cfg.spellChecking.enableProgrammingWordList ["vim-dirtytalk"];
|
||||
configRC.spellchecking = entryAfter ["basic"] ''
|
||||
${optionalString cfg.enable ''
|
||||
set spell
|
||||
set spelllang=${concatStringsSep "," languages}
|
||||
''}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
5
modules/neovim/config.nix
Normal file
5
modules/neovim/config.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
config = {
|
||||
vim.startPlugins = ["plenary-nvim"];
|
||||
};
|
||||
}
|
8
modules/neovim/default.nix
Normal file
8
modules/neovim/default.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
imports = [
|
||||
./basic
|
||||
./mappings
|
||||
|
||||
./config.nix
|
||||
];
|
||||
}
|
55
modules/neovim/mappings/default.nix
Normal file
55
modules/neovim/mappings/default.nix
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
|
||||
cfg = config.vim;
|
||||
in {
|
||||
vim.maps.normal =
|
||||
mkIf cfg.disableArrows {
|
||||
"<up>" = {
|
||||
action = "<nop>";
|
||||
|
||||
noremap = false;
|
||||
};
|
||||
"<down>" = {
|
||||
action = "<nop>";
|
||||
|
||||
noremap = false;
|
||||
};
|
||||
"<left>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
"<right>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
}
|
||||
// mkIf cfg.mapLeaderSpace {
|
||||
"<space>" = {
|
||||
action = "<nop>";
|
||||
};
|
||||
};
|
||||
|
||||
vim.maps.insert = mkIf cfg.disableArrows {
|
||||
"<up>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
"<down>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
"<left>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
"<right>" = {
|
||||
action = "<nop>";
|
||||
noremap = false;
|
||||
};
|
||||
};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue