diff --git a/docs/release-notes/rl-0.7.md b/docs/release-notes/rl-0.7.md index e0dabdf4..21edbddc 100644 --- a/docs/release-notes/rl-0.7.md +++ b/docs/release-notes/rl-0.7.md @@ -4,8 +4,6 @@ Release notes for release 0.7 ## Breaking Changes and Migration Guide {#sec-breaking-changes-and-migration-guide-0-7} -### `vim.configRC` removed - In v0.7 we are removing `vim.configRC` in favor of making `vim.luaConfigRC` the top-level DAG, and thereby making the entire configuration Lua based. This change introduces a few breaking changes: @@ -26,28 +24,6 @@ making good use of its extensive Lua API. Additionally, Vimscript is slow and brings unnecessary performance overhead while working with different configuration formats. -### `vim.maps` rewrite - -Instead of specifying map modes using submodules (eg.: `vim.maps.normal`), a new -`mode` option has mode has been introduced. It can be either a string, or a list -of strings, where a string represents the short-name of the map mode(s), that -the mapping should be set for. See `:help map-modes` for more information. - -For example: - -```nix -vim.maps.normal."m" = { ... }; -``` - -has to be replaced by - -```nix -vim.maps."m" = { - mode = "n"; - ... -}; -``` - ## Changelog {#sec-release-0.7-changelog} [ItsSorae](https://github.com/ItsSorae): @@ -138,8 +114,6 @@ vim.maps."m" = { has been introduced for setting up internal plugins. See the "DAG entries in nvf" manual page for more information. -- Rewrite `vim.maps`, see the breaking changes section above. - [NotAShelf](https://github.com/notashelf): [ts-error-translator.nvim]: https://github.com/dmmulroy/ts-error-translator.nvim @@ -169,10 +143,10 @@ vim.maps."m" = { - Add [neo-tree.nvim] as an alternative file-tree plugin. It will be available under `vim.filetree.neo-tree`, similar to nvimtree. -- Add `nvf-print-config` & `nvf-print-config-path` helper scripts to Neovim +- Add `print-nvf-config` & `print-nvf-config-path` helper scripts to Neovim closure. Both of those scripts have been automatically added to your PATH upon using neovimConfig or `programs.nvf.enable`. - - `nvf-print-config` will display your `init.lua`, in full. - - `nvf-print-config-path` will display the path to _a clone_ of your + - `print-nvf-config` will display your `init.lua`, in full. + - `print-nvf-config-path` will display the path to _a clone_ of your `init.lua`. This is not the path used by the Neovim wrapper, but an identical clone. diff --git a/flake.lock b/flake.lock index 1851eb71..de29be39 100644 --- a/flake.lock +++ b/flake.lock @@ -69,11 +69,11 @@ }, "mnw": { "locked": { - "lastModified": 1723419050, - "narHash": "sha256-Eb8jBUgHwpte+bGsqeXNbKMBfZaDB7RiPQwyb1vzJK8=", + "lastModified": 1722191188, + "narHash": "sha256-YF//iMALbrd2Ni9aju7w8NniH16Qz6RFTRD6md5UkDc=", "owner": "Gerg-L", "repo": "mnw", - "rev": "e625f5965567f16102bc52897c7600dcde53c6c3", + "rev": "c7b289f3f5a31b6e744be37d83fc231816621231", "type": "github" }, "original": { @@ -939,22 +939,6 @@ "type": "github" } }, - "plugin-new-file-template-nvim": { - "flake": false, - "locked": { - "lastModified": 1721518222, - "narHash": "sha256-g0IjJrHRXw7U9goVLzVYUyHBSsDZGHMpi3YZPhg64zA=", - "owner": "otavioschwanck", - "repo": "new-file-template.nvim", - "rev": "6ac66669dbf2dc5cdee184a4fe76d22465ca67e8", - "type": "github" - }, - "original": { - "owner": "otavioschwanck", - "repo": "new-file-template.nvim", - "type": "github" - } - }, "plugin-noice-nvim": { "flake": false, "locked": { @@ -1878,7 +1862,6 @@ "plugin-neo-tree-nvim": "plugin-neo-tree-nvim", "plugin-neocord": "plugin-neocord", "plugin-neodev-nvim": "plugin-neodev-nvim", - "plugin-new-file-template-nvim": "plugin-new-file-template-nvim", "plugin-noice-nvim": "plugin-noice-nvim", "plugin-none-ls": "plugin-none-ls", "plugin-nui-nvim": "plugin-nui-nvim", diff --git a/lib/binds.nix b/lib/binds.nix index a8fbf5f0..8c9e9a62 100644 --- a/lib/binds.nix +++ b/lib/binds.nix @@ -4,68 +4,69 @@ inherit (lib.types) nullOr str; inherit (lib.attrsets) isAttrs mapAttrs; - mkLuaBinding = mode: key: action: desc: - mkIf (key != null) { - ${key} = { - inherit mode action desc; - lua = true; - silent = true; - }; - }; - - mkExprBinding = mode: key: action: desc: - mkIf (key != null) { - ${key} = { - inherit mode action desc; - lua = true; - silent = true; - expr = true; - }; - }; - - mkBinding = mode: key: action: desc: - mkIf (key != null) { - ${key} = { - inherit mode action desc; - silent = true; - }; - }; - - mkMappingOption = description: default: - mkOption { - type = nullOr str; - inherit default description; - }; - - # Utility function that takes two attrsets: - # { someKey = "some_value" } and - # { someKey = { description = "Some Description"; }; } - # and merges them into - # { someKey = { value = "some_value"; description = "Some Description"; }; } - addDescriptionsToMappings = actualMappings: mappingDefinitions: - mapAttrs (name: value: let - isNested = isAttrs value; - returnedValue = - if isNested - then addDescriptionsToMappings actualMappings.${name} mappingDefinitions.${name} - else { - inherit value; - inherit (mappingDefinitions.${name}) description; + binds = rec { + mkLuaBinding = key: action: desc: + mkIf (key != null) { + "${key}" = { + inherit action desc; + lua = true; + silent = true; }; - in - returnedValue) - actualMappings; + }; - mkSetBinding = mode: binding: action: - mkBinding mode binding.value action binding.description; + mkExprBinding = key: action: desc: + mkIf (key != null) { + "${key}" = { + inherit action desc; + lua = true; + silent = true; + expr = true; + }; + }; - mkSetExprBinding = mode: binding: action: - mkExprBinding mode binding.value action binding.description; + mkBinding = key: action: desc: + mkIf (key != null) { + "${key}" = { + inherit action desc; + silent = true; + }; + }; - mkSetLuaBinding = mode: binding: action: - mkLuaBinding mode binding.value action binding.description; + mkMappingOption = description: default: + mkOption { + type = nullOr str; + inherit default description; + }; - pushDownDefault = attr: mapAttrs (_: mkDefault) attr; -in { - inherit mkLuaBinding mkExprBinding mkBinding mkMappingOption addDescriptionsToMappings mkSetBinding mkSetExprBinding mkSetLuaBinding pushDownDefault; -} + # Utility function that takes two attrsets: + # { someKey = "some_value" } and + # { someKey = { description = "Some Description"; }; } + # and merges them into + # { someKey = { value = "some_value"; description = "Some Description"; }; } + addDescriptionsToMappings = actualMappings: mappingDefinitions: + mapAttrs (name: value: let + isNested = isAttrs value; + returnedValue = + if isNested + then addDescriptionsToMappings actualMappings."${name}" mappingDefinitions."${name}" + else { + inherit value; + inherit (mappingDefinitions."${name}") description; + }; + in + returnedValue) + actualMappings; + + mkSetBinding = binding: action: + mkBinding binding.value action binding.description; + + mkSetExprBinding = binding: action: + mkExprBinding binding.value action binding.description; + + mkSetLuaBinding = binding: action: + mkLuaBinding binding.value action binding.description; + + pushDownDefault = attr: mapAttrs (_: mkDefault) attr; + }; +in + binds diff --git a/modules/default.nix b/modules/default.nix index 1ae3b034..227cf205 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -7,65 +7,84 @@ inputs: { extraModules ? [], }: let inherit (pkgs) vimPlugins; + inherit (pkgs.vimUtils) buildVimPlugin; inherit (lib.strings) isString toString; inherit (lib.lists) filter map concatLists; + inherit (lib.attrsets) recursiveUpdate getAttr; + inherit (lib.asserts) assertMsg; # import modules.nix with `check`, `pkgs` and `lib` as arguments # check can be disabled while calling this file is called # to avoid checking in all modules - nvimModules = import ./modules.nix {inherit pkgs check lib;}; + nvimModules = import ./modules.nix { + inherit pkgs check lib; + }; # evaluate the extended library with the modules # optionally with any additional modules passed by the user module = lib.evalModules { - specialArgs = extraSpecialArgs // {modulesPath = toString ./.;}; + specialArgs = recursiveUpdate {modulesPath = toString ./.;} extraSpecialArgs; modules = concatLists [[configuration] nvimModules extraModules]; }; # alias to the internal configuration vimOptions = module.config.vim; - noBuildPlug = {pname, ...} @ attrs: let - src = inputs."plugin-${attrs.pname}"; - in - { - version = src.shortRev or src.shortDirtyRev or "dirty"; - outPath = src; - passthru.vimPlugin = false; - } - // attrs; - # build a vim plugin with the given name and arguments # if the plugin is nvim-treesitter, warn the user to use buildTreesitterPlug # instead - buildPlug = attrs: let - src = inputs."plugin-${attrs.pname}"; + buildPlug = {pname, ...} @ attrs: let + src = getAttr ("plugin-" + pname) inputs; in - pkgs.vimUtils.buildVimPlugin ( - { - version = src.shortRev or src.shortDirtyRev or "dirty"; + pkgs.stdenvNoCC.mkDerivation ({ inherit src; + version = src.shortRev or src.shortDirtyRev or "dirty"; + installPhase = '' + runHook preInstall + + mkdir -p $out + cp -r . $out + + runHook postInstall + ''; } - // attrs - ); + // attrs); + + noBuildPlug = {pname, ...} @ attrs: let + input = getAttr ("plugin-" + pname) inputs; + in + { + version = input.shortRev or input.shortDirtyRev or "dirty"; + outPath = getAttr ("plugin-" + pname) inputs; + } + // attrs; buildTreesitterPlug = grammars: vimPlugins.nvim-treesitter.withPlugins (_: grammars); - pluginBuilders = { - nvim-treesitter = buildTreesitterPlug vimOptions.treesitter.grammars; - flutter-tools-patched = buildPlug { - pname = "flutter-tools"; - patches = [../patches/flutter-tools.patch]; - }; - }; - buildConfigPlugins = plugins: - map ( - plug: - if (isString plug) - then pluginBuilders.${plug} or (noBuildPlug {pname = plug;}) - else plug - ) (filter (f: f != null) plugins); + map + (plug: ( + if (isString plug) + then + ( + if (plug == "nvim-treesitter") + then (buildTreesitterPlug vimOptions.treesitter.grammars) + else if (plug == "flutter-tools-patched") + then + ( + buildPlug + { + pname = "flutter-tools"; + patches = [../patches/flutter-tools.patch]; + } + ) + else noBuildPlug {pname = plug;} + ) + else plug + )) + (filter + (f: f != null) + plugins); # built (or "normalized") plugins that are modified builtStartPlugins = buildConfigPlugins vimOptions.startPlugins; @@ -75,7 +94,7 @@ inputs: { }) (buildConfigPlugins vimOptions.optPlugins); # additional Lua and Python3 packages, mapped to their respective functions - # to conform to the format mnw expects. end user should + # to conform to the format makeNeovimConfig expects. end user should # only ever need to pass a list of packages, which are modified # here extraLuaPackages = ps: map (x: ps.${x}) vimOptions.luaPackages; @@ -85,7 +104,7 @@ inputs: { # generate a wrapped Neovim package. neovim-wrapped = inputs.mnw.lib.wrap pkgs { neovim = vimOptions.package; - plugins = builtStartPlugins ++ builtOptPlugins; + plugins = concatLists [builtStartPlugins builtOptPlugins]; appName = "nvf"; extraBinPath = vimOptions.extraPackages; initLua = vimOptions.builtLuaConfigRC; @@ -95,11 +114,20 @@ inputs: { inherit extraLuaPackages extraPython3Packages; }; - dummyInit = pkgs.writeText "nvf-init.lua" vimOptions.builtLuaConfigRC; # Additional helper scripts for printing and displaying nvf configuration # in your commandline. - printConfig = pkgs.writers.writeDashBin "nvf-print-config" "cat ${dummyInit}"; - printConfigPath = pkgs.writers.writeDashBin "nvf-print-config-path" "echo -n ${dummyInit}"; + printConfig = pkgs.writers.writeDashBin "print-nvf-config" '' + cat << EOF + ${vimOptions.builtLuaConfigRC} + EOF + ''; + + printConfigPath = pkgs.writers.writeDashBin "print-nvf-config-path" '' + realpath ${pkgs.writeTextFile { + name = "nvf-init.lua"; + text = vimOptions.builtLuaConfigRC; + }} + ''; in { inherit (module) options config; inherit (module._module.args) pkgs; @@ -109,7 +137,7 @@ in { neovim = pkgs.symlinkJoin { name = "nvf-with-helpers"; paths = [neovim-wrapped printConfig printConfigPath]; - postBuild = "echo Helpers added"; + postBuild = "echo helpers added"; meta = { description = "Wrapped version of Neovim with additional helper scripts"; diff --git a/modules/neovim/mappings/config.nix b/modules/neovim/mappings/config.nix index 365e1242..28ebf081 100644 --- a/modules/neovim/mappings/config.nix +++ b/modules/neovim/mappings/config.nix @@ -8,26 +8,45 @@ cfg = config.vim; in { config = { - vim.maps = mkIf cfg.disableArrows { - "" = { - mode = ["n" "i"]; - action = ""; - noremap = false; + vim.maps = { + normal = mkIf cfg.disableArrows { + "" = { + action = ""; + + noremap = false; + }; + "" = { + action = ""; + + noremap = false; + }; + "" = { + action = ""; + noremap = false; + }; + "" = { + action = ""; + noremap = false; + }; }; - "" = { - mode = ["n" "i"]; - action = ""; - noremap = false; - }; - "" = { - mode = ["n" "i"]; - action = ""; - noremap = false; - }; - "" = { - mode = ["n" "i"]; - action = ""; - noremap = false; + + insert = mkIf cfg.disableArrows { + "" = { + action = ""; + noremap = false; + }; + "" = { + action = ""; + noremap = false; + }; + "" = { + action = ""; + noremap = false; + }; + "" = { + action = ""; + noremap = false; + }; }; }; }; diff --git a/modules/neovim/mappings/options.nix b/modules/neovim/mappings/options.nix index dcf9cf4d..3b1f2634 100644 --- a/modules/neovim/mappings/options.nix +++ b/modules/neovim/mappings/options.nix @@ -1,49 +1,96 @@ {lib, ...}: let inherit (lib.options) mkOption; - inherit (lib.types) either str listOf attrsOf nullOr submodule; + inherit (lib.types) bool str attrsOf nullOr submodule; inherit (lib.nvim.config) mkBool; + # 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 to a map."; - mapType = submodule { - mode = mkOption { - type = either str (listOf str); - description = '' - The short-name of the mode to set the keymapping for. Passing an empty string is the equivalent of `:map`. + nowait = + mkBool false + "Whether to wait for extra input on ambiguous mappings. Equivalent to adding to a map."; + + script = + mkBool false + "Equivalent to adding