diff --git a/README.md b/README.md index 68ec53a..721c82f 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,4 @@ -# Neovim module +# Gabes `nixCats` Configuration -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. +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. diff --git a/flake.lock b/flake.lock index e934dd7..6905646 100644 --- a/flake.lock +++ b/flake.lock @@ -1,79 +1,40 @@ { "nodes": { - "nixpkgs": { + "nixCats": { "locked": { - "lastModified": 1772674223, - "narHash": "sha256-/suKbHSaSmuC9UY7G0VRQ3aO+QKqxAQPQ19wG7QNkF8=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "66d9241e3dc2296726dc522e62dbfe89c7b449f3", + "lastModified": 1769578476, + "narHash": "sha256-4+KbiBcC6hQ3sh0UbPXjy6TOfLh9yhskRlfPzyZ2FH4=", + "owner": "BirdeeHub", + "repo": "nixCats-nvim", + "rev": "48f8be4bdafccfa19ceaaf08071a15eca36fdb1d", "type": "github" }, "original": { - "owner": "NixOS", + "owner": "BirdeeHub", + "repo": "nixCats-nvim", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1770141374, + "narHash": "sha256-yD4K/vRHPwXbJf5CK3JkptBA6nFWUKNX/jlFp2eKEQc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "41965737c1797c1d83cfb0b644ed0840a6220bd1", + "type": "github" + }, + "original": { + "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": { - "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" + "nixCats": "nixCats", + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index 6ec9f41..7d1686b 100644 --- a/flake.nix +++ b/flake.nix @@ -1,75 +1,436 @@ +# Copyright (c) 2023 BirdeeHub and Gabriel Venberg +# Licensed under the MIT license { - description = "Flake exporting a configured neovim package"; + description = "Gabes neovim config, based on NixCats"; + inputs = { - 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; - }; + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + nixCats.url = "github:BirdeeHub/nixCats-nvim"; }; + + # see :help nixCats.flake.outputs outputs = { self, nixpkgs, - wrappers, ... } @ inputs: let - 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; + inherit (inputs.nixCats) utils; + luaPath = ./.; + # this is flake-utils eachSystem + forEachSystem = utils.eachSystem nixpkgs.lib.platforms.all; + extra_pkg_config = { + # allowUnfree = true; }; - 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; + # 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; }; - }; - # `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" + 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"] ]; }; }; - }; + + # 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 d8690a2..57b52e5 100644 --- a/init.lua +++ b/init.lua @@ -1,96 +1,60 @@ --- 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, +--[[ +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, } +--[[ +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. --- 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) +--[[ +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. +--]] -require('opts') -require('keys') -require('plugins') +--[[ +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') diff --git a/lua/keys.lua b/lua/keys.lua deleted file mode 100644 index 8f0f9f7..0000000 --- a/lua/keys.lua +++ /dev/null @@ -1,37 +0,0 @@ --- [[ 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 new file mode 100644 index 0000000..96f7e50 --- /dev/null +++ b/lua/myLuaConf/LSPs/init.lua @@ -0,0 +1,261 @@ +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 new file mode 100644 index 0000000..947f610 --- /dev/null +++ b/lua/myLuaConf/init.lua @@ -0,0 +1,20 @@ + +-- 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 new file mode 100644 index 0000000..42dd53f --- /dev/null +++ b/lua/myLuaConf/non_nix_download.lua @@ -0,0 +1,92 @@ +-- 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/opts.lua b/lua/myLuaConf/opts_and_keys.lua similarity index 63% rename from lua/opts.lua rename to lua/myLuaConf/opts_and_keys.lua index 92a89ea..7e75433 100644 --- a/lua/opts.lua +++ b/lua/myLuaConf/opts_and_keys.lua @@ -1,4 +1,4 @@ --- NOTE: These 2 should be set up before any plugins with keybinds are loaded. +-- NOTE: These 2 need to be set up before any plugins are loaded. vim.g.mapleader = ';' vim.g.maplocalleader = ';' @@ -6,13 +6,9 @@ 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 = "↪"; @@ -33,7 +29,6 @@ vim.opt.scrolloff = 10 -- Make line numbers default vim.opt.number = true -vim.opt.numberwidth = 3 -- Enable mouse mode vim.opt.mouse = 'a' @@ -45,6 +40,10 @@ 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 @@ -96,6 +95,22 @@ vim.api.nvim_create_autocmd('TextYankPost', { vim.g.netrw_liststyle = 0 vim.g.netrw_banner = 0 +-- [[ Basic Keymaps ]] -vim.g.netrw_liststyle=0 -vim.g.netrw_banner=0 +-- 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' }) diff --git a/lua/myLuaConf/plugins/completion.lua b/lua/myLuaConf/plugins/completion.lua new file mode 100644 index 0000000..0431493 --- /dev/null +++ b/lua/myLuaConf/plugins/completion.lua @@ -0,0 +1,156 @@ +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 new file mode 100644 index 0000000..5e10927 --- /dev/null +++ b/lua/myLuaConf/plugins/gitsigns.lua @@ -0,0 +1,84 @@ +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 new file mode 100644 index 0000000..f44ca18 --- /dev/null +++ b/lua/myLuaConf/plugins/init.lua @@ -0,0 +1,279 @@ +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 new file mode 100644 index 0000000..2a97b3a --- /dev/null +++ b/lua/myLuaConf/plugins/lualine.lua @@ -0,0 +1,43 @@ +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 new file mode 100644 index 0000000..ed8e56f --- /dev/null +++ b/lua/myLuaConf/plugins/treesitter.lua @@ -0,0 +1,42 @@ +-- [[ 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 new file mode 100644 index 0000000..55b73ab --- /dev/null +++ b/lua/myLuaConf/plugins/which-key.lua @@ -0,0 +1,21 @@ +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 new file mode 100644 index 0000000..4cfe835 --- /dev/null +++ b/lua/nixCatsUtils/catPacker.lua @@ -0,0 +1,40 @@ +--[[ + 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 new file mode 100644 index 0000000..b6a6128 --- /dev/null +++ b/lua/nixCatsUtils/init.lua @@ -0,0 +1,129 @@ +--[[ + 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 new file mode 100644 index 0000000..2e2393d --- /dev/null +++ b/lua/nixCatsUtils/lzUtils.lua @@ -0,0 +1,36 @@ +--[[ + 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/plugins.lua b/lua/plugins.lua deleted file mode 100644 index 611819f..0000000 --- a/lua/plugins.lua +++ /dev/null @@ -1,743 +0,0 @@ --- 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 deleted file mode 100644 index 825101d..0000000 --- a/module.nix +++ /dev/null @@ -1,284 +0,0 @@ -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 - ]; - }; -}