mirror of
https://github.com/iofq/nvim.nix.git
synced 2026-03-26 03:30:50 -05:00
Compare commits
No commits in common. "49e373fe9a07480d9ea683d81772c05ce5da2f32" and "71651618566fb03fa9acedbee6276c3e14d3bad3" have entirely different histories.
49e373fe9a
...
7165161856
27 changed files with 1581 additions and 730 deletions
185
flake.lock
generated
185
flake.lock
generated
|
|
@ -1,19 +1,18 @@
|
|||
{
|
||||
"nodes": {
|
||||
"dart": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1760318820,
|
||||
"narHash": "sha256-3ETm+AZ/UEU0OYFSYviMSv/Ov4BN1cEsBH6KNGuTYS4=",
|
||||
"path": "/home/e/dev/dart.nvim",
|
||||
"type": "path"
|
||||
"lastModified": 1754291267,
|
||||
"owner": "iofq",
|
||||
"repo": "dart.nvim",
|
||||
"rev": "617587d40fd2f2727c18758c4e6decac78459529",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"path": "/home/e/dev/dart.nvim",
|
||||
"type": "path"
|
||||
"owner": "iofq",
|
||||
"repo": "dart.nvim",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
|
|
@ -90,11 +89,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1759362264,
|
||||
"narHash": "sha256-wfG0S7pltlYyZTM+qqlhJ7GMw2fTF4mLKCIVhLii/4M=",
|
||||
"lastModified": 1754487366,
|
||||
"narHash": "sha256-pHYj8gUBapuUzKV/kN/tR3Zvqc7o6gdFB9XKXIp1SQ8=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "758cf7296bee11f1706a574c77d072b8a7baa881",
|
||||
"rev": "af66ad14b28a127c5c0f3bbb298218fc63528a18",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -103,6 +102,27 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_3": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"neovim-nightly-overlay",
|
||||
"hercules-ci-effects",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1751413152,
|
||||
"narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "77826244401ea9de6e3bac47c2db46005e1f30b5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "flake-parts",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
|
|
@ -120,24 +140,6 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gen-luarc": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
|
|
@ -148,11 +150,10 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1755304025,
|
||||
"narHash": "sha256-xVKfjFwc0zMbLMjLTiHz+0llggkjs93SmHkhaa9S3M4=",
|
||||
"lastModified": 1754586557,
|
||||
"owner": "mrcjkb",
|
||||
"repo": "nix-gen-luarc-json",
|
||||
"rev": "1865b0ebb753ae5324d7381b1fa8c98c04ec7509",
|
||||
"rev": "4b8d4da04808062e2b1ef0e7bcd0a03bcb93e043",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -195,11 +196,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1759523803,
|
||||
"narHash": "sha256-PTod9NG+i3XbbnBKMl/e5uHDBYpwIWivQ3gOWSEuIEM=",
|
||||
"lastModified": 1754416808,
|
||||
"narHash": "sha256-c6yg0EQ9xVESx6HGDOCMcyRSjaTpNJP10ef+6fRcofA=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "cfc9f7bb163ad8542029d303e599c0f7eee09835",
|
||||
"rev": "9c52372878df6911f9afc1e2a1391f55e4dfc864",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -254,21 +255,18 @@
|
|||
},
|
||||
"hercules-ci-effects": {
|
||||
"inputs": {
|
||||
"flake-parts": [
|
||||
"neovim-nightly-overlay",
|
||||
"flake-parts"
|
||||
],
|
||||
"flake-parts": "flake-parts_3",
|
||||
"nixpkgs": [
|
||||
"neovim-nightly-overlay",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1758022363,
|
||||
"narHash": "sha256-ENUhCRWgSX4ni751HieNuQoq06dJvApV/Nm89kh+/A0=",
|
||||
"lastModified": 1752595130,
|
||||
"narHash": "sha256-CNBgr4OZSuklGtNOa9CnTNo9+Xceqn/EDAC1Tc43fH8=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "hercules-ci-effects",
|
||||
"rev": "1a3667d33e247ad35ca250698d63f49a5453d824",
|
||||
"rev": "5f2e09654b2e70ba643e41609d9f9b6640f22113",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -300,17 +298,14 @@
|
|||
"git-hooks": "git-hooks_2",
|
||||
"hercules-ci-effects": "hercules-ci-effects",
|
||||
"neovim-src": "neovim-src",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs": "nixpkgs",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1760313895,
|
||||
"narHash": "sha256-39JFRb006AOsIcOq+03H3y6YcGyaphk1CW5DRi14cOE=",
|
||||
"lastModified": 1754641381,
|
||||
"owner": "nix-community",
|
||||
"repo": "neovim-nightly-overlay",
|
||||
"rev": "7ff73a295b0065bde2f8b43b31558136ca77bd98",
|
||||
"rev": "83aaf3085f808dec9ea1b5d16b216875a8081b37",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -322,11 +317,11 @@
|
|||
"neovim-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1760312166,
|
||||
"narHash": "sha256-RnB+oJcP37YT9pjr1osUQtJc+1qcVyaaeSbiSyXwm1Y=",
|
||||
"lastModified": 1754610154,
|
||||
"narHash": "sha256-ORfF40X4BGiFxnLNQbdsQbUTW4TkUHfPqyZWHaYL5NE=",
|
||||
"owner": "neovim",
|
||||
"repo": "neovim",
|
||||
"rev": "72b0bfa1fb7e897e5126aabae718a5480f466b9e",
|
||||
"rev": "038eb01b41b66379f75164507571497929f8847c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -337,15 +332,16 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1755660401,
|
||||
"lastModified": 1754393734,
|
||||
"narHash": "sha256-fbnmAwTQkuXHKBlcL5Nq1sMAzd3GFqCOQgEQw6Hy0Ak=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5788de501b965d7413f2beaac10aeeb56f9a19a8",
|
||||
"rev": "a683adc19ff5228af548c6539dbc3440509bfed3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "master",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
@ -380,11 +376,10 @@
|
|||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1760326837,
|
||||
"narHash": "sha256-z+C6KRPRjwqEsTEAwUavapBWcbR7YOlQP91O+W5L1ek=",
|
||||
"lastModified": 1754893210,
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cfe6b045750c3aa5127817bc3f44f2909b1ee175",
|
||||
"rev": "defc725219d1fb9b56662370e014012929e557af",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -394,30 +389,13 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1760038930,
|
||||
"narHash": "sha256-Oncbh0UmHjSlxO7ErQDM3KM0A5/Znfofj2BSzlHLeVw=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0b4defa2584313f3b781240b29d61f6f9f7e0df3",
|
||||
"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": 1754640844,
|
||||
"owner": "nvim-treesitter",
|
||||
"repo": "nvim-treesitter",
|
||||
"rev": "0606c7a9dcaa5c5beee0b0f09043e9fdd1ba0a68",
|
||||
"rev": "9866036ec3c5db40700a9178494e0cfdcfe6ecfd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -427,34 +405,13 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nvim-treesitter-main": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"nvim-treesitter": "nvim-treesitter",
|
||||
"nvim-treesitter-textobjects": "nvim-treesitter-textobjects"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1760324917,
|
||||
"narHash": "sha256-ZlVGaUbxHf4DNR4GWhF1mvlMhP8IBbwF0g8WO1SL+Yw=",
|
||||
"owner": "iofq",
|
||||
"repo": "nvim-treesitter-main",
|
||||
"rev": "da2262419eb66cfa426aa62ccf1fc8fdea33b4a0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "iofq",
|
||||
"repo": "nvim-treesitter-main",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nvim-treesitter-textobjects": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1756368113,
|
||||
"narHash": "sha256-+KmOpRi4JAqm6UqYdtk80jwFrJhLCs0lZM/Liofq0R4=",
|
||||
"lastModified": 1751128959,
|
||||
"owner": "nvim-treesitter",
|
||||
"repo": "nvim-treesitter-textobjects",
|
||||
"rev": "1b2d85d3de6114c4bcea89ffb2cd1ce9e3a19931",
|
||||
"rev": "b54cec389e98c5b0babbe618773acec927437cab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -467,11 +424,12 @@
|
|||
"root": {
|
||||
"inputs": {
|
||||
"dart": "dart",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"flake-utils": "flake-utils",
|
||||
"gen-luarc": "gen-luarc",
|
||||
"neovim-nightly-overlay": "neovim-nightly-overlay",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nvim-treesitter-main": "nvim-treesitter-main"
|
||||
"nvim-treesitter": "nvim-treesitter",
|
||||
"nvim-treesitter-textobjects": "nvim-treesitter-textobjects"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
|
|
@ -489,21 +447,6 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
|
|
@ -512,11 +455,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1760120816,
|
||||
"narHash": "sha256-gq9rdocpmRZCwLS5vsHozwB6b5nrOBDNc2kkEaTXHfg=",
|
||||
"lastModified": 1754492133,
|
||||
"narHash": "sha256-B+3g9+76KlGe34Yk9za8AF3RL+lnbHXkLiVHLjYVOAc=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "761ae7aff00907b607125b2f57338b74177697ed",
|
||||
"rev": "1298185c05a56bff66383a20be0b41a307f52228",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
57
flake.nix
57
flake.nix
|
|
@ -4,23 +4,33 @@
|
|||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/master";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
neovim-nightly-overlay = {
|
||||
url = "github:nix-community/neovim-nightly-overlay";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
|
||||
gen-luarc = {
|
||||
url = "github:mrcjkb/nix-gen-luarc-json";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
dart = {
|
||||
url = "path:/home/e/dev/dart.nvim";
|
||||
url = "github:iofq/dart.nvim";
|
||||
flake = false;
|
||||
};
|
||||
nvim-treesitter-main = {
|
||||
url = "github:iofq/nvim-treesitter-main";
|
||||
nvim-treesitter = {
|
||||
url = "github:nvim-treesitter/nvim-treesitter/main";
|
||||
flake = false;
|
||||
};
|
||||
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,
|
||||
...
|
||||
|
|
@ -29,29 +39,22 @@
|
|||
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;
|
||||
overlays = finalOverlays ++ [
|
||||
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.
|
||||
inputs.gen-luarc.overlays.default
|
||||
];
|
||||
};
|
||||
|
|
@ -59,13 +62,16 @@
|
|||
name = "nvim-devShell";
|
||||
buildInputs = with pkgs; [
|
||||
lua-language-server
|
||||
nixd
|
||||
nil
|
||||
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
|
||||
|
|
@ -74,6 +80,7 @@
|
|||
default = nvim;
|
||||
nvim = pkgs.nvim-pkg;
|
||||
nvim-min = pkgs.nvim-min-pkg;
|
||||
nvim-dev = pkgs.nvim-dev;
|
||||
};
|
||||
devShells = {
|
||||
default = shell;
|
||||
|
|
@ -81,6 +88,6 @@
|
|||
}
|
||||
)
|
||||
// {
|
||||
overlays.default = nixpkgs.lib.composeManyExtensions finalOverlays;
|
||||
overlays.default = neovim-overlay;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
210
nix/mkNeovim.nix
210
nix/mkNeovim.nix
|
|
@ -1,23 +1,197 @@
|
|||
{ pkgs, lib }:
|
||||
# Function for creating a Neovim derivation
|
||||
{
|
||||
plugins ? [ ],
|
||||
packages ? [ ],
|
||||
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 = <plugin-name>; url = <git-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,
|
||||
}:
|
||||
let
|
||||
finalPlugins = plugins ++ [
|
||||
(pkgs.vimUtils.buildVimPlugin {
|
||||
pname = "iofq-nvim";
|
||||
src = lib.cleanSource ../nvim;
|
||||
version = "0.1";
|
||||
doCheck = false;
|
||||
})
|
||||
];
|
||||
wrapperArgs = ''--prefix PATH : "${lib.makeBinPath packages}"'';
|
||||
# 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 = <plugin>; config = <config>; optional = <tf>; ... }
|
||||
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
|
||||
pkgs.wrapNeovimUnstable pkgs.neovim-unwrapped {
|
||||
inherit wrapperArgs;
|
||||
plugins = finalPlugins;
|
||||
withPython3 = false;
|
||||
withRuby = false;
|
||||
vimAlias = true;
|
||||
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";
|
||||
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}
|
||||
'';
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,20 +1,25 @@
|
|||
# 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 = final; };
|
||||
dart-nvim = inputs.dart.packages.x86_64-linux.default;
|
||||
mkNeovim = prev.callPackage ./mkNeovim.nix { pkgs-wrapNeovim = prev; };
|
||||
|
||||
plugins = with prev.vimPlugins; [
|
||||
plugins = with final.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
|
||||
nvim-treesitter.withAllGrammars
|
||||
nvim-treesitter-context
|
||||
nvim-treesitter-textobjects
|
||||
quicker-nvim
|
||||
refactoring-nvim
|
||||
|
|
@ -22,12 +27,12 @@ let
|
|||
snacks-nvim
|
||||
];
|
||||
|
||||
basePackages = with prev; [
|
||||
basePackages = with final; [
|
||||
ripgrep
|
||||
fd
|
||||
];
|
||||
# Extra packages that should be included on nixos but don't need to be bundled
|
||||
extraPackages = with prev; [
|
||||
extraPackages = with final; [
|
||||
# linters
|
||||
yamllint
|
||||
jq
|
||||
|
|
@ -39,21 +44,35 @@ let
|
|||
# LSPs
|
||||
gopls
|
||||
lua-language-server
|
||||
nixd
|
||||
nil
|
||||
basedpyright
|
||||
|
||||
#other
|
||||
jujutsu
|
||||
];
|
||||
in
|
||||
{
|
||||
nvim-pkg = mkNeovim {
|
||||
inherit plugins;
|
||||
packages = basePackages ++ extraPackages;
|
||||
extraPackages = basePackages ++ extraPackages;
|
||||
};
|
||||
|
||||
nvim-min-pkg = mkNeovim {
|
||||
inherit plugins;
|
||||
packages = basePackages;
|
||||
extraPackages = 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;
|
||||
};
|
||||
|
|
|
|||
29
nix/plugin-overlay.nix
Normal file
29
nix/plugin-overlay.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{ 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" ];
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,52 +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, 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
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
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)
|
||||
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,
|
||||
})
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
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', '<leader>gb', '<Cmd>Git blame -- %<CR>')
|
||||
map('n', '<leader>go', function()
|
||||
return MiniGit.show_at_cursor()
|
||||
end)
|
||||
|
||||
local jump = require('mini.jump2d')
|
||||
jump.setup {
|
||||
mappings = {
|
||||
start_jumping = '<leader>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', '<leader>gp', MiniDiff.toggle_overlay)
|
||||
|
||||
require('mini.files').setup {
|
||||
mappings = { go_in_plus = '<CR>' },
|
||||
windows = {
|
||||
preview = true,
|
||||
width_preview = 50,
|
||||
},
|
||||
}
|
||||
map('n', '<leader>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', '<leader>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)
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
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' }, '<C-\\>', Snacks.terminal.toggle)
|
||||
map('n', '<leader>ff', Snacks.picker.smart)
|
||||
map('n', '<leader><leader>', Snacks.picker.smart)
|
||||
map('n', '<leader>fa', Snacks.picker.grep)
|
||||
map('n', '<leader>f8', Snacks.picker.grep_word)
|
||||
map('n', '<leader>f?', Snacks.picker.pickers)
|
||||
map('n', '<leader>fu', Snacks.picker.undo)
|
||||
map('n', '<leader>fj', Snacks.picker.jumps)
|
||||
map('n', '<leader>f.', Snacks.picker.resume)
|
||||
map('n', '<leader>fb', Snacks.picker.buffers)
|
||||
map('n', '<leader>fq', Snacks.picker.qflist)
|
||||
map('n', '<leader>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', '<leader>rr', require('refactoring').select_refactor)
|
||||
map('n', '<leader>rv', function()
|
||||
require('refactoring').refactor('Inline Variable')
|
||||
end)
|
||||
|
||||
require('quicker').setup()
|
||||
map('n', '<leader>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)
|
||||
|
|
@ -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', fg = "grey" })
|
||||
hi(0, 'StatusLineNC', { bg = 'none' })
|
||||
hi(0, 'String', { fg = '#7aa4a1' })
|
||||
hi(0, 'Substitute', { bg = '#e85c51', fg = '#152528' })
|
||||
hi(0, 'SymbolOutlineConnector', { link = 'Conceal' })
|
||||
34
nvim/init.lua
Normal file
34
nvim/init.lua
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
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')
|
||||
|
|
@ -19,6 +19,9 @@ return {
|
|||
end,
|
||||
settings = {
|
||||
Lua = {
|
||||
codeLens = {
|
||||
enable = true,
|
||||
},
|
||||
hint = {
|
||||
enable = true,
|
||||
arrayIndex = 'Enable',
|
||||
105
nvim/lua/config/autocmd.lua
Normal file
105
nvim/lua/config/autocmd.lua
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
-- 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,
|
||||
})
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
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
|
||||
|
|
@ -35,30 +31,7 @@ vim.diagnostic.config {
|
|||
source = 'if_many',
|
||||
},
|
||||
}
|
||||
|
||||
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)
|
||||
vim.schedule(function()
|
||||
require('config.autocmd')
|
||||
require('config.keymaps')
|
||||
end)
|
||||
map({ 'v', 'i' }, 'wq', '<esc>l')
|
||||
map('v', '<', '<gv')
|
||||
map('v', '>', '>gv')
|
||||
map('n', 'n', 'nzz', { noremap = true })
|
||||
map('n', 'N', 'Nzz', { noremap = true })
|
||||
map('n', '<C-u>', '<C-u>zz', { noremap = true })
|
||||
map('n', '<C-d>', '<C-d>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')
|
||||
18
nvim/lua/config/keymaps.lua
Normal file
18
nvim/lua/config/keymaps.lua
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
-- 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', '<esc>l', { noremap = true, silent = true })
|
||||
vim.keymap.set('v', '<', '<gv')
|
||||
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', '<C-u>', '<C-u>zz', { noremap = true })
|
||||
vim.keymap.set('n', '<C-d>', '<C-d>zz', { noremap = true })
|
||||
vim.keymap.set('v', '<A-j>', ":m '>+1<CR>gv=gv", { desc = 'move selection down' })
|
||||
vim.keymap.set('v', '<A-k>', ":m '<-2<CR>gv=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' })
|
||||
87
nvim/lua/plugins/completion.lua
Normal file
87
nvim/lua/plugins/completion.lua
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
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,
|
||||
},
|
||||
}
|
||||
162
nvim/lua/plugins/lib/minidiff_jj.lua
Normal file
162
nvim/lua/plugins/lib/minidiff_jj.lua
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
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
|
||||
71
nvim/lua/plugins/lib/session_jj.lua
Normal file
71
nvim/lua/plugins/lib/session_jj.lua
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
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', '<leader>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
|
||||
121
nvim/lua/plugins/lib/snacks_jj.lua
Normal file
121
nvim/lua/plugins/lib/snacks_jj.lua
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
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
|
||||
133
nvim/lua/plugins/lsp.lua
Normal file
133
nvim/lua/plugins/lsp.lua
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
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,
|
||||
},
|
||||
}
|
||||
163
nvim/lua/plugins/mini.lua
Normal file
163
nvim/lua/plugins/mini.lua
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
return {
|
||||
{
|
||||
'echasnovski/mini.nvim',
|
||||
lazy = false,
|
||||
keys = {
|
||||
{
|
||||
'<leader>gp',
|
||||
function()
|
||||
MiniDiff.toggle_overlay(0)
|
||||
end,
|
||||
noremap = true,
|
||||
desc = 'git diff overlay',
|
||||
},
|
||||
{
|
||||
'<leader>go',
|
||||
function()
|
||||
return MiniGit.show_at_cursor()
|
||||
end,
|
||||
noremap = true,
|
||||
desc = 'git show at cursor',
|
||||
},
|
||||
{
|
||||
'<leader>gb',
|
||||
'<Cmd>Git blame -- %<CR>',
|
||||
desc = 'git blame',
|
||||
},
|
||||
{
|
||||
'<leader>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 = '<Leader>' },
|
||||
{ mode = 'n', keys = 'g' },
|
||||
{ mode = 'n', keys = "'" },
|
||||
{ mode = 'n', keys = '`' },
|
||||
{ mode = 'n', keys = '"' },
|
||||
{ mode = 'n', keys = '<C-w>' },
|
||||
{ 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 = '<CR>',
|
||||
},
|
||||
windows = {
|
||||
preview = true,
|
||||
width_focus = 30,
|
||||
width_preview = 50,
|
||||
},
|
||||
}
|
||||
vim.keymap.set('n', '<leader>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', '<leader>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' }, '<Tab>', { 'blink_accept', 'vimsnippet_next', 'increase_indent' })
|
||||
multi({ 'i', 's' }, '<S-Tab>', { 'vimsnippet_prev', 'decrease_indent' })
|
||||
end)
|
||||
end,
|
||||
},
|
||||
}
|
||||
143
nvim/lua/plugins/misc.lua
Normal file
143
nvim/lua/plugins/misc.lua
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
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 = {
|
||||
{ '<leader>nb', vim.cmd.DiffviewOpen, desc = 'diffview open' },
|
||||
{
|
||||
'<leader>nh',
|
||||
'<cmd>DiffviewFileHistory %<cr>',
|
||||
mode = { 'n', 'v' },
|
||||
desc = 'diffview history',
|
||||
},
|
||||
{
|
||||
'<leader>nH',
|
||||
'<cmd>DiffviewFileHistory<cr>',
|
||||
mode = { 'n', 'v' },
|
||||
desc = 'diffview history',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
'ThePrimeagen/refactoring.nvim',
|
||||
event = 'VeryLazy',
|
||||
config = true,
|
||||
keys = {
|
||||
{ '<leader>rv', '<cmd>Refactor inline_var<cr>dd', mode = { 'n', 'x' } },
|
||||
{
|
||||
'<leader>rr',
|
||||
function()
|
||||
require('refactoring').select_refactor { prefer_ex_cmd = true }
|
||||
end,
|
||||
mode = { 'n', 'x' },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
'stevearc/quicker.nvim',
|
||||
event = 'VeryLazy',
|
||||
opts = {
|
||||
follow = {
|
||||
enabled = true,
|
||||
},
|
||||
},
|
||||
keys = {
|
||||
{
|
||||
'<leader>qf',
|
||||
function()
|
||||
require('quicker').toggle { max_height = 20 }
|
||||
end,
|
||||
desc = 'Toggle qflist',
|
||||
},
|
||||
{
|
||||
'<leader>qr',
|
||||
function()
|
||||
require('quicker').refresh()
|
||||
end,
|
||||
desc = 'Refresh qflist',
|
||||
},
|
||||
{
|
||||
'<leader>q>',
|
||||
function()
|
||||
require('quicker').expand { before = 2, after = 2, add_to_existing = true }
|
||||
end,
|
||||
desc = 'Expand quickfix context',
|
||||
},
|
||||
{
|
||||
'<leader>q<',
|
||||
function()
|
||||
require('quicker').collapse()
|
||||
end,
|
||||
desc = 'Collapse quickfix context',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
191
nvim/lua/plugins/snacks.lua
Normal file
191
nvim/lua/plugins/snacks.lua
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
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 = {
|
||||
{
|
||||
'<C-\\>',
|
||||
function()
|
||||
Snacks.terminal.toggle()
|
||||
end,
|
||||
mode = { 'n', 't' },
|
||||
desc = 'terminal open',
|
||||
},
|
||||
{
|
||||
'<C-/>',
|
||||
function()
|
||||
Snacks.terminal.toggle('command -v fish >/dev/null && exec fish || exec bash')
|
||||
end,
|
||||
mode = { 'n', 't' },
|
||||
desc = 'terminal open',
|
||||
},
|
||||
{
|
||||
'<leader><leader>',
|
||||
function()
|
||||
vim.cmd.delmarks { args = { '0-9' } }
|
||||
vim.cmd.delmarks { args = { '"' } }
|
||||
Snacks.picker.smart()
|
||||
end,
|
||||
desc = 'Fuzzy find smart',
|
||||
},
|
||||
{
|
||||
'<leader>fe',
|
||||
function()
|
||||
Snacks.explorer()
|
||||
end,
|
||||
desc = 'snacks explorer',
|
||||
},
|
||||
{
|
||||
'<leader>ff',
|
||||
function()
|
||||
Snacks.picker.files()
|
||||
end,
|
||||
desc = 'Fuzzy find files',
|
||||
},
|
||||
{
|
||||
'<leader>fa',
|
||||
function()
|
||||
Snacks.picker.grep()
|
||||
end,
|
||||
desc = 'Fuzzy find grep',
|
||||
},
|
||||
{
|
||||
'<leader>f8',
|
||||
function()
|
||||
Snacks.picker.grep_word()
|
||||
end,
|
||||
desc = 'Fuzzy find grep word',
|
||||
},
|
||||
{
|
||||
'<leader>f?',
|
||||
function()
|
||||
Snacks.picker.pickers()
|
||||
end,
|
||||
desc = 'See all pickers',
|
||||
},
|
||||
{
|
||||
'<leader>fu',
|
||||
function()
|
||||
Snacks.picker.undo()
|
||||
end,
|
||||
desc = 'Pick undotree',
|
||||
},
|
||||
{
|
||||
'<leader>fj',
|
||||
function()
|
||||
Snacks.picker.jumps()
|
||||
end,
|
||||
desc = 'Pick jumps',
|
||||
},
|
||||
{
|
||||
'<leader>f.',
|
||||
function()
|
||||
Snacks.picker.resume()
|
||||
end,
|
||||
desc = 'Fuzzy find resume',
|
||||
},
|
||||
{
|
||||
'<leader>fb',
|
||||
function()
|
||||
Snacks.picker.buffers()
|
||||
end,
|
||||
desc = 'Fuzzy find buffers',
|
||||
},
|
||||
{
|
||||
'<leader>fn',
|
||||
function()
|
||||
Snacks.picker.notifications()
|
||||
end,
|
||||
desc = 'pick notifications',
|
||||
},
|
||||
{
|
||||
'gO',
|
||||
function()
|
||||
Snacks.picker.treesitter()
|
||||
end,
|
||||
desc = 'pick treesitter nodes',
|
||||
},
|
||||
{
|
||||
'<leader>fq',
|
||||
function()
|
||||
Snacks.picker.qflist()
|
||||
end,
|
||||
desc = 'pick quickfix list',
|
||||
},
|
||||
{
|
||||
'<leader>jf',
|
||||
function()
|
||||
require('plugins.lib.snacks_jj').status()
|
||||
end,
|
||||
desc = 'pick notifications',
|
||||
},
|
||||
{
|
||||
'<leader>jj',
|
||||
function()
|
||||
require('plugins.lib.snacks_jj').revs()
|
||||
end,
|
||||
desc = 'pick notifications',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue