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
|
# Home Manager module
|
||||||
packages: inputs: {
|
packages: inputs: {
|
||||||
pkgs,
|
|
||||||
config,
|
config,
|
||||||
|
pkgs,
|
||||||
lib ? pkgs.lib,
|
lib ? pkgs.lib,
|
||||||
self,
|
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
with lib; let
|
inherit (lib) maintainers;
|
||||||
|
inherit (lib.modules) mkIf;
|
||||||
|
inherit (lib.options) mkOption mkEnableOption literalExpression;
|
||||||
|
inherit (lib.types) attrsOf anything;
|
||||||
|
|
||||||
cfg = config.programs.neovim-flake;
|
cfg = config.programs.neovim-flake;
|
||||||
inherit (import ../../configuration.nix inputs) neovimConfiguration;
|
inherit (import ../../configuration.nix inputs) neovimConfiguration;
|
||||||
set = neovimConfiguration {
|
|
||||||
|
builtPackage = neovimConfiguration {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
modules = [cfg.settings];
|
modules = [cfg.settings];
|
||||||
};
|
};
|
||||||
|
@ -17,10 +21,10 @@ in {
|
||||||
meta.maintainers = with maintainers; [NotAShelf];
|
meta.maintainers = with maintainers; [NotAShelf];
|
||||||
|
|
||||||
options.programs.neovim-flake = {
|
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 {
|
settings = mkOption {
|
||||||
type = types.attrsOf types.anything;
|
type = attrsOf anything;
|
||||||
default = {};
|
default = {};
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
|
@ -44,6 +48,6 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
home.packages = [set.neovim];
|
home.packages = [builtPackage];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{lib}: {
|
{lib}: {
|
||||||
types = import ./types {inherit lib;};
|
types = import ./types {inherit lib;};
|
||||||
|
|
||||||
binds = import ./binds.nix {inherit lib;};
|
binds = import ./binds.nix {inherit lib;};
|
||||||
dag = import ./dag.nix {inherit lib;};
|
dag = import ./dag.nix {inherit lib;};
|
||||||
languages = import ./languages.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 = [
|
imports = [
|
||||||
./config.nix
|
./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,
|
imports = [
|
||||||
lib,
|
./build
|
||||||
...
|
./warnings
|
||||||
}: 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
|
|
||||||
];
|
];
|
||||||
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,
|
lib,
|
||||||
check ? true,
|
check ? true,
|
||||||
}: let
|
}: let
|
||||||
modules = [
|
inherit (lib.modules) mkDefault;
|
||||||
./completion
|
inherit (lib.lists) concatLists;
|
||||||
./theme
|
|
||||||
./core
|
core = map (p: ./core + "/${p}") [
|
||||||
./basic
|
"build"
|
||||||
./statusline
|
"warnings"
|
||||||
./tabline
|
|
||||||
./filetree
|
|
||||||
./visuals
|
|
||||||
./lsp
|
|
||||||
./treesitter
|
|
||||||
./autopairs
|
|
||||||
./snippets
|
|
||||||
./git
|
|
||||||
./minimap
|
|
||||||
./dashboard
|
|
||||||
./utility
|
|
||||||
./rich-presence
|
|
||||||
./notes
|
|
||||||
./terminal
|
|
||||||
./ui
|
|
||||||
./assistant
|
|
||||||
./session
|
|
||||||
./comments
|
|
||||||
./projects
|
|
||||||
./languages
|
|
||||||
./debugger
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
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, ...}: {
|
pkgsModule = {config, ...}: {
|
||||||
config = {
|
config = {
|
||||||
_module = {
|
_module = {
|
||||||
inherit check;
|
inherit check;
|
||||||
args = {
|
args = {
|
||||||
baseModules = modules;
|
baseModules = allModules;
|
||||||
pkgsPath = lib.mkDefault pkgs.path;
|
pkgsPath = mkDefault pkgs.path;
|
||||||
pkgs = lib.mkDefault pkgs;
|
pkgs = mkDefault pkgs;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
modules ++ [pkgsModule]
|
allModules ++ [pkgsModule]
|
||||||
|
|
|
@ -1,54 +1,22 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
config,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.options) mkEnableOption mkOption;
|
inherit (lib.options) mkOption;
|
||||||
inherit (lib.types) package path str bool int listOf enum nullOr;
|
inherit (lib.strings) optionalString;
|
||||||
|
inherit (lib.types) enum bool str int nullOr;
|
||||||
|
inherit (lib.nvim.dag) entryAfter;
|
||||||
|
|
||||||
|
cfg = config.vim;
|
||||||
in {
|
in {
|
||||||
options.vim = {
|
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 {
|
leaderKey = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
description = "The leader key to be used internally";
|
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 {
|
colourTerm = mkOption {
|
||||||
type = bool;
|
type = bool;
|
||||||
default = true;
|
default = true;
|
||||||
|
@ -115,15 +83,20 @@ in {
|
||||||
type = enum ["relative" "number" "relNumber" "none"];
|
type = enum ["relative" "number" "relNumber" "none"];
|
||||||
default = "relNumber";
|
default = "relNumber";
|
||||||
description = ''
|
description = ''
|
||||||
How line numbers are displayed. Available options are
|
How line numbers are displayed.
|
||||||
none, relative, number, relNumber
|
|
||||||
|
Available options are:
|
||||||
|
* none
|
||||||
|
* relative
|
||||||
|
* number
|
||||||
|
* relNumber
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
preventJunkFiles = mkOption {
|
preventJunkFiles = mkOption {
|
||||||
type = bool;
|
type = bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "Prevent swapfile, backupfile from being created";
|
description = "Prevent swapfile and backupfile from being created";
|
||||||
};
|
};
|
||||||
|
|
||||||
tabWidth = mkOption {
|
tabWidth = mkOption {
|
||||||
|
@ -197,4 +170,124 @@ in {
|
||||||
description = "Set the case sensitivity of search";
|
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