From 7c9d33f7bbff1d261509bf7f3ca8419218b76783 Mon Sep 17 00:00:00 2001 From: Gabe Venberg Date: Sun, 8 Mar 2026 23:01:58 +0100 Subject: [PATCH] nix-wrapper-modules port. Basic modules.nix, gotta port the lua still. --- README.md | 91 ++- flake.lock | 83 +- flake.nix | 483 ++---------- init.lua | 150 ++-- lua/keys.lua | 37 + lua/myLuaConf/LSPs/init.lua | 261 ------ lua/myLuaConf/init.lua | 20 - lua/myLuaConf/non_nix_download.lua | 92 --- lua/myLuaConf/plugins/completion.lua | 156 ---- lua/myLuaConf/plugins/gitsigns.lua | 84 -- lua/myLuaConf/plugins/init.lua | 279 ------- lua/myLuaConf/plugins/lualine.lua | 43 - lua/myLuaConf/plugins/treesitter.lua | 42 - lua/myLuaConf/plugins/which-key.lua | 21 - lua/nixCatsUtils/catPacker.lua | 40 - lua/nixCatsUtils/init.lua | 129 --- lua/nixCatsUtils/lzUtils.lua | 36 - lua/{myLuaConf/opts_and_keys.lua => opts.lua} | 31 +- lua/plugins.lua | 743 ++++++++++++++++++ module.nix | 284 +++++++ 20 files changed, 1375 insertions(+), 1730 deletions(-) create mode 100644 lua/keys.lua delete mode 100644 lua/myLuaConf/LSPs/init.lua delete mode 100644 lua/myLuaConf/init.lua delete mode 100644 lua/myLuaConf/non_nix_download.lua delete mode 100644 lua/myLuaConf/plugins/completion.lua delete mode 100644 lua/myLuaConf/plugins/gitsigns.lua delete mode 100644 lua/myLuaConf/plugins/init.lua delete mode 100644 lua/myLuaConf/plugins/lualine.lua delete mode 100644 lua/myLuaConf/plugins/treesitter.lua delete mode 100644 lua/myLuaConf/plugins/which-key.lua delete mode 100644 lua/nixCatsUtils/catPacker.lua delete mode 100644 lua/nixCatsUtils/init.lua delete mode 100644 lua/nixCatsUtils/lzUtils.lua rename lua/{myLuaConf/opts_and_keys.lua => opts.lua} (63%) create mode 100644 lua/plugins.lua create mode 100644 module.nix diff --git a/README.md b/README.md index 721c82f..68ec53a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,89 @@ -# Gabes `nixCats` Configuration +# Neovim module -My preferred way of setting up neovim. This configuration has organically grown since 2016, -originally as a vimscript config, then as a lua config, then as a nixvim config, and finally a nix/lua hybrid. +This is a demonstration of the [neovim module](https://birdeehub.github.io/nix-wrapper-modules/wrapperModules/neovim.html) + +It makes use of the tips in the [tips and tricks](https://birdeehub.github.io/nix-wrapper-modules/wrapperModules/neovim.html#tips-and-tricks) section of the documentation. + +This template configuration is by no means a perfect, complete configuration. + +However, it is plenty to start on, and covers some interesting ways to use the module (and how to lazily load plugins and config). + +This configuration is 1 `lua` file, however the whole set of directories from a normal `neovim` configuration directory are available. + +To see what directories you can put stuff in, see: [:help 'rtp'](https://neovim.io/doc/user/options.html#'rtp') + +The main reason it is in 1 file is that it is following the style of [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim). + +The other reason it is in 1 file, is that it makes it a cleaner experience to init this template into an existing configuration. + +This template config uses [lze](https://github.com/BirdeeHub/lze) for lazy loading of the configuration. + +You may also be interested in [lz.n](https://github.com/lumen-oss/lz.n) for this purpose. + +Both achieve the same general result and main interface, +but have different underlying implementations and thus have different handler features. + +Both are fantastic for lazy loading with both nix and the builtin plugin manager. + +You may also decide you don't need lazy loading at all. This is fine, many plugins mostly handle that themselves. + +To initialize this template flake into the current directory, run: + +```bash +nix flake init -t github:BirdeeHub/nix-wrapper-modules#neovim +``` + +It will not replace existing files. + +If you are using `zsh` you may need to escape the `#` + +To build it from that directory + +```bash +nix build . +``` + +It exports a package! (and other things) + +If you don't want your config in a separate flake, just call the `module.nix` file like: + +```nix +inputs: # <-- get the library somehow +{ pkgs, ... }: { + # call the module and install the package (nixos example) + environment.systemPackages = [ (inputs.nix-wrapper-modules.lib.evalPackage [ ./module.nix { inherit pkgs; } ]) ]; +} +``` + +There are a lot of other ways to install it as well, see [the getting started documentation](https://birdeehub.github.io/nix-wrapper-modules/md/getting-started.html) + +You may also wish to view the `flake.nix` of this template, as it demonstrates some of those things when setting up its outputs. + +--- + +The nix in this template is not as simple as it could possibly be, as it demonstrates some things +from the [tips and tricks](https://birdeehub.github.io/nix-wrapper-modules/wrapperModules/neovim.html#tips-and-tricks) section of the documentation. + +If you wanted as simple as possible, you could use something more like the following as your `module.nix` + +```nix +{ wlib, config, pkgs, lib, ... }: + imports = [ wlib.wrapperModules.neovim ]; + specs.general = with pkgs.vimPlugins; [ + # plugins which are loaded at startup ... + ]; + specs.lazy = { + lazy = true; + data = with pkgs.vimPlugins; [ + # plugins which are not loaded until you vim.cmd.packadd them ... + ]; + }; + extraPackages = with pkgs; [ + # lsps, formatters, etc... + ]; + settings.config_directory = ./.; # or lib.generators.mkLuaInline "vim.fn.stdpath('config')"; +} +``` + +At the same time, you may find that the `module.nix` file from this template is not massively more complex than that either, +and contains some useful tricks and information. diff --git a/flake.lock b/flake.lock index 6905646..e934dd7 100644 --- a/flake.lock +++ b/flake.lock @@ -1,40 +1,79 @@ { "nodes": { - "nixCats": { - "locked": { - "lastModified": 1769578476, - "narHash": "sha256-4+KbiBcC6hQ3sh0UbPXjy6TOfLh9yhskRlfPzyZ2FH4=", - "owner": "BirdeeHub", - "repo": "nixCats-nvim", - "rev": "48f8be4bdafccfa19ceaaf08071a15eca36fdb1d", - "type": "github" - }, - "original": { - "owner": "BirdeeHub", - "repo": "nixCats-nvim", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1770141374, - "narHash": "sha256-yD4K/vRHPwXbJf5CK3JkptBA6nFWUKNX/jlFp2eKEQc=", - "owner": "nixos", + "lastModified": 1772674223, + "narHash": "sha256-/suKbHSaSmuC9UY7G0VRQ3aO+QKqxAQPQ19wG7QNkF8=", + "owner": "NixOS", "repo": "nixpkgs", - "rev": "41965737c1797c1d83cfb0b644ed0840a6220bd1", + "rev": "66d9241e3dc2296726dc522e62dbfe89c7b449f3", "type": "github" }, "original": { - "owner": "nixos", + "owner": "NixOS", "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } }, + "plugins-lze": { + "flake": false, + "locked": { + "lastModified": 1772337062, + "narHash": "sha256-joi1087b2iDmwOHv7/0YCrDPucbu0osbS8WQmDYoyE4=", + "owner": "BirdeeHub", + "repo": "lze", + "rev": "f50a84a5d84f6b16e254091e755f5a9e839a9924", + "type": "github" + }, + "original": { + "owner": "BirdeeHub", + "repo": "lze", + "type": "github" + } + }, + "plugins-lzextras": { + "flake": false, + "locked": { + "lastModified": 1772336997, + "narHash": "sha256-BsoZTfXpISPeTnTQWtnZkDXzvo9ocILB5IO2vU8IvAM=", + "owner": "BirdeeHub", + "repo": "lzextras", + "rev": "abdda956a2947d0617133a018992d035fc5781da", + "type": "github" + }, + "original": { + "owner": "BirdeeHub", + "repo": "lzextras", + "type": "github" + } + }, "root": { "inputs": { - "nixCats": "nixCats", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "plugins-lze": "plugins-lze", + "plugins-lzextras": "plugins-lzextras", + "wrappers": "wrappers" + } + }, + "wrappers": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1772662098, + "narHash": "sha256-BKxBM4RNWP+5q0ZQ6v3JlJ0e6fFj/YoYNZ7/OpgabdU=", + "owner": "BirdeeHub", + "repo": "nix-wrapper-modules", + "rev": "2c0a3b795766b25d15ad1ec9eef3a06160154c9a", + "type": "github" + }, + "original": { + "owner": "BirdeeHub", + "repo": "nix-wrapper-modules", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index 7d1686b..6ec9f41 100644 --- a/flake.nix +++ b/flake.nix @@ -1,436 +1,75 @@ -# Copyright (c) 2023 BirdeeHub and Gabriel Venberg -# Licensed under the MIT license { - description = "Gabes neovim config, based on NixCats"; - + description = "Flake exporting a configured neovim package"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; - nixCats.url = "github:BirdeeHub/nixCats-nvim"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + wrappers = { + url = "github:BirdeeHub/nix-wrapper-modules"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + plugins-lze = { + url = "github:BirdeeHub/lze"; + flake = false; + }; + plugins-lzextras = { + url = "github:BirdeeHub/lzextras"; + flake = false; + }; }; - - # see :help nixCats.flake.outputs outputs = { self, nixpkgs, + wrappers, ... } @ inputs: let - inherit (inputs.nixCats) utils; - luaPath = ./.; - # this is flake-utils eachSystem - forEachSystem = utils.eachSystem nixpkgs.lib.platforms.all; - extra_pkg_config = { - # allowUnfree = true; + forAllSystems = nixpkgs.lib.genAttrs [ + "x86_64-linux" + "aarch64-linux" + ]; + module = nixpkgs.lib.modules.importApply ./module.nix inputs; + wrapper = wrappers.lib.evalModule module; + in { + formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra); + overlays = { + neovim = final: prev: {neovim = wrapper.config.wrap {pkgs = final;};}; + default = self.overlays.neovim; }; - # management of the system variable is one of the harder parts of using flakes. - - # so I have done it here in an interesting way to keep it out of the way. - # It gets resolved within the builder itself, and then passed to your - # categoryDefinitions and packageDefinitions. - - # this allows you to use ${pkgs.system} whenever you want in those sections - # without fear. - - # see :help nixCats.flake.outputs.overlays - dependencyOverlays = - /* - (import ./overlays inputs) ++ - */ - [ - # This overlay grabs all the inputs named in the format - # `plugins-` - # Once we add this overlay to our nixpkgs, we are able to - # use `pkgs.neovimPlugins`, which is a set of our plugins. - (utils.standardPluginOverlay inputs) - # add any other flake overlays here. - ]; - - # see :help nixCats.flake.outputs.categories - # and - # :help nixCats.flake.outputs.categoryDefinitions.scheme - categoryDefinitions = { - pkgs, - settings, - categories, - extra, - name, - mkPlugin, - ... - } @ packageDef: let - colorschemes = with pkgs.vimPlugins; { - "onedark" = onedark-nvim; - "catppuccin" = catppuccin-nvim; - "tokyonight" = tokyonight-nvim; - "nord" = nord-nvim; - "gruvbox" = gruvbox-nvim; + wrapperModules = { + neovim = module; + default = self.wrapperModules.neovim; + }; + wrappers = { + neovim = wrapper.config; + default = self.wrappers.neovim; + }; + packages = forAllSystems ( + system: let + pkgs = import nixpkgs {inherit system;}; + in { + neovim = wrapper.config.wrap {inherit pkgs;}; + default = self.packages.${system}.neovim; + } + ); + # `wrappers.neovim.enable = true` + nixosModules = { + default = self.nixosModules.neovim; + neovim = wrappers.lib.mkInstallModule { + name = "neovim"; + value = module; }; - in { - # to define and use a new category, simply add a new list to a set here, - # and later, you will include categoryname = true; in the set you - # provide when you build the package using this builder function. - # see :help nixCats.flake.outputs.packageDefinitions for info on that section. - - # lspsAndRuntimeDeps: - # this section is for dependencies that should be available - # at RUN TIME for plugins. Will be available to PATH within neovim terminal - # this includes LSPs - lspsAndRuntimeDeps = with pkgs; { - # some categories of stuff. - always = [ - universal-ctags - ripgrep - fd - fzf - lazygit - zoxide - ]; - markdown = [ - mermaid-cli - imagemagick - texliveSmall - ]; - git = [ - lazygit - git - ]; - lsp = { - rust = [ - rust-analyzer - cargo - ]; - lua = [ - lua-language-server - ]; - nix = [ - nix-doc - nixd - alejandra - ]; - python = [ - basedpyright - ruff - ]; - C = [ - libclang - ]; - bash = [ - shellcheck - bash-language-server - ]; - typst = [ - tinymist - ]; - }; - format = [ - ]; - }; - - # This is for plugins that will load at startup without using packadd: - startupPlugins = with pkgs.vimPlugins; { - always = [ - lze - lzextras - plenary-nvim - oil-nvim - nvim-web-devicons - snacks-nvim - nvim-numbertoggle - lualine-nvim - which-key-nvim - todo-comments-nvim - marks-nvim - ]; - lsp = { - rust = [ - rustaceanvim - ]; - }; - debug = [ - nvim-nio - ]; - treesitter = [ - comment-nvim - rainbow-delimiters-nvim - nvim-treesitter.withAllGrammars - treesj - ]; - allcolorschemes = colorschemes; - # You can retreive information from the - # packageDefinitions of the package this was packaged with. - # :help nixCats.flake.outputs.categoryDefinitions.scheme - themer = builtins.getAttr (categories.colorscheme or "gruvbox") colorschemes; - # This is obviously a fairly basic usecase for this, but still nice. - }; - - # not loaded automatically at startup. - # use with packadd and an autocommand in config to achieve lazy loading - # or a tool for organizing this like lze or lz.n! - # to get the name packadd expects, use the - # `:NixCats pawsible` command to see them all - optionalPlugins = with pkgs.vimPlugins; { - debug = { - default = [ - nvim-dap - nvim-dap-ui - nvim-dap-virtual-text - venn-nvim - ]; - }; - lint = [ - nvim-lint - ]; - format = [ - conform-nvim - ]; - markdown = [ - markdown-preview-nvim - ]; - lsp = { - default = [ - trouble-nvim - lualine-lsp-progress - nvim-lspconfig - ]; - zk = [ - zk-nvim - ]; - lua = [ - lazydev-nvim - ]; - typst = [ - typst-preview-nvim - ]; - }; - git = [ - gitsigns-nvim - ]; - always = [ - nvim-surround - leap-nvim - ]; - completion = [ - luasnip - friendly-snippets - cmp-cmdline - blink-cmp - blink-emoji-nvim - blink-compat - colorful-menu-nvim - ]; - extra = [ - vim-startuptime - ]; - }; - - # shared libraries to be added to LD_LIBRARY_PATH - # variable available to nvim runtime - sharedLibraries = { - }; - - # environmentVariables: - # this section is for environmentVariables that should be available - # at RUN TIME for plugins. Will be available to path within neovim terminal - environmentVariables = { - }; - - # If you know what these are, you can provide custom ones by category here. - # If you dont, check this link out: - # https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/make-wrapper.sh - extraWrapperArgs = { - }; - - # populates $LUA_PATH and $LUA_CPATH - extraLuaPackages = { - }; - - # see :help nixCats.flake.outputs.categoryDefinitions.default_values - # this will enable test.default and debug.default - # if any subcategory of test or debug is enabled - # WARNING: use of categories argument in this set will cause infinite recursion - # The categories argument of this function is the FINAL value. - # You may use it in any of the other sets. - extraCats = { - debug = [ - ["debug" "default"] - ]; - lsp = [ - ["lsp" "default"] + }; + # `wrappers.neovim.enable = true` + # You can set any of the options. + # But that is how you enable it. + homeModules = { + default = self.homeModules.neovim; + neovim = wrappers.lib.mkInstallModule { + name = "neovim"; + value = module; + loc = [ + "home" + "packages" ]; }; }; - - # packageDefinitions: - - # Now build a package with specific categories from above - # All categories you wish to include must be marked true, - # but false may be omitted. - # This entire set is also passed to nixCats for querying within the lua. - # It is directly translated to a Lua table, and a get function is defined. - # The get function is to prevent errors when querying subcategories. - - # see :help nixCats.flake.outputs.packageDefinitions - packageDefinitions = { - # the name here is the name of the package - # and also the default command name for it. - nvim = { - pkgs, - name, - ... - } @ misc: { - # these also recieve our pkgs variable - # see :help nixCats.flake.outputs.packageDefinitions - settings = { - suffix-path = true; - suffix-LD = true; - # WARNING: MAKE SURE THESE DONT CONFLICT WITH OTHER INSTALLED PACKAGES ON YOUR PATH - # That would result in a failed build, as nixos and home manager modules validate for collisions on your path - aliases = []; - - wrapRc = true; - configDirName = "nvim"; - }; - categories = { - always = true; - git = true; - treesitter = true; - markdown = true; - lsp = true; - completion = true; - debug = true; - lspDebugMode = false; - allcolorschemes = true; - colorscheme = "gruvbox"; - }; - extra = { - }; - }; - nvim-minimal = { - pkgs, - name, - ... - } @ misc: { - settings = { - suffix-path = true; - suffix-LD = true; - # WARNING: MAKE SURE THESE DONT CONFLICT WITH OTHER INSTALLED PACKAGES ON YOUR PATH - # That would result in a failed build, as nixos and home manager modules validate for collisions on your path - aliases = ["vim"]; - wrapRc = true; - configDirName = "nvim-minimal"; - }; - categories = { - always = true; - treesitter = true; - completion = true; - lspDebugMode = false; - lsp = false; - git = false; - themer = true; - colorscheme = "gruvbox"; - }; - extra = { - }; - }; - }; - - defaultPackageName = "nvim"; - # defaultPackageName is also passed to utils.mkNixosModules and utils.mkHomeModules - # and it controls the name of the top level option set. - # If you made a package named `nixCats` your default package as we did here, - # the modules generated would be set at: - # config.nixCats = { - # enable = true; - # packageNames = [ "nixCats" ]; # <- the packages you want installed - # - # } - # In addition, every package exports its own module via passthru, and is overrideable. - # so you can yourpackage.homeModule and then the namespace would be that packages name. - in - # see :help nixCats.flake.outputs.exports - forEachSystem (system: let - # and this will be our builder! it takes a name from our packageDefinitions as an argument, and builds an nvim. - nixCatsBuilder = - utils.baseBuilder luaPath { - # we pass in the things to make a pkgs variable to build nvim with later - inherit nixpkgs system dependencyOverlays extra_pkg_config; - # and also our categoryDefinitions and packageDefinitions - } - categoryDefinitions - packageDefinitions; - # call it with our defaultPackageName - defaultPackage = nixCatsBuilder defaultPackageName; - - # this pkgs variable is just for using utils such as pkgs.mkShell - # within this outputs set. - pkgs = import nixpkgs {inherit system;}; - # The one used to build neovim is resolved inside the builder - # and is passed to our categoryDefinitions and packageDefinitions - in { - # these outputs will be wrapped with ${system} by utils.eachSystem - - # this will generate a set of all the packages - # in the packageDefinitions defined above - # from the package we give it. - # and additionally output the original as default. - packages = utils.mkAllWithDefault defaultPackage; - - formatter = pkgs.alejandra; - - # choose your package for devShell - # and add whatever else you want in it. - devShells = { - default = pkgs.mkShell { - name = defaultPackageName; - packages = [defaultPackage]; - inputsFrom = []; - shellHook = '' - ''; - }; - }; - }) - // (let - # we also export a nixos module to allow reconfiguration from configuration.nix - nixosModule = utils.mkNixosModules { - moduleNamespace = [defaultPackageName]; - inherit - defaultPackageName - dependencyOverlays - luaPath - categoryDefinitions - packageDefinitions - extra_pkg_config - nixpkgs - ; - }; - # and the same for home manager - homeModule = utils.mkHomeModules { - moduleNamespace = [defaultPackageName]; - inherit - defaultPackageName - dependencyOverlays - luaPath - categoryDefinitions - packageDefinitions - extra_pkg_config - nixpkgs - ; - }; - in { - # these outputs will be NOT wrapped with ${system} - - # this will make an overlay out of each of the packageDefinitions defined above - # and set the default overlay to the one named here. - overlays = - utils.makeOverlays luaPath { - inherit nixpkgs dependencyOverlays extra_pkg_config; - } - categoryDefinitions - packageDefinitions - defaultPackageName; - - nixosModules.default = nixosModule; - homeModules.default = homeModule; - - inherit utils nixosModule homeModule; - inherit (utils) templates; - }); + }; } diff --git a/init.lua b/init.lua index 57b52e5..d8690a2 100644 --- a/init.lua +++ b/init.lua @@ -1,60 +1,96 @@ ---[[ -NOTE: -if you plan to always load your nixCats via nix, -you can safely ignore this setup call, -and the require('myLuaConf.non_nix_download') call below it. -as well as the entire lua/myLuaConf/non_nix_download file. -Unless you want the lzUtils file, or the lazy wrapper, you also wont need lua/nixCatsUtils - -IF YOU DO NOT DO THIS SETUP CALL: -the result will be that, when you load this folder without using nix, -the global nixCats function which you use everywhere -to check for categories will throw an error. -This setup function will give it a default value. -Of course, if you only ever download nvim with nix, this isnt needed.]] ---[[ ----------------------------------- ]] ---[[ This setup function will provide ]] ---[[ a default value for the nixCats('') ]] ---[[ function so that it will not throw ]] ---[[ an error if not loaded via nixCats ]] ---[[ ----------------------------------- ]] -require('nixCatsUtils').setup { - non_nix_value = true, +-- NOTE: Welcome to your neovim configuration! +-- The first 100ish lines are setup, +-- the rest is usage of lze and various core plugins! +vim.loader.enable() -- <- bytecode caching +do + -- Set up a global in a way that also handles non-nix compat + local ok + ok, _G.nixInfo = pcall(require, vim.g.nix_info_plugin_name) + if not ok then + package.loaded[vim.g.nix_info_plugin_name] = setmetatable({}, { + __call = function (_, default) return default end + }) + _G.nixInfo = require(vim.g.nix_info_plugin_name) + -- If you always use the fetcher function to fetch nix values, + -- rather than indexing into the tables directly, + -- it will use the value you specified as the default + -- TODO: for non-nix compat, vim.pack.add in another file and require here. + end + nixInfo.isNix = vim.g.nix_info_plugin_name ~= nil + ---@module 'lzextras' + ---@type lzextras | lze + nixInfo.lze = setmetatable(require('lze'), getmetatable(require('lzextras'))) + function nixInfo.get_nix_plugin_path(name) + return nixInfo(nil, "plugins", "lazy", name) or nixInfo(nil, "plugins", "start", name) + end +end +nixInfo.lze.register_handlers { + { + -- adds an `auto_enable` field to lze specs + -- if true, will disable it if not installed by nix. + -- if string, will disable if that name was not installed by nix. + -- if a table of strings, it will disable if any were not. + spec_field = "auto_enable", + set_lazy = false, + modify = function(plugin) + if vim.g.nix_info_plugin_name then + if type(plugin.auto_enable) == "table" then + for _, name in pairs(plugin.auto_enable) do + if not nixInfo.get_nix_plugin_path(name) then + plugin.enabled = false + break + end + end + elseif type(plugin.auto_enable) == "string" then + if not nixInfo.get_nix_plugin_path(plugin.auto_enable) then + plugin.enabled = false + end + elseif type(plugin.auto_enable) == "boolean" and plugin.auto_enable then + if not nixInfo.get_nix_plugin_path(plugin.name) then + plugin.enabled = false + end + end + end + return plugin + end, + }, + { + -- we made an options.settings.cats with the value of enable for our top level specs + -- give for_cat = "name" to disable if that one is not enabled + spec_field = "for_cat", + set_lazy = false, + modify = function(plugin) + if vim.g.nix_info_plugin_name then + if type(plugin.for_cat) == "string" then + plugin.enabled = nixInfo(false, "settings", "cats", plugin.for_cat) + end + end + return plugin + end, + }, + -- From lzextras. This one makes it so that + -- you can set up lsps within lze specs, + -- and trigger lspconfig setup hooks only on the correct filetypes + -- It is (unfortunately) important that it be registered after the above 2, + -- as it also relies on the modify hook, and the value of enabled at that point + nixInfo.lze.lsp, } ---[[ -Nix puts the plugins -into the directories paq-nvim expects them to be in, -because both follow the normal neovim scheme. -So you just put the URLs and build steps in there, and use its opt option to do the same -thing as putting a plugin in nixCat's optionalPlugins field. -then load the plugins via paq-nvim -YOU are in charge of putting the plugin -urls and build steps in there, which will only be used when not on nix, -and you should keep any setup functions -OUT of that file, as they are ONLY loaded when this -configuration is NOT loaded via nix. ---]] -require("myLuaConf.non_nix_download") --- OK, again, that isnt needed if you load this setup via nix, but it is an option. ---[[ -outside of when you want to use the nixCats global command -to decide if something should be loaded, or to pass info from nix to lua, -thats pretty much everything specific to nixCats that -needs to be in your config. -If you always want to load it via nix, -you pretty much dont need this file at all, and you also won't need -anything within lua/nixCatsUtils, nor will that be in the default template. -that directory is addable via the luaUtils template. -it is not required, but has some useful utility functions. ---]] +-- NOTE: This config uses lzextras.lsp handler https://github.com/BirdeeHub/lzextras?tab=readme-ov-file#lsp-handler +-- Because we have the paths, we can set a more performant fallback function +-- for when you don't provide a filetype to trigger on yourself. +-- If you do provide a filetype, this will never be called. +nixInfo.lze.h.lsp.set_ft_fallback(function(name) + local lspcfg = nixInfo.get_nix_plugin_path "nvim-lspconfig" + if lspcfg then + local ok, cfg = pcall(dofile, lspcfg .. "/lsp/" .. name .. ".lua") + return (ok and cfg or {}).filetypes or {} + else + -- the less performant thing we are trying to avoid at startup + return (vim.lsp.config[name] or {}).filetypes or {} + end +end) ---[[ -ok thats enough for 1 file. Off to lua/myLuaConf/init.lua -all the config starts there in this example config. -This config is loadable with and without nix due to the above, -and the lua/myLuaConf/non_nix_download.lua file. -the rest is just example of how to configure nvim making use of various -features of nixCats and using the plugin lze for lazy loading. ---]] -require('myLuaConf') +require('opts') +require('keys') +require('plugins') diff --git a/lua/keys.lua b/lua/keys.lua new file mode 100644 index 0000000..8f0f9f7 --- /dev/null +++ b/lua/keys.lua @@ -0,0 +1,37 @@ +-- [[ Basic Keymaps ]] + +-- Keymaps for better default experience +-- See `:help vim.keymap.set()` +vim.keymap.set("v", "J", ":m '>+1gv=gv", { desc = 'Moves Line Down' }) +vim.keymap.set("v", "K", ":m '<-2gv=gv", { desc = 'Moves Line Up' }) +vim.keymap.set("n", "", "zz", { desc = 'Scroll Down' }) +vim.keymap.set("n", "", "zz", { desc = 'Scroll Up' }) +vim.keymap.set("n", "n", "nzzzv", { desc = 'Next Search Result' }) +vim.keymap.set("n", "N", "Nzzzv", { desc = 'Previous Search Result' }) + +-- Remap for dealing with word wrap +vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) +vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) + +-- Diagnostic keymaps +vim.keymap.set('n', 'e', vim.diagnostic.open_float, { desc = 'Open floating diagnostic message' }) +vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostics list' }) +vim.keymap.set('n', '[d', function() vim.diagnostic.jump({ count = -1, float = true }) end, + { desc = 'Go to previous diagnostic' }) +vim.keymap.set('n', ']d', function() vim.diagnostic.jump({ count = 1, float = true }) end, + { desc = 'Go to next diagnostic' }) + +-- moving between splits +vim.keymap.set('n', '', 'h', { desc = 'move to right split' }) +vim.keymap.set('n', '', 'j', { desc = 'move to below split' }) +vim.keymap.set('n', '', 'k', { desc = 'move to above split' }) +vim.keymap.set('n', '', 'l', { desc = 'move to left split' }) + +-- You should instead use these keybindings so that they are still easy to use, but dont conflict +vim.keymap.set({ "v", "x", "n" }, 'y', '"+y', { noremap = true, silent = true, desc = 'Yank to clipboard' }) +vim.keymap.set({ "n", "v", "x" }, 'Y', '"+yy', { noremap = true, silent = true, desc = 'Yank line to clipboard' }) +vim.keymap.set({ 'n', 'v', 'x' }, 'p', '"+p', { noremap = true, silent = true, desc = 'Paste from clipboard' }) +vim.keymap.set('i', '', '+', + { noremap = true, silent = true, desc = 'Paste from clipboard from within insert mode' }) +vim.keymap.set("x", "P", '"_dP', + { noremap = true, silent = true, desc = 'Paste over selection without erasing unnamed register' }) diff --git a/lua/myLuaConf/LSPs/init.lua b/lua/myLuaConf/LSPs/init.lua deleted file mode 100644 index 96f7e50..0000000 --- a/lua/myLuaConf/LSPs/init.lua +++ /dev/null @@ -1,261 +0,0 @@ -local catUtils = require('nixCatsUtils') -if (catUtils.isNixCats and nixCats('lspDebugMode')) then - vim.lsp.set_log_level("debug") -end - -local Snacks = require("snacks") - -vim.keymap.set("n", "lI", Snacks.picker.lsp_implementations, { desc = "Goto [I]mplementation" }) -vim.keymap.set("n", "lR", Snacks.picker.lsp_references, { desc = "Goto [R]eferences" }) -vim.keymap.set("n", "li", Snacks.picker.diagnostics, { desc = "D[i]agnostics" }) -vim.keymap.set("n", "ls", Snacks.picker.lsp_symbols, { desc = "Document [S]ymbols" }) -vim.keymap.set("n", "lws", Snacks.picker.lsp_workspace_symbols, { desc = "[W]orkspace [S]ymbols" }) - -vim.keymap.set("n", "lD", vim.lsp.buf.declaration, { desc = "Goto [D]eclaration" }) -vim.keymap.set("n", "lt", vim.lsp.buf.type_definition, { desc = "Type [D]efinition" }) -vim.keymap.set({"n", "v",}, "la", vim.lsp.buf.code_action, { desc = "[C]ode Action" }) -vim.keymap.set("n", "ld", vim.lsp.buf.definition, { desc = "Goto [D]efinition" }) -vim.keymap.set("n", "lf", vim.lsp.buf.format, { desc = "Format buffer" }) -vim.keymap.set("n", "lh", vim.lsp.buf.hover, { desc = "Hover Documentation" }) -vim.keymap.set("n", "lr", vim.lsp.buf.rename, { desc = "[R]ename" }) -vim.keymap.set("n", "ls", vim.lsp.buf.signature_help, { desc = "Signature Documentation" }) -vim.keymap.set("n", "lwa", vim.lsp.buf.add_workspace_folder, { desc = "[W]orkspace [A]dd Folder" }) -vim.keymap.set("n", "lwl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, - { desc = "[W]orkspace [L]ist Folders" }) -vim.keymap.set("n", "lwr", vim.lsp.buf.remove_workspace_folder, { desc = "[W]orkspace [R]emove Folder" }) - --- setup lsp progress notifications -local progress = vim.defaulttable() -vim.api.nvim_create_autocmd("LspProgress", { - callback = function(ev) - local client = vim.lsp.get_client_by_id(ev.data.client_id) - local value = ev.data.params - .value --[[@as {percentage?: number, title?: string, message?: string, kind: "begin" | "report" | "end"}]] - if not client or type(value) ~= "table" then - return - end - local p = progress[client.id] - - for i = 1, #p + 1 do - if i == #p + 1 or p[i].token == ev.data.params.token then - p[i] = { - token = ev.data.params.token, - msg = ("[%3d%%] %s%s"):format( - value.kind == "end" and 100 or value.percentage or 100, - value.title or "", - value.message and (" **%s**"):format(value.message) or "" - ), - done = value.kind == "end", - } - break - end - end - - local msg = {} ---@type string[] - progress[client.id] = vim.tbl_filter(function(v) - return table.insert(msg, v.msg) or not v.done - end, p) - - local spinner = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" } - vim.notify(table.concat(msg, "\n"), "info", { - id = "lsp_progress", - title = client.name, - opts = function(notif) - notif.icon = #progress[client.id] == 0 and " " - or spinner[math.floor(vim.uv.hrtime() / (1e6 * 80)) % #spinner + 1] - end, - }) - end, -}) - --- NOTE: This file uses lzextras.lsp handler https://github.com/BirdeeHub/lzextras?tab=readme-ov-file#lsp-handler --- This is a slightly more performant fallback function --- for when you don't provide a filetype to trigger on yourself. --- nixCats gives us the paths, which is faster than searching the rtp! -local old_ft_fallback = require('lze').h.lsp.get_ft_fallback() -require('lze').h.lsp.set_ft_fallback(function(name) - local lspcfg = nixCats.pawsible({ "allPlugins", "opt", "nvim-lspconfig" }) or - nixCats.pawsible({ "allPlugins", "start", "nvim-lspconfig" }) - if lspcfg then - local ok, cfg = pcall(dofile, lspcfg .. "/lsp/" .. name .. ".lua") - if not ok then - ok, cfg = pcall(dofile, lspcfg .. "/lua/lspconfig/configs/" .. name .. ".lua") - end - return (ok and cfg or {}).filetypes or {} - else - return old_ft_fallback(name) - end -end) -require('lze').load { - { - "nvim-lspconfig", - for_cat = "lsp", - on_require = { "lspconfig" }, - -- rustaceanvim and zk-nvim dont require("lspconfig") - ft = { "markdown", "rust" }, - -- NOTE: define a function for lsp, - -- and it will run for all specs with type(plugin.lsp) == table - -- when their filetype trigger loads them - lsp = function(plugin) - vim.lsp.config(plugin.name, plugin.lsp or {}) - vim.lsp.enable(plugin.name) - end, - }, - { - "mason.nvim", - -- only run it when not on nix - enabled = not catUtils.isNixCats, - on_plugin = { "nvim-lspconfig" }, - load = function(name) - vim.cmd.packadd(name) - vim.cmd.packadd("mason-lspconfig.nvim") - require('mason').setup() - -- auto install will make it install servers when lspconfig is called on them. - require('mason-lspconfig').setup { automatic_installation = true, } - end, - }, - { - -- lazydev makes your lsp way better in your config without needing extra lsp configuration. - "lazydev.nvim", - for_cat = "lsp.lua", - cmd = { "LazyDev" }, - ft = "lua", - after = function(_) - require('lazydev').setup({ - library = { - { words = { "nixCats" }, path = (nixCats.nixCatsPath or "") .. '/lua' }, - }, - }) - end, - }, - { - -- name of the lsp - "lua_ls", - enabled = nixCats('lsp.lua'), - -- provide a table containing filetypes, - -- and then whatever your functions defined in the function type specs expect. - -- in our case, it just expects the normal lspconfig setup options, - -- but with a default on_attach and capabilities - lsp = { - -- if you provide the filetypes it doesn't ask lspconfig for the filetypes - filetypes = { 'lua' }, - settings = { - Lua = { - runtime = { version = 'LuaJIT' }, - formatters = { - ignoreComments = true, - }, - signatureHelp = { enabled = true }, - diagnostics = { - globals = { "nixCats", "vim", }, - disable = { 'missing-fields' }, - }, - telemetry = { enabled = false }, - }, - }, - }, - -- also these are regular specs and you can use before and after and all the other normal fields - }, - { - "basedpyright", - enabled = nixCats("lsp.python"), - lsp = {}, - }, - { - "bashls", - enabled = nixCats("lsp.bash"), - lsp = {}, - }, - { - "clangd", - enabled = nixCats("lsp.c"), - lsp = {}, - }, - { - "ruff", - enabled = nixCats("lsp.python"), - lsp = {}, - }, - { - "tinymist", - enabled = nixCats("lsp.tinymist"), - lsp = { - filetypes = { "typst" }, - settings = { - formatterMode = "typstyle", - - }, - }, - }, - { - "nixd", - enabled = catUtils.isNixCats and nixCats('lsp.nix'), - lsp = { - filetypes = { "nix" }, - settings = { - nixd = { - -- nixd requires some configuration. - -- luckily, the nixCats plugin is here to pass whatever we need! - -- we passed this in via the `extra` table in our packageDefinitions - -- for additional configuration options, refer to: - -- https://github.com/nix-community/nixd/blob/main/nixd/docs/configuration.md - nixpkgs = { - -- in the extras set of your package definition: - -- nixdExtras.nixpkgs = ''import ${pkgs.path} {}'' - expr = nixCats.extra("nixdExtras.nixpkgs") - }, - options = { - -- If you integrated with your system flake, - -- you should use inputs.self as the path to your system flake - -- that way it will ALWAYS work, regardless - -- of where your config actually was. - nixos = { - -- nixdExtras.nixos_options = ''(builtins.getFlake "path:${builtins.toString inputs.self.outPath}").nixosConfigurations.configname.options'' - expr = nixCats.extra("nixdExtras.nixos_options") - }, - -- If you have your config as a separate flake, inputs.self would be referring to the wrong flake. - -- You can override the correct one into your package definition on import in your main configuration, - -- or just put an absolute path to where it usually is and accept the impurity. - ["home-manager"] = { - -- nixdExtras.home_manager_options = ''(builtins.getFlake "path:${builtins.toString inputs.self.outPath}").homeConfigurations.configname.options'' - expr = nixCats.extra("nixdExtras.home_manager_options") - } - }, - formatting = { - command = { "alejandra" } - }, - diagnostic = { - suppress = { - "sema-escaping-with" - } - } - } - }, - }, - }, - { - "rustaceanvim", - for_cat = "lsp.rust", - }, - { - "zk-nvim", - for_cat = "lsp.zk", - ft = "markdown", - after = function() - require("zk").setup({ picker = "snacks_picker" }) - - vim.api.nvim_set_keymap("n", "zb", "ZkBackLinks", { desc = "Show [B]acklinkgs" }) - vim.api.nvim_set_keymap("n", "zl", "ZkLinks", { desc = "Show [L]inks" }) - vim.api.nvim_set_keymap("n", "zi", ":'<,'>ZkInsertLink", { desc = "[I]nsert link" }) - vim.api.nvim_set_keymap("n", "zn", "ZkNew { title = vim.fn.input('Title: ') }", - { desc = "[N]ew note" }) - vim.api.nvim_set_keymap("n", "zo", "ZkNotes { sort = { 'modified' } }", { desc = "[O]pen notes" }) - vim.api.nvim_set_keymap("n", "zt", "ZkTags", { desc = "Search [T]ags" }) - vim.api.nvim_set_keymap("v", "zf", ":'<,'>ZkMatch", { desc = "[F]ind note from selection" }) - vim.api.nvim_set_keymap("v", "zn", ":'<,'>ZkNewFromTitleSelection", { - desc = - "[N]ew note from selection" - }) - end - }, -} diff --git a/lua/myLuaConf/init.lua b/lua/myLuaConf/init.lua deleted file mode 100644 index 947f610..0000000 --- a/lua/myLuaConf/init.lua +++ /dev/null @@ -1,20 +0,0 @@ - --- TODO: split up the plugins a bit. --- NOTE: various, non-plugin config -require('myLuaConf.opts_and_keys') - --- NOTE: register an extra lze handler with the spec_field 'for_cat' --- that makes enabling an lze spec for a category slightly nicer -require("lze").register_handlers(require('nixCatsUtils.lzUtils').for_cat) - --- NOTE: Register another one from lzextras. This one makes it so that --- you can set up lsps within lze specs, --- and trigger lspconfig setup hooks only on the correct filetypes -require('lze').register_handlers(require('lzextras').lsp) --- demonstrated in ./LSPs/init.lua - --- NOTE: general plugins -require("myLuaConf.plugins") - --- NOTE: obviously, more plugins, but more organized by what they do below -require("myLuaConf.LSPs") diff --git a/lua/myLuaConf/non_nix_download.lua b/lua/myLuaConf/non_nix_download.lua deleted file mode 100644 index 42dd53f..0000000 --- a/lua/myLuaConf/non_nix_download.lua +++ /dev/null @@ -1,92 +0,0 @@ --- TODO: completley out of date --- load the plugins via paq-nvim when not on nix --- YOU are in charge of putting the plugin --- urls and build steps in here, which will only be used when not on nix. --- and you should keep any setup functions OUT of this file - --- again, you dont need this file if you only use nix to load the config, --- this is a fallback only, and is optional. -require('nixCatsUtils.catPacker').setup({ ---[[ ------------------------------------------ ]] ---[[ The way to think of this is, its very ]] ---[[ similar to the main nix file for nixCats ]] ---[[ ]] ---[[ It can be used to download your plugins, ]] ---[[ and it has an opt for optional plugins. ]] ---[[ ]] ---[[ We dont want to handle anything about ]] ---[[ loading those plugins here, so that we can ]] ---[[ use the same loading code that we use for ]] ---[[ our normal nix-loaded config. ]] ---[[ we will do all our loading and configuring ]] ---[[ elsewhere in our configuration, so that ]] ---[[ we dont have to write it twice. ]] ---[[ ------------------------------------------ ]] - { "BirdeeHub/lze", }, - { "BirdeeHub/lzextras", }, - { "stevearc/oil.nvim", }, - { 'ellisonleao/gruvbox.nvim', }, - { 'nvim-tree/nvim-web-devicons', }, - { 'nvim-lua/plenary.nvim', }, - { 'tpope/vim-repeat', }, - { 'rcarriga/nvim-notify', }, - - { 'nvim-treesitter/nvim-treesitter-textobjects', opt = true, }, - { 'nvim-treesitter/nvim-treesitter', build = ':TSUpdate', opt = true, }, - - { 'nvim-telescope/telescope-fzf-native.nvim', build = ':!which make && make', opt = true, }, - { 'nvim-telescope/telescope-ui-select.nvim', opt = true, }, - {'nvim-telescope/telescope.nvim', opt = true, }, - - -- lsp - { 'williamboman/mason.nvim', opt = true, }, - { 'williamboman/mason-lspconfig.nvim', opt = true, }, - { 'j-hui/fidget.nvim', opt = true, }, - { 'neovim/nvim-lspconfig', opt = true, }, - - -- NOTE: we take care of lazy loading elsewhere in an autocommand - -- so that we can use the same code on and off nix. - -- so here we just tell it not to auto load it - { 'folke/lazydev.nvim', opt = true, }, - - -- completion - { 'L3MON4D3/LuaSnip', opt = true, as = "luasnip", }, - { 'hrsh7th/cmp-cmdline', opt = true, }, - { 'Saghen/blink.cmp', opt = true, }, - { 'Saghen/blink.compat', opt = true, }, - { 'xzbdmw/colorful-menu.nvim', opt = true, }, - - -- lint and format - { 'mfussenegger/nvim-lint', opt = true, }, - { 'stevearc/conform.nvim', opt = true, }, - - -- dap - { 'nvim-neotest/nvim-nio', opt = true, }, - { 'rcarriga/nvim-dap-ui', opt = true, }, - { 'theHamsta/nvim-dap-virtual-text', opt = true, }, - { 'jay-babu/mason-nvim-dap.nvim', opt = true, }, - { 'mfussenegger/nvim-dap', opt = true, }, - - -- { 'm-demare/hlargs.nvim', }, - { 'mbbill/undotree', opt = true, }, - { 'tpope/vim-fugitive', opt = true, }, - { 'tpope/vim-rhubarb', opt = true, }, - { 'tpope/vim-sleuth', opt = true, }, - { 'folke/which-key.nvim', opt = true, }, - { 'lewis6991/gitsigns.nvim', opt = true, }, - { 'nvim-lualine/lualine.nvim', opt = true, }, - { 'lukas-reineke/indent-blankline.nvim', opt = true, }, - { 'numToStr/Comment.nvim', opt = true, as = "comment.nvim", }, - { 'kylechui/nvim-surround', opt = true, }, - { - "iamcco/markdown-preview.nvim", - build = ":call mkdp#util#install()", - opt = true, - }, - - -- all the rest of the setup will be done using the normal setup functions later, - -- thus working regardless of what method loads the plugins. - -- only stuff pertaining to downloading should be added to paq. - -}) --- OK, again, that isnt needed if you load this setup via nix, but it is an option. diff --git a/lua/myLuaConf/plugins/completion.lua b/lua/myLuaConf/plugins/completion.lua deleted file mode 100644 index 0431493..0000000 --- a/lua/myLuaConf/plugins/completion.lua +++ /dev/null @@ -1,156 +0,0 @@ -local load_w_after = function(name) - vim.cmd.packadd(name) - vim.cmd.packadd(name .. '/after') -end - -return { - { - "cmp-cmdline", - for_cat = "completion", - on_plugin = { "blink.cmp" }, - load = load_w_after, - }, - { - "blink.compat", - for_cat = "completion", - dep_of = { "cmp-cmdline" }, - }, - { - "luasnip", - for_cat = "completion", - dep_of = { "blink.cmp" }, - after = function(_) - vim.cmd.packadd("friendly-snippets") - local luasnip = require 'luasnip' - require('luasnip.loaders.from_vscode').lazy_load() - luasnip.config.setup {} - - local ls = require('luasnip') - - vim.keymap.set({ "i", "s" }, "", function() - if ls.choice_active() then - ls.change_choice(1) - end - end) - end, - }, - { - "colorful-menu.nvim", - for_cat = "completion", - on_plugin = { "blink.cmp" }, - }, - { - "blink-emoji.nvim", - for_cat = "completion", - on_plugin = { "blink.cmp" }, - }, - { - "blink.cmp", - for_cat = "completion", - event = "DeferredUIEnter", - after = function(_) - require("blink.cmp").setup({ - -- 'default' (recommended) for mappings similar to built-in completions (C-y to accept) - -- See :h blink-cmp-config-keymap for configuring keymaps - keymap = { preset = "enter", }, - cmdline = { - enabled = true, - completion = { - menu = { - auto_show = true, - }, - }, - sources = function() - local type = vim.fn.getcmdtype() - -- Search forward and backward - if type == '/' or type == '?' then return { 'buffer' } end - -- Commands - if type == ':' or type == '@' then return { 'cmdline', 'cmp_cmdline' } end - return {} - end, - }, - fuzzy = { - sorts = { - 'exact', - -- defaults - 'score', - 'sort_text', - }, - }, - signature = { - enabled = true, - window = { - show_documentation = true, - }, - }, - completion = { - list = { - selection = { - preselect = false, - auto_insert = false, - }, - }, - menu = { - draw = { - treesitter = { 'lsp' }, - components = { - label = { - text = function(ctx) - return require("colorful-menu").blink_components_text(ctx) - end, - highlight = function(ctx) - return require("colorful-menu").blink_components_highlight(ctx) - end, - }, - }, - }, - }, - documentation = { - auto_show = true, - }, - }, - snippets = { - preset = 'luasnip', - active = function(filter) - local snippet = require "luasnip" - local blink = require "blink.cmp" - if snippet.in_snippet() and not blink.is_visible() then - return true - else - if not snippet.in_snippet() and vim.fn.mode() == "n" then snippet.unlink_current() end - return false - end - end, - }, - sources = { - default = { 'lsp', 'path', 'snippets', 'buffer', 'omni', 'emoji', }, - providers = { - path = { - score_offset = 50, - }, - lsp = { - score_offset = 40, - }, - snippets = { - score_offset = 40, - }, - emoji = { - module = "blink-emoji", - name = "Emoji", - score_offset = 15, - opts = { insert = true }, - }, - cmp_cmdline = { - name = 'cmp_cmdline', - module = 'blink.compat.source', - score_offset = -100, - opts = { - cmp_name = 'cmdline', - }, - }, - }, - }, - }) - end, - }, -} diff --git a/lua/myLuaConf/plugins/gitsigns.lua b/lua/myLuaConf/plugins/gitsigns.lua deleted file mode 100644 index 5e10927..0000000 --- a/lua/myLuaConf/plugins/gitsigns.lua +++ /dev/null @@ -1,84 +0,0 @@ -return { - "gitsigns.nvim", - for_cat = 'git', - event = "DeferredUIEnter", - -- cmd = { "" }, - -- ft = "", - -- keys = "", - -- colorscheme = "", - after = function() - require('gitsigns').setup({ - -- See `:help gitsigns.txt` - signs = { - add = { text = '+' }, - change = { text = '~' }, - delete = { text = '_' }, - topdelete = { text = '‾' }, - changedelete = { text = '~' }, - }, - on_attach = function(bufnr) - local gs = package.loaded.gitsigns - - local function map(mode, l, r, opts) - opts = opts or {} - opts.buffer = bufnr - vim.keymap.set(mode, l, r, opts) - end - - -- Navigation - map({ 'n', 'v' }, ']c', function() - if vim.wo.diff then - return ']c' - end - vim.schedule(function() - gs.next_hunk() - end) - return '' - end, { expr = true, desc = 'Jump to next hunk' }) - - map({ 'n', 'v' }, '[c', function() - if vim.wo.diff then - return '[c' - end - vim.schedule(function() - gs.prev_hunk() - end) - return '' - end, { expr = true, desc = 'Jump to previous hunk' }) - - -- Actions - -- visual mode - map('v', 'hs', function() - gs.stage_hunk { vim.fn.line '.', vim.fn.line 'v' } - end, { desc = 'stage git hunk' }) - map('v', 'hr', function() - gs.reset_hunk { vim.fn.line '.', vim.fn.line 'v' } - end, { desc = 'reset git hunk' }) - -- normal mode - map('n', 'gs', gs.stage_hunk, { desc = 'git stage hunk' }) - map('n', 'gr', gs.reset_hunk, { desc = 'git reset hunk' }) - map('n', 'gS', gs.stage_buffer, { desc = 'git Stage buffer' }) - map('n', 'gu', gs.undo_stage_hunk, { desc = 'undo stage hunk' }) - map('n', 'gR', gs.reset_buffer, { desc = 'git Reset buffer' }) - map('n', 'gp', gs.preview_hunk, { desc = 'preview git hunk' }) - map('n', 'gb', function() - gs.blame_line { full = false } - end, { desc = 'git blame line' }) - map('n', 'gd', gs.diffthis, { desc = 'git diff against index' }) - map('n', 'gD', function() - gs.diffthis '~' - end, { desc = 'git diff against last commit' }) - - -- Toggles - map('n', 'gtb', gs.toggle_current_line_blame, { desc = 'toggle git blame line' }) - map('n', 'gtd', gs.toggle_deleted, { desc = 'toggle git show deleted' }) - - -- Text object - map({ 'o', 'x' }, 'ih', ':Gitsigns select_hunk', { desc = 'select git hunk' }) - end, - }) - vim.cmd([[hi GitSignsAdd guifg=#04de21]]) - vim.cmd([[hi GitSignsChange guifg=#83fce6]]) - vim.cmd([[hi GitSignsDelete guifg=#fa2525]]) - end, -} diff --git a/lua/myLuaConf/plugins/init.lua b/lua/myLuaConf/plugins/init.lua deleted file mode 100644 index f44ca18..0000000 --- a/lua/myLuaConf/plugins/init.lua +++ /dev/null @@ -1,279 +0,0 @@ -local colorschemeName = nixCats('colorscheme') -if not require('nixCatsUtils').isNixCats then - colorschemeName = 'gruvbox' -end --- Could I lazy load on colorscheme with lze? --- sure. But I was going to call vim.cmd.colorscheme() during startup anyway --- this is just an example, feel free to do a better job! -vim.cmd.colorscheme(colorschemeName) - -local ok, notify = pcall(require, "notify") -if ok then - notify.setup({ - on_open = function(win) - vim.api.nvim_win_set_config(win, { focusable = false }) - end, - }) - vim.notify = notify - vim.keymap.set("n", "", function() - notify.dismiss({ silent = true, }) - end, { desc = "dismiss notify popup and clear hlsearch" }) -end - --- NOTE: you can check if you included the category with the thing wherever you want. -if nixCats('always') then - -- I didnt want to bother with lazy loading this. - -- I could put it in opt and put it in a spec anyway - -- and then not set any handlers and it would load at startup, - -- but why... I guess I could make it load - -- after the other lze definitions in the next call using priority value? - -- didnt seem necessary. - vim.g.loaded_netrwPlugin = 1 - require("oil").setup({ - default_file_explorer = false, - view_options = { - show_hidden = true - }, - columns = { - "icon", - "permissions", - "size", - -- "mtime", - }, - keymaps = { - ["g?"] = "actions.show_help", - [""] = "actions.select", - [""] = "actions.select_vsplit", - [""] = "actions.select_split", - [""] = "actions.select_tab", - [""] = "actions.preview", - [""] = "actions.close", - [""] = "actions.refresh", - ["-"] = "actions.parent", - ["_"] = "actions.open_cwd", - ["`"] = "actions.cd", - ["~"] = "actions.tcd", - ["gs"] = "actions.change_sort", - ["gx"] = "actions.open_external", - ["g."] = "actions.toggle_hidden", - ["g\\"] = "actions.toggle_trash", - }, - }) - vim.keymap.set("n", "-", "Oil", { noremap = true, desc = 'Open Parent Directory' }) - vim.keymap.set("n", "-", "Oil .", { noremap = true, desc = 'Open nvim root directory' }) -end - -if nixCats("always") then - -- Potentially checkout the lazygit module. - local Snacks = require("snacks") - local config = { - bufdelete = { enable = true }, - dim = { enable = true }, - git = { enable = true }, - input = { enable = true }, - notifier = { enable = true }, - terminal = { enable = true }, - toggle = { enable = true }, - quickfile = { enable = true }, - scope = { enable = true }, - statuscolumn = { enable = true }, - - explorer = { replace_netrw = true }, - picker = { - enabled = true, - ui_select = true, - matcher = { - fuzzy = true, - frecency = true, - }, - previewers = { - diff = { - builtin = true, -- use Neovim for previewing diffs (true) or use an external tool (false) - cmd = { "delta" }, -- example to show a diff with delta - }, - git = { - builtin = true, -- use Neovim for previewing git output (true) or use git (false) - }, - }, - }, - indent = { - enabled = true, - animate = { enabled = false }, - scope = { enabled = true }, - chunk = { enabled = true }, - }, - image = { enabled = false, inline = false, float = false }, - lazygit = { enabled = false, configure = false }, - } - if nixCats("markdown") then - config.image.enable = true - end - if nixCats("git") then - config.lazygit.enable = true - end - Snacks.setup(config) - - -- setup keybinds. - vim.keymap.set("n", "bd", Snacks.bufdelete.delete, { desc = "delete buffer" }) - vim.keymap.set("n", "t", function() Snacks.explorer() end, { desc = "File [T]ree" }) - vim.keymap.set("n", "i", Snacks.image.hover, { desc = "[I]mage preview" }) - - -- picker keybinds - vim.keymap.set("n", "fGb", Snacks.picker.grep_buffers, { desc = "[G]rep buffers" }) - vim.keymap.set("n", "fGl", Snacks.picker.lines, { desc = "[L]ines in buffer" }) - vim.keymap.set("n", "fb", Snacks.picker.buffers, { desc = "[B]uffers" }) - vim.keymap.set("n", "ff", Snacks.picker.files, { desc = "[F]iles" }) - vim.keymap.set("n", "fg", Snacks.picker.grep, { desc = "[G]rep all" }) - vim.keymap.set("n", "fh", Snacks.picker.help, { desc = "[H]elp" }) - vim.keymap.set("n", "fi", Snacks.picker.icons, { desc = "[I]cons" }) - vim.keymap.set("n", "fm", Snacks.picker.marks, { desc = "[M]arks" }) - vim.keymap.set("n", "fs", Snacks.picker.spelling, { desc = "[S]pelling" }) - vim.keymap.set("n", "ft", Snacks.picker.treesitter, { desc = "[T]reesitter" }) - vim.keymap.set("n", "fu", Snacks.picker.undo, { desc = "[U]ndo" }) - vim.keymap.set("n", "fz", Snacks.picker.zoxide, { desc = "[Z]oxide" }) - - -- picker git keybinds - vim.keymap.set("n", "gB", Snacks.git.blame_line, { desc = "[G]it [B]lame" }) - vim.keymap.set("n", "gb", Snacks.picker.git_branches, { desc = "[G]it [B]ranch" }) - vim.keymap.set("n", "gl", Snacks.picker.git_log, { desc = "[G]it [L]og" }) - vim.keymap.set("n", "gd", Snacks.picker.git_diff, { desc = "[G]it [D]iff" }) - vim.keymap.set("n", "gt", Snacks.lazygit.open, { desc = "lazy[G]it [T]UI" }) - - -- setup toggles - Snacks.toggle.option("spell", { name = "spelling" }):map("cs") - Snacks.toggle.option("relativenumber", { name = "Relative Numbering" }):map("n") - Snacks.toggle.dim():map("d") - - -- terminal keybinds - vim.keymap.set("n", "s", function() - Snacks.terminal.toggle(nil, { win = { position = "float" } }) - end, { desc = "terminal" }) - - vim.keymap.set("t", "", function(self) - self.esc_timer = self.esc_timer or (vim.uv or vim.loop).new_timer() - if self.esc_timer:is_active() then - self.esc_timer:stop() - vim.cmd("stopinsert") - else - self.esc_timer:start(200, 0, function() end) - return "" - end - end, { expr = true, desc = "Double tap to escape terminal" }) - - -- setup rename autocmds - local prev = { new_name = "", old_name = "" } -- Prevents duplicate events - vim.api.nvim_create_autocmd("User", { - pattern = "OilActionsPost", - callback = function(event) - if event.data.actions.type == "move" then - Snacks.rename.on_rename_file(event.data.actions.src_url, event.data.actions.dest_url) - end - end, - }) -end - -require('lze').load { - { import = "myLuaConf.plugins.treesitter", }, - { import = "myLuaConf.plugins.completion", }, - { import = "myLuaConf.plugins.gitsigns", }, - { import = "myLuaConf.plugins.lualine", }, - { import = "myLuaConf.plugins.which-key", }, - { - "markdown-preview.nvim", - -- NOTE: for_cat is a custom handler that just sets enabled value for us, - -- based on result of nixCats('cat.name') and allows us to set a different default if we wish - -- it is defined in luaUtils template in lua/nixCatsUtils/lzUtils.lua - -- you could replace this with enabled = nixCats('cat.name') == true - -- if you didnt care to set a different default for when not using nix than the default you already set - for_cat = 'markdown', - cmd = { "MarkdownPreview", "MarkdownPreviewStop", "MarkdownPreviewToggle", }, - ft = "markdown", - keys = { - { "pmp", "MarkdownPreview ", mode = { "n" }, noremap = true, desc = "markdown preview" }, - { "pms", "MarkdownPreviewStop ", mode = { "n" }, noremap = true, desc = "markdown preview stop" }, - { "pmt", "MarkdownPreviewToggle ", mode = { "n" }, noremap = true, desc = "markdown preview toggle" }, - }, - before = function() - vim.g.mkdp_auto_close = 0 - end, - }, - { - "typst-preview.nvim", - for_cat = "lsp.typst", - ft = "typst", - cmd = { "TypstPreview", "TypstPreviewStop", "TypstPreviewToggle", }, - keys = { - { "ptp", "TypstPreview ", mode = { "n" }, noremap = true, desc = "typst preview" }, - { "pts", "TypstPreviewStop ", mode = { "n" }, noremap = true, desc = "typst preview stop" }, - { "ptt", "TypstPreviewToggle ", mode = { "n" }, noremap = true, desc = "typst preview toggle" }, - }, - after = function() - require('typst-preview').setup {} - end - }, - { - "leap.nvim", - for_cat = 'always', - event = "DeferredUIEnter", - keys = { - { "s", "(leap)", mode = { "n", "x", "o", "v" }, noremap = true, desc = "leap to char sequence" } - }, - }, - { - "nvim-surround", - for_cat = 'always', - event = "DeferredUIEnter", - after = function() - require('nvim-surround').setup() - end, - }, - { - "marks.nvim", - for_cat = "always", - after = function() - require('marks').setup({}) - end - }, - { - "venn.nvim", - for_cat = "always", - keys = { - { "v", function() Toggle_venn() end, desc = "toggle diagram drawing" } - }, - before = function() - -- venn.nvim: enable or disable keymappings - function _G.Toggle_venn() - local venn_enabled = vim.inspect(vim.b.venn_enabled) - if venn_enabled == "nil" then - vim.b.venn_enabled = true - vim.o.virtualedit = "all" - -- draw a line on HJKL keystokes - vim.api.nvim_buf_set_keymap(0, "n", "J", "j:VBox", { noremap = true }) - vim.api.nvim_buf_set_keymap(0, "n", "K", "k:VBox", { noremap = true }) - vim.api.nvim_buf_set_keymap(0, "n", "L", "l:VBox", { noremap = true }) - vim.api.nvim_buf_set_keymap(0, "n", "H", "h:VBox", { noremap = true }) - -- draw a box by pressing "f" with visual selection - vim.api.nvim_buf_set_keymap(0, "v", "f", ":VBox", { noremap = true }) - else - vim.o.virtualedit = "" - vim.api.nvim_buf_del_keymap(0, "n", "J") - vim.api.nvim_buf_del_keymap(0, "n", "K") - vim.api.nvim_buf_del_keymap(0, "n", "L") - vim.api.nvim_buf_del_keymap(0, "n", "H") - vim.api.nvim_buf_del_keymap(0, "v", "f") - vim.b.venn_enabled = nil - end - end - end - }, - { - "vim-startuptime", - for_cat = 'extra', - cmd = { "StartupTime" }, - before = function(_) - vim.g.startuptime_event_width = 0 - vim.g.startuptime_tries = 10 - vim.g.startuptime_exe_path = nixCats.packageBinPath - end, - } -} diff --git a/lua/myLuaConf/plugins/lualine.lua b/lua/myLuaConf/plugins/lualine.lua deleted file mode 100644 index 2a97b3a..0000000 --- a/lua/myLuaConf/plugins/lualine.lua +++ /dev/null @@ -1,43 +0,0 @@ -return { - "lualine.nvim", - for_cat = 'always', - -- cmd = { "" }, - event = "DeferredUIEnter", - -- ft = "", - -- keys = "", - -- colorscheme = "", - after = function() - require('lualine').setup({ - options = { - alwaysDivideMiddle = true, - icons_enabled = true, - component_separators = { left = '', right = '' }, - section_separators = { left = '', right = '' }, - }, - inactive_sections = { - lualine_a = {}, - lualine_b = {}, - lualine_c = { "filename" }, - lualine_x = { "filetype" }, - lualine_y = {}, - lualine_z = {}, - }, - sections = { - lualine_a = { "mode" }, - lualine_b = { "branch", "diff", "diagnostics" }, - lualine_c = { { "filename", path = 1 } }, - lualine_x = { "encoding", "fileformat", "filetype" }, - lualine_y = { "progress" }, - lualine_z = { "location" }, - }, - tabline = { - lualine_a = { { "buffers", mode = 4 } }, - lualine_b = {}, - lualine_c = {}, - lualine_x = {}, - lualine_y = {}, - lualine_z = { { "tabs", mode = 2 } } - }, - }) - end, - } diff --git a/lua/myLuaConf/plugins/treesitter.lua b/lua/myLuaConf/plugins/treesitter.lua deleted file mode 100644 index ed8e56f..0000000 --- a/lua/myLuaConf/plugins/treesitter.lua +++ /dev/null @@ -1,42 +0,0 @@ --- [[ Configure Treesitter ]] --- See `:help nvim-treesitter` -return { - { - "nvim-treesitter", - for_cat = 'treesitter', - -- cmd = { "" }, - event = "DeferredUIEnter", - -- ft = "", - -- keys = "", - -- colorscheme = "", - load = function(name) - vim.cmd.packadd(name) - vim.cmd.packadd("rainbow-delimiters.nvim") - end, - after = function(plugin) - -- [[ Configure Treesitter ]] - -- See `:help nvim-treesitter` - require('nvim-treesitter').setup { - highlight = { enable = true, }, - indent = { enable = false, }, - } - end, - }, - { - "comment.nvim", - for_cat = 'treesitter', - after = function(plugin) - require('Comment').setup() - end, - }, - { - "treesj", - for_cat = 'treesitter', - keys = { { "j", "TSJToggle", mode = { "n" }, desc = "Treesitter join" }, }, - after = function(_) - require("treesj").setup({ - use_default_keymaps = false - }) - end - }, -} diff --git a/lua/myLuaConf/plugins/which-key.lua b/lua/myLuaConf/plugins/which-key.lua deleted file mode 100644 index 55b73ab..0000000 --- a/lua/myLuaConf/plugins/which-key.lua +++ /dev/null @@ -1,21 +0,0 @@ -return { - "which-key.nvim", - for_cat = 'always', - after = function() - require('which-key').setup({ - }) - require('which-key').add { - { "g", group = "[g]it" }, - { "z", group = "[z]ettelkasten" }, - { "gt", group = "[t]oggle" }, - { "p", group = "[p]review" }, - { "pt", group = "[p]review [t]ypst" }, - { "pm", group = "[p]review [m]arkdown" }, - { "f", group = "[f]ind" }, - { "t", group = "[t]ree" }, - { "c", group = "[c]heck" }, - { "l", group = "[l]sp" }, - { "lw", group = "[l]sp [w]orkspace" }, - } - end, -} diff --git a/lua/nixCatsUtils/catPacker.lua b/lua/nixCatsUtils/catPacker.lua deleted file mode 100644 index 4cfe835..0000000 --- a/lua/nixCatsUtils/catPacker.lua +++ /dev/null @@ -1,40 +0,0 @@ ---[[ - This directory is the luaUtils template. - You can choose what things from it that you would like to use. - And then delete the rest. - Everything in this directory is optional. ---]] - -local M = {} --- NOTE: This function is for defining a paq.nvim fallback method of downloading plugins --- when nixCats was not used to install your config. --- If you only ever load your config using nixCats, you don't need this file. - --- it literally just only runs it when not on nixCats --- all neovim package managers that use the regular plugin loading scheme --- can be used this way, just do whatever the plugin manager needs to put it in the --- opt directory for lazy loading, and add the build steps so that when theres no nix the steps are ran -function M.setup(v) - if not vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] then - local function clone_paq() - local path = vim.fn.stdpath("data") .. "/site/pack/paqs/start/paq-nvim" - local is_installed = vim.fn.empty(vim.fn.glob(path)) == 0 - if not is_installed then - vim.fn.system { "git", "clone", "--depth=1", "https://github.com/savq/paq-nvim.git", path } - return true - end - end - local function bootstrap_paq(packages) - local first_install = clone_paq() - vim.cmd.packadd("paq-nvim") - local paq = require("paq") - if first_install then - vim.notify("Installing plugins... If prompted, hit Enter to continue.") - end - paq(packages) - paq.install() - end - bootstrap_paq(vim.list_extend({"savq/paq-nvim"},v)) - end -end -return M diff --git a/lua/nixCatsUtils/init.lua b/lua/nixCatsUtils/init.lua deleted file mode 100644 index b6a6128..0000000 --- a/lua/nixCatsUtils/init.lua +++ /dev/null @@ -1,129 +0,0 @@ ---[[ - This directory is the luaUtils template. - You can choose what things from it that you would like to use. - And then delete the rest. - Everything in this directory is optional. ---]] - -local M = {} - ---[[ - This file is for making your config still work WITHOUT nixCats. - When you don't use nixCats to load your config, - you wont have the nixCats plugin. - - The setup function defined here defines a mock nixCats plugin when nixCats wasnt used to load the config. - This will help avoid indexing errors when the nixCats plugin doesnt exist. - - NOTE: If you only ever use nixCats to load your config, you don't need this file. ---]] - ----@type boolean -M.isNixCats = vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] ~= nil - ----@class nixCatsSetupOpts ----@field non_nix_value boolean|nil - ----This function will setup a mock nixCats plugin when not using nix ----It will help prevent you from running into indexing errors without a nixCats plugin from nix. ----If you loaded the config via nix, it does nothing ----non_nix_value defaults to true if not provided or is not a boolean. ----@param v nixCatsSetupOpts -function M.setup(v) - if not M.isNixCats then - local nixCats_default_value - if type(v) == "table" and type(v.non_nix_value) == "boolean" then - nixCats_default_value = v.non_nix_value - else - nixCats_default_value = true - end - local mk_with_meta = function (tbl) - return setmetatable(tbl, { - __call = function(_, attrpath) - local strtable = {} - if type(attrpath) == "table" then - strtable = attrpath - elseif type(attrpath) == "string" then - for key in attrpath:gmatch("([^%.]+)") do - table.insert(strtable, key) - end - else - print("function requires a table of strings or a dot separated string") - return - end - return vim.tbl_get(tbl, unpack(strtable)); - end - }) - end - package.preload['nixCats'] = function () - local ncsub = { - get = function(_) return nixCats_default_value end, - cats = mk_with_meta({ - nixCats_config_location = vim.fn.stdpath('config'), - wrapRc = false, - }), - settings = mk_with_meta({ - nixCats_config_location = vim.fn.stdpath('config'), - configDirName = os.getenv("NVIM_APPNAME") or "nvim", - wrapRc = false, - }), - petShop = mk_with_meta({}), - extra = mk_with_meta({}), - pawsible = mk_with_meta({ - allPlugins = { - start = {}, - opt = {}, - }, - }), - configDir = vim.fn.stdpath('config'), - packageBinPath = os.getenv('NVIM_WRAPPER_PATH_NIX') or vim.v.progpath - } - return setmetatable(ncsub, {__call = function(_, cat) return ncsub.get(cat) end}) - end - _G.nixCats = require('nixCats') - end -end - ----allows you to guarantee a boolean is returned, and also declare a different ----default value than specified in setup when not using nix to load the config ----@overload fun(v: string|string[]): boolean ----@overload fun(v: string|string[], default: boolean): boolean -function M.enableForCategory(v, default) - if M.isNixCats or default == nil then - if nixCats(v) then - return true - else - return false - end - else - return default - end -end - ----if nix, return value of nixCats(v) else return default ----Exists to specify a different non_nix_value than the one in setup() ----@param v string|string[] ----@param default any ----@return any -function M.getCatOrDefault(v, default) - if M.isNixCats then - return nixCats(v) - else - return default - end -end - ----for conditionally disabling build steps on nix, as they are done via nix ----I should probably have named it dontAddIfCats or something. ----@overload fun(v: any): any|nil ----Will return the second value if nix, otherwise the first ----@overload fun(v: any, o: any): any -function M.lazyAdd(v, o) - if M.isNixCats then - return o - else - return v - end -end - -return M diff --git a/lua/nixCatsUtils/lzUtils.lua b/lua/nixCatsUtils/lzUtils.lua deleted file mode 100644 index 2e2393d..0000000 --- a/lua/nixCatsUtils/lzUtils.lua +++ /dev/null @@ -1,36 +0,0 @@ ---[[ - This directory is the luaUtils template. - You can choose what things from it that you would like to use. - And then delete the rest. - Everything in this directory is optional. ---]] - -local M = {} --- A nixCats specific lze handler that you can use to conditionally enable by category easier. --- at the start of your config, register with --- require('lze').register_handlers(require('nixCatsUtils.lzUtils').for_cat) --- before any calls to require('lze').load using the handler have been made. --- accepts: --- for_cat = { "your" "cat" }; --- for_cat = { cat = { "your" "cat" }, default = bool } --- for_cat = "your.cat"; --- for_cat = { cat = "your.cat", default = bool } --- where default is an alternate value for when nixCats was NOT used to install the config -M.for_cat = { - spec_field = "for_cat", - set_lazy = false, - modify = function(plugin) - if type(plugin.for_cat) == "table" and plugin.for_cat.cat ~= nil then - if vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] ~= nil then - plugin.enabled = nixCats(plugin.for_cat.cat) or false - else - plugin.enabled = plugin.for_cat.default - end - else - plugin.enabled = nixCats(plugin.for_cat) or false - end - return plugin - end, -} - -return M diff --git a/lua/myLuaConf/opts_and_keys.lua b/lua/opts.lua similarity index 63% rename from lua/myLuaConf/opts_and_keys.lua rename to lua/opts.lua index 7e75433..92a89ea 100644 --- a/lua/myLuaConf/opts_and_keys.lua +++ b/lua/opts.lua @@ -1,4 +1,4 @@ --- NOTE: These 2 need to be set up before any plugins are loaded. +-- NOTE: These 2 should be set up before any plugins with keybinds are loaded. vim.g.mapleader = ';' vim.g.maplocalleader = ';' @@ -6,9 +6,13 @@ vim.g.maplocalleader = ';' -- See `:help vim.o` -- NOTE: You can change these options as you wish! +-- allow .nvim.lua in current dir and parents (project config) +vim.o.exrc = false -- can be toggled off in that file to stop it from searching further + -- Sets how neovim will display certain whitespace characters in the editor. -- See `:help 'list'` -- and `:help 'listchars'` +-- and `:help 'showbreak'` vim.opt.list = true vim.opt.listchars = { eol = "↲", extends = "⟩", nbsp = "␣", precedes = "⟨", tab = ">-", trail = "•" } vim.opt.showbreak = "↪"; @@ -29,6 +33,7 @@ vim.opt.scrolloff = 10 -- Make line numbers default vim.opt.number = true +vim.opt.numberwidth = 3 -- Enable mouse mode vim.opt.mouse = 'a' @@ -40,10 +45,6 @@ vim.opt.wrapmargin = 0 -- get nice visual guides for 80, 100, and 120 cols. vim.opt.colorcolumn = { "90", "100", "120", } --- add line numbers -vim.opt.number = true -vim.opt.numberwidth = 3 - -- Indent vim.opt.smarttab = true vim.opt.expandtab = true @@ -95,22 +96,6 @@ vim.api.nvim_create_autocmd('TextYankPost', { vim.g.netrw_liststyle = 0 vim.g.netrw_banner = 0 --- [[ Basic Keymaps ]] --- make quick system clipboard opts easier -vim.keymap.set({ 'n', 'v', 'x' }, 'p', '"+p', { noremap = true, silent = true, desc = 'Paste from clipboard' }) -vim.keymap.set({ "v", "x", "n" }, 'y', '"+y', { noremap = true, silent = true, desc = 'Yank to clipboard' }) -vim.keymap.set({ "n", "v", "x" }, 'Y', '"+yy', { noremap = true, silent = true, desc = 'Yank line to clipboard' }) -vim.keymap.set('i', '', '+', - { noremap = true, silent = true, desc = 'Paste from clipboard from within insert mode' }) - --- Diagnostic keymaps -vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous diagnostic message' }) -vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next diagnostic message' }) -vim.keymap.set('n', 'd', vim.diagnostic.open_float, { desc = 'Open floating diagnostic message' }) - --- moving between splits -vim.keymap.set('n', '', 'h', { desc = 'move to right split' }) -vim.keymap.set('n', '', 'j', { desc = 'move to below split' }) -vim.keymap.set('n', '', 'k', { desc = 'move to above split' }) -vim.keymap.set('n', '', 'l', { desc = 'move to left split' }) +vim.g.netrw_liststyle=0 +vim.g.netrw_banner=0 diff --git a/lua/plugins.lua b/lua/plugins.lua new file mode 100644 index 0000000..611819f --- /dev/null +++ b/lua/plugins.lua @@ -0,0 +1,743 @@ +-- NOTE: You will likely want to break this up into more files. +-- You can call this more than once. +-- You can also include other files from within the specs via an `import` spec. +-- see https://github.com/BirdeeHub/lze?tab=readme-ov-file#structuring-your-plugins + +nixInfo.lze.load { + { + -- lze specs need a name + "trigger_colorscheme", + -- lazy loaded colorscheme. + -- This means you will need to add the colorscheme you want to lze sometime before VimEnter is done + event = "VimEnter", + -- Also, lze can load more than just plugins. + -- The default load field contains vim.cmd.packadd + -- Here we override it to schedule when our colorscheme is loaded + load = function(_name) + -- schedule so it runs after VimEnter + vim.schedule(function() + vim.cmd.colorscheme(nixInfo("onedark_dark", "settings", "colorscheme")) + vim.schedule(function() + -- I like this color. Use vim.schedule again to set it after the colorscheme is finished + vim.cmd([[hi LineNr guifg=#bb9af7]]) + end) + end) + end + }, + { + -- NOTE: view these names in the info plugin! + -- :lua nixInfo.lze.debug.display(nixInfo.plugins) + -- The display function is from lzextras + "onedarkpro.nvim", + auto_enable = true, -- <- auto enable is useful here + colorscheme = { "onedark", "onedark_dark", "onedark_vivid", "onelight" }, + }, + { + "vim-moonfly-colors", + auto_enable = true, + colorscheme = "moonfly", + }, + { + "snacks.nvim", + auto_enable = true, + -- snacks makes a global, and then lazily loads itself + lazy = false, + -- priority only affects startup plugins + -- unless otherwise specified by a particular handler + priority = 1000, + after = function(plugin) + -- I also like this color + vim.api.nvim_set_hl(0, "MySnacksIndent", { fg = "#32a88f" }) + require('snacks').setup({ + explorer = { replace_netrw = true, }, + picker = { + sources = { + explorer = { + auto_close = true, + }, + }, + }, + git = {}, + terminal = {}, + scope = {}, + indent = { + scope = { + hl = 'MySnacksIndent', + }, + chunk = { + -- enabled = true, + hl = 'MySnacksIndent', + } + }, + statuscolumn = { + left = { "mark", "git" }, -- priority of signs on the left (high to low) + right = { "sign", "fold" }, -- priority of signs on the right (high to low) + folds = { + open = false, -- show open fold icons + git_hl = false, -- use Git Signs hl for fold icons + }, + git = { + -- patterns to match Git signs + patterns = { "GitSign", "MiniDiffSign" }, + }, + refresh = 50, -- refresh at most every 50ms + }, + -- make sure lazygit always reopens the correct program + -- hopefully this can be removed one day + lazygit = { + config = { + os = { + editPreset = "nvim-remote", + edit = vim.v.progpath .. [=[ --server "$NVIM" --remote-send 'lua nixInfo.lazygit_fix({{filename}})']=], + editAtLine = vim.v.progpath .. [=[ --server "$NVIM" --remote-send 'lua nixInfo.lazygit_fix({{filename}}, {{line}})']=], + openDirInEditor = vim.v.progpath .. [=[ --server "$NVIM" --remote-send 'lua nixInfo.lazygit_fix({{dir}})']=], + -- this one isnt a remote command, make sure it gets our config regardless of if we name it nvim or not + editAtLineAndWait = nixInfo(vim.v.progpath, "progpath") .. " +{{line}} {{filename}}", + }, + }, + }, + }) + -- Handle the backend of those remote commands. + -- hopefully this can be removed one day + nixInfo.lazygit_fix = function(path, line) + local prev = vim.fn.bufnr("#") + local prev_win = vim.fn.bufwinid(prev) + vim.api.nvim_feedkeys("q", "n", false) + if line then + vim.api.nvim_buf_call(prev, function() + vim.cmd.edit(path) + local buf = vim.api.nvim_get_current_buf() + vim.schedule(function() + if buf then + vim.api.nvim_win_set_buf(prev_win, buf) + vim.api.nvim_win_set_cursor(0, { line or 0, 0}) + end + end) + end) + else + vim.api.nvim_buf_call(prev, function() + vim.cmd.edit(path) + local buf = vim.api.nvim_get_current_buf() + vim.schedule(function() + if buf then + vim.api.nvim_win_set_buf(prev_win, buf) + end + end) + end) + end + end + -- NOTE: we aren't loading this lazily, and the keybinds already are so it is fine to just set these here + vim.keymap.set("n", "-", function() Snacks.explorer.open() end, { desc = 'Snacks file explorer' }) + vim.keymap.set("n", "", function() Snacks.terminal.open() end, { desc = 'Snacks Terminal' }) + vim.keymap.set("n", "_", function() Snacks.lazygit.open() end, { desc = 'Snacks LazyGit' }) + vim.keymap.set('n', "sf", function() Snacks.picker.smart() end, { desc = "Smart Find Files" }) + vim.keymap.set('n', "s", function() Snacks.picker.buffers() end, { desc = "Search Buffers" }) + -- find + vim.keymap.set('n', "ff", function() Snacks.picker.files() end, { desc = "Find Files" }) + vim.keymap.set('n', "fg", function() Snacks.picker.git_files() end, { desc = "Find Git Files" }) + -- Grep + vim.keymap.set('n', "sb", function() Snacks.picker.lines() end, { desc = "Buffer Lines" }) + vim.keymap.set('n', "sB", function() Snacks.picker.grep_buffers() end, { desc = "Grep Open Buffers" }) + vim.keymap.set('n', "sg", function() Snacks.picker.grep() end, { desc = "Grep" }) + vim.keymap.set({ "n", "x" }, "sw", function() Snacks.picker.grep_word() end, { desc = "Visual selection or ord" }) + -- search + vim.keymap.set('n', "sb", function() Snacks.picker.lines() end, { desc = "Buffer Lines" }) + vim.keymap.set('n', "sd", function() Snacks.picker.diagnostics() end, { desc = "Diagnostics" }) + vim.keymap.set('n', "sD", function() Snacks.picker.diagnostics_buffer() end, { desc = "Buffer Diagnostics" }) + vim.keymap.set('n', "sh", function() Snacks.picker.help() end, { desc = "Help Pages" }) + vim.keymap.set('n', "sj", function() Snacks.picker.jumps() end, { desc = "Jumps" }) + vim.keymap.set('n', "sk", function() Snacks.picker.keymaps() end, { desc = "Keymaps" }) + vim.keymap.set('n', "sl", function() Snacks.picker.loclist() end, { desc = "Location List" }) + vim.keymap.set('n', "sm", function() Snacks.picker.marks() end, { desc = "Marks" }) + vim.keymap.set('n', "sM", function() Snacks.picker.man() end, { desc = "Man Pages" }) + vim.keymap.set('n', "sq", function() Snacks.picker.qflist() end, { desc = "Quickfix List" }) + vim.keymap.set('n', "sR", function() Snacks.picker.resume() end, { desc = "Resume" }) + vim.keymap.set('n', "su", function() Snacks.picker.undo() end, { desc = "Undo History" }) + end + }, + { + "nvim-lspconfig", + auto_enable = true, + -- NOTE: define a function for lsp, + -- and it will run for all specs with type(plugin.lsp) == table + -- when their filetype trigger loads them + lsp = function(plugin) + vim.lsp.config(plugin.name, plugin.lsp or {}) + vim.lsp.enable(plugin.name) + end, + -- set up our on_attach function once before the spec loads + before = function(_) + vim.lsp.config('*', { + on_attach = function(_, bufnr) + + -- we create a function that lets us more easily define mappings specific + -- for LSP related items. It sets the mode, buffer and description for us each time. + local nmap = function(keys, func, desc) + if desc then + desc = 'LSP: ' .. desc + end + vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc }) + end + + nmap('rn', vim.lsp.buf.rename, '[R]e[n]ame') + nmap('ca', vim.lsp.buf.code_action, '[C]ode [A]ction') + nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition') + nmap('D', vim.lsp.buf.type_definition, 'Type [D]efinition') + nmap('gr', function() Snacks.picker.lsp_references() end, '[G]oto [R]eferences') + nmap('gI', function() Snacks.picker.lsp_implementations() end, '[G]oto [I]mplementation') + nmap('ds', function() Snacks.picker.lsp_symbols() end, '[D]ocument [S]ymbols') + nmap('ws', function() Snacks.picker.lsp_workspace_symbols() end, '[W]orkspace [S]ymbols') + + -- See `:help K` for why this keymap + nmap('K', vim.lsp.buf.hover, 'Hover Documentation') + nmap('', vim.lsp.buf.signature_help, 'Signature Documentation') + + -- Lesser used LSP functionality + nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') + nmap('wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder') + nmap('wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder') + nmap('wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, '[W]orkspace [L]ist Folders') + + -- Create a command `:Format` local to the LSP buffer + vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) + vim.lsp.buf.format() + end, { desc = 'Format current buffer with LSP' }) + end + }) + end, + }, + { + "mason.nvim", + enabled = not nixInfo.isNix, + priority = 100, -- <- run lsp hook before lspconfig's hook + on_plugin = { "nvim-lspconfig" }, + lsp = function(plugin) + vim.cmd.MasonInstall(plugin.name) + end, + }, + { + -- lazydev makes your lua lsp load only the relevant definitions for a file. + -- It also gives us a nice way to correlate globals we create with files. + "lazydev.nvim", + auto_enable = true, + cmd = { "LazyDev" }, + ft = "lua", + after = function(_) + require('lazydev').setup({ + library = { + { words = { "nixInfo%.lze" }, path = nixInfo("lze", "plugins", "start", "lze") .. '/lua', }, + { words = { "nixInfo%.lze" }, path = nixInfo("lzextras", "plugins", "start", "lzextras") .. '/lua' }, + }, + }) + end, + }, + { + -- name of the lsp + "lua_ls", + for_cat = "lua", + -- provide a table containing filetypes, + -- and then whatever your functions defined in the function type specs expect. + -- in our case, it just expects the normal lspconfig setup options, + -- but with a default on_attach and capabilities + lsp = { + -- if you provide the filetypes it doesn't ask lspconfig for the filetypes + -- (meaning it doesn't call the callback function we defined in the main init.lua) + filetypes = { 'lua' }, + settings = { + Lua = { + signatureHelp = { enabled = true }, + diagnostics = { + globals = { "nixInfo", "vim", }, + disable = { 'missing-fields' }, + }, + }, + }, + }, + -- also these are regular specs and you can use before and after and all the other normal fields + }, + { + "nixd", + enabled = nixInfo.isNix, -- mason doesn't have nixd + for_cat = "nix", + lsp = { + filetypes = { "nix" }, + settings = { + nixd = { + nixpkgs = { + expr = [[import {}]], + }, + options = { + }, + formatting = { + command = { "alejandra" } + }, + diagnostic = { + suppress = { + "sema-escaping-with" + } + } + } + }, + }, + }, + { + "nvim-treesitter", + lazy = false, + auto_enable = true, + after = function(plugin) + ---@param buf integer + ---@param language string + local function treesitter_try_attach(buf, language) + -- check if parser exists and load it + if not vim.treesitter.language.add(language) then + return false + end + -- enables syntax highlighting and other treesitter features + vim.treesitter.start(buf, language) + + -- enables treesitter based folds + vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()" + vim.wo.foldmethod = "expr" + -- ensure folds are open to begin with + vim.o.foldlevel = 99 + + -- enables treesitter based indentation + vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" + + return true + end + + local installable_parsers = require("nvim-treesitter").get_available() + vim.api.nvim_create_autocmd("FileType", { + callback = function(args) + local buf, filetype = args.buf, args.match + local language = vim.treesitter.language.get_lang(filetype) + if not language then + return + end + + if not treesitter_try_attach(buf,language) then + if vim.tbl_contains(installable_parsers, language) then + -- not already installed, so try to install them via nvim-treesitter if possible + require("nvim-treesitter").install(language):await(function() + treesitter_try_attach(buf, language) + end) + end + end + end, + }) + end, + }, + { + "nvim-treesitter-textobjects", + auto_enable = true, + lazy = false, + before = function(plugin) + -- https://github.com/nvim-treesitter/nvim-treesitter-textobjects/tree/main?tab=readme-ov-file#using-a-package-manager + -- Disable entire built-in ftplugin mappings to avoid conflicts. + -- See https://github.com/neovim/neovim/tree/master/runtime/ftplugin for built-in ftplugins. + vim.g.no_plugin_maps = true + + -- Or, disable per filetype (add as you like) + -- vim.g.no_python_maps = true + -- vim.g.no_ruby_maps = true + -- vim.g.no_rust_maps = true + -- vim.g.no_go_maps = true + end, + after = function(plugin) + require("nvim-treesitter-textobjects").setup { + select = { + -- Automatically jump forward to textobj, similar to targets.vim + lookahead = true, + -- You can choose the select mode (default is charwise 'v') + -- + -- Can also be a function which gets passed a table with the keys + -- * query_string: eg '@function.inner' + -- * method: eg 'v' or 'o' + -- and should return the mode ('v', 'V', or '') or a table + -- mapping query_strings to modes. + selection_modes = { + ['@parameter.outer'] = 'v', -- charwise + ['@function.outer'] = 'V', -- linewise + -- ['@class.outer'] = '', -- blockwise + }, + -- If you set this to `true` (default is `false`) then any textobject is + -- extended to include preceding or succeeding whitespace. Succeeding + -- whitespace has priority in order to act similarly to eg the built-in + -- `ap`. + -- + -- Can also be a function which gets passed a table with the keys + -- * query_string: eg '@function.inner' + -- * selection_mode: eg 'v' + -- and should return true of false + include_surrounding_whitespace = false, + }, + } + + -- keymaps + -- You can use the capture groups defined in `textobjects.scm` + vim.keymap.set({ "x", "o" }, "am", function() + require "nvim-treesitter-textobjects.select".select_textobject("@function.outer", "textobjects") + end) + vim.keymap.set({ "x", "o" }, "im", function() + require "nvim-treesitter-textobjects.select".select_textobject("@function.inner", "textobjects") + end) + vim.keymap.set({ "x", "o" }, "ac", function() + require "nvim-treesitter-textobjects.select".select_textobject("@class.outer", "textobjects") + end) + vim.keymap.set({ "x", "o" }, "ic", function() + require "nvim-treesitter-textobjects.select".select_textobject("@class.inner", "textobjects") + end) + -- You can also use captures from other query groups like `locals.scm` + vim.keymap.set({ "x", "o" }, "as", function() + require "nvim-treesitter-textobjects.select".select_textobject("@local.scope", "locals") + end) + + -- NOTE: for more textobjects options, see the following link. + -- This template is using the new `main` branch of the repo. + -- https://github.com/nvim-treesitter/nvim-treesitter-textobjects/tree/main + end, + }, + { + "conform.nvim", + auto_enable = true, + -- cmd = { "" }, + -- event = "", + -- ft = "", + keys = { + { "FF", desc = "[F]ormat [F]ile" }, + }, + -- colorscheme = "", + after = function (plugin) + local conform = require("conform") + + conform.setup({ + formatters_by_ft = { + -- NOTE: download some formatters + -- and configure them here + lua = nixInfo(nil, "settings", "cats", "lua") and { "stylua" } or nil, + -- go = { "gofmt", "golint" }, + -- templ = { "templ" }, + -- Conform will run multiple formatters sequentially + -- python = { "isort", "black" }, + -- Use a sub-list to run only the first available formatter + -- javascript = { { "prettierd", "prettier" } }, + }, + }) + + vim.keymap.set({ "n", "v" }, "FF", function() + conform.format({ + lsp_fallback = true, + async = false, + timeout_ms = 1000, + }) + end, { desc = "[F]ormat [F]ile" }) + end, + }, + { + "nvim-lint", + auto_enable = true, + -- cmd = { "" }, + event = "FileType", + -- ft = "", + -- keys = "", + -- colorscheme = "", + after = function (plugin) + require('lint').linters_by_ft = { + -- NOTE: download some linters + -- and configure them here + -- markdown = {'vale',}, + -- javascript = { 'eslint' }, + -- typescript = { 'eslint' }, + } + + vim.api.nvim_create_autocmd({ "BufWritePost" }, { + callback = function() + require("lint").try_lint() + end, + }) + end, + }, + { + "cmp-cmdline", + auto_enable = true, + on_plugin = { "blink.cmp" }, + load = nixInfo.lze.loaders.with_after, + }, + { + "blink.compat", + auto_enable = true, + dep_of = { "cmp-cmdline" }, + }, + { + "colorful-menu.nvim", + auto_enable = true, + on_plugin = { "blink.cmp" }, + }, + { + "blink.cmp", + auto_enable = true, + event = "DeferredUIEnter", + after = function (_) + require("blink.cmp").setup({ + -- 'default' (recommended) for mappings similar to built-in completions (C-y to accept) + -- See :h blink-cmp-config-keymap for configuring keymaps + keymap = { + preset = 'default', + }, + cmdline = { + enabled = true, + completion = { + menu = { + auto_show = true, + }, + }, + sources = function() + local type = vim.fn.getcmdtype() + -- Search forward and backward + if type == '/' or type == '?' then return { 'buffer' } end + -- Commands + if type == ':' or type == '@' then return { 'cmdline', 'cmp_cmdline' } end + return {} + end, + }, + fuzzy = { + sorts = { + 'exact', + -- defaults + 'score', + 'sort_text', + }, + }, + signature = { + enabled = true, + window = { + show_documentation = true, + }, + }, + completion = { + menu = { + draw = { + treesitter = { 'lsp' }, + components = { + label = { + text = function(ctx) + return require("colorful-menu").blink_components_text(ctx) + end, + highlight = function(ctx) + return require("colorful-menu").blink_components_highlight(ctx) + end, + }, + }, + }, + }, + documentation = { + auto_show = true, + }, + }, + sources = { + default = { 'lsp', 'path', 'buffer', 'omni' }, + providers = { + path = { + score_offset = 50, + }, + lsp = { + score_offset = 40, + }, + cmp_cmdline = { + name = 'cmp_cmdline', + module = 'blink.compat.source', + score_offset = -100, + opts = { + cmp_name = 'cmdline', + }, + }, + }, + }, + }) + end, + }, + { + "nvim-surround", + auto_enable = true, + event = "DeferredUIEnter", + -- keys = "", + after = function(plugin) + require('nvim-surround').setup() + end, + }, + { + "vim-startuptime", + auto_enable = true, + cmd = { "StartupTime" }, + before = function(_) + vim.g.startuptime_event_width = 0 + vim.g.startuptime_tries = 10 + vim.g.startuptime_exe_path = nixInfo(vim.v.progpath, "progpath") + end, + }, + { + "fidget.nvim", + auto_enable = true, + event = "DeferredUIEnter", + -- keys = "", + after = function(plugin) + require('fidget').setup({}) + end, + }, + { + "lualine.nvim", + auto_enable = true, + -- cmd = { "" }, + event = "DeferredUIEnter", + -- ft = "", + -- keys = "", + -- colorscheme = "", + after = function (plugin) + require('lualine').setup({ + options = { + icons_enabled = false, + theme = nixInfo("onedark_dark", "settings", "colorscheme"), + component_separators = '|', + section_separators = '', + }, + sections = { + lualine_c = { + { 'filename', path = 1, status = true, }, + }, + }, + inactive_sections = { + lualine_b = { + { 'filename', path = 3, status = true, }, + }, + lualine_x = {'filetype'}, + }, + tabline = { + lualine_a = { 'buffers' }, + -- if you use lualine-lsp-progress, I have mine here instead of fidget + -- lualine_b = { 'lsp_progress', }, + lualine_z = { 'tabs' } + }, + }) + end, + }, + { + "gitsigns.nvim", + auto_enable = true, + event = "DeferredUIEnter", + -- cmd = { "" }, + -- ft = "", + -- keys = "", + -- colorscheme = "", + after = function (plugin) + require('gitsigns').setup({ + -- See `:help gitsigns.txt` + signs = { + add = { text = '+' }, + change = { text = '~' }, + delete = { text = '_' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + }, + on_attach = function(bufnr) + local gs = package.loaded.gitsigns + + local function map(mode, l, r, opts) + opts = opts or {} + opts.buffer = bufnr + vim.keymap.set(mode, l, r, opts) + end + + -- Navigation + map({ 'n', 'v' }, ']c', function() + if vim.wo.diff then + return ']c' + end + vim.schedule(function() + gs.next_hunk() + end) + return '' + end, { expr = true, desc = 'Jump to next hunk' }) + + map({ 'n', 'v' }, '[c', function() + if vim.wo.diff then + return '[c' + end + vim.schedule(function() + gs.prev_hunk() + end) + return '' + end, { expr = true, desc = 'Jump to previous hunk' }) + + -- Actions + -- visual mode + map('v', 'hs', function() + gs.stage_hunk { vim.fn.line '.', vim.fn.line 'v' } + end, { desc = 'stage git hunk' }) + map('v', 'hr', function() + gs.reset_hunk { vim.fn.line '.', vim.fn.line 'v' } + end, { desc = 'reset git hunk' }) + -- normal mode + map('n', 'gs', gs.stage_hunk, { desc = 'git stage hunk' }) + map('n', 'gr', gs.reset_hunk, { desc = 'git reset hunk' }) + map('n', 'gS', gs.stage_buffer, { desc = 'git Stage buffer' }) + map('n', 'gu', gs.undo_stage_hunk, { desc = 'undo stage hunk' }) + map('n', 'gR', gs.reset_buffer, { desc = 'git Reset buffer' }) + map('n', 'gp', gs.preview_hunk, { desc = 'preview git hunk' }) + map('n', 'gb', function() + gs.blame_line { full = false } + end, { desc = 'git blame line' }) + map('n', 'gd', gs.diffthis, { desc = 'git diff against index' }) + map('n', 'gD', function() + gs.diffthis '~' + end, { desc = 'git diff against last commit' }) + + -- Toggles + map('n', 'gtb', gs.toggle_current_line_blame, { desc = 'toggle git blame line' }) + map('n', 'gtd', gs.toggle_deleted, { desc = 'toggle git show deleted' }) + + -- Text object + map({ 'o', 'x' }, 'ih', ':Gitsigns select_hunk', { desc = 'select git hunk' }) + end, + }) + vim.cmd([[hi GitSignsAdd guifg=#04de21]]) + vim.cmd([[hi GitSignsChange guifg=#83fce6]]) + vim.cmd([[hi GitSignsDelete guifg=#fa2525]]) + end, + }, + { + "which-key.nvim", + auto_enable = true, + -- cmd = { "" }, + event = "DeferredUIEnter", + -- ft = "", + -- keys = "", + -- colorscheme = "", + after = function (plugin) + require('which-key').setup({ + }) + require('which-key').add { + { "", group = "buffer commands" }, + { "_", hidden = true }, + { "c", group = "[c]ode" }, + { "c_", hidden = true }, + { "d", group = "[d]ocument" }, + { "d_", hidden = true }, + { "g", group = "[g]it" }, + { "g_", hidden = true }, + { "m", group = "[m]arkdown" }, + { "m_", hidden = true }, + { "r", group = "[r]ename" }, + { "r_", hidden = true }, + { "s", group = "[s]earch" }, + { "s_", hidden = true }, + { "t", group = "[t]oggles" }, + { "t_", hidden = true }, + { "w", group = "[w]orkspace" }, + { "w_", hidden = true }, + } + end, + }, +} diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..825101d --- /dev/null +++ b/module.nix @@ -0,0 +1,284 @@ +inputs: { + config, + wlib, + lib, + pkgs, + ... +}: { + imports = [wlib.wrapperModules.neovim]; + # NOTE: see the tips and tricks section or the bottom of this file + flake inputs to understand this value + options.nvim-lib.neovimPlugins = lib.mkOption { + readOnly = true; + type = lib.types.attrsOf wlib.types.stringable; + # Makes plugins autobuilt from our inputs available with + # `config.nvim-lib.neovimPlugins.` + default = config.nvim-lib.pluginsFromPrefix "plugins-" inputs; + }; + + # choose a directory for your config. + config.settings.config_directory = ./.; + # you can also use an impure path! + # config.settings.config_directory = lib.generators.mkLuaInline "vim.fn.stdpath('config')"; + # config.settings.config_directory = "/home//.config/nvim"; + # If you do that, it will not be provisioned by nix, but it will have normal reload for quick edits! + + # If you want to install multiple neovim derivations via home.packages or environment.systemPackages + # in order to prevent path collisions: + + # set this to true: + # config.settings.dont_link = true; + + # and make sure these dont share values: + # config.binName = "nvim"; + # config.settings.aliases = [ ]; + + # To add a wrapped $out/bin/${config.binName}-neovide to the resulting neovim derivation + # config.hosts.neovide.nvim-host.enable = true; + + # You can declare your own options! + options.settings.colorscheme = lib.mkOption { + type = lib.types.str; + default = "onedark_dark"; + }; + options.settings.minimal = lib.mkOption { + type = lib.types.bool; + default = false; + }; + config.settings.colorscheme = "gruvbox"; # <- just demonstrating that it is an option + # and grab it in lua with `require(vim.g.nix_info_plugin_name)("onedark", "settings", "colorscheme") == "moonfly"` + config.specs.colorscheme = { + lazy = true; + enable = lib.mkIf config.settings.minimal (lib.mkDefault true); + data = builtins.getAttr config.settings.colorscheme ( + with pkgs.vimPlugins; { + "onedark_dark" = onedarkpro-nvim; + "onedark_vivid" = onedarkpro-nvim; + "onedark" = onedarkpro-nvim; + "onelight" = onedarkpro-nvim; + "moonfly" = vim-moonfly-colors; + "catppuccin" = catppuccin-nvim; + "tokyonight" = tokyonight-nvim; + "nord" = nord-nvim; + "gruvbox" = gruvbox-nvim; + } + ); + }; + config.specs.lze = { + enable = lib.mkIf config.settings.minimal (lib.mkDefault true); + data = [ + config.nvim-lib.neovimPlugins.lze + config.nvim-lib.neovimPlugins.lzextras + ]; + }; + + config.specs.general = { + # this would ensure any config included from nix in here will be ran after any provided by the `lze` spec + # If we provided any from within either spec, anyway + after = ["lze"]; + enable = lib.mkIf config.settings.minimal (lib.mkDefault true); + extraPackages = with pkgs; [ + ripgrep + fd + fzf + zoxide + git + lazygit + tree-sitter + ]; + # here we chose a DAL of plugins, but we can also pass a single plugin, or null + data = with pkgs.vimPlugins; [ + snacks-nvim + lualine-nvim + plenary-nvim + oil-nvim + nvim-web-devicons + nvim-numbertoggle + lualine-nvim + marks-nvim + ]; + }; + config.specs.lazy = { + after = ["lze"]; + enable = lib.mkIf config.settings.minimal (lib.mkDefault true); + lazy = true; + data = with pkgs.vimPlugins; [ + gitsigns-nvim + nvim-surround + treesj + which-key-nvim + todo-comments-nvim + comment-nvim + rainbow-delimiters-nvim + nvim-treesitter.withAllGrammars + ]; + }; + config.specs.completion = { + after = ["lze"]; + lazy = true; + enable = lib.mkIf config.settings.minimal false; + data = with pkgs.vimPlugins; [ + luasnip + friendly-snippets + cmp-cmdline + blink-cmp + blink-emoji-nvim + blink-compat + colorful-menu-nvim + ]; + }; + + config.specs.markdown = { + after = ["general" "lazy"]; + enable = lib.mkIf config.settings.minimal false; + lazy = true; + data = with pkgs.vimPlugins; [ + markdown-preview-nvim + ]; + extraPackages = with pkgs; [ + mermaid-cli + imagemagick + texliveSmall + ]; + }; + + config.specs.lsp = { + enable = lib.mkIf config.settings.minimal false; + after = ["general" "lazy"]; + lazy = true; + + data = with pkgs.vimPlugins; [ + trouble-nvim + lualine-lsp-progress + nvim-lspconfig + ]; + }; + + config.specs.zk = { + after = ["general" "lazy"]; + data = with pkgs.vimPlugins; [ + zk-nvim + ]; + extraPackages = with pkgs; [ + zk + ]; + }; + + config.specs.typst = { + name = "typst"; + after = ["general" "lazy"]; + data = with pkgs.vimPlugins; [ + typst-preview-nvim + ]; + extraPackages = with pkgs; [ + typst + tinymist + ]; + }; + + config.specs.nix = { + name = "nix"; + after = ["general" "lazy"]; + data = null; + extraPackages = with pkgs; [ + nixd + alejandra + ]; + }; + + config.specs.lua = { + name = "lua"; + after = ["general" "lazy"]; + data = with pkgs.vimPlugins; [ + lazydev-nvim + ]; + extraPackages = with pkgs; [ + lua-language-server + stylua + ]; + }; + + config.specs.rust = { + name = "rust"; + after = ["general" "lazy"]; + data = with pkgs.vimPlugins; [ + rustaceanvim + ]; + extraPackages = with pkgs; [ + rust-analyzer + cargo + ]; + }; + + config.specs.python = { + name = "python"; + after = ["general" "lazy"]; + data = null; + extraPackages = with pkgs; [ + ty + ruff + ]; + }; + + config.specs.C = { + name = "C"; + after = ["general" "lazy"]; + data = null; + extraPackages = with pkgs; [ + libclang + ]; + }; + + config.specs.bash = { + name = "bash"; + after = ["general" "lazy"]; + lazy = true; + data = null; + extraPackages = with pkgs; [ + shellcheck + bash-language-server + ]; + }; + + config.specMods = lib.mkMerge [ + { + options.extraPackages = lib.mkOption { + type = lib.types.listOf wlib.types.stringable; + default = []; + description = "a extraPackages spec field to put packages to suffix to the PATH"; + }; + } + # Makes enable be false by default if minimal is set. + (lib.mkIf config.settings.minimal ( + {parentSpec, ...}: { + config.enable = lib.mkOverride 1400 (parentSpec.enable or false); # 1400 is 100 higher than mkOptionDefault (1500) + } + )) + ]; + + config.extraPackages = config.specCollect (acc: v: acc ++ (v.extraPackages or [])) []; + # Inform our lua of which top level specs are enabled + options.settings.cats = lib.mkOption { + readOnly = true; + type = lib.types.attrsOf lib.types.bool; + default = builtins.mapAttrs (_: v: v.enable) config.specs; + }; + # build plugins from inputs set + options.nvim-lib.pluginsFromPrefix = lib.mkOption { + type = lib.types.raw; + readOnly = true; + default = prefix: inputs: + lib.pipe inputs [ + builtins.attrNames + (builtins.filter (s: lib.hasPrefix prefix s)) + (map ( + input: let + name = lib.removePrefix prefix input; + in { + inherit name; + value = config.nvim-lib.mkPlugin name inputs.${input}; + } + )) + builtins.listToAttrs + ]; + }; +}