diff --git a/README.md b/README.md index 721c82f..8a04a0d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -# Gabes `nixCats` Configuration +# Neovim module -My preferred way of setting up neovim. This configuration has organically grown since 2016, -originally as a vimscript config, then as a lua config, then as a nixvim config, and finally a nix/lua hybrid. +A wrapper around nvim that includes the plugins I use day to day. diff --git a/flake.lock b/flake.lock index 6905646..6836d9d 100644 --- a/flake.lock +++ b/flake.lock @@ -1,40 +1,79 @@ { "nodes": { - "nixCats": { - "locked": { - "lastModified": 1769578476, - "narHash": "sha256-4+KbiBcC6hQ3sh0UbPXjy6TOfLh9yhskRlfPzyZ2FH4=", - "owner": "BirdeeHub", - "repo": "nixCats-nvim", - "rev": "48f8be4bdafccfa19ceaaf08071a15eca36fdb1d", - "type": "github" - }, - "original": { - "owner": "BirdeeHub", - "repo": "nixCats-nvim", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1770141374, - "narHash": "sha256-yD4K/vRHPwXbJf5CK3JkptBA6nFWUKNX/jlFp2eKEQc=", - "owner": "nixos", + "lastModified": 1773231277, + "narHash": "sha256-Xy3WEpUAbpsz8ydgvVAQAGGB/WB+8cNA5cshiL0McTI=", + "owner": "NixOS", "repo": "nixpkgs", - "rev": "41965737c1797c1d83cfb0b644ed0840a6220bd1", + "rev": "75690239f08f885ca9b0267580101f60d10fbe62", "type": "github" }, "original": { - "owner": "nixos", + "owner": "NixOS", "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } }, + "plugins-lze": { + "flake": false, + "locked": { + "lastModified": 1772949858, + "narHash": "sha256-skLhmn/MvxOZbrBiceF/xiLRRmmEs6ZQS2sGrBrUyLU=", + "owner": "BirdeeHub", + "repo": "lze", + "rev": "a3ba1a2d469d4ab26acb629aba8c7d70a6cbe558", + "type": "github" + }, + "original": { + "owner": "BirdeeHub", + "repo": "lze", + "type": "github" + } + }, + "plugins-lzextras": { + "flake": false, + "locked": { + "lastModified": 1772949841, + "narHash": "sha256-MQ1h2R5axM3u6mLNTDzXF/40o8+U0JOWb48UTQO9jfc=", + "owner": "BirdeeHub", + "repo": "lzextras", + "rev": "a6ac9a7bee380881af2dfbfd238ccb1697d677d7", + "type": "github" + }, + "original": { + "owner": "BirdeeHub", + "repo": "lzextras", + "type": "github" + } + }, "root": { "inputs": { - "nixCats": "nixCats", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "plugins-lze": "plugins-lze", + "plugins-lzextras": "plugins-lzextras", + "wrappers": "wrappers" + } + }, + "wrappers": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1773360496, + "narHash": "sha256-AQN5UhIc2WHvELT4TWIsD1W05ksLXWRkS5NjPm3jkc0=", + "owner": "BirdeeHub", + "repo": "nix-wrapper-modules", + "rev": "8f1770c6d58a89a4757849713c0e6d9ace7b4ac3", + "type": "github" + }, + "original": { + "owner": "BirdeeHub", + "repo": "nix-wrapper-modules", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index 7d1686b..6ec9f41 100644 --- a/flake.nix +++ b/flake.nix @@ -1,436 +1,75 @@ -# Copyright (c) 2023 BirdeeHub and Gabriel Venberg -# Licensed under the MIT license { - description = "Gabes neovim config, based on NixCats"; - + description = "Flake exporting a configured neovim package"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; - nixCats.url = "github:BirdeeHub/nixCats-nvim"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + wrappers = { + url = "github:BirdeeHub/nix-wrapper-modules"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + plugins-lze = { + url = "github:BirdeeHub/lze"; + flake = false; + }; + plugins-lzextras = { + url = "github:BirdeeHub/lzextras"; + flake = false; + }; }; - - # see :help nixCats.flake.outputs outputs = { self, nixpkgs, + wrappers, ... } @ inputs: let - inherit (inputs.nixCats) utils; - luaPath = ./.; - # this is flake-utils eachSystem - forEachSystem = utils.eachSystem nixpkgs.lib.platforms.all; - extra_pkg_config = { - # allowUnfree = true; + forAllSystems = nixpkgs.lib.genAttrs [ + "x86_64-linux" + "aarch64-linux" + ]; + module = nixpkgs.lib.modules.importApply ./module.nix inputs; + wrapper = wrappers.lib.evalModule module; + in { + formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra); + overlays = { + neovim = final: prev: {neovim = wrapper.config.wrap {pkgs = final;};}; + default = self.overlays.neovim; }; - # management of the system variable is one of the harder parts of using flakes. - - # so I have done it here in an interesting way to keep it out of the way. - # It gets resolved within the builder itself, and then passed to your - # categoryDefinitions and packageDefinitions. - - # this allows you to use ${pkgs.system} whenever you want in those sections - # without fear. - - # see :help nixCats.flake.outputs.overlays - dependencyOverlays = - /* - (import ./overlays inputs) ++ - */ - [ - # This overlay grabs all the inputs named in the format - # `plugins-` - # Once we add this overlay to our nixpkgs, we are able to - # use `pkgs.neovimPlugins`, which is a set of our plugins. - (utils.standardPluginOverlay inputs) - # add any other flake overlays here. - ]; - - # see :help nixCats.flake.outputs.categories - # and - # :help nixCats.flake.outputs.categoryDefinitions.scheme - categoryDefinitions = { - pkgs, - settings, - categories, - extra, - name, - mkPlugin, - ... - } @ packageDef: let - colorschemes = with pkgs.vimPlugins; { - "onedark" = onedark-nvim; - "catppuccin" = catppuccin-nvim; - "tokyonight" = tokyonight-nvim; - "nord" = nord-nvim; - "gruvbox" = gruvbox-nvim; + wrapperModules = { + neovim = module; + default = self.wrapperModules.neovim; + }; + wrappers = { + neovim = wrapper.config; + default = self.wrappers.neovim; + }; + packages = forAllSystems ( + system: let + pkgs = import nixpkgs {inherit system;}; + in { + neovim = wrapper.config.wrap {inherit pkgs;}; + default = self.packages.${system}.neovim; + } + ); + # `wrappers.neovim.enable = true` + nixosModules = { + default = self.nixosModules.neovim; + neovim = wrappers.lib.mkInstallModule { + name = "neovim"; + value = module; }; - in { - # to define and use a new category, simply add a new list to a set here, - # and later, you will include categoryname = true; in the set you - # provide when you build the package using this builder function. - # see :help nixCats.flake.outputs.packageDefinitions for info on that section. - - # lspsAndRuntimeDeps: - # this section is for dependencies that should be available - # at RUN TIME for plugins. Will be available to PATH within neovim terminal - # this includes LSPs - lspsAndRuntimeDeps = with pkgs; { - # some categories of stuff. - always = [ - universal-ctags - ripgrep - fd - fzf - lazygit - zoxide - ]; - markdown = [ - mermaid-cli - imagemagick - texliveSmall - ]; - git = [ - lazygit - git - ]; - lsp = { - rust = [ - rust-analyzer - cargo - ]; - lua = [ - lua-language-server - ]; - nix = [ - nix-doc - nixd - alejandra - ]; - python = [ - basedpyright - ruff - ]; - C = [ - libclang - ]; - bash = [ - shellcheck - bash-language-server - ]; - typst = [ - tinymist - ]; - }; - format = [ - ]; - }; - - # This is for plugins that will load at startup without using packadd: - startupPlugins = with pkgs.vimPlugins; { - always = [ - lze - lzextras - plenary-nvim - oil-nvim - nvim-web-devicons - snacks-nvim - nvim-numbertoggle - lualine-nvim - which-key-nvim - todo-comments-nvim - marks-nvim - ]; - lsp = { - rust = [ - rustaceanvim - ]; - }; - debug = [ - nvim-nio - ]; - treesitter = [ - comment-nvim - rainbow-delimiters-nvim - nvim-treesitter.withAllGrammars - treesj - ]; - allcolorschemes = colorschemes; - # You can retreive information from the - # packageDefinitions of the package this was packaged with. - # :help nixCats.flake.outputs.categoryDefinitions.scheme - themer = builtins.getAttr (categories.colorscheme or "gruvbox") colorschemes; - # This is obviously a fairly basic usecase for this, but still nice. - }; - - # not loaded automatically at startup. - # use with packadd and an autocommand in config to achieve lazy loading - # or a tool for organizing this like lze or lz.n! - # to get the name packadd expects, use the - # `:NixCats pawsible` command to see them all - optionalPlugins = with pkgs.vimPlugins; { - debug = { - default = [ - nvim-dap - nvim-dap-ui - nvim-dap-virtual-text - venn-nvim - ]; - }; - lint = [ - nvim-lint - ]; - format = [ - conform-nvim - ]; - markdown = [ - markdown-preview-nvim - ]; - lsp = { - default = [ - trouble-nvim - lualine-lsp-progress - nvim-lspconfig - ]; - zk = [ - zk-nvim - ]; - lua = [ - lazydev-nvim - ]; - typst = [ - typst-preview-nvim - ]; - }; - git = [ - gitsigns-nvim - ]; - always = [ - nvim-surround - leap-nvim - ]; - completion = [ - luasnip - friendly-snippets - cmp-cmdline - blink-cmp - blink-emoji-nvim - blink-compat - colorful-menu-nvim - ]; - extra = [ - vim-startuptime - ]; - }; - - # shared libraries to be added to LD_LIBRARY_PATH - # variable available to nvim runtime - sharedLibraries = { - }; - - # environmentVariables: - # this section is for environmentVariables that should be available - # at RUN TIME for plugins. Will be available to path within neovim terminal - environmentVariables = { - }; - - # If you know what these are, you can provide custom ones by category here. - # If you dont, check this link out: - # https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/make-wrapper.sh - extraWrapperArgs = { - }; - - # populates $LUA_PATH and $LUA_CPATH - extraLuaPackages = { - }; - - # see :help nixCats.flake.outputs.categoryDefinitions.default_values - # this will enable test.default and debug.default - # if any subcategory of test or debug is enabled - # WARNING: use of categories argument in this set will cause infinite recursion - # The categories argument of this function is the FINAL value. - # You may use it in any of the other sets. - extraCats = { - debug = [ - ["debug" "default"] - ]; - lsp = [ - ["lsp" "default"] + }; + # `wrappers.neovim.enable = true` + # You can set any of the options. + # But that is how you enable it. + homeModules = { + default = self.homeModules.neovim; + neovim = wrappers.lib.mkInstallModule { + name = "neovim"; + value = module; + loc = [ + "home" + "packages" ]; }; }; - - # packageDefinitions: - - # Now build a package with specific categories from above - # All categories you wish to include must be marked true, - # but false may be omitted. - # This entire set is also passed to nixCats for querying within the lua. - # It is directly translated to a Lua table, and a get function is defined. - # The get function is to prevent errors when querying subcategories. - - # see :help nixCats.flake.outputs.packageDefinitions - packageDefinitions = { - # the name here is the name of the package - # and also the default command name for it. - nvim = { - pkgs, - name, - ... - } @ misc: { - # these also recieve our pkgs variable - # see :help nixCats.flake.outputs.packageDefinitions - settings = { - suffix-path = true; - suffix-LD = true; - # WARNING: MAKE SURE THESE DONT CONFLICT WITH OTHER INSTALLED PACKAGES ON YOUR PATH - # That would result in a failed build, as nixos and home manager modules validate for collisions on your path - aliases = []; - - wrapRc = true; - configDirName = "nvim"; - }; - categories = { - always = true; - git = true; - treesitter = true; - markdown = true; - lsp = true; - completion = true; - debug = true; - lspDebugMode = false; - allcolorschemes = true; - colorscheme = "gruvbox"; - }; - extra = { - }; - }; - nvim-minimal = { - pkgs, - name, - ... - } @ misc: { - settings = { - suffix-path = true; - suffix-LD = true; - # WARNING: MAKE SURE THESE DONT CONFLICT WITH OTHER INSTALLED PACKAGES ON YOUR PATH - # That would result in a failed build, as nixos and home manager modules validate for collisions on your path - aliases = ["vim"]; - wrapRc = true; - configDirName = "nvim-minimal"; - }; - categories = { - always = true; - treesitter = true; - completion = true; - lspDebugMode = false; - lsp = false; - git = false; - themer = true; - colorscheme = "gruvbox"; - }; - extra = { - }; - }; - }; - - defaultPackageName = "nvim"; - # defaultPackageName is also passed to utils.mkNixosModules and utils.mkHomeModules - # and it controls the name of the top level option set. - # If you made a package named `nixCats` your default package as we did here, - # the modules generated would be set at: - # config.nixCats = { - # enable = true; - # packageNames = [ "nixCats" ]; # <- the packages you want installed - # - # } - # In addition, every package exports its own module via passthru, and is overrideable. - # so you can yourpackage.homeModule and then the namespace would be that packages name. - in - # see :help nixCats.flake.outputs.exports - forEachSystem (system: let - # and this will be our builder! it takes a name from our packageDefinitions as an argument, and builds an nvim. - nixCatsBuilder = - utils.baseBuilder luaPath { - # we pass in the things to make a pkgs variable to build nvim with later - inherit nixpkgs system dependencyOverlays extra_pkg_config; - # and also our categoryDefinitions and packageDefinitions - } - categoryDefinitions - packageDefinitions; - # call it with our defaultPackageName - defaultPackage = nixCatsBuilder defaultPackageName; - - # this pkgs variable is just for using utils such as pkgs.mkShell - # within this outputs set. - pkgs = import nixpkgs {inherit system;}; - # The one used to build neovim is resolved inside the builder - # and is passed to our categoryDefinitions and packageDefinitions - in { - # these outputs will be wrapped with ${system} by utils.eachSystem - - # this will generate a set of all the packages - # in the packageDefinitions defined above - # from the package we give it. - # and additionally output the original as default. - packages = utils.mkAllWithDefault defaultPackage; - - formatter = pkgs.alejandra; - - # choose your package for devShell - # and add whatever else you want in it. - devShells = { - default = pkgs.mkShell { - name = defaultPackageName; - packages = [defaultPackage]; - inputsFrom = []; - shellHook = '' - ''; - }; - }; - }) - // (let - # we also export a nixos module to allow reconfiguration from configuration.nix - nixosModule = utils.mkNixosModules { - moduleNamespace = [defaultPackageName]; - inherit - defaultPackageName - dependencyOverlays - luaPath - categoryDefinitions - packageDefinitions - extra_pkg_config - nixpkgs - ; - }; - # and the same for home manager - homeModule = utils.mkHomeModules { - moduleNamespace = [defaultPackageName]; - inherit - defaultPackageName - dependencyOverlays - luaPath - categoryDefinitions - packageDefinitions - extra_pkg_config - nixpkgs - ; - }; - in { - # these outputs will be NOT wrapped with ${system} - - # this will make an overlay out of each of the packageDefinitions defined above - # and set the default overlay to the one named here. - overlays = - utils.makeOverlays luaPath { - inherit nixpkgs dependencyOverlays extra_pkg_config; - } - categoryDefinitions - packageDefinitions - defaultPackageName; - - nixosModules.default = nixosModule; - homeModules.default = homeModule; - - inherit utils nixosModule homeModule; - inherit (utils) templates; - }); + }; } diff --git a/init.lua b/init.lua index 57b52e5..0662935 100644 --- a/init.lua +++ b/init.lua @@ -1,60 +1,96 @@ ---[[ -NOTE: -if you plan to always load your nixCats via nix, -you can safely ignore this setup call, -and the require('myLuaConf.non_nix_download') call below it. -as well as the entire lua/myLuaConf/non_nix_download file. -Unless you want the lzUtils file, or the lazy wrapper, you also wont need lua/nixCatsUtils - -IF YOU DO NOT DO THIS SETUP CALL: -the result will be that, when you load this folder without using nix, -the global nixCats function which you use everywhere -to check for categories will throw an error. -This setup function will give it a default value. -Of course, if you only ever download nvim with nix, this isnt needed.]] ---[[ ----------------------------------- ]] ---[[ This setup function will provide ]] ---[[ a default value for the nixCats('') ]] ---[[ function so that it will not throw ]] ---[[ an error if not loaded via nixCats ]] ---[[ ----------------------------------- ]] -require('nixCatsUtils').setup { - non_nix_value = true, +-- The first 100ish lines are setup, +-- the rest is usage of require(vim.g.nix_info_plugin_name)lze and various core plugins! +vim.loader.enable() -- <- bytecode caching +do + -- Set up a global in a way that also handles non-nix compat + local ok + ok, _G.nixInfo = pcall(require, vim.g.nix_info_plugin_name) + if not ok then + package.loaded[vim.g.nix_info_plugin_name] = setmetatable({}, { + __call = function (_, default) return default end + }) + _G.nixInfo = require(vim.g.nix_info_plugin_name) + -- If you always use the fetcher function to fetch nix values, + -- rather than indexing into the tables directly, + -- it will use the value you specified as the default + -- TODO: for non-nix compat, vim.pack.add in another file and require here. + end + nixInfo.isNix = vim.g.nix_info_plugin_name ~= nil + ---@module "lzextras" + ---@type lzextras | lze + nixInfo.lze = setmetatable(require("lze"), getmetatable(require("lzextras"))) + function nixInfo.get_nix_plugin_path(name) + return nixInfo(nil, "plugins", "lazy", name) or nixInfo(nil, "plugins", "start", name) + end +end +nixInfo.lze.register_handlers { + { + -- adds an `auto_enable` field to lze specs + -- if true, will disable it if not installed by nix. + -- if string, will disable if that name was not installed by nix. + -- if a table of strings, it will disable if any were not. + spec_field = "auto_enable", + set_lazy = false, + modify = function(plugin) + if vim.g.nix_info_plugin_name then + if type(plugin.auto_enable) == "table" then + for _, name in pairs(plugin.auto_enable) do + if not nixInfo.get_nix_plugin_path(name) then + plugin.enabled = false + break + end + end + elseif type(plugin.auto_enable) == "string" then + if not nixInfo.get_nix_plugin_path(plugin.auto_enable) then + plugin.enabled = false + end + elseif type(plugin.auto_enable) == "boolean" and plugin.auto_enable then + if not nixInfo.get_nix_plugin_path(plugin.name) then + plugin.enabled = false + end + end + end + return plugin + end, + }, + { + -- we made an options.settings.cats with the value of enable for our top level specs + -- give for_cat = "name" to disable if that one is not enabled + spec_field = "for_cat", + set_lazy = false, + modify = function(plugin) + if vim.g.nix_info_plugin_name then + if type(plugin.for_cat) == "string" then + plugin.enabled = nixInfo(false, "settings", "cats", plugin.for_cat) + end + end + return plugin + end, + }, + -- From lzextras. This one makes it so that + -- you can set up lsps within lze specs, + -- and trigger lspconfig setup hooks only on the correct filetypes + -- It is (unfortunately) important that it be registered after the above 2, + -- as it also relies on the modify hook, and the value of enabled at that point + nixInfo.lze.lsp, } ---[[ -Nix puts the plugins -into the directories paq-nvim expects them to be in, -because both follow the normal neovim scheme. -So you just put the URLs and build steps in there, and use its opt option to do the same -thing as putting a plugin in nixCat's optionalPlugins field. -then load the plugins via paq-nvim -YOU are in charge of putting the plugin -urls and build steps in there, which will only be used when not on nix, -and you should keep any setup functions -OUT of that file, as they are ONLY loaded when this -configuration is NOT loaded via nix. ---]] -require("myLuaConf.non_nix_download") --- OK, again, that isnt needed if you load this setup via nix, but it is an option. ---[[ -outside of when you want to use the nixCats global command -to decide if something should be loaded, or to pass info from nix to lua, -thats pretty much everything specific to nixCats that -needs to be in your config. -If you always want to load it via nix, -you pretty much dont need this file at all, and you also won't need -anything within lua/nixCatsUtils, nor will that be in the default template. -that directory is addable via the luaUtils template. -it is not required, but has some useful utility functions. ---]] +-- NOTE: This config uses lzextras.lsp handler https://github.com/BirdeeHub/lzextras?tab=readme-ov-file#lsp-handler +-- Because we have the paths, we can set a more performant fallback function +-- for when you don"t provide a filetype to trigger on yourself. +-- If you do provide a filetype, this will never be called. +nixInfo.lze.h.lsp.set_ft_fallback(function(name) + local lspcfg = nixInfo.get_nix_plugin_path "nvim-lspconfig" + if lspcfg then + local ok, cfg = pcall(dofile, lspcfg .. "/lsp/" .. name .. ".lua") + return (ok and cfg or {}).filetypes or {} + else + -- the less performant thing we are trying to avoid at startup + return (vim.lsp.config[name] or {}).filetypes or {} + end +end) ---[[ -ok thats enough for 1 file. Off to lua/myLuaConf/init.lua -all the config starts there in this example config. -This config is loadable with and without nix due to the above, -and the lua/myLuaConf/non_nix_download.lua file. -the rest is just example of how to configure nvim making use of various -features of nixCats and using the plugin lze for lazy loading. ---]] -require('myLuaConf') +require("opts") +require("keys") +require("plugins") +require("lsp") diff --git a/lua/keys.lua b/lua/keys.lua new file mode 100644 index 0000000..b07a6e6 --- /dev/null +++ b/lua/keys.lua @@ -0,0 +1,37 @@ +-- [[ Basic Keymaps ]] + +-- Keymaps for better default experience +-- See `:help vim.keymap.set()` +vim.keymap.set("v", "J", ":m '>+1gv=gv", { desc = "Moves Line Down" }) +vim.keymap.set("v", "K", ":m '<-2gv=gv", { desc = "Moves Line Up" }) +vim.keymap.set("n", "", "zz", { desc = 'Scroll Down' }) +vim.keymap.set("n", "", "zz", { desc = 'Scroll Up' }) +vim.keymap.set("n", "n", "nzzzv", { desc = 'Next Search Result' }) +vim.keymap.set("n", "N", "Nzzzv", { desc = 'Previous Search Result' }) + +-- Remap for dealing with word wrap +vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) +vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) + +-- Diagnostic keymaps +vim.keymap.set('n', 'e', vim.diagnostic.open_float, { desc = 'Open floating diagnostic message' }) +vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostics list' }) +vim.keymap.set('n', '[d', function() vim.diagnostic.jump({ count = -1, float = true }) end, + { desc = 'Go to previous diagnostic' }) +vim.keymap.set('n', ']d', function() vim.diagnostic.jump({ count = 1, float = true }) end, + { desc = 'Go to next diagnostic' }) + +-- moving between splits +vim.keymap.set('n', '', 'h', { desc = 'move to right split' }) +vim.keymap.set('n', '', 'j', { desc = 'move to below split' }) +vim.keymap.set('n', '', 'k', { desc = 'move to above split' }) +vim.keymap.set('n', '', 'l', { desc = 'move to left split' }) + +-- You should instead use these keybindings so that they are still easy to use, but dont conflict +vim.keymap.set({ "v", "x", "n" }, 'y', '"+y', { noremap = true, silent = true, desc = 'Yank to clipboard' }) +vim.keymap.set({ "n", "v", "x" }, 'Y', '"+yy', { noremap = true, silent = true, desc = 'Yank line to clipboard' }) +vim.keymap.set({ 'n', 'v', 'x' }, 'p', '"+p', { noremap = true, silent = true, desc = 'Paste from clipboard' }) +vim.keymap.set('i', '', '+', + { noremap = true, silent = true, desc = 'Paste from clipboard from within insert mode' }) +vim.keymap.set("x", "P", '"_dP', + { noremap = true, silent = true, desc = 'Paste over selection without erasing unnamed register' }) diff --git a/lua/lsp/C.lua b/lua/lsp/C.lua new file mode 100644 index 0000000..b382d76 --- /dev/null +++ b/lua/lsp/C.lua @@ -0,0 +1,7 @@ +return { + { + "clangd", + for_cat = "C", + lsp = {}, + }, +} diff --git a/lua/lsp/bash.lua b/lua/lsp/bash.lua new file mode 100644 index 0000000..c8bca4d --- /dev/null +++ b/lua/lsp/bash.lua @@ -0,0 +1,7 @@ +return { + { + "bashls", + for_cat = "bash", + lsp = {}, + }, +} diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua new file mode 100644 index 0000000..66d1e61 --- /dev/null +++ b/lua/lsp/init.lua @@ -0,0 +1,92 @@ +local lspEnabled = nixInfo("settings", "cat", "lsp") + +if lspEnabled then + 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, + }) +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, + }, + { import = "lsp.lua" }, + { import = "lsp.python" }, + { import = "lsp.C" }, + { import = "lsp.nix" }, + { import = "lsp.typst" }, + { import = "lsp.bash" }, + { import = "lsp.zk" }, + { import = "lsp.rust" }, +} diff --git a/lua/lsp/lua.lua b/lua/lsp/lua.lua new file mode 100644 index 0000000..22f8cc2 --- /dev/null +++ b/lua/lsp/lua.lua @@ -0,0 +1,45 @@ +return { + { + -- lazydev makes your lsp way better in your config without needing extra lsp configuration. + "lazydev.nvim", + for_cat = "lua", + 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 + filetypes = { 'lua' }, + settings = { + Lua = { + runtime = { version = 'LuaJIT' }, + formatters = { + ignoreComments = true, + }, + signatureHelp = { enabled = true }, + diagnostics = { + globals = { "nixInfo", "vim", }, + disable = { 'missing-fields' }, + }, + telemetry = { enabled = false }, + }, + }, + }, + }, +} diff --git a/lua/lsp/nix.lua b/lua/lsp/nix.lua new file mode 100644 index 0000000..4463427 --- /dev/null +++ b/lua/lsp/nix.lua @@ -0,0 +1,27 @@ +return { + { + "nixd", + enabled = nixInfo.isNix, -- mason doesn't have nixd + for_cat = "nix", + lsp = { + filetypes = { "nix" }, + settings = { + nixd = { + nixpkgs = { + expr = [[import {}]], + }, + options = { + }, + formatting = { + command = { "nixfmt" } + }, + diagnostic = { + suppress = { + "sema-escaping-with" + } + } + } + }, + }, + }, +} diff --git a/lua/lsp/python.lua b/lua/lsp/python.lua new file mode 100644 index 0000000..4bd6e38 --- /dev/null +++ b/lua/lsp/python.lua @@ -0,0 +1,12 @@ +return { + { + "ty", + for_cat = "python", + lsp = {}, + }, + { + "ruff", + for_cat = "python", + lsp = {}, + }, +} diff --git a/lua/lsp/rust.lua b/lua/lsp/rust.lua new file mode 100644 index 0000000..3ebc601 --- /dev/null +++ b/lua/lsp/rust.lua @@ -0,0 +1,6 @@ +return { + { + "rustaceanvim", + for_cat = "rust", + }, +} diff --git a/lua/lsp/typst.lua b/lua/lsp/typst.lua new file mode 100644 index 0000000..40dfe81 --- /dev/null +++ b/lua/lsp/typst.lua @@ -0,0 +1,13 @@ +return { + { + "tinymist", + for_cat = "typst", + lsp = { + filetypes = { "typst" }, + settings = { + formatterMode = "typstyle", + + }, + }, + }, +} diff --git a/lua/lsp/zk.lua b/lua/lsp/zk.lua new file mode 100644 index 0000000..13e663a --- /dev/null +++ b/lua/lsp/zk.lua @@ -0,0 +1,23 @@ +return { + { + "zk-nvim", + for_cat = "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/LSPs/init.lua b/lua/myLuaConf/LSPs/init.lua deleted file mode 100644 index 96f7e50..0000000 --- a/lua/myLuaConf/LSPs/init.lua +++ /dev/null @@ -1,261 +0,0 @@ -local catUtils = require('nixCatsUtils') -if (catUtils.isNixCats and nixCats('lspDebugMode')) then - vim.lsp.set_log_level("debug") -end - -local Snacks = require("snacks") - -vim.keymap.set("n", "lI", Snacks.picker.lsp_implementations, { desc = "Goto [I]mplementation" }) -vim.keymap.set("n", "lR", Snacks.picker.lsp_references, { desc = "Goto [R]eferences" }) -vim.keymap.set("n", "li", Snacks.picker.diagnostics, { desc = "D[i]agnostics" }) -vim.keymap.set("n", "ls", Snacks.picker.lsp_symbols, { desc = "Document [S]ymbols" }) -vim.keymap.set("n", "lws", Snacks.picker.lsp_workspace_symbols, { desc = "[W]orkspace [S]ymbols" }) - -vim.keymap.set("n", "lD", vim.lsp.buf.declaration, { desc = "Goto [D]eclaration" }) -vim.keymap.set("n", "lt", vim.lsp.buf.type_definition, { desc = "Type [D]efinition" }) -vim.keymap.set({"n", "v",}, "la", vim.lsp.buf.code_action, { desc = "[C]ode Action" }) -vim.keymap.set("n", "ld", vim.lsp.buf.definition, { desc = "Goto [D]efinition" }) -vim.keymap.set("n", "lf", vim.lsp.buf.format, { desc = "Format buffer" }) -vim.keymap.set("n", "lh", vim.lsp.buf.hover, { desc = "Hover Documentation" }) -vim.keymap.set("n", "lr", vim.lsp.buf.rename, { desc = "[R]ename" }) -vim.keymap.set("n", "ls", vim.lsp.buf.signature_help, { desc = "Signature Documentation" }) -vim.keymap.set("n", "lwa", vim.lsp.buf.add_workspace_folder, { desc = "[W]orkspace [A]dd Folder" }) -vim.keymap.set("n", "lwl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, - { desc = "[W]orkspace [L]ist Folders" }) -vim.keymap.set("n", "lwr", vim.lsp.buf.remove_workspace_folder, { desc = "[W]orkspace [R]emove Folder" }) - --- setup lsp progress notifications -local progress = vim.defaulttable() -vim.api.nvim_create_autocmd("LspProgress", { - callback = function(ev) - local client = vim.lsp.get_client_by_id(ev.data.client_id) - local value = ev.data.params - .value --[[@as {percentage?: number, title?: string, message?: string, kind: "begin" | "report" | "end"}]] - if not client or type(value) ~= "table" then - return - end - local p = progress[client.id] - - for i = 1, #p + 1 do - if i == #p + 1 or p[i].token == ev.data.params.token then - p[i] = { - token = ev.data.params.token, - msg = ("[%3d%%] %s%s"):format( - value.kind == "end" and 100 or value.percentage or 100, - value.title or "", - value.message and (" **%s**"):format(value.message) or "" - ), - done = value.kind == "end", - } - break - end - end - - local msg = {} ---@type string[] - progress[client.id] = vim.tbl_filter(function(v) - return table.insert(msg, v.msg) or not v.done - end, p) - - local spinner = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" } - vim.notify(table.concat(msg, "\n"), "info", { - id = "lsp_progress", - title = client.name, - opts = function(notif) - notif.icon = #progress[client.id] == 0 and " " - or spinner[math.floor(vim.uv.hrtime() / (1e6 * 80)) % #spinner + 1] - end, - }) - end, -}) - --- NOTE: This file uses lzextras.lsp handler https://github.com/BirdeeHub/lzextras?tab=readme-ov-file#lsp-handler --- This is a slightly more performant fallback function --- for when you don't provide a filetype to trigger on yourself. --- nixCats gives us the paths, which is faster than searching the rtp! -local old_ft_fallback = require('lze').h.lsp.get_ft_fallback() -require('lze').h.lsp.set_ft_fallback(function(name) - local lspcfg = nixCats.pawsible({ "allPlugins", "opt", "nvim-lspconfig" }) or - nixCats.pawsible({ "allPlugins", "start", "nvim-lspconfig" }) - if lspcfg then - local ok, cfg = pcall(dofile, lspcfg .. "/lsp/" .. name .. ".lua") - if not ok then - ok, cfg = pcall(dofile, lspcfg .. "/lua/lspconfig/configs/" .. name .. ".lua") - end - return (ok and cfg or {}).filetypes or {} - else - return old_ft_fallback(name) - end -end) -require('lze').load { - { - "nvim-lspconfig", - for_cat = "lsp", - on_require = { "lspconfig" }, - -- rustaceanvim and zk-nvim dont require("lspconfig") - ft = { "markdown", "rust" }, - -- NOTE: define a function for lsp, - -- and it will run for all specs with type(plugin.lsp) == table - -- when their filetype trigger loads them - lsp = function(plugin) - vim.lsp.config(plugin.name, plugin.lsp or {}) - vim.lsp.enable(plugin.name) - end, - }, - { - "mason.nvim", - -- only run it when not on nix - enabled = not catUtils.isNixCats, - on_plugin = { "nvim-lspconfig" }, - load = function(name) - vim.cmd.packadd(name) - vim.cmd.packadd("mason-lspconfig.nvim") - require('mason').setup() - -- auto install will make it install servers when lspconfig is called on them. - require('mason-lspconfig').setup { automatic_installation = true, } - end, - }, - { - -- lazydev makes your lsp way better in your config without needing extra lsp configuration. - "lazydev.nvim", - for_cat = "lsp.lua", - cmd = { "LazyDev" }, - ft = "lua", - after = function(_) - require('lazydev').setup({ - library = { - { words = { "nixCats" }, path = (nixCats.nixCatsPath or "") .. '/lua' }, - }, - }) - end, - }, - { - -- name of the lsp - "lua_ls", - enabled = nixCats('lsp.lua'), - -- provide a table containing filetypes, - -- and then whatever your functions defined in the function type specs expect. - -- in our case, it just expects the normal lspconfig setup options, - -- but with a default on_attach and capabilities - lsp = { - -- if you provide the filetypes it doesn't ask lspconfig for the filetypes - filetypes = { 'lua' }, - settings = { - Lua = { - runtime = { version = 'LuaJIT' }, - formatters = { - ignoreComments = true, - }, - signatureHelp = { enabled = true }, - diagnostics = { - globals = { "nixCats", "vim", }, - disable = { 'missing-fields' }, - }, - telemetry = { enabled = false }, - }, - }, - }, - -- also these are regular specs and you can use before and after and all the other normal fields - }, - { - "basedpyright", - enabled = nixCats("lsp.python"), - lsp = {}, - }, - { - "bashls", - enabled = nixCats("lsp.bash"), - lsp = {}, - }, - { - "clangd", - enabled = nixCats("lsp.c"), - lsp = {}, - }, - { - "ruff", - enabled = nixCats("lsp.python"), - lsp = {}, - }, - { - "tinymist", - enabled = nixCats("lsp.tinymist"), - lsp = { - filetypes = { "typst" }, - settings = { - formatterMode = "typstyle", - - }, - }, - }, - { - "nixd", - enabled = catUtils.isNixCats and nixCats('lsp.nix'), - lsp = { - filetypes = { "nix" }, - settings = { - nixd = { - -- nixd requires some configuration. - -- luckily, the nixCats plugin is here to pass whatever we need! - -- we passed this in via the `extra` table in our packageDefinitions - -- for additional configuration options, refer to: - -- https://github.com/nix-community/nixd/blob/main/nixd/docs/configuration.md - nixpkgs = { - -- in the extras set of your package definition: - -- nixdExtras.nixpkgs = ''import ${pkgs.path} {}'' - expr = nixCats.extra("nixdExtras.nixpkgs") - }, - options = { - -- If you integrated with your system flake, - -- you should use inputs.self as the path to your system flake - -- that way it will ALWAYS work, regardless - -- of where your config actually was. - nixos = { - -- nixdExtras.nixos_options = ''(builtins.getFlake "path:${builtins.toString inputs.self.outPath}").nixosConfigurations.configname.options'' - expr = nixCats.extra("nixdExtras.nixos_options") - }, - -- If you have your config as a separate flake, inputs.self would be referring to the wrong flake. - -- You can override the correct one into your package definition on import in your main configuration, - -- or just put an absolute path to where it usually is and accept the impurity. - ["home-manager"] = { - -- nixdExtras.home_manager_options = ''(builtins.getFlake "path:${builtins.toString inputs.self.outPath}").homeConfigurations.configname.options'' - expr = nixCats.extra("nixdExtras.home_manager_options") - } - }, - formatting = { - command = { "alejandra" } - }, - diagnostic = { - suppress = { - "sema-escaping-with" - } - } - } - }, - }, - }, - { - "rustaceanvim", - for_cat = "lsp.rust", - }, - { - "zk-nvim", - for_cat = "lsp.zk", - ft = "markdown", - after = function() - require("zk").setup({ picker = "snacks_picker" }) - - vim.api.nvim_set_keymap("n", "zb", "ZkBackLinks", { desc = "Show [B]acklinkgs" }) - vim.api.nvim_set_keymap("n", "zl", "ZkLinks", { desc = "Show [L]inks" }) - vim.api.nvim_set_keymap("n", "zi", ":'<,'>ZkInsertLink", { desc = "[I]nsert link" }) - vim.api.nvim_set_keymap("n", "zn", "ZkNew { title = vim.fn.input('Title: ') }", - { desc = "[N]ew note" }) - vim.api.nvim_set_keymap("n", "zo", "ZkNotes { sort = { 'modified' } }", { desc = "[O]pen notes" }) - vim.api.nvim_set_keymap("n", "zt", "ZkTags", { desc = "Search [T]ags" }) - vim.api.nvim_set_keymap("v", "zf", ":'<,'>ZkMatch", { desc = "[F]ind note from selection" }) - vim.api.nvim_set_keymap("v", "zn", ":'<,'>ZkNewFromTitleSelection", { - desc = - "[N]ew note from selection" - }) - end - }, -} diff --git a/lua/myLuaConf/init.lua b/lua/myLuaConf/init.lua deleted file mode 100644 index 947f610..0000000 --- a/lua/myLuaConf/init.lua +++ /dev/null @@ -1,20 +0,0 @@ - --- TODO: split up the plugins a bit. --- NOTE: various, non-plugin config -require('myLuaConf.opts_and_keys') - --- NOTE: register an extra lze handler with the spec_field 'for_cat' --- that makes enabling an lze spec for a category slightly nicer -require("lze").register_handlers(require('nixCatsUtils.lzUtils').for_cat) - --- NOTE: Register another one from lzextras. This one makes it so that --- you can set up lsps within lze specs, --- and trigger lspconfig setup hooks only on the correct filetypes -require('lze').register_handlers(require('lzextras').lsp) --- demonstrated in ./LSPs/init.lua - --- NOTE: general plugins -require("myLuaConf.plugins") - --- NOTE: obviously, more plugins, but more organized by what they do below -require("myLuaConf.LSPs") diff --git a/lua/myLuaConf/non_nix_download.lua b/lua/myLuaConf/non_nix_download.lua deleted file mode 100644 index 42dd53f..0000000 --- a/lua/myLuaConf/non_nix_download.lua +++ /dev/null @@ -1,92 +0,0 @@ --- TODO: completley out of date --- load the plugins via paq-nvim when not on nix --- YOU are in charge of putting the plugin --- urls and build steps in here, which will only be used when not on nix. --- and you should keep any setup functions OUT of this file - --- again, you dont need this file if you only use nix to load the config, --- this is a fallback only, and is optional. -require('nixCatsUtils.catPacker').setup({ ---[[ ------------------------------------------ ]] ---[[ The way to think of this is, its very ]] ---[[ similar to the main nix file for nixCats ]] ---[[ ]] ---[[ It can be used to download your plugins, ]] ---[[ and it has an opt for optional plugins. ]] ---[[ ]] ---[[ We dont want to handle anything about ]] ---[[ loading those plugins here, so that we can ]] ---[[ use the same loading code that we use for ]] ---[[ our normal nix-loaded config. ]] ---[[ we will do all our loading and configuring ]] ---[[ elsewhere in our configuration, so that ]] ---[[ we dont have to write it twice. ]] ---[[ ------------------------------------------ ]] - { "BirdeeHub/lze", }, - { "BirdeeHub/lzextras", }, - { "stevearc/oil.nvim", }, - { 'ellisonleao/gruvbox.nvim', }, - { 'nvim-tree/nvim-web-devicons', }, - { 'nvim-lua/plenary.nvim', }, - { 'tpope/vim-repeat', }, - { 'rcarriga/nvim-notify', }, - - { 'nvim-treesitter/nvim-treesitter-textobjects', opt = true, }, - { 'nvim-treesitter/nvim-treesitter', build = ':TSUpdate', opt = true, }, - - { 'nvim-telescope/telescope-fzf-native.nvim', build = ':!which make && make', opt = true, }, - { 'nvim-telescope/telescope-ui-select.nvim', opt = true, }, - {'nvim-telescope/telescope.nvim', opt = true, }, - - -- lsp - { 'williamboman/mason.nvim', opt = true, }, - { 'williamboman/mason-lspconfig.nvim', opt = true, }, - { 'j-hui/fidget.nvim', opt = true, }, - { 'neovim/nvim-lspconfig', opt = true, }, - - -- NOTE: we take care of lazy loading elsewhere in an autocommand - -- so that we can use the same code on and off nix. - -- so here we just tell it not to auto load it - { 'folke/lazydev.nvim', opt = true, }, - - -- completion - { 'L3MON4D3/LuaSnip', opt = true, as = "luasnip", }, - { 'hrsh7th/cmp-cmdline', opt = true, }, - { 'Saghen/blink.cmp', opt = true, }, - { 'Saghen/blink.compat', opt = true, }, - { 'xzbdmw/colorful-menu.nvim', opt = true, }, - - -- lint and format - { 'mfussenegger/nvim-lint', opt = true, }, - { 'stevearc/conform.nvim', opt = true, }, - - -- dap - { 'nvim-neotest/nvim-nio', opt = true, }, - { 'rcarriga/nvim-dap-ui', opt = true, }, - { 'theHamsta/nvim-dap-virtual-text', opt = true, }, - { 'jay-babu/mason-nvim-dap.nvim', opt = true, }, - { 'mfussenegger/nvim-dap', opt = true, }, - - -- { 'm-demare/hlargs.nvim', }, - { 'mbbill/undotree', opt = true, }, - { 'tpope/vim-fugitive', opt = true, }, - { 'tpope/vim-rhubarb', opt = true, }, - { 'tpope/vim-sleuth', opt = true, }, - { 'folke/which-key.nvim', opt = true, }, - { 'lewis6991/gitsigns.nvim', opt = true, }, - { 'nvim-lualine/lualine.nvim', opt = true, }, - { 'lukas-reineke/indent-blankline.nvim', opt = true, }, - { 'numToStr/Comment.nvim', opt = true, as = "comment.nvim", }, - { 'kylechui/nvim-surround', opt = true, }, - { - "iamcco/markdown-preview.nvim", - build = ":call mkdp#util#install()", - opt = true, - }, - - -- all the rest of the setup will be done using the normal setup functions later, - -- thus working regardless of what method loads the plugins. - -- only stuff pertaining to downloading should be added to paq. - -}) --- OK, again, that isnt needed if you load this setup via nix, but it is an option. diff --git a/lua/myLuaConf/plugins/gitsigns.lua b/lua/myLuaConf/plugins/gitsigns.lua deleted file mode 100644 index 5e10927..0000000 --- a/lua/myLuaConf/plugins/gitsigns.lua +++ /dev/null @@ -1,84 +0,0 @@ -return { - "gitsigns.nvim", - for_cat = 'git', - event = "DeferredUIEnter", - -- cmd = { "" }, - -- ft = "", - -- keys = "", - -- colorscheme = "", - after = function() - require('gitsigns').setup({ - -- See `:help gitsigns.txt` - signs = { - add = { text = '+' }, - change = { text = '~' }, - delete = { text = '_' }, - topdelete = { text = '‾' }, - changedelete = { text = '~' }, - }, - on_attach = function(bufnr) - local gs = package.loaded.gitsigns - - local function map(mode, l, r, opts) - opts = opts or {} - opts.buffer = bufnr - vim.keymap.set(mode, l, r, opts) - end - - -- Navigation - map({ 'n', 'v' }, ']c', function() - if vim.wo.diff then - return ']c' - end - vim.schedule(function() - gs.next_hunk() - end) - return '' - end, { expr = true, desc = 'Jump to next hunk' }) - - map({ 'n', 'v' }, '[c', function() - if vim.wo.diff then - return '[c' - end - vim.schedule(function() - gs.prev_hunk() - end) - return '' - end, { expr = true, desc = 'Jump to previous hunk' }) - - -- Actions - -- visual mode - map('v', 'hs', function() - gs.stage_hunk { vim.fn.line '.', vim.fn.line 'v' } - end, { desc = 'stage git hunk' }) - map('v', 'hr', function() - gs.reset_hunk { vim.fn.line '.', vim.fn.line 'v' } - end, { desc = 'reset git hunk' }) - -- normal mode - map('n', 'gs', gs.stage_hunk, { desc = 'git stage hunk' }) - map('n', 'gr', gs.reset_hunk, { desc = 'git reset hunk' }) - map('n', 'gS', gs.stage_buffer, { desc = 'git Stage buffer' }) - map('n', 'gu', gs.undo_stage_hunk, { desc = 'undo stage hunk' }) - map('n', 'gR', gs.reset_buffer, { desc = 'git Reset buffer' }) - map('n', 'gp', gs.preview_hunk, { desc = 'preview git hunk' }) - map('n', 'gb', function() - gs.blame_line { full = false } - end, { desc = 'git blame line' }) - map('n', 'gd', gs.diffthis, { desc = 'git diff against index' }) - map('n', 'gD', function() - gs.diffthis '~' - end, { desc = 'git diff against last commit' }) - - -- Toggles - map('n', 'gtb', gs.toggle_current_line_blame, { desc = 'toggle git blame line' }) - map('n', 'gtd', gs.toggle_deleted, { desc = 'toggle git show deleted' }) - - -- Text object - map({ 'o', 'x' }, 'ih', ':Gitsigns select_hunk', { desc = 'select git hunk' }) - end, - }) - vim.cmd([[hi GitSignsAdd guifg=#04de21]]) - vim.cmd([[hi GitSignsChange guifg=#83fce6]]) - vim.cmd([[hi GitSignsDelete guifg=#fa2525]]) - end, -} diff --git a/lua/myLuaConf/plugins/init.lua b/lua/myLuaConf/plugins/init.lua deleted file mode 100644 index f44ca18..0000000 --- a/lua/myLuaConf/plugins/init.lua +++ /dev/null @@ -1,279 +0,0 @@ -local colorschemeName = nixCats('colorscheme') -if not require('nixCatsUtils').isNixCats then - colorschemeName = 'gruvbox' -end --- Could I lazy load on colorscheme with lze? --- sure. But I was going to call vim.cmd.colorscheme() during startup anyway --- this is just an example, feel free to do a better job! -vim.cmd.colorscheme(colorschemeName) - -local ok, notify = pcall(require, "notify") -if ok then - notify.setup({ - on_open = function(win) - vim.api.nvim_win_set_config(win, { focusable = false }) - end, - }) - vim.notify = notify - vim.keymap.set("n", "", function() - notify.dismiss({ silent = true, }) - end, { desc = "dismiss notify popup and clear hlsearch" }) -end - --- NOTE: you can check if you included the category with the thing wherever you want. -if nixCats('always') then - -- I didnt want to bother with lazy loading this. - -- I could put it in opt and put it in a spec anyway - -- and then not set any handlers and it would load at startup, - -- but why... I guess I could make it load - -- after the other lze definitions in the next call using priority value? - -- didnt seem necessary. - vim.g.loaded_netrwPlugin = 1 - require("oil").setup({ - default_file_explorer = false, - view_options = { - show_hidden = true - }, - columns = { - "icon", - "permissions", - "size", - -- "mtime", - }, - keymaps = { - ["g?"] = "actions.show_help", - [""] = "actions.select", - [""] = "actions.select_vsplit", - [""] = "actions.select_split", - [""] = "actions.select_tab", - [""] = "actions.preview", - [""] = "actions.close", - [""] = "actions.refresh", - ["-"] = "actions.parent", - ["_"] = "actions.open_cwd", - ["`"] = "actions.cd", - ["~"] = "actions.tcd", - ["gs"] = "actions.change_sort", - ["gx"] = "actions.open_external", - ["g."] = "actions.toggle_hidden", - ["g\\"] = "actions.toggle_trash", - }, - }) - vim.keymap.set("n", "-", "Oil", { noremap = true, desc = 'Open Parent Directory' }) - vim.keymap.set("n", "-", "Oil .", { noremap = true, desc = 'Open nvim root directory' }) -end - -if nixCats("always") then - -- Potentially checkout the lazygit module. - local Snacks = require("snacks") - local config = { - bufdelete = { enable = true }, - dim = { enable = true }, - git = { enable = true }, - input = { enable = true }, - notifier = { enable = true }, - terminal = { enable = true }, - toggle = { enable = true }, - quickfile = { enable = true }, - scope = { enable = true }, - statuscolumn = { enable = true }, - - explorer = { replace_netrw = true }, - picker = { - enabled = true, - ui_select = true, - matcher = { - fuzzy = true, - frecency = true, - }, - previewers = { - diff = { - builtin = true, -- use Neovim for previewing diffs (true) or use an external tool (false) - cmd = { "delta" }, -- example to show a diff with delta - }, - git = { - builtin = true, -- use Neovim for previewing git output (true) or use git (false) - }, - }, - }, - indent = { - enabled = true, - animate = { enabled = false }, - scope = { enabled = true }, - chunk = { enabled = true }, - }, - image = { enabled = false, inline = false, float = false }, - lazygit = { enabled = false, configure = false }, - } - if nixCats("markdown") then - config.image.enable = true - end - if nixCats("git") then - config.lazygit.enable = true - end - Snacks.setup(config) - - -- setup keybinds. - vim.keymap.set("n", "bd", Snacks.bufdelete.delete, { desc = "delete buffer" }) - vim.keymap.set("n", "t", function() Snacks.explorer() end, { desc = "File [T]ree" }) - vim.keymap.set("n", "i", Snacks.image.hover, { desc = "[I]mage preview" }) - - -- picker keybinds - vim.keymap.set("n", "fGb", Snacks.picker.grep_buffers, { desc = "[G]rep buffers" }) - vim.keymap.set("n", "fGl", Snacks.picker.lines, { desc = "[L]ines in buffer" }) - vim.keymap.set("n", "fb", Snacks.picker.buffers, { desc = "[B]uffers" }) - vim.keymap.set("n", "ff", Snacks.picker.files, { desc = "[F]iles" }) - vim.keymap.set("n", "fg", Snacks.picker.grep, { desc = "[G]rep all" }) - vim.keymap.set("n", "fh", Snacks.picker.help, { desc = "[H]elp" }) - vim.keymap.set("n", "fi", Snacks.picker.icons, { desc = "[I]cons" }) - vim.keymap.set("n", "fm", Snacks.picker.marks, { desc = "[M]arks" }) - vim.keymap.set("n", "fs", Snacks.picker.spelling, { desc = "[S]pelling" }) - vim.keymap.set("n", "ft", Snacks.picker.treesitter, { desc = "[T]reesitter" }) - vim.keymap.set("n", "fu", Snacks.picker.undo, { desc = "[U]ndo" }) - vim.keymap.set("n", "fz", Snacks.picker.zoxide, { desc = "[Z]oxide" }) - - -- picker git keybinds - vim.keymap.set("n", "gB", Snacks.git.blame_line, { desc = "[G]it [B]lame" }) - vim.keymap.set("n", "gb", Snacks.picker.git_branches, { desc = "[G]it [B]ranch" }) - vim.keymap.set("n", "gl", Snacks.picker.git_log, { desc = "[G]it [L]og" }) - vim.keymap.set("n", "gd", Snacks.picker.git_diff, { desc = "[G]it [D]iff" }) - vim.keymap.set("n", "gt", Snacks.lazygit.open, { desc = "lazy[G]it [T]UI" }) - - -- setup toggles - Snacks.toggle.option("spell", { name = "spelling" }):map("cs") - Snacks.toggle.option("relativenumber", { name = "Relative Numbering" }):map("n") - Snacks.toggle.dim():map("d") - - -- terminal keybinds - vim.keymap.set("n", "s", function() - Snacks.terminal.toggle(nil, { win = { position = "float" } }) - end, { desc = "terminal" }) - - vim.keymap.set("t", "", function(self) - self.esc_timer = self.esc_timer or (vim.uv or vim.loop).new_timer() - if self.esc_timer:is_active() then - self.esc_timer:stop() - vim.cmd("stopinsert") - else - self.esc_timer:start(200, 0, function() end) - return "" - end - end, { expr = true, desc = "Double tap to escape terminal" }) - - -- setup rename autocmds - local prev = { new_name = "", old_name = "" } -- Prevents duplicate events - vim.api.nvim_create_autocmd("User", { - pattern = "OilActionsPost", - callback = function(event) - if event.data.actions.type == "move" then - Snacks.rename.on_rename_file(event.data.actions.src_url, event.data.actions.dest_url) - end - end, - }) -end - -require('lze').load { - { import = "myLuaConf.plugins.treesitter", }, - { import = "myLuaConf.plugins.completion", }, - { import = "myLuaConf.plugins.gitsigns", }, - { import = "myLuaConf.plugins.lualine", }, - { import = "myLuaConf.plugins.which-key", }, - { - "markdown-preview.nvim", - -- NOTE: for_cat is a custom handler that just sets enabled value for us, - -- based on result of nixCats('cat.name') and allows us to set a different default if we wish - -- it is defined in luaUtils template in lua/nixCatsUtils/lzUtils.lua - -- you could replace this with enabled = nixCats('cat.name') == true - -- if you didnt care to set a different default for when not using nix than the default you already set - for_cat = 'markdown', - cmd = { "MarkdownPreview", "MarkdownPreviewStop", "MarkdownPreviewToggle", }, - ft = "markdown", - keys = { - { "pmp", "MarkdownPreview ", mode = { "n" }, noremap = true, desc = "markdown preview" }, - { "pms", "MarkdownPreviewStop ", mode = { "n" }, noremap = true, desc = "markdown preview stop" }, - { "pmt", "MarkdownPreviewToggle ", mode = { "n" }, noremap = true, desc = "markdown preview toggle" }, - }, - before = function() - vim.g.mkdp_auto_close = 0 - end, - }, - { - "typst-preview.nvim", - for_cat = "lsp.typst", - ft = "typst", - cmd = { "TypstPreview", "TypstPreviewStop", "TypstPreviewToggle", }, - keys = { - { "ptp", "TypstPreview ", mode = { "n" }, noremap = true, desc = "typst preview" }, - { "pts", "TypstPreviewStop ", mode = { "n" }, noremap = true, desc = "typst preview stop" }, - { "ptt", "TypstPreviewToggle ", mode = { "n" }, noremap = true, desc = "typst preview toggle" }, - }, - after = function() - require('typst-preview').setup {} - end - }, - { - "leap.nvim", - for_cat = 'always', - event = "DeferredUIEnter", - keys = { - { "s", "(leap)", mode = { "n", "x", "o", "v" }, noremap = true, desc = "leap to char sequence" } - }, - }, - { - "nvim-surround", - for_cat = 'always', - event = "DeferredUIEnter", - after = function() - require('nvim-surround').setup() - end, - }, - { - "marks.nvim", - for_cat = "always", - after = function() - require('marks').setup({}) - end - }, - { - "venn.nvim", - for_cat = "always", - keys = { - { "v", function() Toggle_venn() end, desc = "toggle diagram drawing" } - }, - before = function() - -- venn.nvim: enable or disable keymappings - function _G.Toggle_venn() - local venn_enabled = vim.inspect(vim.b.venn_enabled) - if venn_enabled == "nil" then - vim.b.venn_enabled = true - vim.o.virtualedit = "all" - -- draw a line on HJKL keystokes - vim.api.nvim_buf_set_keymap(0, "n", "J", "j:VBox", { noremap = true }) - vim.api.nvim_buf_set_keymap(0, "n", "K", "k:VBox", { noremap = true }) - vim.api.nvim_buf_set_keymap(0, "n", "L", "l:VBox", { noremap = true }) - vim.api.nvim_buf_set_keymap(0, "n", "H", "h:VBox", { noremap = true }) - -- draw a box by pressing "f" with visual selection - vim.api.nvim_buf_set_keymap(0, "v", "f", ":VBox", { noremap = true }) - else - vim.o.virtualedit = "" - vim.api.nvim_buf_del_keymap(0, "n", "J") - vim.api.nvim_buf_del_keymap(0, "n", "K") - vim.api.nvim_buf_del_keymap(0, "n", "L") - vim.api.nvim_buf_del_keymap(0, "n", "H") - vim.api.nvim_buf_del_keymap(0, "v", "f") - vim.b.venn_enabled = nil - end - end - end - }, - { - "vim-startuptime", - for_cat = 'extra', - cmd = { "StartupTime" }, - before = function(_) - vim.g.startuptime_event_width = 0 - vim.g.startuptime_tries = 10 - vim.g.startuptime_exe_path = nixCats.packageBinPath - end, - } -} diff --git a/lua/myLuaConf/plugins/lualine.lua b/lua/myLuaConf/plugins/lualine.lua deleted file mode 100644 index 2a97b3a..0000000 --- a/lua/myLuaConf/plugins/lualine.lua +++ /dev/null @@ -1,43 +0,0 @@ -return { - "lualine.nvim", - for_cat = 'always', - -- cmd = { "" }, - event = "DeferredUIEnter", - -- ft = "", - -- keys = "", - -- colorscheme = "", - after = function() - require('lualine').setup({ - options = { - alwaysDivideMiddle = true, - icons_enabled = true, - component_separators = { left = '', right = '' }, - section_separators = { left = '', right = '' }, - }, - inactive_sections = { - lualine_a = {}, - lualine_b = {}, - lualine_c = { "filename" }, - lualine_x = { "filetype" }, - lualine_y = {}, - lualine_z = {}, - }, - sections = { - lualine_a = { "mode" }, - lualine_b = { "branch", "diff", "diagnostics" }, - lualine_c = { { "filename", path = 1 } }, - lualine_x = { "encoding", "fileformat", "filetype" }, - lualine_y = { "progress" }, - lualine_z = { "location" }, - }, - tabline = { - lualine_a = { { "buffers", mode = 4 } }, - lualine_b = {}, - lualine_c = {}, - lualine_x = {}, - lualine_y = {}, - lualine_z = { { "tabs", mode = 2 } } - }, - }) - end, - } diff --git a/lua/myLuaConf/plugins/which-key.lua b/lua/myLuaConf/plugins/which-key.lua deleted file mode 100644 index 55b73ab..0000000 --- a/lua/myLuaConf/plugins/which-key.lua +++ /dev/null @@ -1,21 +0,0 @@ -return { - "which-key.nvim", - for_cat = 'always', - after = function() - require('which-key').setup({ - }) - require('which-key').add { - { "g", group = "[g]it" }, - { "z", group = "[z]ettelkasten" }, - { "gt", group = "[t]oggle" }, - { "p", group = "[p]review" }, - { "pt", group = "[p]review [t]ypst" }, - { "pm", group = "[p]review [m]arkdown" }, - { "f", group = "[f]ind" }, - { "t", group = "[t]ree" }, - { "c", group = "[c]heck" }, - { "l", group = "[l]sp" }, - { "lw", group = "[l]sp [w]orkspace" }, - } - end, -} diff --git a/lua/nixCatsUtils/catPacker.lua b/lua/nixCatsUtils/catPacker.lua deleted file mode 100644 index 4cfe835..0000000 --- a/lua/nixCatsUtils/catPacker.lua +++ /dev/null @@ -1,40 +0,0 @@ ---[[ - This directory is the luaUtils template. - You can choose what things from it that you would like to use. - And then delete the rest. - Everything in this directory is optional. ---]] - -local M = {} --- NOTE: This function is for defining a paq.nvim fallback method of downloading plugins --- when nixCats was not used to install your config. --- If you only ever load your config using nixCats, you don't need this file. - --- it literally just only runs it when not on nixCats --- all neovim package managers that use the regular plugin loading scheme --- can be used this way, just do whatever the plugin manager needs to put it in the --- opt directory for lazy loading, and add the build steps so that when theres no nix the steps are ran -function M.setup(v) - if not vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] then - local function clone_paq() - local path = vim.fn.stdpath("data") .. "/site/pack/paqs/start/paq-nvim" - local is_installed = vim.fn.empty(vim.fn.glob(path)) == 0 - if not is_installed then - vim.fn.system { "git", "clone", "--depth=1", "https://github.com/savq/paq-nvim.git", path } - return true - end - end - local function bootstrap_paq(packages) - local first_install = clone_paq() - vim.cmd.packadd("paq-nvim") - local paq = require("paq") - if first_install then - vim.notify("Installing plugins... If prompted, hit Enter to continue.") - end - paq(packages) - paq.install() - end - bootstrap_paq(vim.list_extend({"savq/paq-nvim"},v)) - end -end -return M diff --git a/lua/nixCatsUtils/init.lua b/lua/nixCatsUtils/init.lua deleted file mode 100644 index b6a6128..0000000 --- a/lua/nixCatsUtils/init.lua +++ /dev/null @@ -1,129 +0,0 @@ ---[[ - This directory is the luaUtils template. - You can choose what things from it that you would like to use. - And then delete the rest. - Everything in this directory is optional. ---]] - -local M = {} - ---[[ - This file is for making your config still work WITHOUT nixCats. - When you don't use nixCats to load your config, - you wont have the nixCats plugin. - - The setup function defined here defines a mock nixCats plugin when nixCats wasnt used to load the config. - This will help avoid indexing errors when the nixCats plugin doesnt exist. - - NOTE: If you only ever use nixCats to load your config, you don't need this file. ---]] - ----@type boolean -M.isNixCats = vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] ~= nil - ----@class nixCatsSetupOpts ----@field non_nix_value boolean|nil - ----This function will setup a mock nixCats plugin when not using nix ----It will help prevent you from running into indexing errors without a nixCats plugin from nix. ----If you loaded the config via nix, it does nothing ----non_nix_value defaults to true if not provided or is not a boolean. ----@param v nixCatsSetupOpts -function M.setup(v) - if not M.isNixCats then - local nixCats_default_value - if type(v) == "table" and type(v.non_nix_value) == "boolean" then - nixCats_default_value = v.non_nix_value - else - nixCats_default_value = true - end - local mk_with_meta = function (tbl) - return setmetatable(tbl, { - __call = function(_, attrpath) - local strtable = {} - if type(attrpath) == "table" then - strtable = attrpath - elseif type(attrpath) == "string" then - for key in attrpath:gmatch("([^%.]+)") do - table.insert(strtable, key) - end - else - print("function requires a table of strings or a dot separated string") - return - end - return vim.tbl_get(tbl, unpack(strtable)); - end - }) - end - package.preload['nixCats'] = function () - local ncsub = { - get = function(_) return nixCats_default_value end, - cats = mk_with_meta({ - nixCats_config_location = vim.fn.stdpath('config'), - wrapRc = false, - }), - settings = mk_with_meta({ - nixCats_config_location = vim.fn.stdpath('config'), - configDirName = os.getenv("NVIM_APPNAME") or "nvim", - wrapRc = false, - }), - petShop = mk_with_meta({}), - extra = mk_with_meta({}), - pawsible = mk_with_meta({ - allPlugins = { - start = {}, - opt = {}, - }, - }), - configDir = vim.fn.stdpath('config'), - packageBinPath = os.getenv('NVIM_WRAPPER_PATH_NIX') or vim.v.progpath - } - return setmetatable(ncsub, {__call = function(_, cat) return ncsub.get(cat) end}) - end - _G.nixCats = require('nixCats') - end -end - ----allows you to guarantee a boolean is returned, and also declare a different ----default value than specified in setup when not using nix to load the config ----@overload fun(v: string|string[]): boolean ----@overload fun(v: string|string[], default: boolean): boolean -function M.enableForCategory(v, default) - if M.isNixCats or default == nil then - if nixCats(v) then - return true - else - return false - end - else - return default - end -end - ----if nix, return value of nixCats(v) else return default ----Exists to specify a different non_nix_value than the one in setup() ----@param v string|string[] ----@param default any ----@return any -function M.getCatOrDefault(v, default) - if M.isNixCats then - return nixCats(v) - else - return default - end -end - ----for conditionally disabling build steps on nix, as they are done via nix ----I should probably have named it dontAddIfCats or something. ----@overload fun(v: any): any|nil ----Will return the second value if nix, otherwise the first ----@overload fun(v: any, o: any): any -function M.lazyAdd(v, o) - if M.isNixCats then - return o - else - return v - end -end - -return M diff --git a/lua/nixCatsUtils/lzUtils.lua b/lua/nixCatsUtils/lzUtils.lua deleted file mode 100644 index 2e2393d..0000000 --- a/lua/nixCatsUtils/lzUtils.lua +++ /dev/null @@ -1,36 +0,0 @@ ---[[ - This directory is the luaUtils template. - You can choose what things from it that you would like to use. - And then delete the rest. - Everything in this directory is optional. ---]] - -local M = {} --- A nixCats specific lze handler that you can use to conditionally enable by category easier. --- at the start of your config, register with --- require('lze').register_handlers(require('nixCatsUtils.lzUtils').for_cat) --- before any calls to require('lze').load using the handler have been made. --- accepts: --- for_cat = { "your" "cat" }; --- for_cat = { cat = { "your" "cat" }, default = bool } --- for_cat = "your.cat"; --- for_cat = { cat = "your.cat", default = bool } --- where default is an alternate value for when nixCats was NOT used to install the config -M.for_cat = { - spec_field = "for_cat", - set_lazy = false, - modify = function(plugin) - if type(plugin.for_cat) == "table" and plugin.for_cat.cat ~= nil then - if vim.g[ [[nixCats-special-rtp-entry-nixCats]] ] ~= nil then - plugin.enabled = nixCats(plugin.for_cat.cat) or false - else - plugin.enabled = plugin.for_cat.default - end - else - plugin.enabled = nixCats(plugin.for_cat) or false - end - return plugin - end, -} - -return M diff --git a/lua/myLuaConf/opts_and_keys.lua b/lua/opts.lua similarity index 51% rename from lua/myLuaConf/opts_and_keys.lua rename to lua/opts.lua index 7e75433..49fb35c 100644 --- a/lua/myLuaConf/opts_and_keys.lua +++ b/lua/opts.lua @@ -1,14 +1,18 @@ --- NOTE: These 2 need to be set up before any plugins are loaded. -vim.g.mapleader = ';' -vim.g.maplocalleader = ';' +-- NOTE: These 2 should be set up before any plugins with keybinds are loaded. +vim.g.mapleader = ";" +vim.g.maplocalleader = ";" -- [[ Setting options ]] -- 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'` +-- 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 = "↪"; @@ -16,10 +20,10 @@ vim.opt.showbreak = "↪"; -- Set highlight on search vim.opt.hlsearch = true vim.opt.incsearch = true -vim.keymap.set('n', '', 'nohlsearch') +vim.keymap.set("n", "", "nohlsearch") -- Preview substitutions live, as you type! -vim.opt.inccommand = 'split' +vim.opt.inccommand = "split" -- Automatically load changed files vim.opt.autoread = true @@ -29,9 +33,10 @@ vim.opt.scrolloff = 10 -- Make line numbers default vim.opt.number = true +vim.opt.numberwidth = 3 -- Enable mouse mode -vim.opt.mouse = 'a' +vim.opt.mouse = "a" -- no hard wrapping vim.opt.textwidth = 0 @@ -40,10 +45,6 @@ vim.opt.wrapmargin = 0 -- get nice visual guides for 80, 100, and 120 cols. vim.opt.colorcolumn = { "90", "100", "120", } --- add line numbers -vim.opt.number = true -vim.opt.numberwidth = 3 - -- Indent vim.opt.smarttab = true vim.opt.expandtab = true @@ -61,7 +62,7 @@ vim.opt.ignorecase = true vim.opt.smartcase = true -- Keep signcolumn on by default -vim.opt.signcolumn = 'yes' +vim.opt.signcolumn = "yes" vim.opt.relativenumber = true -- Decrease update time @@ -69,7 +70,7 @@ vim.opt.updatetime = 250 vim.opt.timeoutlen = 300 -- Set completeopt to have a better completion experience -vim.opt.completeopt = { 'menu', 'preview', 'noselect' } +vim.opt.completeopt = { "menu", "preview", "noselect" } vim.opt.termguicolors = true @@ -84,33 +85,17 @@ vim.opt.formatoptions = "rojq" -- [[ Highlight on yank ]] -- See `:help vim.highlight.on_yank()` -local highlight_group = vim.api.nvim_create_augroup('YankHighlight', { clear = true }) -vim.api.nvim_create_autocmd('TextYankPost', { +local highlight_group = vim.api.nvim_create_augroup("YankHighlight", { clear = true }) +vim.api.nvim_create_autocmd("TextYankPost", { callback = function() vim.highlight.on_yank() end, group = highlight_group, - pattern = '*', + pattern = "*", }) vim.g.netrw_liststyle = 0 vim.g.netrw_banner = 0 --- [[ Basic Keymaps ]] --- make quick system clipboard opts easier -vim.keymap.set({ 'n', 'v', 'x' }, 'p', '"+p', { noremap = true, silent = true, desc = 'Paste from clipboard' }) -vim.keymap.set({ "v", "x", "n" }, 'y', '"+y', { noremap = true, silent = true, desc = 'Yank to clipboard' }) -vim.keymap.set({ "n", "v", "x" }, 'Y', '"+yy', { noremap = true, silent = true, desc = 'Yank line to clipboard' }) -vim.keymap.set('i', '', '+', - { noremap = true, silent = true, desc = 'Paste from clipboard from within insert mode' }) - --- Diagnostic keymaps -vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous diagnostic message' }) -vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next diagnostic message' }) -vim.keymap.set('n', 'd', vim.diagnostic.open_float, { desc = 'Open floating diagnostic message' }) - --- moving between splits -vim.keymap.set('n', '', 'h', { desc = 'move to right split' }) -vim.keymap.set('n', '', 'j', { desc = 'move to below split' }) -vim.keymap.set('n', '', 'k', { desc = 'move to above split' }) -vim.keymap.set('n', '', 'l', { desc = 'move to left split' }) +vim.g.netrw_liststyle=0 +vim.g.netrw_banner=0 diff --git a/lua/myLuaConf/plugins/completion.lua b/lua/plugins/completion.lua similarity index 95% rename from lua/myLuaConf/plugins/completion.lua rename to lua/plugins/completion.lua index 0431493..d861e3a 100644 --- a/lua/myLuaConf/plugins/completion.lua +++ b/lua/plugins/completion.lua @@ -6,18 +6,18 @@ end return { { "cmp-cmdline", - for_cat = "completion", + for_cat = "lazy", on_plugin = { "blink.cmp" }, load = load_w_after, }, { "blink.compat", - for_cat = "completion", + for_cat = "lazy", dep_of = { "cmp-cmdline" }, }, { "luasnip", - for_cat = "completion", + for_cat = "lazy", dep_of = { "blink.cmp" }, after = function(_) vim.cmd.packadd("friendly-snippets") @@ -36,17 +36,17 @@ return { }, { "colorful-menu.nvim", - for_cat = "completion", + for_cat = "lazy", on_plugin = { "blink.cmp" }, }, { "blink-emoji.nvim", - for_cat = "completion", + for_cat = "lazy", on_plugin = { "blink.cmp" }, }, { "blink.cmp", - for_cat = "completion", + for_cat = "lazy", event = "DeferredUIEnter", after = function(_) require("blink.cmp").setup({ diff --git a/lua/plugins/gitsigns.lua b/lua/plugins/gitsigns.lua new file mode 100644 index 0000000..f75b4ab --- /dev/null +++ b/lua/plugins/gitsigns.lua @@ -0,0 +1,86 @@ +return { + { + "gitsigns.nvim", + for_cat = 'lazy', + 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/plugins/init.lua b/lua/plugins/init.lua new file mode 100644 index 0000000..75916ad --- /dev/null +++ b/lua/plugins/init.lua @@ -0,0 +1,39 @@ +local colorschemeName = nixInfo("retrobox", "settings", "colorscheme") + +vim.cmd.colorscheme(colorschemeName) + +require("plugins.lualine") +require("plugins.oil") +require("plugins.snacks") + +require('lze').load { + { import = "plugins.treesitter", }, + { import = "plugins.gitsigns", }, + { import = "plugins.which-key", }, + { import = "plugins.completion", }, + { import = "plugins.preview.markdown", }, + { import = "plugins.preview.typst", }, + { + "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 + }, +} diff --git a/lua/plugins/lualine.lua b/lua/plugins/lualine.lua new file mode 100644 index 0000000..8326653 --- /dev/null +++ b/lua/plugins/lualine.lua @@ -0,0 +1,36 @@ +-- lualine +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 } } + }, +}) + +-- marks.nvim +require("marks").setup({}) diff --git a/lua/plugins/oil.lua b/lua/plugins/oil.lua new file mode 100644 index 0000000..0acfa22 --- /dev/null +++ b/lua/plugins/oil.lua @@ -0,0 +1,45 @@ +-- oil.nvim +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", + }, +}) +-- 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, +}) +-- oil keybinds +vim.keymap.set("n", "-", "Oil", { noremap = true, desc = "Open Parent Directory" }) +vim.keymap.set("n", "-", "Oil .", { noremap = true, desc = "Open nvim root directory" }) diff --git a/lua/plugins/preview/markdown.lua b/lua/plugins/preview/markdown.lua new file mode 100644 index 0000000..c15a09b --- /dev/null +++ b/lua/plugins/preview/markdown.lua @@ -0,0 +1,19 @@ +return { + "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, +} diff --git a/lua/plugins/preview/typst.lua b/lua/plugins/preview/typst.lua new file mode 100644 index 0000000..5faa5dd --- /dev/null +++ b/lua/plugins/preview/typst.lua @@ -0,0 +1,14 @@ +return { + "typst-preview.nvim", + for_cat = "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 +} diff --git a/lua/plugins/snacks.lua b/lua/plugins/snacks.lua new file mode 100644 index 0000000..3ed8815 --- /dev/null +++ b/lua/plugins/snacks.lua @@ -0,0 +1,87 @@ +-- snacks.nvim setup +require("snacks").setup({ + 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 = true, configure = false }, +}) +-- 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" }) + +-- double tap escape leaves terminal mode +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" }) diff --git a/lua/myLuaConf/plugins/treesitter.lua b/lua/plugins/treesitter.lua similarity index 72% rename from lua/myLuaConf/plugins/treesitter.lua rename to lua/plugins/treesitter.lua index ed8e56f..9b49fcf 100644 --- a/lua/myLuaConf/plugins/treesitter.lua +++ b/lua/plugins/treesitter.lua @@ -3,19 +3,13 @@ return { { "nvim-treesitter", - for_cat = 'treesitter', - -- cmd = { "" }, + for_cat = 'lazy', 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` + after = function() require('nvim-treesitter').setup { highlight = { enable = true, }, indent = { enable = false, }, @@ -24,14 +18,14 @@ return { }, { "comment.nvim", - for_cat = 'treesitter', + for_cat = 'lazy', after = function(plugin) require('Comment').setup() end, }, { "treesj", - for_cat = 'treesitter', + for_cat = 'lazy', keys = { { "j", "TSJToggle", mode = { "n" }, desc = "Treesitter join" }, }, after = function(_) require("treesj").setup({ diff --git a/lua/plugins/which-key.lua b/lua/plugins/which-key.lua new file mode 100644 index 0000000..c91aa99 --- /dev/null +++ b/lua/plugins/which-key.lua @@ -0,0 +1,22 @@ +return { + { + "which-key.nvim", + for_cat = 'lazy', + 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/module.nix b/module.nix new file mode 100644 index 0000000..5937917 --- /dev/null +++ b/module.nix @@ -0,0 +1,283 @@ +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 = "gruvbox"; + }; + 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 = { + 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 + delta + 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 + 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 + ]; + }; +}