diff --git a/flake.lock b/flake.lock index 73d791e..a9853c4 100644 --- a/flake.lock +++ b/flake.lock @@ -1,13 +1,16 @@ { "nodes": { "dart": { - "flake": false, + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, "locked": { - "lastModified": 1760366615, - "narHash": "sha256-qGWNl+UQLvdFl8AAgywOHthizfKovk8az1xhRhQeVn8=", + "lastModified": 1761202123, + "narHash": "sha256-ULrZW4b8SKRvPpJPt8/jkqqc/blQiIWUriNWVXA33so=", "owner": "iofq", "repo": "dart.nvim", - "rev": "5fac43b0f7b5500c69a51a3717aef8ccceacd178", + "rev": "71421e7ef5aee8267e24dc562fdd07a83bda192e", "type": "github" }, "original": { @@ -32,38 +35,6 @@ "type": "github" } }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_3": { - "flake": false, - "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" @@ -90,11 +61,11 @@ ] }, "locked": { - "lastModified": 1759362264, - "narHash": "sha256-wfG0S7pltlYyZTM+qqlhJ7GMw2fTF4mLKCIVhLii/4M=", + "lastModified": 1760948891, + "narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "758cf7296bee11f1706a574c77d072b8a7baa881", + "rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04", "type": "github" }, "original": { @@ -107,6 +78,23 @@ "inputs": { "systems": "systems" }, + "locked": { + "lastModified": 1731533236, + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, "locked": { "lastModified": 1731533236, "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", @@ -168,29 +156,6 @@ "type": "github" } }, - "git-hooks_2": { - "inputs": { - "flake-compat": "flake-compat_3", - "gitignore": "gitignore_2", - "nixpkgs": [ - "neovim-nightly-overlay", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1760392170, - "narHash": "sha256-WftxJgr2MeDDFK47fQKywzC72L2jRc/PWcyGdjaDzkw=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "46d55f0aeb1d567a78223e69729734f3dca25a85", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, "gitignore": { "inputs": { "nixpkgs": [ @@ -213,53 +178,6 @@ "type": "github" } }, - "gitignore_2": { - "inputs": { - "nixpkgs": [ - "neovim-nightly-overlay", - "git-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "hercules-ci-effects": { - "inputs": { - "flake-parts": [ - "neovim-nightly-overlay", - "flake-parts" - ], - "nixpkgs": [ - "neovim-nightly-overlay", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1758022363, - "narHash": "sha256-ENUhCRWgSX4ni751HieNuQoq06dJvApV/Nm89kh+/A0=", - "owner": "hercules-ci", - "repo": "hercules-ci-effects", - "rev": "1a3667d33e247ad35ca250698d63f49a5453d824", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "hercules-ci-effects", - "type": "github" - } - }, "luvit-meta": { "flake": false, "locked": { @@ -278,20 +196,18 @@ }, "neovim-nightly-overlay": { "inputs": { - "flake-compat": "flake-compat_2", "flake-parts": "flake-parts_2", - "git-hooks": "git-hooks_2", - "hercules-ci-effects": "hercules-ci-effects", "neovim-src": "neovim-src", - "nixpkgs": "nixpkgs", - "treefmt-nix": "treefmt-nix" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { - "lastModified": 1760400370, - "narHash": "sha256-ghN+xxNfS9xz9VT2f49KjhVAWYBMfo2Z1r8YttPqZvc=", + "lastModified": 1761955453, + "narHash": "sha256-hQomzSbBiFsDXDMCjHmWXrAMgFlQlCiy7T37Eq7RvT4=", "owner": "nix-community", "repo": "neovim-nightly-overlay", - "rev": "921a313d1522414e15f0843bae028f5327b0e2e6", + "rev": "c58076a0d9b24bf77fef4fa2e7c43950914edf71", "type": "github" }, "original": { @@ -303,11 +219,11 @@ "neovim-src": { "flake": false, "locked": { - "lastModified": 1760398177, - "narHash": "sha256-E9Qv7RWRU3qxHtidPyjOMCiow9pRUI5yiNldYaWIeV8=", + "lastModified": 1761949631, + "narHash": "sha256-YgMQaFD4L9+PEYSkUlBkqaKt+ALPHiVgzgRbjOSW4tE=", "owner": "neovim", "repo": "neovim", - "rev": "0ed5e00077dcc8ab1a99dd76a85628b11504ffa4", + "rev": "1fddd74da7428e38b79ccb817dbd6952ff1d8ac6", "type": "github" }, "original": { @@ -318,16 +234,15 @@ }, "nixpkgs": { "locked": { - "lastModified": 1760349414, - "narHash": "sha256-W4Ri1ZwYuNcBzqQQa7NnWfrv0wHMo7rduTWjIeU9dZk=", + "lastModified": 1755660401, "owner": "NixOS", "repo": "nixpkgs", - "rev": "c12c63cd6c5eb34c7b4c3076c6a99e00fcab86ec", + "rev": "5788de501b965d7413f2beaac10aeeb56f9a19a8", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-unstable", + "ref": "master", "repo": "nixpkgs", "type": "github" } @@ -362,11 +277,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1760435515, - "narHash": "sha256-E9D5sWHmPCmWsrCB3Jogvr/7ODiVaKynDrOpG4ba2tI=", + "lastModified": 1761991861, + "narHash": "sha256-rccG7eGGelDsu4eXPi2vdBR1pddZFZAd/JlB3NLjgy4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "db25466bd95abdbe3012be2900a5562fcfb95d51", + "rev": "0e65d6bc462e57fe6a76a49d4eea909ba08b1dc1", "type": "github" }, "original": { @@ -376,14 +291,30 @@ "type": "github" } }, + "nixpkgs_3": { + "locked": { + "lastModified": 1761114652, + "narHash": "sha256-f/QCJM/YhrV/lavyCVz8iU3rlZun6d+dAiC3H+CDle4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "01f116e4df6a15f4ccdffb1bcd41096869fb385c", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nvim-treesitter": { "flake": false, "locked": { - "lastModified": 1760260935, - "narHash": "sha256-To/syCZPs7vKA0WkuBz7ZxCGT/wzj705QfxZng6Nsjo=", + "lastModified": 1761385693, + "narHash": "sha256-/SGikTPEMxI7rcfGvuJlNZs73/wZiQx14QX9xlfsTv0=", "owner": "nvim-treesitter", "repo": "nvim-treesitter", - "rev": "0606c7a9dcaa5c5beee0b0f09043e9fdd1ba0a68", + "rev": "98fe644cb3b5ba390d1bc3f89299f93c70020803", "type": "github" }, "original": { @@ -393,6 +324,26 @@ "type": "github" } }, + "nvim-treesitter-main": { + "inputs": { + "nixpkgs": "nixpkgs_3", + "nvim-treesitter": "nvim-treesitter", + "nvim-treesitter-textobjects": "nvim-treesitter-textobjects" + }, + "locked": { + "lastModified": 1761496664, + "narHash": "sha256-xTQUiJu0jJNSEHEv4La1HbaFokup0eWr67Kqf/wDENA=", + "owner": "iofq", + "repo": "nvim-treesitter-main", + "rev": "834d66648bb7a96a2ad11d53a33f2d9b13766447", + "type": "github" + }, + "original": { + "owner": "iofq", + "repo": "nvim-treesitter-main", + "type": "github" + } + }, "nvim-treesitter-textobjects": { "flake": false, "locked": { @@ -413,12 +364,11 @@ "root": { "inputs": { "dart": "dart", - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "gen-luarc": "gen-luarc", "neovim-nightly-overlay": "neovim-nightly-overlay", "nixpkgs": "nixpkgs_2", - "nvim-treesitter": "nvim-treesitter", - "nvim-treesitter-textobjects": "nvim-treesitter-textobjects" + "nvim-treesitter-main": "nvim-treesitter-main" } }, "systems": { @@ -436,24 +386,18 @@ "type": "github" } }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "neovim-nightly-overlay", - "nixpkgs" - ] - }, + "systems_2": { "locked": { - "lastModified": 1760120816, - "narHash": "sha256-gq9rdocpmRZCwLS5vsHozwB6b5nrOBDNc2kkEaTXHfg=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "761ae7aff00907b607125b2f57338b74177697ed", + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", "type": "github" }, "original": { - "owner": "numtide", - "repo": "treefmt-nix", + "owner": "nix-systems", + "repo": "default", "type": "github" } } diff --git a/flake.nix b/flake.nix index 68da80f..a9cc1ad 100644 --- a/flake.nix +++ b/flake.nix @@ -4,33 +4,23 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/master"; flake-utils.url = "github:numtide/flake-utils"; - neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay"; + neovim-nightly-overlay = { + url = "github:nix-community/neovim-nightly-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; gen-luarc = { url = "github:mrcjkb/nix-gen-luarc-json"; inputs.nixpkgs.follows = "nixpkgs"; }; dart = { url = "github:iofq/dart.nvim"; - flake = false; }; - nvim-treesitter = { - url = "github:nvim-treesitter/nvim-treesitter/main"; - flake = false; + nvim-treesitter-main = { + url = "github:iofq/nvim-treesitter-main"; }; - nvim-treesitter-textobjects = { - url = "github:nvim-treesitter/nvim-treesitter-textobjects/main"; - flake = false; - }; - # Add bleeding-edge plugins here. - # They can be updated with `nix flake update` (make sure to commit the generated flake.lock) - # wf-nvim = { - # url = "github:Cassin01/wf.nvim"; - # flake = false; - # }; }; outputs = inputs@{ - self, nixpkgs, flake-utils, ... @@ -39,22 +29,29 @@ systems = builtins.attrNames nixpkgs.legacyPackages; # This is where the Neovim derivation is built. - plugin-overlay = import ./nix/plugin-overlay.nix { inherit inputs; }; neovim-overlay = import ./nix/neovim-overlay.nix { inherit inputs; }; + finalOverlays = [ + inputs.neovim-nightly-overlay.overlays.default + inputs.nvim-treesitter-main.overlays.default + (final: prev: { + vimPlugins = prev.vimPlugins.extend ( + f: p: { + nvim-treesitter = p.nvim-treesitter.withAllGrammars; + nvim-treesitter-textobjects = p.nvim-treesitter-textobjects.overrideAttrs { + dependencies = [ f.nvim-treesitter ]; + }; + } + ); + }) + neovim-overlay + ]; in flake-utils.lib.eachSystem systems ( system: let pkgs = import nixpkgs { inherit system; - config.allowUnfree = true; - overlays = [ - inputs.neovim-nightly-overlay.overlays.default - plugin-overlay - neovim-overlay - # This adds a function can be used to generate a .luarc.json - # containing the Neovim API all plugins in the workspace directory. - # The generated file can be symlinked in the devShell's shellHook. + overlays = finalOverlays ++ [ inputs.gen-luarc.overlays.default ]; }; @@ -62,16 +59,13 @@ name = "nvim-devShell"; buildInputs = with pkgs; [ lua-language-server - nil + nixd stylua luajitPackages.luacheck - nvim-dev ]; shellHook = '' # symlink the .luarc.json generated in the overlay ln -fs ${pkgs.nvim-luarc-json} .luarc.json - # allow quick iteration of lua configs - ln -Tfns $PWD/nvim ~/.config/nvim-dev ''; }; in @@ -80,7 +74,6 @@ default = nvim; nvim = pkgs.nvim-pkg; nvim-min = pkgs.nvim-min-pkg; - nvim-dev = pkgs.nvim-dev; }; devShells = { default = shell; @@ -88,6 +81,6 @@ } ) // { - overlays.default = neovim-overlay; + overlays.default = nixpkgs.lib.composeManyExtensions finalOverlays; }; } diff --git a/nix/mkNeovim.nix b/nix/mkNeovim.nix index 7d2e3a6..83baf98 100644 --- a/nix/mkNeovim.nix +++ b/nix/mkNeovim.nix @@ -1,197 +1,23 @@ -# Function for creating a Neovim derivation +{ pkgs, lib }: { - pkgs, - lib, - stdenv, - # Set by the overlay to ensure we use a compatible version of `wrapNeovimUnstable` - pkgs-wrapNeovim ? pkgs, -}: -with lib; -{ - # NVIM_APPNAME - Defaults to 'nvim' if not set. - # If set to something else, this will also rename the binary. - appName ? "nvim", - # The Neovim package to wrap - neovim-unwrapped ? pkgs-wrapNeovim.neovim-unwrapped, - plugins ? [ ], # List of plugins - # List of dev plugins (will be bootstrapped) - useful for plugin developers - # { name = ; url = ; } - devPlugins ? [ ], - # Regexes for config files to ignore, relative to the nvim directory. - # e.g. [ "^plugin/neogit.lua" "^ftplugin/.*.lua" ] - ignoreConfigRegexes ? [ ], - extraPackages ? [ ], # Extra runtime dependencies (e.g. ripgrep, ...) - # The below arguments can typically be left as their defaults - # Additional lua packages (not plugins), e.g. from luarocks.org. - # e.g. p: [p.jsregexp] - extraLuaPackages ? p: [ ], - extraPython3Packages ? p: [ ], # Additional python 3 packages - withPython3 ? false, # Build Neovim with Python 3 support? - withRuby ? false, # Build Neovim with Ruby support? - withNodeJs ? false, # Build Neovim with NodeJS support? - withSqlite ? true, # Add sqlite? This is a dependency for some plugins - # You probably don't want to create vi or vim aliases - # if the appName is something different than "nvim" - viAlias ? appName == "nvim", # Add a "vi" binary to the build output as an alias? - vimAlias ? appName == "nvim", # Add a "vim" binary to the build output as an alias? - wrapRc ? true, + plugins ? [ ], + packages ? [ ], }: let - # This is the structure of a plugin definition. - # Each plugin in the `plugins` argument list can also be defined as this attrset - defaultPlugin = { - plugin = null; # e.g. nvim-lspconfig - config = null; # plugin config - # If `optional` is set to `false`, the plugin is installed in the 'start' packpath - # set to `true`, it is installed in the 'opt' packpath, and can be lazy loaded with - # ':packadd! {plugin-name} - optional = false; - runtime = { }; - }; - - externalPackages = extraPackages ++ (optionals withSqlite [ pkgs.sqlite ]); - - # Map all plugins to an attrset { plugin = ; config = ; optional = ; ... } - normalizedPlugins = map (x: defaultPlugin // (if x ? plugin then x else { plugin = x; })) plugins; - - # This nixpkgs util function creates an attrset - # that pkgs.wrapNeovimUnstable uses to configure the Neovim build. - neovimConfig = pkgs-wrapNeovim.neovimUtils.makeNeovimConfig { - inherit - extraPython3Packages - withPython3 - withRuby - withNodeJs - viAlias - vimAlias - ; - plugins = normalizedPlugins; - }; - - packDir = pkgs.neovimUtils.packDir { - myNeovimPackages = pkgs.neovimUtils.normalizedPluginsToVimPackage normalizedPlugins; - }; - - # This uses the ignoreConfigRegexes list to filter - # the nvim directory - nvimRtpSrc = - let - src = ../nvim; - in - lib.cleanSourceWith { - inherit src; - name = "nvim-rtp-src"; - filter = - path: tyoe: - let - srcPrefix = toString src + "/"; - relPath = lib.removePrefix srcPrefix (toString path); - in - lib.all (regex: builtins.match regex relPath == null) ignoreConfigRegexes; - }; - - # Split runtimepath into 3 directories: - # - lua, to be prepended to the rtp at the beginning of init.lua - # - nvim, containing plugin, ftplugin, ... subdirectories - # - after, to be sourced last in the startup initialization - # See also: https://neovim.io/doc/user/starting.html - nvimRtp = stdenv.mkDerivation { - name = "nvim-rtp"; - src = nvimRtpSrc; - - buildPhase = '' - mkdir -p $out/ - ''; - - installPhase = '' - cp -r . $out/ - ''; - }; - - # The final init.lua content that we pass to the Neovim wrapper. - # It wraps the user init.lua, prepends the lua lib directory to the RTP - # and prepends the nvim and after directory to the RTP - initLua = '' - LAZY_OPTS = { - performance = { - reset_packpath = false, - rtp = { - reset = false, - disabled_plugins = { - "netrwPlugin", - "tutor", - }, - }, - }, - dev = { - path = "${packDir}/pack/myNeovimPackages/start", - patterns = {""}, - }, - checker = { - enabled = false, - }, - install = { missing = false, }, - spec = {{ import = "plugins" }}, - } - vim.opt.rtp:prepend('${nvimRtp}') - '' - + (builtins.readFile ../nvim/init.lua); - - # Add arguments to the Neovim wrapper script - extraMakeWrapperArgs = builtins.concatStringsSep " " ( - # Set the NVIM_APPNAME environment variable - (optional ( - appName != "nvim" && appName != null && appName != "" - ) ''--set NVIM_APPNAME "${appName}"'') - # Add external packages to the PATH - ++ (optional (externalPackages != [ ]) ''--prefix PATH : "${makeBinPath externalPackages}"'') - # Set the LIBSQLITE_CLIB_PATH if sqlite is enabled - ++ (optional withSqlite ''--set LIBSQLITE_CLIB_PATH "${pkgs.sqlite.out}/lib/libsqlite3.so"'') - # Set the LIBSQLITE environment variable if sqlite is enabled - ++ (optional withSqlite ''--set LIBSQLITE "${pkgs.sqlite.out}/lib/libsqlite3.so"'') - ); - - luaPackages = neovim-unwrapped.lua.pkgs; - resolvedExtraLuaPackages = extraLuaPackages luaPackages; - - # Native Lua libraries - extraMakeWrapperLuaCArgs = - optionalString (resolvedExtraLuaPackages != [ ]) - ''--suffix LUA_CPATH ";" "${ - concatMapStringsSep ";" luaPackages.getLuaCPath resolvedExtraLuaPackages - }"''; - - # Lua libraries - extraMakeWrapperLuaArgs = - optionalString (resolvedExtraLuaPackages != [ ]) - ''--suffix LUA_PATH ";" "${ - concatMapStringsSep ";" luaPackages.getLuaPath resolvedExtraLuaPackages - }"''; - - # wrapNeovimUnstable is the nixpkgs utility function for building a Neovim derivation. - neovim-wrapped = pkgs-wrapNeovim.wrapNeovimUnstable neovim-unwrapped ( - neovimConfig - // { - luaRcContent = initLua; - wrapperArgs = - escapeShellArgs neovimConfig.wrapperArgs - + " " - + extraMakeWrapperArgs - + " " - + extraMakeWrapperLuaCArgs - + " " - + extraMakeWrapperLuaArgs; - wrapRc = wrapRc; - } - ); - - isCustomAppName = appName != null && appName != "nvim"; + finalPlugins = plugins ++ [ + (pkgs.vimUtils.buildVimPlugin { + pname = "iofq-nvim"; + src = lib.cleanSource ../nvim; + version = "0.1"; + doCheck = false; + }) + ]; + wrapperArgs = ''--prefix PATH : "${lib.makeBinPath packages}"''; in -neovim-wrapped.overrideAttrs (oa: { - buildPhase = - oa.buildPhase - # If a custom NVIM_APPNAME has been set, rename the `nvim` binary - + lib.optionalString isCustomAppName '' - mv $out/bin/nvim $out/bin/${lib.escapeShellArg appName} - ''; -}) +pkgs.wrapNeovimUnstable pkgs.neovim-unwrapped { + inherit wrapperArgs; + plugins = finalPlugins; + withPython3 = false; + withRuby = false; + vimAlias = true; +} diff --git a/nix/neovim-overlay.nix b/nix/neovim-overlay.nix index 204e118..430c345 100644 --- a/nix/neovim-overlay.nix +++ b/nix/neovim-overlay.nix @@ -1,25 +1,20 @@ # This overlay, when applied to nixpkgs, adds the final neovim derivation to nixpkgs. { inputs }: final: prev: -with final.pkgs.lib; let - mkNeovim = prev.callPackage ./mkNeovim.nix { pkgs-wrapNeovim = prev; }; + mkNeovim = prev.callPackage ./mkNeovim.nix { pkgs = final; }; + dart-nvim = inputs.dart.packages.x86_64-linux.default; - plugins = with final.vimPlugins; [ + plugins = with prev.vimPlugins; [ blink-cmp blink-ripgrep-nvim conform-nvim dart-nvim - diffview-nvim - eyeliner-nvim - friendly-snippets - lazy-nvim mini-nvim nvim-autopairs nvim-lint nvim-lspconfig - nvim-treesitter.withAllGrammars - nvim-treesitter-context + nvim-treesitter nvim-treesitter-textobjects quicker-nvim refactoring-nvim @@ -27,12 +22,12 @@ let snacks-nvim ]; - basePackages = with final; [ + basePackages = with prev; [ ripgrep fd ]; # Extra packages that should be included on nixos but don't need to be bundled - extraPackages = with final; [ + extraPackages = with prev; [ # linters yamllint jq @@ -44,35 +39,21 @@ let # LSPs gopls lua-language-server - nil + nixd basedpyright - - #other - jujutsu ]; in { nvim-pkg = mkNeovim { inherit plugins; - extraPackages = basePackages ++ extraPackages; + packages = basePackages ++ extraPackages; }; nvim-min-pkg = mkNeovim { inherit plugins; - extraPackages = basePackages; + packages = basePackages; }; - # This is meant to be used within a devshell. - # Instead of loading the lua Neovim configuration from - # the Nix store, it is loaded from $XDG_CONFIG_HOME/nvim-dev - nvim-dev = mkNeovim { - inherit plugins; - extraPackages = basePackages ++ extraPackages; - appName = "nvim-dev"; - wrapRc = false; - }; - - # This can be symlinked in the devShell's shellHook nvim-luarc-json = final.mk-luarc-json { inherit plugins; }; diff --git a/nix/plugin-overlay.nix b/nix/plugin-overlay.nix deleted file mode 100644 index 9a51a54..0000000 --- a/nix/plugin-overlay.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ inputs, ... }: -final: prev: -let - mkNvimPlugin = - src: pname: - prev.vimUtils.buildVimPlugin { - inherit pname src; - version = src.lastModifiedDate; - }; -in -{ - vimPlugins = prev.vimPlugins.extend ( - final': prev': { - dart-nvim = mkNvimPlugin inputs.dart "dart.nvim"; - nvim-treesitter-textobjects = mkNvimPlugin inputs.nvim-treesitter-textobjects "nvim-treesitter-textobjects"; - nvim-treesitter = prev'.nvim-treesitter.overrideAttrs (old: rec { - src = inputs.nvim-treesitter; - name = "${old.pname}-${src.rev}"; - postPatch = ""; - # ensure runtime queries get linked to RTP (:TSInstall does this too) - buildPhase = " - mkdir -p $out/queries - cp -a $src/runtime/queries/* $out/queries - "; - nvimSkipModules = [ "nvim-treesitter._meta.parsers" ]; - }); - } - ); -} diff --git a/nvim/colors/iofq.lua b/nvim/after/colors/iofq.lua similarity index 99% rename from nvim/colors/iofq.lua rename to nvim/after/colors/iofq.lua index be525d8..7d80403 100644 --- a/nvim/colors/iofq.lua +++ b/nvim/after/colors/iofq.lua @@ -626,7 +626,7 @@ hi(0, 'SpellLocal', { sp = '#5a93aa', undercurl = true }) hi(0, 'SpellRare', { sp = '#5a93aa', undercurl = true }) hi(0, 'Statement', { fg = '#ad5c7c' }) hi(0, 'StatusLine', { bg = 'none' }) -hi(0, 'StatusLineNC', { bg = 'none' }) +hi(0, 'StatusLineNC', { bg = 'none', fg = "grey" }) hi(0, 'String', { fg = '#7aa4a1' }) hi(0, 'Substitute', { bg = '#e85c51', fg = '#152528' }) hi(0, 'SymbolOutlineConnector', { link = 'Conceal' }) diff --git a/nvim/ftplugin/go.lua b/nvim/after/ftplugin/go.lua similarity index 100% rename from nvim/ftplugin/go.lua rename to nvim/after/ftplugin/go.lua diff --git a/nvim/ftplugin/php.lua b/nvim/after/ftplugin/php.lua similarity index 100% rename from nvim/ftplugin/php.lua rename to nvim/after/ftplugin/php.lua diff --git a/nvim/lsp/gopls.lua b/nvim/after/lsp/gopls.lua similarity index 100% rename from nvim/lsp/gopls.lua rename to nvim/after/lsp/gopls.lua diff --git a/nvim/lsp/lua_ls.lua b/nvim/after/lsp/lua_ls.lua similarity index 92% rename from nvim/lsp/lua_ls.lua rename to nvim/after/lsp/lua_ls.lua index 4be10e8..f71f2bd 100644 --- a/nvim/lsp/lua_ls.lua +++ b/nvim/after/lsp/lua_ls.lua @@ -19,9 +19,6 @@ return { end, settings = { Lua = { - codeLens = { - enable = true, - }, hint = { enable = true, arrayIndex = 'Enable', diff --git a/nvim/after/lua/iofq/minidiff_jj.lua b/nvim/after/lua/iofq/minidiff_jj.lua new file mode 100644 index 0000000..0294773 --- /dev/null +++ b/nvim/after/lua/iofq/minidiff_jj.lua @@ -0,0 +1,103 @@ +local diff = require('mini.diff') +local M = { + cache = {}, +} + +M.get_buf_realpath = function(buf_id) + local path = vim.loop.fs_realpath(vim.api.nvim_buf_get_name(buf_id)) or '' + local cwd, basename = vim.fn.fnamemodify(path, ':h'), vim.fn.fnamemodify(path, ':t') + return path, cwd, basename +end + +M.jj_start_watching_tree_state = function(buf_id, path) + local on_not_in_jj = vim.schedule_wrap(function() + if not vim.api.nvim_buf_is_valid(buf_id) then + M.cache[buf_id] = nil + return false + end + diff.fail_attach(buf_id) + M.cache[buf_id] = {} + end) + + vim.system( + { 'jj', 'workspace', 'root', '--ignore-working-copy' }, + {cwd = vim.fn.fnamemodify(path, ':h')}, + function(obj) + if obj.code ~= 0 then + return on_not_in_jj() + end + + -- Set up index watching + local root = obj.stdout:gsub('\n+$', '') .. '/.jj/working_copy/tree_state' + local buf_fs_event = vim.loop.new_fs_event() + + buf_fs_event:start(root, { stat = true }, function() + M.jj_set_ref_text(buf_id) + end) + M.cache[buf_id] = { fs_event = buf_fs_event } + + -- Set reference text immediately + M.jj_set_ref_text(buf_id) + end + ) +end + +M.jj_set_ref_text = vim.schedule_wrap(function(buf_id) + if not vim.api.nvim_buf_is_valid(buf_id) then + return + end + + local buf_set_ref_text = function(text) + pcall(diff.set_ref_text, buf_id, text) + end + + -- react to possible rename + local path, cwd, basename = M.get_buf_realpath(buf_id) + if path == '' then + return buf_set_ref_text {} + end + + vim.system( + { 'jj', 'file', 'show', '--no-pager', '--ignore-working-copy', '-r', '@-', './' .. basename }, + { cwd = cwd }, + vim.schedule_wrap(function(obj) + if obj.code ~= 0 then return buf_set_ref_text {} end + buf_set_ref_text(obj.stdout:gsub('\r\n', '\n')) + end) + ) +end) + +M.jj_invalidate_cache = function(buf_id) + pcall(vim.loop.fs_event_stop, M.cache[buf_id].fs_event) + M.cache[buf_id] = nil +end + +M.gen_source = function() + local attach = function(buf_id) + -- Try attaching to a buffer only once + if M.cache[buf_id] ~= nil then + return false + end + -- - Possibly resolve symlinks to get data from the original repo + local path = M.get_buf_realpath(buf_id) + if path == '' then + return false + end + + M.cache[buf_id] = {} + M.jj_start_watching_tree_state(buf_id, path) + end + + local detach = function(buf_id) + M.jj_invalidate_cache(buf_id) + end + + + return { + name = 'jj', + attach = attach, + detach = detach, + apply_hunks = function(_, _) end -- staging does not apply for jj + } +end +return M diff --git a/nvim/after/lua/iofq/snacks_jj.lua b/nvim/after/lua/iofq/snacks_jj.lua new file mode 100644 index 0000000..639ecfd --- /dev/null +++ b/nvim/after/lua/iofq/snacks_jj.lua @@ -0,0 +1,52 @@ +local M = {} + +function M.status() + local function get_files() + local status_raw = vim.fn.system('jj diff --no-pager --quiet --summary') + local files = {} + + for status in status_raw:gmatch('[^\r\n]+') do + local state, file = string.match(status, '^(%a)%s(.+)$') + + if state and file then + local hl = '' + if state == 'A' then + hl = 'SnacksPickerGitStatusAdded' + elseif state == 'M' then + hl = 'SnacksPickerGitStatusModified' + elseif state == 'D' then + hl = 'SnacksPickerGitStatusDeleted' + elseif state == 'R' then + hl = 'SnacksPickerGitStatusRenamed' + file = string.match(file, '{.-=>%s*(.-)}') + end + + local diff = vim.fn.system('jj diff ' .. file .. ' --no-pager --stat --git') + table.insert(files, { + file = file, + filename_hl = hl, + diff = diff, + }) + end + end + + return files + end + + Snacks.picker.pick { + source = 'jj_status', + items = get_files(), + format = 'file', + title = 'jj status', + preview = function(ctx) + if ctx.item.file then + Snacks.picker.preview.diff(ctx) + else + ctx.preview:reset() + ctx.preview:set_title('No preview') + end + end, + } +end + +return M diff --git a/nvim/after/plugin/autocmd.lua b/nvim/after/plugin/autocmd.lua new file mode 100644 index 0000000..e22f2b7 --- /dev/null +++ b/nvim/after/plugin/autocmd.lua @@ -0,0 +1,139 @@ +local cmd = vim.api.nvim_create_autocmd +-- open :h in buffers +cmd('FileType', { + group = vim.api.nvim_create_augroup('help', { clear = true }), + pattern = 'help', + callback = function(_) + vim.cmd.only() + vim.keymap.set('n', 'q', vim.cmd.bdelete, { noremap = true }) + vim.bo.buflisted = false + end, +}) + +-- resize splits if window got resized +cmd({ 'VimResized' }, { + group = vim.api.nvim_create_augroup('resize_splits', { clear = true }), + callback = function() + vim.cmd('tabdo wincmd =') + vim.cmd('tabnext ' .. vim.fn.tabpagenr()) + end, +}) + +-- Check if we need to reload the file when it changed +cmd({ 'FocusGained', 'TermClose', 'TermLeave' }, { + group = vim.api.nvim_create_augroup('check_reload', { clear = true }), + callback = function() + if vim.o.buftype ~= 'nofile' then + vim.cmd('checktime') + end + end, +}) + +-- Configure difftool buffers +vim.api.nvim_create_autocmd('FileType', { + pattern = 'qf', + group = vim.api.nvim_create_augroup('difftool', { clear = true }), + callback = function(event) + local function exec(fmt, str) + return os.execute(string.format(fmt, str)) + end + local function refresh() + local qf = vim.fn.getqflist() + + local entry = qf[1] + if not entry or not entry.user_data.diff then + return nil + end + + local ns = vim.api.nvim_create_namespace('nvim.difftool.hl') + vim.api.nvim_buf_clear_namespace(event.buf, ns, 0, -1) + for i, item in ipairs(qf) do + local path = vim.fn.fnamemodify(item.user_data.right, ':t') + local hl = 'Added' + if + exec('git diff --quiet -- %s', path) ~= 0 + or exec('git ls-files --error-unmatch -- %s > /dev/null 2>&1', path) ~= 0 + then + hl = 'Removed' + end + vim.hl.range(event.buf, ns, hl, { i - 1, 0 }, { i - 1, -1 }) + end + end + vim.keymap.set('n', 'gh', function() + local idx = vim.api.nvim_win_get_cursor(0)[1] + local qf = vim.fn.getqflist() + local filename = qf[idx].user_data.rel + + if exec('git diff --quiet --cached -- %s', filename) ~= 0 then + exec('git restore --quiet --staged -- %s', filename) + else + exec('git add -- %s', filename) + end + refresh() + end) + vim.schedule(refresh) + end, +}) + +-- Init treesitter +cmd('FileType', { + group = vim.api.nvim_create_augroup('treesitter', { clear = true }), + callback = function(event) + local bufnr = event.buf + + vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" + pcall(vim.treesitter.start, bufnr) + + vim.keymap.set({ 'v', 'n' }, ']]', function() + require('nvim-treesitter-textobjects.move').goto_next_start('@function.outer', 'textobjects') + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, '[[', function() + require('nvim-treesitter-textobjects.move').goto_previous_start('@function.outer', 'textobjects') + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, ']a', function() + require('nvim-treesitter-textobjects.move').goto_next_start('@parameter.inner', 'textobjects') + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, '[a', function() + require('nvim-treesitter-textobjects.move').goto_previous_start('@parameter.inner', 'textobjects') + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, ']A', function() + require('nvim-treesitter-textobjects.swap').swap_next('@parameter.inner') + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, '[A', function() + require('nvim-treesitter-textobjects.swap').swap_previous('@parameter.inner') + end, { buffer = bufnr }) + end, +}) + +-- Init LSP +cmd('LspAttach', { + group = vim.api.nvim_create_augroup('UserLspConfig', {}), + callback = function(ev) + local client = vim.lsp.get_client_by_id(ev.data.client_id) + if not client then + return + end + vim.keymap.set('n', 'gO', function() + Snacks.picker.lsp_symbols { focus = 'list' } + end, { buffer = ev.buf }) + + vim.keymap.set('n', 'grh', function() + vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) + end, { buffer = ev.buf }) + vim.keymap.set('n', 'grl', vim.lsp.codelens.run, { buffer = ev.buf }) + + vim.keymap.set('n', 'gre', vim.diagnostic.setloclist, { buffer = ev.buf }) + vim.keymap.set('n', 'grE', vim.diagnostic.setqflist, { buffer = ev.buf }) + + -- Auto-refresh code lenses + if client:supports_method('textDocument/codeLens') or client.server_capabilities.codeLensProvider then + vim.lsp.codelens.refresh { bufnr = ev.buf } + cmd({ 'InsertLeave', 'TextChanged' }, { + callback = function() + vim.lsp.codelens.refresh { bufnr = ev.buf } + end, + buffer = ev.buf, + }) + end + end, +}) diff --git a/nvim/lua/config/init.lua b/nvim/after/plugin/init.lua similarity index 58% rename from nvim/lua/config/init.lua rename to nvim/after/plugin/init.lua index f9ba85f..b2afa6a 100644 --- a/nvim/lua/config/init.lua +++ b/nvim/after/plugin/init.lua @@ -1,6 +1,10 @@ +vim.cmd('colorscheme iofq') + +vim.g.mapleader = ' ' vim.opt.autowrite = true vim.opt.backspace = 'indent,eol,start' vim.opt.confirm = true +vim.opt.completeopt = 'menuone,popup,noselect,fuzzy' vim.opt.diffopt = 'internal,filler,closeoff,inline:char' vim.opt.expandtab = true -- insert tabs as spaces vim.opt.inccommand = 'split' -- incremental live completion @@ -31,7 +35,30 @@ vim.diagnostic.config { source = 'if_many', }, } -vim.schedule(function() - require('config.autocmd') - require('config.keymaps') + +vim.lsp.enable { + 'nixd', + 'phpactor', + 'gopls', + 'lua_ls', + 'basedpyright', +} + +local map = vim.keymap.set +map('n', '\\t', function() -- Switch tab length on the fly + vim.o.tabstop = vim.o.tabstop == 8 and 2 or 2 * vim.o.tabstop + vim.notify('tabstop: ' .. vim.o.tabstop) end) +map({ 'v', 'i' }, 'wq', 'l') +map('v', '<', '', '>gv') +map('n', 'n', 'nzz', { noremap = true }) +map('n', 'N', 'Nzz', { noremap = true }) +map('n', '', 'zz', { noremap = true }) +map('n', '', 'zz', { noremap = true }) +map('n', 'gq', vim.cmd.bdelete, { noremap = true }) +map('n', 'gQ', function() + vim.cmd('bufdo bdelete') +end, { noremap = true }) + +vim.cmd.packadd('nvim.difftool') diff --git a/nvim/after/plugin/mini.lua b/nvim/after/plugin/mini.lua new file mode 100644 index 0000000..c60ec00 --- /dev/null +++ b/nvim/after/plugin/mini.lua @@ -0,0 +1,78 @@ +local map = vim.keymap.set + +vim.schedule(function() + require('mini.align').setup() + require('mini.surround').setup() + require('mini.splitjoin').setup { detect = { separator = '[,;\n]' } } + + local ai = require('mini.ai') + ai.setup { + n_lines = 300, + custom_textobjects = { + i = require('mini.extra').gen_ai_spec.indent(), + b = require('mini.extra').gen_ai_spec.buffer(), + a = ai.gen_spec.treesitter { a = '@parameter.outer', i = '@parameter.inner' }, + f = ai.gen_spec.treesitter { a = '@function.outer', i = '@function.inner' }, + }, + } + + require('mini.git').setup() + map('n', 'gb', 'Git blame -- %') + map('n', 'go', function() + return MiniGit.show_at_cursor() + end) + + local jump = require('mini.jump2d') + jump.setup { + mappings = { + start_jumping = 's', + }, + view = { n_steps_ahead = 1, dim = true }, + spotter = jump.gen_spotter.vimpattern(), + } + + local diff = require('mini.diff') + diff.setup { + source = { + require('iofq.minidiff_jj').gen_source(), + diff.gen_source.git(), + }, + } + map('n', 'gp', MiniDiff.toggle_overlay) + + require('mini.files').setup { + mappings = { go_in_plus = '' }, + windows = { + preview = true, + width_preview = 50, + }, + } + map('n', 'nc', function() + MiniFiles.open(vim.api.nvim_buf_get_name(0), false) -- open current buffer's dir + end) + vim.api.nvim_create_autocmd('User', { + pattern = 'MiniFilesBufferCreate', + callback = function(args) + map('n', 'nc', function() + MiniFiles.synchronize() + MiniFiles.close() + end, { buffer = args.data.buf_id }) + map('n', '`', function() + local _, cur_entry_path = pcall(MiniFiles.get_fs_entry().path) + local cur_directory = vim.fs.dirname(cur_entry_path) + if cur_directory ~= '' then + vim.fn.chdir(cur_directory) + end + end, { buffer = args.data.buf_id }) + end, + }) + + -- pass file rename events to LSP + vim.api.nvim_create_autocmd('User', { + group = vim.api.nvim_create_augroup('snacks_rename', { clear = true }), + pattern = 'MiniFilesActionRename', + callback = function(event) + Snacks.rename.on_rename_file(event.data.from, event.data.to) + end, + }) +end) diff --git a/nvim/after/plugin/plugins.lua b/nvim/after/plugin/plugins.lua new file mode 100644 index 0000000..58dae3e --- /dev/null +++ b/nvim/after/plugin/plugins.lua @@ -0,0 +1,153 @@ +local map = vim.keymap.set + +require('mini.basics').setup { mappings = { windows = true } } +require('mini.icons').setup() + +require('dart').setup { + tabline = { + icons = false, + label_marked_fg = 'cyan', + }, +} + +require('snacks').setup { + bigfile = { enabled = true }, + terminal = { enabled = true }, + indent = { enabled = true }, + input = { enabled = true }, + notifier = { enabled = true }, + styles = { notification = { wo = { wrap = true } } }, + picker = { + enabled = true, + matcher = { + frecency = true, + cwd_bonus = true, + }, + layout = 'ivy_split', + sources = { + grep = { hidden = true }, + lsp_symbols = { + filter = { default = true }, + layout = { + preset = 'left', + layout = { width = 90, min_width = 90 }, + }, + }, + smart = { + multi = { + 'buffers', + { source = 'files', hidden = true }, + { source = 'git_files', untracked = true }, + }, + }, + }, + }, +} + +map({ 'n', 't' }, '', Snacks.terminal.toggle) +map('n', 'ff', Snacks.picker.smart) +map('n', '', Snacks.picker.smart) +map('n', 'fa', Snacks.picker.grep) +map('n', 'f8', Snacks.picker.grep_word) +map('n', 'f?', Snacks.picker.pickers) +map('n', 'fu', Snacks.picker.undo) +map('n', 'fj', Snacks.picker.jumps) +map('n', 'f.', Snacks.picker.resume) +map('n', 'fb', Snacks.picker.buffers) +map('n', 'fq', Snacks.picker.qflist) +map('n', 'jf', require('iofq.snacks_jj').status) + +vim.schedule(function() + require('nvim-treesitter').setup() + require('nvim-treesitter-textobjects').setup() + require('render-markdown').setup() + require('nvim-autopairs').setup() + + require('refactoring').setup() + map('n', 'rr', require('refactoring').select_refactor) + map('n', 'rv', function() + require('refactoring').refactor('Inline Variable') + end) + + require('quicker').setup() + map('n', 'qf', function() + require('quicker').toggle { max_height = 20 } + end) + + require('conform').setup { + notify_no_formatters = false, + formatters_by_ft = { + json = { 'jq' }, + lua = { 'stylua' }, + python = { 'ruff' }, + nix = { 'nixfmt' }, + fish = { 'fish_indent' }, + ['*'] = { 'trim_whitespace' }, + }, + format_on_save = function(bufnr) + -- Disable with a global or buffer-local variable + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + return { timeout_ms = 1500, lsp_format = 'fallback' } + end, + } + map('n', '\\f', function() + vim.b.disable_autoformat = not vim.b.disable_autoformat + vim.notify(string.format('Buffer formatting disabled: %s', vim.b.disable_autoformat)) + end) + map('n', '\\F', function() + vim.g.disable_autoformat = not vim.g.disable_autoformat + vim.notify(string.format('Global formatting disabled: %s', vim.g.disable_autoformat)) + end) + + require('lint').linters_by_ft = { + docker = { 'hadolint' }, + yaml = { 'yamllint' }, + sh = { 'shellcheck' }, + go = { 'golangcilint' }, + ruby = { 'rubocop' }, + fish = { 'fish' }, + bash = { 'bash' }, + nix = { 'nix' }, + php = { 'php' }, + } + vim.api.nvim_create_autocmd({ 'BufWritePost' }, { + callback = function() + require('lint').try_lint(nil, { ignore_errors = true }) + end, + }) + + vim.treesitter.language.register('markdown', 'blink-cmp-documentation') + require('blink.cmp').setup { + enabled = function() + return not vim.tbl_contains({ 'snacks_picker_input' }, vim.bo.filetype) + end, + sources = { + default = { 'lsp', 'path', 'snippets', 'ripgrep', 'buffer' }, + providers = { + lsp = { fallbacks = {} }, -- include buffer even when LSP is active + path = { opts = { get_cwd = vim.fn.getcwd } }, -- use nvim pwd instead of current file pwd + ripgrep = { + module = 'blink-ripgrep', + name = 'rg', + score_offset = -10, + async = true, + }, + }, + }, + cmdline = { completion = { menu = { auto_show = true } } }, + completion = { + documentation = { auto_show = true }, + menu = { + draw = { + columns = { + { 'label', 'label_description', gap = 1 }, + { 'source_name', 'kind', gap = 1 }, + }, + }, + }, + }, + signature = { enabled = true, trigger = { show_on_insert = true } }, + } +end) diff --git a/nvim/init.lua b/nvim/init.lua deleted file mode 100644 index 622287b..0000000 --- a/nvim/init.lua +++ /dev/null @@ -1,34 +0,0 @@ -vim.g.mapleader = ' ' --- If lazy_opts is set, we're running in wrapped neovim via nix -if not LAZY_OPTS then - -- Bootstrapping lazy.nvim - local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' - if not vim.loop.fs_stat(lazypath) then - vim.fn.system { - 'git', - 'clone', - '--filter=blob:none', - 'https://github.com/folke/lazy.nvim.git', - '--branch=stable', -- latest stable release - lazypath, - } - end - vim.opt.rtp:prepend(lazypath) - LAZY_OPTS = { - spec = { { import = 'plugins' } }, - performance = { - reset_packpath = false, - rtp = { - reset = false, - disabled_plugins = { - 'netrwPlugin', - 'tutor', - }, - }, - }, - } -end -vim.cmd('packadd cfilter') -vim.cmd('colorscheme iofq') -require('lazy').setup(LAZY_OPTS) -require('config') diff --git a/nvim/lua/config/autocmd.lua b/nvim/lua/config/autocmd.lua deleted file mode 100644 index d40ad17..0000000 --- a/nvim/lua/config/autocmd.lua +++ /dev/null @@ -1,105 +0,0 @@ --- open :h in buffers -vim.api.nvim_create_autocmd('BufWinEnter', { - pattern = '*', - callback = function(event) - if vim.bo[event.buf].filetype == 'help' then - vim.cmd.only() - vim.keymap.set('n', 'q', vim.cmd.bdelete, { noremap = true, silent = true }) - vim.bo.buflisted = false - end - end, -}) - --- Allow basic deletion in qflist -vim.api.nvim_create_autocmd({ 'FileType' }, { - pattern = 'qf', - callback = function() - vim.keymap.set({ 'n', 'i' }, 'dd', function() - local ln = vim.fn.line('.') - local qf = vim.fn.getqflist() - if #qf == 0 then - return - end - table.remove(qf, ln) - vim.fn.setqflist(qf, 'r') - vim.cmd('copen') - -- move cursor to stay at same index (or up one if at EOF) - vim.api.nvim_win_set_cursor(vim.fn.win_getid(), { ln < #qf and ln or math.max(ln - 1, 1), 0 }) - require('quicker').refresh() - end, { buffer = true }) - end, -}) - --- resize splits if window got resized -vim.api.nvim_create_autocmd({ 'VimResized' }, { - group = vim.api.nvim_create_augroup('resize_splits', { clear = true }), - callback = function() - local current_tab = vim.fn.tabpagenr() - vim.cmd('tabdo wincmd =') - vim.cmd('tabnext ' .. current_tab) - end, -}) - --- Check if we need to reload the file when it changed -vim.api.nvim_create_autocmd({ 'FocusGained', 'TermClose', 'TermLeave' }, { - group = vim.api.nvim_create_augroup('check_reload', { clear = true }), - callback = function() - if vim.o.buftype ~= 'nofile' then - vim.cmd('checktime') - end - end, -}) - --- Init treesitter -vim.api.nvim_create_autocmd('FileType', { - callback = function(event) - local bufnr = event.buf - local filetype = vim.api.nvim_get_option_value('filetype', { buf = bufnr }) - - if filetype == '' then - return - end - - local parser_name = vim.treesitter.language.get_lang(filetype) - if not parser_name then - return - end - local parser_installed = pcall(vim.treesitter.get_parser, bufnr, parser_name) - if not parser_installed then - return - end - - local function map(lhs, rhs, opts) - if lhs == '' then - return - end - opts = vim.tbl_deep_extend('force', { silent = true }, opts or {}) - vim.keymap.set({ 'v', 'n' }, lhs, rhs, opts) - end - - vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" - vim.treesitter.start() - - map('[c', function() - require('treesitter-context').go_to_context(vim.v.count1) - end, { buffer = bufnr, desc = 'jump to TS context' }) - map(']f', function() - require('nvim-treesitter-textobjects.move').goto_next_start('@function.outer', 'textobjects') - end, { buffer = bufnr, desc = 'next function def' }) - map('[f', function() - require('nvim-treesitter-textobjects.move').goto_previous_start('@function.outer', 'textobjects') - end, { buffer = bufnr, desc = 'prev function def' }) - map(']a', function() - require('nvim-treesitter-textobjects.move').goto_next_start('@parameter.inner', 'textobjects') - end, { buffer = bufnr, desc = 'next param def' }) - map('[a', function() - require('nvim-treesitter-textobjects.move').goto_previous_start('@parameter.inner', 'textobjects') - end, { buffer = bufnr, desc = 'prev param def' }) - map('a]', function() - require('nvim-treesitter-textobjects.swap').swap_next('@parameter.inner') - end, { buffer = bufnr, desc = 'swap next arg' }) - map('a[', function() - require('nvim-treesitter-textobjects.swap').swap_previous('@parameter.inner') - end, { buffer = bufnr, desc = 'swap prev arg' }) - end, -}) diff --git a/nvim/lua/config/keymaps.lua b/nvim/lua/config/keymaps.lua deleted file mode 100644 index 62c630c..0000000 --- a/nvim/lua/config/keymaps.lua +++ /dev/null @@ -1,18 +0,0 @@ --- Switch tab length on the fly -vim.keymap.set('n', '\\t', function() - vim.o.tabstop = vim.o.tabstop == 8 and 2 or 2 * vim.o.tabstop - vim.notify('tabstop: ' .. vim.o.tabstop) -end, { silent = true, desc = 'toggle tabstop' }) -vim.keymap.set({ 'v', 'i' }, 'wq', 'l', { noremap = true, silent = true }) -vim.keymap.set('v', '<', '', '>gv') -vim.keymap.set('n', 'n', 'nzz', { noremap = true }) -vim.keymap.set('n', 'N', 'Nzz', { noremap = true }) -vim.keymap.set('n', '', 'zz', { noremap = true }) -vim.keymap.set('n', '', 'zz', { noremap = true }) -vim.keymap.set('v', '', ":m '>+1gv=gv", { desc = 'move selection down' }) -vim.keymap.set('v', '', ":m '<-2gv=gv", { desc = 'move selection up' }) -vim.keymap.set('n', 'gq', vim.cmd.bdelete, { noremap = true, silent = true, desc = 'close buffer' }) -vim.keymap.set('n', 'gQ', function() - vim.cmd('bufdo bdelete') -end, { noremap = true, silent = true, desc = 'close all buffers' }) diff --git a/nvim/lua/plugins/completion.lua b/nvim/lua/plugins/completion.lua deleted file mode 100644 index 20480dc..0000000 --- a/nvim/lua/plugins/completion.lua +++ /dev/null @@ -1,87 +0,0 @@ -return { - { - 'saghen/blink.cmp', - event = 'VeryLazy', - dependencies = { - 'mikavilpas/blink-ripgrep.nvim', - }, - opts = { - enabled = function() - return not vim.tbl_contains({ 'snacks_picker_input' }, vim.bo.filetype) - end, - fuzzy = { - sorts = { - 'exact', - 'score', - 'sort_text', - }, - }, - sources = { - default = { - 'lsp', - 'path', - 'snippets', - 'ripgrep', - 'buffer', - }, - providers = { - lsp = { - fallbacks = {}, -- include buffer even when LSP is active - score_offset = 10, - }, - snippets = { - score_offset = -10, - }, - path = { - opts = { - get_cwd = function(_) - return vim.fn.getcwd() -- use nvim pwd instead of current file pwd - end, - }, - }, - ripgrep = { - module = 'blink-ripgrep', - name = 'rg', - score_offset = -10, - async = true, - }, - }, - }, - cmdline = { - completion = { - menu = { - auto_show = true, - }, - }, - }, - completion = { - documentation = { - auto_show = true, - auto_show_delay_ms = 500, - }, - menu = { - draw = { - treesitter = { 'lsp' }, - columns = { - { 'label', 'label_description', gap = 1 }, - { 'source_name', 'kind', gap = 1 }, - }, - }, - }, - trigger = { - show_on_keyword = true, - }, - }, - signature = { - enabled = true, - trigger = { - show_on_insert = true, - }, - }, - }, - config = function(_, opts) - require('blink.cmp').setup(opts) - vim.treesitter.language.register('markdown', 'blink-cmp-documentation') - end, - }, -} diff --git a/nvim/lua/plugins/lib/minidiff_jj.lua b/nvim/lua/plugins/lib/minidiff_jj.lua deleted file mode 100644 index d5b93d8..0000000 --- a/nvim/lua/plugins/lib/minidiff_jj.lua +++ /dev/null @@ -1,162 +0,0 @@ -local diff = require('mini.diff') -local M = { - cache = {}, -} - -M.get_buf_realpath = function(buf_id) - return vim.loop.fs_realpath(vim.api.nvim_buf_get_name(buf_id)) or '' -end - -M.jj_start_watching_tree_state = function(buf_id, path) - local stdout = vim.loop.new_pipe() - local args = { 'workspace', 'root', '--ignore-working-copy' } - local spawn_opts = { - args = args, - cwd = vim.fn.fnamemodify(path, ':h'), - stdio = { nil, stdout, nil }, - } - - local on_not_in_jj = vim.schedule_wrap(function() - if not vim.api.nvim_buf_is_valid(buf_id) then - M.cache[buf_id] = nil - return false - end - diff.fail_attach(buf_id) - M.cache[buf_id] = {} - end) - - local process, stdout_feed = nil, {} - local on_exit = function(exit_code) - process:close() - - -- Watch index only if there was no error retrieving path to it - if exit_code ~= 0 or stdout_feed[1] == nil then - return on_not_in_jj() - end - - -- Set up index watching - local jj_dir_path = table.concat(stdout_feed, ''):gsub('\n+$', '') .. '/.jj/working_copy' - M.jj_setup_tree_state_watch(buf_id, jj_dir_path) - - -- Set reference text immediately - M.jj_set_ref_text(buf_id) - end - - process = vim.loop.spawn('jj', spawn_opts, on_exit) - M.jj_read_stream(stdout, stdout_feed) -end - -M.jj_setup_tree_state_watch = function(buf_id, jj_dir_path) - local buf_fs_event, timer = vim.loop.new_fs_event(), vim.loop.new_timer() - local buf_jj_set_ref_text = function() - M.jj_set_ref_text(buf_id) - end - - local watch_tree_state = function(_, filename, _) - if filename ~= 'tree_state' then - return - end - -- Debounce to not overload during incremental staging (like in script) - timer:stop() - timer:start(50, 0, buf_jj_set_ref_text) - end - buf_fs_event:start(jj_dir_path, { stat = true }, watch_tree_state) - - M.jj_invalidate_cache(M.cache[buf_id]) - M.cache[buf_id] = { fs_event = buf_fs_event, timer = timer } -end -M.jj_set_ref_text = vim.schedule_wrap(function(buf_id) - if not vim.api.nvim_buf_is_valid(buf_id) then - return - end - - local buf_set_ref_text = vim.schedule_wrap(function(text) - pcall(diff.set_ref_text, buf_id, text) - end) - - -- NOTE: Do not cache buffer's name to react to its possible rename - local path = M.get_buf_realpath(buf_id) - if path == '' then - return buf_set_ref_text {} - end - local cwd, basename = vim.fn.fnamemodify(path, ':h'), vim.fn.fnamemodify(path, ':t') - - -- Set - local stdout = vim.loop.new_pipe() - local spawn_opts = { - args = { 'file', 'show', '--no-pager', '--ignore-working-copy', '-r', '@-', './' .. basename }, - cwd = cwd, - stdio = { nil, stdout, nil }, - } - - local process, stdout_feed = nil, {} - process = vim.loop.spawn('jj', spawn_opts, function(exit_code) - process:close() - - if exit_code ~= 0 or stdout_feed[1] == nil then - return buf_set_ref_text {} - end - - -- Set reference text accounting for possible 'crlf' end of line in index - local text = table.concat(stdout_feed, ''):gsub('\r\n', '\n') - buf_set_ref_text(text) - end) - - M.jj_read_stream(stdout, stdout_feed) -end) - -M.jj_read_stream = function(stream, feed) - local callback = function(err, data) - if data ~= nil then - return table.insert(feed, data) - end - if err then - feed[1] = nil - end - stream:close() - end - stream:read_start(callback) -end - -M.jj_invalidate_cache = function(cache) - if cache == nil then - return - end - pcall(vim.loop.fs_event_stop, cache.fs_event) - pcall(vim.loop.timer_stop, cache.timer) -end - -M.gen_source = function() - local attach = function(buf_id) - -- Try attaching to a buffer only once - if M.cache[buf_id] ~= nil then - return false - end - -- - Possibly resolve symlinks to get data from the original repo - local path = M.get_buf_realpath(buf_id) - if path == '' then - return false - end - - M.cache[buf_id] = {} - M.jj_start_watching_tree_state(buf_id, path) - end - - local detach = function(buf_id) - local cache = M.cache[buf_id] - M.cache[buf_id] = nil - M.jj_invalidate_cache(cache) - end - - local apply_hunks = function(_, _) - -- staging does not apply for jj - end - - return { - name = 'jj', - attach = attach, - detach = detach, - apply_hunks = apply_hunks, - } -end -return M diff --git a/nvim/lua/plugins/lib/session_jj.lua b/nvim/lua/plugins/lib/session_jj.lua deleted file mode 100644 index 5e81803..0000000 --- a/nvim/lua/plugins/lib/session_jj.lua +++ /dev/null @@ -1,71 +0,0 @@ -local M = {} - -M.setup = function() - local id = M.get_id() - if M.check_exists(id) then - vim.notify('Existing session for ' .. id) - end - - vim.keymap.set('n', 'fs', function() - require('plugins.lib.session_jj').load() - end, { noremap = true, desc = 'mini session select' }) -end - -M.get_id = function() - local jj_root = vim.system({ 'jj', 'workspace', 'root' }):wait() - - if jj_root.code ~= 0 then - return - end - - local result = vim - .system({ - 'jj', - 'log', - '-r', - 'latest(heads(::@ & bookmarks()))', - '--template', - 'bookmarks', - '--no-pager', - '--no-graph', - }) - :wait() - local branch = vim.trim(string.gsub(result.stdout, '[\n*]', '')) -- trim newlines and unpushed indicator - local root = vim.trim(string.gsub(jj_root.stdout, '\n', '')) - local id = string.gsub(string.format('jj:%s:%s', root, branch), '[./]', '-') -- slugify - return id -end - -M.check_exists = function(id) - for name, _ in pairs(MiniSessions.detected) do - if name == id then - return true - end - end - return false -end - -M.load = function() - local id = M.get_id() - if id == '' then - return - end - vim.opt.shadafile = vim.fn.stdpath('data') .. '/myshada/' .. id .. '.shada' - if M.check_exists(id) then - vim.ui.select({ - 'Yes', - 'No', - }, { prompt = 'Session found at ' .. id .. ', load it?' }, function(c) - if c == 'Yes' then - -- load session (buffers, etc) as well as shada (marks) - MiniSessions.read(id) - vim.notify('loaded jj session: ' .. id) - end - end) - else - MiniSessions.write(id) - end -end - -_G.M = M -return M diff --git a/nvim/lua/plugins/lib/snacks_jj.lua b/nvim/lua/plugins/lib/snacks_jj.lua deleted file mode 100644 index da442eb..0000000 --- a/nvim/lua/plugins/lib/snacks_jj.lua +++ /dev/null @@ -1,121 +0,0 @@ -local M = {} - -function M.status() - local function get_files() - local status_raw = vim.fn.system('jj diff --no-pager --quiet --summary') - local files = {} - - for status in status_raw:gmatch('[^\r\n]+') do - local state, text = string.match(status, '^(%a)%s(.+)$') - - if state and text then - local file = text - - local hl = '' - if state == 'A' then - hl = 'SnacksPickerGitStatusAdded' - elseif state == 'M' then - hl = 'SnacksPickerGitStatusModified' - elseif state == 'D' then - hl = 'SnacksPickerGitStatusDeleted' - elseif state == 'R' then - hl = 'SnacksPickerGitStatusRenamed' - file = string.match(text, '{.-=>%s*(.-)}') - end - - local diff = vim.fn.system('jj diff ' .. file .. ' --ignore-working-copy --no-pager --stat --git') - table.insert(files, { - text = text, - file = file, - filename_hl = hl, - state = state, - diff = diff, - }) - end - end - - return files - end - - local files = get_files() - - Snacks.picker.pick { - source = 'jj_status', - items = files, - format = 'file', - title = 'jj status', - preview = function(ctx) - if ctx.item.file then - Snacks.picker.preview.diff(ctx) - else - ctx.preview:reset() - ctx.preview:set_title('No preview') - end - end, - } -end - -function M.revs() - local function jj_new(picker, item) - picker:close() - if item then - if not item.rev then - vim.notify.warn('No branch or commit found', { title = 'Snacks Picker' }) - return - end - local cmd = { 'jj', 'new', '-r', item.rev } - Snacks.picker.util.cmd(cmd, function() - vim.notify('Checking out revision: ' .. item.rev, { title = 'Snacks Picker' }) - vim.cmd.checktime() - require('plugins.lib.session_jj').load() - end, { cwd = item.cwd }) - end - end - - local function jj_rev_cmd(ctx) - if ctx.item.rev then - Snacks.picker.preview.cmd({ 'jj', 'show', '--ignore-working-copy', '--git', '-r', ctx.item.rev }, ctx) - else - ctx.preview:reset() - return 'No preview available.' - end - end - - local function jj_log(revset) - if revset == nil then - revset = '-r "ancestors(@,25)"' - else - revset = '-r ' .. revset - end - local status_raw = vim.fn.system( - 'jj log --ignore-working-copy ' - .. revset - .. - ' --template \'if(root, format_root_commit(self), label(if(current_working_copy, "working_copy"), concat(separate(" ", self.change_id().shortest(8), self.bookmarks()), " | ", if(empty, label("empty", "(empty)")), if(description, description.first_line(), label(if(empty, "empty"), description_placeholder),),) ++ "\n",),)\'' - ) - local lines = {} - - for line in status_raw:gmatch('[^\r\n]+') do - local sign, rev = string.match(line, '(.)%s(%a+)%s.*') - table.insert(lines, { - text = line, - sign = sign, - rev = rev, - }) - end - - return lines - end - - Snacks.picker.pick { - source = 'jj_revs', - layout = 'ivy', - format = 'text', - title = 'jj log', - items = jj_log(), - confirm = jj_new, - preview = jj_rev_cmd, - } -end - -return M diff --git a/nvim/lua/plugins/lsp.lua b/nvim/lua/plugins/lsp.lua deleted file mode 100644 index 6015930..0000000 --- a/nvim/lua/plugins/lsp.lua +++ /dev/null @@ -1,133 +0,0 @@ -return { - { - 'neovim/nvim-lspconfig', - event = 'VeryLazy', - config = function() - vim.lsp.enable { - 'nil_ls', - 'phpactor', - 'gopls', - 'lua_ls', - 'basedpyright', - } - - vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('UserLspConfig', {}), - callback = function(ev) - local client = vim.lsp.get_client_by_id(ev.data.client_id) - if not client then - return - end - vim.keymap.set('n', 'gO', function() - Snacks.picker.lsp_symbols { focus = 'list' } - end, { buffer = ev.buf, desc = 'LSP symbols' }) - - vim.keymap.set('n', 'grh', function() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) - end, { buffer = ev.buf, desc = 'LSP hints toggle' }) - vim.keymap.set('n', 'grl', vim.lsp.codelens.run, { buffer = ev.buf, desc = 'vim.lsp.codelens.run()' }) - - vim.keymap.set('n', 'gre', function() - vim.diagnostic.setloclist() - end, { buffer = ev.buf, desc = 'LSP buffer diagnostics' }) - vim.keymap.set('n', 'grE', function() - vim.diagnostic.setqflist() - end, { buffer = ev.buf, desc = 'LSP diagnostics' }) - - vim.keymap.set('n', 'grc', function() - vim.lsp.buf.incoming_calls() - end, { buffer = ev.buf, desc = 'LSP incoming_calls' }) - vim.keymap.set('n', 'gro', function() - vim.lsp.buf.outgoing_calls() - end, { buffer = ev.buf, desc = 'LSP outgoing_calls' }) - - -- Auto-refresh code lenses - if client:supports_method('textDocument/codeLens') or client.server_capabilities.codeLensProvider then - vim.api.nvim_create_autocmd({ 'InsertLeave', 'TextChanged' }, { - group = vim.api.nvim_create_augroup(string.format('lsp-%s-%s', ev.buf, client.id), {}), - callback = function() - vim.lsp.codelens.refresh { bufnr = ev.buf } - end, - buffer = ev.buf, - }) - vim.lsp.codelens.refresh() - end - end, - }) - vim.api.nvim_exec_autocmds('FileType', {}) - end, - }, - { - 'stevearc/conform.nvim', - event = 'VeryLazy', - keys = { - { - '\\f', - function() - vim.b.disable_autoformat = not vim.b.disable_autoformat - Snacks.notify(string.format('Buffer formatting disabled: %s', vim.b.disable_autoformat)) - end, - mode = { 'n', 'x' }, - desc = 'toggle buffer formatting', - }, - { - '\\F', - function() - vim.g.disable_autoformat = not vim.g.disable_autoformat - Snacks.notify(string.format('Global formatting disabled: %s', vim.g.disable_autoformat)) - end, - mode = { 'n', 'x' }, - desc = 'toggle global formatting', - }, - }, - opts = { - notify_no_formatters = false, - formatters_by_ft = { - json = { 'jq' }, - puppet = { 'puppet-lint' }, - lua = { 'stylua' }, - python = { 'ruff' }, - nix = { 'nixfmt' }, - fish = { 'fish_indent' }, - ['*'] = { 'trim_whitespace' }, - }, - format_on_save = function(bufnr) - -- Disable with a global or buffer-local variable - if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then - return - end - return { timeout_ms = 1500, lsp_format = 'fallback' } - end, - default_format_opts = { - timeout_ms = 1500, - lsp_format = 'fallback', - }, - }, - }, - { - 'mfussenegger/nvim-lint', - event = 'VeryLazy', - config = function() - require('lint').linters_by_ft = { - docker = { 'hadolint' }, - yaml = { 'yamllint' }, - puppet = { 'puppet-lint' }, - sh = { 'shellcheck' }, - go = { 'golangcilint' }, - ruby = { 'rubocop' }, - fish = { 'fish' }, - bash = { 'bash' }, - nix = { 'nix' }, - php = { 'php' }, - } - vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { - group = vim.api.nvim_create_augroup('lint', { clear = true }), - callback = function() - if vim.bo.modifiable then - require('lint').try_lint() - end - end, - }) - end, - }, -} diff --git a/nvim/lua/plugins/mini.lua b/nvim/lua/plugins/mini.lua deleted file mode 100644 index c82350c..0000000 --- a/nvim/lua/plugins/mini.lua +++ /dev/null @@ -1,163 +0,0 @@ -return { - { - 'echasnovski/mini.nvim', - lazy = false, - keys = { - { - 'gp', - function() - MiniDiff.toggle_overlay(0) - end, - noremap = true, - desc = 'git diff overlay', - }, - { - 'go', - function() - return MiniGit.show_at_cursor() - end, - noremap = true, - desc = 'git show at cursor', - }, - { - 'gb', - 'Git blame -- %', - desc = 'git blame', - }, - { - 'gg', - ':Git ', - desc = 'git command', - }, - }, - config = function() - require('mini.basics').setup { mappings = { windows = true } } - vim.schedule(function() - local ai = require('mini.ai') - local extra_ai = require('mini.extra').gen_ai_spec - ai.setup { - n_lines = 300, - custom_textobjects = { - i = extra_ai.indent(), - g = extra_ai.buffer(), - e = extra_ai.line(), - u = ai.gen_spec.function_call(), - a = ai.gen_spec.treesitter { a = '@parameter.outer', i = '@parameter.inner' }, - k = ai.gen_spec.treesitter { a = '@assignment.lhs', i = '@assignment.lhs' }, - v = ai.gen_spec.treesitter { a = '@assignment.rhs', i = '@assignment.rhs' }, - f = ai.gen_spec.treesitter { a = '@function.outer', i = '@function.inner' }, - o = ai.gen_spec.treesitter { - a = { '@block.outer', '@conditional.outer', '@loop.outer' }, - i = { '@block.inner', '@conditional.inner', '@loop.inner' }, - }, - }, - } - require('mini.align').setup() - require('mini.bracketed').setup { file = { suffix = 'm' } } - require('mini.icons').setup() - require('mini.git').setup() - require('mini.surround').setup() - require('mini.splitjoin').setup { detect = { separator = '[,;\n]' } } - - require('mini.sessions').setup { - file = '', - autowrite = true, - hooks = { - pre = { - read = function(session) -- load Dart state *before* buffers are loaded - vim.cmd('rshada') - Dart.read_session(session['name']) - end, - write = function(session) - vim.cmd('wshada') - Dart.write_session(session['name']) - end, - }, - }, - } - require('plugins.lib.session_jj').setup() - - local jump = require('mini.jump2d') - jump.setup { - view = { n_steps_ahead = 1, dim = true }, - spotter = jump.gen_spotter.vimpattern(), - } - - local diff = require('mini.diff') - diff.setup { - options = { wrap_goto = true }, - source = { - require('plugins.lib.minidiff_jj').gen_source(), - diff.gen_source.git(), - }, - } - local miniclue = require('mini.clue') - miniclue.setup { - triggers = { - { mode = 'n', keys = '' }, - { mode = 'n', keys = 'g' }, - { mode = 'n', keys = "'" }, - { mode = 'n', keys = '`' }, - { mode = 'n', keys = '"' }, - { mode = 'n', keys = '' }, - { mode = 'n', keys = 'z' }, - { mode = 'n', keys = ']' }, - { mode = 'n', keys = '[' }, - { mode = 'n', keys = '\\' }, - }, - window = { - config = { width = 'auto' }, - }, - clues = { - miniclue.gen_clues.g(), - miniclue.gen_clues.marks(), - miniclue.gen_clues.registers(), - miniclue.gen_clues.windows(), - miniclue.gen_clues.z(), - }, - } - local files = require('mini.files') - files.setup { - mappings = { - go_in_plus = '', - }, - windows = { - preview = true, - width_focus = 30, - width_preview = 50, - }, - } - vim.keymap.set('n', 'nc', function() - files.open(vim.api.nvim_buf_get_name(0), false) -- open current buffer's dir - files.reveal_cwd() - end, { desc = 'minifiles open' }) - vim.api.nvim_create_autocmd('User', { - pattern = 'MiniFilesBufferCreate', - callback = function(args) - vim.keymap.set('n', 'nc', function() - files.synchronize() - files.close() - end, { buffer = args.data.buf_id }) - vim.keymap.set('n', '`', function() - local cur_entry_path = MiniFiles.get_fs_entry().path - local cur_directory = vim.fs.dirname(cur_entry_path) - if cur_directory ~= '' then - vim.fn.chdir(cur_directory) - end - end, { buffer = args.data.buf_id }) - end, - }) - vim.api.nvim_create_autocmd('User', { - pattern = 'MiniFilesActionRename', - callback = function(event) - Snacks.rename.on_rename_file(event.data.from, event.data.to) - end, - }) - - local multi = require('mini.keymap').map_multistep - multi({ 'i', 's' }, '', { 'blink_accept', 'vimsnippet_next', 'increase_indent' }) - multi({ 'i', 's' }, '', { 'vimsnippet_prev', 'decrease_indent' }) - end) - end, - }, -} diff --git a/nvim/lua/plugins/misc.lua b/nvim/lua/plugins/misc.lua deleted file mode 100644 index 7dacf20..0000000 --- a/nvim/lua/plugins/misc.lua +++ /dev/null @@ -1,143 +0,0 @@ -return { - { - 'iofq/dart.nvim', - lazy = false, - priority = 1001, - config = true, - }, - { - 'windwp/nvim-autopairs', - event = 'VeryLazy', - config = true, - }, - { - 'nvim-treesitter/nvim-treesitter', - event = 'VeryLazy', - branch = 'main', - dependencies = { - { - 'nvim-treesitter/nvim-treesitter-textobjects', - branch = 'main', - config = true, - }, - { - 'nvim-treesitter/nvim-treesitter-context', - opts = { - max_lines = 5, - min_window_height = 50, - }, - }, - }, - }, - { - 'jinh0/eyeliner.nvim', - event = 'VeryLazy', - config = true, - }, - { - 'MeanderingProgrammer/render-markdown.nvim', - event = 'VeryLazy', - opts = { - completions = { - blink = { enabled = true }, - }, - }, - }, - { - 'sindrets/diffview.nvim', - event = 'VeryLazy', - opts = { - use_icons = false, - enhanced_diff_hl = true, - default_args = { - DiffviewOpen = { '--imply-local' }, - }, - view = { - merge_tool = { - layout = 'diff4_mixed', - disable_diagnostics = true, - }, - }, - keymaps = { - view = { - { { 'n' }, 'q', vim.cmd.DiffviewClose, { desc = 'Close Diffview' } }, - }, - file_panel = { - { { 'n' }, 'q', vim.cmd.DiffviewClose, { desc = 'Close Diffview' } }, - }, - file_history_panel = { - { { 'n' }, 'q', vim.cmd.DiffviewClose, { desc = 'Close Diffview' } }, - }, - }, - }, - keys = { - { 'nb', vim.cmd.DiffviewOpen, desc = 'diffview open' }, - { - 'nh', - 'DiffviewFileHistory %', - mode = { 'n', 'v' }, - desc = 'diffview history', - }, - { - 'nH', - 'DiffviewFileHistory', - mode = { 'n', 'v' }, - desc = 'diffview history', - }, - }, - }, - { - 'ThePrimeagen/refactoring.nvim', - event = 'VeryLazy', - config = true, - keys = { - { 'rv', 'Refactor inline_vardd', mode = { 'n', 'x' } }, - { - 'rr', - function() - require('refactoring').select_refactor { prefer_ex_cmd = true } - end, - mode = { 'n', 'x' }, - }, - }, - }, - { - 'stevearc/quicker.nvim', - event = 'VeryLazy', - opts = { - follow = { - enabled = true, - }, - }, - keys = { - { - 'qf', - function() - require('quicker').toggle { max_height = 20 } - end, - desc = 'Toggle qflist', - }, - { - 'qr', - function() - require('quicker').refresh() - end, - desc = 'Refresh qflist', - }, - { - 'q>', - function() - require('quicker').expand { before = 2, after = 2, add_to_existing = true } - end, - desc = 'Expand quickfix context', - }, - { - 'q<', - function() - require('quicker').collapse() - end, - desc = 'Collapse quickfix context', - }, - }, - }, -} diff --git a/nvim/lua/plugins/snacks.lua b/nvim/lua/plugins/snacks.lua deleted file mode 100644 index d6dd0b2..0000000 --- a/nvim/lua/plugins/snacks.lua +++ /dev/null @@ -1,191 +0,0 @@ -return { - { - 'folke/snacks.nvim', - lazy = false, - priority = 1000, - opts = { - bigfile = { enabled = true }, - notifier = { - enabled = true, - timeout = 4000, - }, - styles = { - notification = { - wo = { wrap = true }, - }, - terminal = { - border = 'rounded', - }, - }, - terminal = { enabled = true }, - indent = { enabled = true }, - input = { enabled = true }, - picker = { - enabled = true, - jump = { reuse_win = true }, - matcher = { - frecency = true, - history_bonus = true, - cwd_bonus = true, - }, - layout = 'ivy_split', - sources = { - grep = { hidden = true }, - explorer = { hidden = true }, - lsp_symbols = { - filter = { default = true }, - layout = 'left', - }, - smart = { - sort = { - fields = { - 'score:desc', - 'idx', - '#text', - }, - }, - multi = { - 'marks', - { source = 'buffers', current = false }, - { source = 'files', hidden = true }, - { source = 'git_files', untracked = true }, - }, - }, - }, - win = { - input = { - keys = { ['wq'] = { 'close', mode = 'i' } }, - }, - list = { - keys = { ['wq'] = { 'close', mode = 'i' } }, - }, - }, - }, - }, - keys = { - { - '', - function() - Snacks.terminal.toggle() - end, - mode = { 'n', 't' }, - desc = 'terminal open', - }, - { - '', - function() - Snacks.terminal.toggle('command -v fish >/dev/null && exec fish || exec bash') - end, - mode = { 'n', 't' }, - desc = 'terminal open', - }, - { - '', - function() - vim.cmd.delmarks { args = { '0-9' } } - vim.cmd.delmarks { args = { '"' } } - Snacks.picker.smart() - end, - desc = 'Fuzzy find smart', - }, - { - 'fe', - function() - Snacks.explorer() - end, - desc = 'snacks explorer', - }, - { - 'ff', - function() - Snacks.picker.files() - end, - desc = 'Fuzzy find files', - }, - { - 'fa', - function() - Snacks.picker.grep() - end, - desc = 'Fuzzy find grep', - }, - { - 'f8', - function() - Snacks.picker.grep_word() - end, - desc = 'Fuzzy find grep word', - }, - { - 'f?', - function() - Snacks.picker.pickers() - end, - desc = 'See all pickers', - }, - { - 'fu', - function() - Snacks.picker.undo() - end, - desc = 'Pick undotree', - }, - { - 'fj', - function() - Snacks.picker.jumps() - end, - desc = 'Pick jumps', - }, - { - 'f.', - function() - Snacks.picker.resume() - end, - desc = 'Fuzzy find resume', - }, - { - 'fb', - function() - Snacks.picker.buffers() - end, - desc = 'Fuzzy find buffers', - }, - { - 'fn', - function() - Snacks.picker.notifications() - end, - desc = 'pick notifications', - }, - { - 'gO', - function() - Snacks.picker.treesitter() - end, - desc = 'pick treesitter nodes', - }, - { - 'fq', - function() - Snacks.picker.qflist() - end, - desc = 'pick quickfix list', - }, - { - 'jf', - function() - require('plugins.lib.snacks_jj').status() - end, - desc = 'pick notifications', - }, - { - 'jj', - function() - require('plugins.lib.snacks_jj').revs() - end, - desc = 'pick notifications', - }, - }, - }, -}