Compare commits

...

40 Commits

Author SHA1 Message Date
b5908349cb chore(deps): use fork of godotdev.nvim 2026-01-10 10:59:20 -03:00
996111c2f8 feat(keymaps): next and previous harpoon keymaps 2026-01-10 10:59:19 -03:00
6bf602a98c feat(keymaps): use standard F5 and F8 for debugger 2026-01-10 10:59:19 -03:00
ae44993926 fix(keymaps): telescope keymaps not ending with <cr> 2026-01-10 10:59:19 -03:00
e62ded5546 refactor(plugins): change plugin initiatin order 2026-01-10 10:59:19 -03:00
3218d73dce fix(plugins): lazy trigger for git repositories 2026-01-10 10:59:19 -03:00
43cc8f1eaf feat(plugins,nix): godot integration 2026-01-10 10:59:18 -03:00
1c1cd0ca52 feat(nix): provide home-manager and nixos modules directly in flake.nix 2025-12-14 21:59:29 -03:00
b71abaec7a feat(package): missing ripgrep depenndency for telescope 2025-12-14 21:59:29 -03:00
144b5cdde9 feat(plugins): nvim-autopairs 2025-12-14 21:59:29 -03:00
c00702d1cb feat(nix): reorganize plugins in neovim package for nix 2025-12-14 21:59:28 -03:00
aa88049fab chore(deps): update flakes 2025-12-14 21:59:28 -03:00
4d7aa88641 feat(plugins,formatters): move formatters to dedicated file 2025-12-14 21:59:28 -03:00
e8e109babb feat(keymaps): tweaks to keymaps 2025-12-14 21:59:28 -03:00
196da5309e feat(keymap): spellingn toggle and correction 2025-12-14 21:59:28 -03:00
be99745640 feat(debugger): golang adapter for dap 2025-12-14 21:59:27 -03:00
a9a59ec260 feat(debugger,keymaps): dap and dapui debugging configuration 2025-12-14 21:59:27 -03:00
1fdc7ec7fe fixup! feat(keymaps,plugins): navigation and keymaps with telescope and harpoon 2025-12-14 21:59:27 -03:00
7fc1d34a1c feat(commands): replace Ex command for yazi 2025-12-14 21:59:27 -03:00
a68a167264 feat(commands): grip command for markdown preview 2025-12-14 21:59:27 -03:00
526a626136 feat: file managing with yazi 2025-12-14 21:59:26 -03:00
8b935a5760 feat(plugins): secret hidding with cloak.nvim 2025-12-14 21:59:26 -03:00
eaf3ff77e9 feat(plugins): appearance settings and theme 2025-12-14 21:59:26 -03:00
430fefba32 fixup! feat(plugins): auto-formatting with conform.nvim 2025-12-14 21:59:26 -03:00
fb5ea210ba feat(plugins): auto-saving and auto-sessions 2025-12-14 21:59:26 -03:00
534be8b067 feat(plugins): auto completion with blink.cmp 2025-12-14 20:53:38 -03:00
e437de5a92 feat(plugins): auto-formatting with conform.nvim 2025-12-14 20:53:37 -03:00
675b02f147 feat: auto-highlight on mouse hover and yank 2025-12-14 20:53:37 -03:00
b99a3a6505 feat(keymaps,plugins): navigation and keymaps with telescope and harpoon 2025-12-14 20:53:37 -03:00
62dcb05405 feat(lsp,plugins): plugins and lsp configuration with lze and lzextras 2025-12-14 20:53:37 -03:00
b5219c3889 feat: diagnostics virtual text and icons 2025-12-14 20:53:37 -03:00
aafa1d5599 feat: dot plugin for new configuration 2025-12-14 20:53:36 -03:00
2fb6af9ea2 refactor(nix): use pkgs.callPackage insted of import 2025-12-08 21:39:26 -03:00
845575ef33 chore(deps): remove go-grip and blink-cmp flake inputs 2025-12-08 21:38:16 -03:00
21646b69b3 feat(lsp): setup lua_ls for neovim 2025-12-08 21:36:09 -03:00
abf916554e style: format formatting.lua 2025-12-08 21:35:45 -03:00
616bda8d06 chore(deps): update lsp 2025-11-28 19:10:51 -03:00
5c6bc37b7c feat(formatters): use prettier for scss and less 2025-11-28 19:10:13 -03:00
d19738bc59 feat(lsp): re-enable htmx 2025-11-10 11:39:56 -03:00
e344fbc259 feat(ide): add todo-comments-nvim 2025-11-10 11:39:53 -03:00
33 changed files with 2056 additions and 1386 deletions

View File

@@ -37,7 +37,7 @@ you can run the configured Neovim binary with just:
nix run git+https://forge.capytal.company/dot013/nvim
# GitHub mirror
niix run github:dot013/nvim
nix run github:dot013/nvim
```
It also can be used as a NixOS or [Home-Manager](https://github.com/nix-community/home-manager)

146
flake.lock generated
View File

@@ -1,85 +1,19 @@
{
"nodes": {
"blink-cmp": {
"inputs": {
"fenix": "fenix",
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs"
]
},
"godotdev": {
"flake": false,
"locked": {
"lastModified": 1762359884,
"narHash": "sha256-0+KyxOh7WUm6rRLfb936X48qBhYL5aRYn2OBEj4G1/s=",
"owner": "Saghen",
"repo": "blink.cmp",
"rev": "40380e711b616a28affb0f4086a2f7de2f2a556b",
"type": "github"
"lastModified": 1768050065,
"narHash": "sha256-52tWEZ092Sskxn1113aWBSTQW6iBPPhyAfpwCS+F9XI=",
"ref": "refs/heads/master",
"rev": "61fcb7a627d6a417d70913cecb0fda17a181a49a",
"revCount": 80,
"type": "git",
"url": "https://code.capytal.cc/dot013/godotdev.nvim"
},
"original": {
"owner": "Saghen",
"repo": "blink.cmp",
"type": "github"
}
},
"fenix": {
"inputs": {
"nixpkgs": [
"blink-cmp",
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1761028747,
"narHash": "sha256-UqCbRuqnsVURCB0hLZL9SwFNDNftIE1Zxj7Ykf1aRj4=",
"owner": "nix-community",
"repo": "fenix",
"rev": "1dd37dd710195936f675eb0d36cf284806f99a94",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1733312601,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"go-grip": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1741110408,
"narHash": "sha256-SN4ZNafPGtXvJEfVNEPch8dtGQlm4PZrnKBw5SZwYxg=",
"owner": "guz013",
"repo": "go-grip",
"rev": "deb857f70d6f2ff2ca5cf52d55b2eb5e40f2e916",
"type": "github"
},
"original": {
"owner": "guz013",
"repo": "go-grip",
"type": "github"
"type": "git",
"url": "https://code.capytal.cc/dot013/godotdev.nvim"
}
},
"mdfmt": {
@@ -100,11 +34,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1762596750,
"narHash": "sha256-rXXuz51Bq7DHBlfIjN7jO8Bu3du5TV+3DSADBX7/9YQ=",
"lastModified": 1767892417,
"narHash": "sha256-dhhvQY67aboBk8b0/u0XB6vwHdgbROZT3fJAjyNh5Ww=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b6a8526db03f735b89dd5ff348f53f752e7ddc8e",
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
"type": "github"
},
"original": {
@@ -114,59 +48,11 @@
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1733096140,
"narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
}
},
"nordic-nvim-src": {
"flake": false,
"locked": {
"lastModified": 1676228565,
"narHash": "sha256-u/QNfWt45XXaDeiycT0VfLLrVS360u76up4axcX/ZOU=",
"owner": "andersevenrud",
"repo": "nordic.nvim",
"rev": "3338c514e5b5feade29a9c2ed295c9f034f7f05b",
"type": "github"
},
"original": {
"owner": "andersevenrud",
"ref": "pull/93/head",
"repo": "nordic.nvim",
"type": "github"
}
},
"root": {
"inputs": {
"blink-cmp": "blink-cmp",
"go-grip": "go-grip",
"godotdev": "godotdev",
"mdfmt": "mdfmt",
"nixpkgs": "nixpkgs",
"nordic-nvim-src": "nordic-nvim-src"
}
},
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1760976639,
"narHash": "sha256-v+teOfOLbR9UFLuaMfbsd/L5ckJBcQJyeFj23V3lz8g=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "4a305f565ab964caf22dc72980a44b2970a9c2f1",
"type": "github"
},
"original": {
"owner": "rust-lang",
"ref": "nightly",
"repo": "rust-analyzer",
"type": "github"
"nixpkgs": "nixpkgs"
}
}
},

212
flake.nix
View File

@@ -1,20 +1,18 @@
{
description = "My Neovim configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
blink-cmp = {
url = "github:Saghen/blink.cmp";
inputs.nixpkgs.follows = "nixpkgs";
};
go-grip = {
url = "github:guz013/go-grip";
inputs.nixpkgs.follows = "nixpkgs";
};
mdfmt = {
url = "github:moorereason/mdfmt";
flake = false;
};
godotdev = {
url = "git+https://code.capytal.cc/dot013/godotdev.nvim";
# url = "github:Mathijs-Bakker/godotdev.nvim";
# url = "git+file:///home/guz/.projects/guz013-godotdev-nvim";
flake = false;
};
};
outputs = {
self,
@@ -37,6 +35,7 @@
inherit (pkgs) lib stdenv;
}
);
neovim-pkgs = system: import nixpkgs {inherit system;};
in {
formatter = forAllSystems ({pkgs, ...}: pkgs.alejandra);
@@ -47,18 +46,97 @@
stdenv,
...
}: {
neovim = import ./package.nix {
inherit pkgs lib;
blink-cmp = inputs.blink-cmp.packages.${stdenv.hostPlatform.system}.default;
go-grip = inputs.go-grip.packages.${stdenv.hostPlatform.system}.default;
mdfmt = self.packages.${stdenv.hostPlatform.system}.mdfmt;
neovim = pkgs.callPackage ./package.nix {
mdfmt = self.packages.${pkgs.system}.mdfmt;
godotdev = self.packages.${pkgs.system}.godotdev;
};
godotdev = pkgs.vimUtils.buildVimPlugin {
pname = "godotdev.nvim";
version = "v0.2.3";
src = inputs.godotdev;
};
godot-neovim = pkgs.writeShellScriptBin "godot-neovim" (builtins.readFile ./scripts/godot-neovim.sh);
gh-actions-language-server = pkgs.callPackage ({
stdenv,
lib,
makeBinaryWrapper,
buildNpmPackage,
bun,
nodejs,
npmHooks,
...
}: let
pname = "gh-actions-language-server";
src = fetchGit {
url = "https://github.com/lttb/gh-actions-language-server";
rev = "0287d3081d7b74fef88824ca3bd6e9a44323a54d";
};
packageJson = lib.importJSON "${src}/package.json";
version = packageJson.version;
node_modules = stdenv.mkDerivation {
inherit src version;
pname = "${pname}-node_modules";
nativeBuildInputs = [bun];
dontConfigure = true;
buildPhase = ''
bun install --no-progress --frozen-lockfile
'';
installPhase = ''
mkdir -p $out/node_modules
cp -R ./node_modules/* $out/node_modules
ls -la $out/node_modules
'';
dontFixup = true;
dontPathShebangs = true;
outputHash = "sha256-HfMP9OI07CpiOQw5xkpcRPKPv/MflU1FjtSMOuCkYtg=";
outputHashAlgo = "sha256";
outputHashMode = "recursive";
};
in
stdenv.mkDerivation {
inherit pname src version;
buildInputs = [bun nodejs];
nativeBuildInputs = [makeBinaryWrapper];
dontConfigure = true;
buildPhase = ''
runHook preBuild
ln -s "${node_modules}/node_modules" ./
bun run build:node
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out
mv ./bin/$pname $out/$pname
makeBinaryWrapper ${lib.getExe nodejs} $out/bin/$pname \
--prefix PATH : ${lib.makeBinPath [nodejs]} \
--add-flags "$out/$pname"
runHook postInstall
'';
# installPhase = ''
# runHook preInstall
#
# mkdir -p $out/bin
# makeBinaryWrapper ${lib.getExe nodejs} $out/bin/$pname \
# --prefix PATH : "${lib.makeBinPath [nodejs]}"
# --add-flags "$out/$pname"
#
# runHook postInstall
# '';
}) {};
mdfmt = pkgs.buildGoModule {
name = "mdfmt";
src = inputs.mdfmt;
vendorHash = "sha256-JtYvDgjUoEc1Mp7Eq8lbu9jWI+RR9yBo4ujGY+J70J4=";
};
default = self.packages."${stdenv.hostPlatform.system}".neovim;
default = self.packages."${pkgs.system}".neovim;
}
);
devShells = forAllSystems (
@@ -72,11 +150,111 @@
);
nixosModules = {
neovim = import ./nixos.nix {inherit self;};
neovim = {
config,
lib,
pkgs,
stdenv,
...
}: let
cfg = config.neovim;
npkgs = neovim-pkgs pkgs.system;
in
with lib; {
options.neovim = {
enable = mkOption {
type = with types; bool;
default = true;
};
package = mkOption {
type = with types; package;
default = self.packages.${pkgs.system}.default;
readOnly = true;
};
defaultEditor = mkOption {
type = with types; bool;
default = true;
};
integrations.godot.enable = mkEnableOption "";
};
config = mkIf cfg.enable {
environment.variables = {
EDITOR = "nvim";
};
environment.systemPackages =
[
(npkgs.callPackage ./package.nix {
mdfmt = self.packages.${pkgs.system}.mdfmt;
}
// (optionalAttrs config.programs.yazi.enable {
yazi = config.programs.yazi.package;
}))
]
++ (optionals cfg.integrations.godot.enable [
self.packages."${pkgs.system}".godot-neovim
]);
# Disable NixOS's Neovim
programs.neovim.enable = mkForce false;
};
};
default = self.nixosModules.neovim;
};
homeManagerModules = {
neovim = import ./home.nix {inherit self;};
neovim = {
config,
lib,
pkgs,
stdenv,
...
}: let
cfg = config.neovim;
npkgs = neovim-pkgs pkgs.system;
in
with lib; {
options.neovim = {
enable = mkOption {
type = with types; bool;
default = true;
};
vimdiffAlias = mkOption {
type = with types; bool;
default = true;
};
defaultEditor = mkOption {
type = with types; bool;
default = true;
};
integrations.godot.enable = mkEnableOption "";
};
config = mkIf cfg.enable {
home.sessionVariables = {
EDITOR = "nvim";
};
home.packages =
[
(npkgs.callPackage ./package.nix {
mdfmt = self.packages.${pkgs.system}.mdfmt;
}
// (optionalAttrs config.programs.yazi.enable {
yazi = config.programs.yazi.package;
}))
]
++ (optionals cfg.integrations.godot.enable [
self.packages."${pkgs.system}".godot-neovim
]);
programs.bash.shellAliases = mkIf cfg.vimdiffAlias {vimdiff = "nvim -d";};
programs.fish.shellAliases = mkIf cfg.vimdiffAlias {vimdiff = "nvim -d";};
programs.zsh.shellAliases = mkIf cfg.vimdiffAlias {vimdiff = "nvim -d";};
# Disable home-manager's Neovim
programs.neovim.enable = mkForce false;
};
};
default = self.homeManagerModules.neovim;
};
};

View File

@@ -1,42 +0,0 @@
{self}: {
config,
osConfig,
lib,
pkgs,
...
}: let
cfg = config.neovim;
in
with lib; {
options.neovim = {
enable = mkOption {
type = with types; bool;
default = true;
};
package = mkOption {
type = with types; package;
default = self.packages.${pkgs.system}.default;
};
vimdiffAlias = mkOption {
type = with types; bool;
default = true;
};
defaultEditor = mkOption {
type = with types; bool;
default = true;
};
};
config = mkIf cfg.enable {
home.sessionVariables = {
EDITOR = "nvim";
};
home.packages = [cfg.package];
programs.bash.shellAliases = mkIf cfg.vimdiffAlias {vimdiff = "nvim -d";};
programs.fish.shellAliases = mkIf cfg.vimdiffAlias {vimdiff = "nvim -d";};
programs.zsh.shellAliases = mkIf cfg.vimdiffAlias {vimdiff = "nvim -d";};
# Disable home-manager's Neovim
programs.neovim.enable = mkForce false;
};
}

27
lua/dap-go/COPYRIGHT Normal file
View File

@@ -0,0 +1,27 @@
Contents of `dap-go/init.lua` and `dap-go/ts.lua` were copied from Leonardo Luz Almeida's
nvim-dap-go plugin at Git commit `b4421153ead5d726603b02743ea40cf26a51ed5f` <https://github.com/leoluz/nvim-dap-go/tree/b4421153ead5d726603b02743ea40cf26a51ed5f>,
which is licensed under the MIT License. A copy of the original license can be found at
the nvim-dap-go's GitHub repositoy <https://github.com/leoluz/nvim-dap-go/blob/b4421153ead5d726603b02743ea40cf26a51ed5f/LICENSE>
and below:
MIT License
Copyright (c) 2023 Leonardo Luz Almeida
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

272
lua/dap-go/init.lua Normal file
View File

@@ -0,0 +1,272 @@
local ts = require("dap-go.ts")
local M = {
last_testname = "",
last_testpath = "",
test_buildflags = "",
test_verbose = false,
}
local default_config = {
delve = {
path = "dlv",
initialize_timeout_sec = 20,
port = "${port}",
args = {},
build_flags = "",
-- Automatically handle the issue on delve Windows versions < 1.24.0
-- where delve needs to be run in attched mode or it will fail (actually crashes).
detached = vim.fn.has("win32") == 0,
output_mode = "remote",
},
tests = {
verbose = false,
},
}
local internal_global_config = {}
local function load_module(module_name)
local ok, module = pcall(require, module_name)
assert(ok, string.format("dap-go dependency error: %s not installed", module_name))
return module
end
local function get_arguments()
return coroutine.create(function(dap_run_co)
local args = {}
vim.ui.input({ prompt = "Args: " }, function(input)
args = vim.split(input or "", " ")
coroutine.resume(dap_run_co, args)
end)
end)
end
local function get_build_flags(config)
return coroutine.create(function(dap_run_co)
local build_flags = config.build_flags
vim.ui.input({ prompt = "Build Flags: " }, function(input)
build_flags = vim.split(input or "", " ")
coroutine.resume(dap_run_co, build_flags)
end)
end)
end
local function filtered_pick_process()
local opts = {}
vim.ui.input(
{ prompt = "Search by process name (lua pattern), or hit enter to select from the process list: " },
function(input)
opts["filter"] = input or ""
end
)
return require("dap.utils").pick_process(opts)
end
local function setup_delve_adapter(dap, config)
local args = { "dap", "-l", "127.0.0.1:" .. config.delve.port }
vim.list_extend(args, config.delve.args)
local delve_config = {
type = "server",
port = config.delve.port,
executable = {
command = config.delve.path,
args = args,
detached = config.delve.detached,
cwd = config.delve.cwd,
},
options = {
initialize_timeout_sec = config.delve.initialize_timeout_sec,
},
}
dap.adapters.go = function(callback, client_config)
if client_config.port == nil then
callback(delve_config)
return
end
local host = client_config.host
if host == nil then
host = "127.0.0.1"
end
local listener_addr = host .. ":" .. client_config.port
delve_config.port = client_config.port
delve_config.executable.args = { "dap", "-l", listener_addr }
callback(delve_config)
end
end
local function setup_go_configuration(dap, configs)
local common_debug_configs = {
{
type = "go",
name = "Debug",
request = "launch",
program = "${file}",
buildFlags = configs.delve.build_flags,
outputMode = configs.delve.output_mode,
},
{
type = "go",
name = "Debug (Arguments)",
request = "launch",
program = "${file}",
args = get_arguments,
buildFlags = configs.delve.build_flags,
outputMode = configs.delve.output_mode,
},
{
type = "go",
name = "Debug (Arguments & Build Flags)",
request = "launch",
program = "${file}",
args = get_arguments,
buildFlags = get_build_flags,
outputMode = configs.delve.output_mode,
},
{
type = "go",
name = "Debug Package",
request = "launch",
program = "${fileDirname}",
buildFlags = configs.delve.build_flags,
outputMode = configs.delve.output_mode,
},
{
type = "go",
name = "Attach",
mode = "local",
request = "attach",
processId = filtered_pick_process,
buildFlags = configs.delve.build_flags,
},
{
type = "go",
name = "Debug test",
request = "launch",
mode = "test",
program = "${file}",
buildFlags = configs.delve.build_flags,
outputMode = configs.delve.output_mode,
},
{
type = "go",
name = "Debug test (go.mod)",
request = "launch",
mode = "test",
program = "./${relativeFileDirname}",
buildFlags = configs.delve.build_flags,
outputMode = configs.delve.output_mode,
},
}
if dap.configurations.go == nil then
dap.configurations.go = {}
end
for _, config in ipairs(common_debug_configs) do
table.insert(dap.configurations.go, config)
end
if configs == nil or configs.dap_configurations == nil then
return
end
for _, config in ipairs(configs.dap_configurations) do
if config.type == "go" then
table.insert(dap.configurations.go, config)
end
end
end
function M.setup(opts)
internal_global_config = vim.tbl_deep_extend("force", default_config, opts or {})
M.test_buildflags = internal_global_config.delve.build_flags
M.test_verbose = internal_global_config.tests.verbose
local dap = load_module("dap")
setup_delve_adapter(dap, internal_global_config)
setup_go_configuration(dap, internal_global_config)
end
local function debug_test(testname, testpath, build_flags, extra_args, custom_config)
local dap = load_module("dap")
local config = {
type = "go",
name = testname,
request = "launch",
mode = "test",
program = testpath,
args = { "-test.run", "^" .. testname .. "$" },
buildFlags = build_flags,
outputMode = "remote",
}
config = vim.tbl_deep_extend("force", config, custom_config or {})
if not vim.tbl_isempty(extra_args) then
table.move(extra_args, 1, #extra_args, #config.args + 1, config.args)
end
dap.run(config)
end
function M.debug_test(custom_config)
local test = ts.closest_test()
if test.name == "" or test.name == nil then
vim.notify("no test found")
return false
end
M.last_testname = test.name
M.last_testpath = test.package
local msg = string.format("starting debug session '%s : %s'...", test.package, test.name)
vim.notify(msg)
local extra_args = {}
if M.test_verbose then
extra_args = { "-test.v" }
end
debug_test(test.name, test.package, M.test_buildflags, extra_args, custom_config)
return true
end
function M.debug_last_test()
local testname = M.last_testname
local testpath = M.last_testpath
if testname == "" then
vim.notify("no last run test found")
return false
end
local msg = string.format("starting debug session '%s : %s'...", testpath, testname)
vim.notify(msg)
local extra_args = {}
if M.test_verbose then
extra_args = { "-test.v" }
end
debug_test(testname, testpath, M.test_buildflags, extra_args)
return true
end
function M.get_build_flags()
return get_build_flags(internal_global_config)
end
function M.get_arguments()
return get_arguments()
end
return M

175
lua/dap-go/ts.lua Normal file
View File

@@ -0,0 +1,175 @@
local M = {}
local tests_query = [[
(function_declaration
name: (identifier) @testname
parameters: (parameter_list
. (parameter_declaration
type: (pointer_type) @type) .)
(#match? @type "*testing.(T|M)")
(#match? @testname "^Test.+$")) @parent
]]
local subtests_query = [[
(call_expression
function: (selector_expression
operand: (identifier)
field: (field_identifier) @run)
arguments: (argument_list
(interpreted_string_literal) @testname
[
(func_literal)
(identifier)
])
(#eq? @run "Run")) @parent
]]
local function format_subtest(testcase, test_tree)
local parent
if testcase.parent then
for _, curr in pairs(test_tree) do
if curr.name == testcase.parent then
parent = curr
break
end
end
return string.format("%s/%s", format_subtest(parent, test_tree), testcase.name)
else
return testcase.name
end
end
local function get_closest_above_cursor(test_tree)
local result
for _, curr in pairs(test_tree) do
if not result then
result = curr
else
local node_row1, _, _, _ = curr.node:range()
local result_row1, _, _, _ = result.node:range()
if node_row1 > result_row1 then
result = curr
end
end
end
if result then
return format_subtest(result, test_tree)
end
return nil
end
local function is_parent(dest, source)
if not (dest and source) then
return false
end
if dest == source then
return false
end
local current = source
while current ~= nil do
if current == dest then
return true
end
current = current:parent()
end
return false
end
local function get_closest_test()
local stop_row = vim.api.nvim_win_get_cursor(0)[1]
local ft = vim.api.nvim_buf_get_option(0, "filetype")
assert(ft == "go", "can only find test in go files, not " .. ft)
local parser = vim.treesitter.get_parser(0)
local root = (parser:parse()[1]):root()
local test_tree = {}
local test_query = vim.treesitter.query.parse(ft, tests_query)
assert(test_query, "could not parse test query")
for _, match, _ in test_query:iter_matches(root, 0, 0, stop_row, { all = true }) do
local test_match = {}
for id, nodes in pairs(match) do
for _, node in ipairs(nodes) do
local capture = test_query.captures[id]
if capture == "testname" then
local name = vim.treesitter.get_node_text(node, 0)
test_match.name = name
end
if capture == "parent" then
test_match.node = node
end
end
end
table.insert(test_tree, test_match)
end
local subtest_query = vim.treesitter.query.parse(ft, subtests_query)
assert(subtest_query, "could not parse test query")
for _, match, _ in subtest_query:iter_matches(root, 0, 0, stop_row, { all = true }) do
local test_match = {}
for id, nodes in pairs(match) do
for _, node in ipairs(nodes) do
local capture = subtest_query.captures[id]
if capture == "testname" then
local name = vim.treesitter.get_node_text(node, 0)
test_match.name = string.gsub(string.gsub(name, " ", "_"), '"', "")
end
if capture == "parent" then
test_match.node = node
end
end
end
table.insert(test_tree, test_match)
end
table.sort(test_tree, function(a, b)
return is_parent(a.node, b.node)
end)
for _, parent in ipairs(test_tree) do
for _, child in ipairs(test_tree) do
if is_parent(parent.node, child.node) then
child.parent = parent.name
end
end
end
return get_closest_above_cursor(test_tree)
end
local function get_package_name()
local test_dir = vim.fn.fnamemodify(vim.fn.expand("%:.:h"), ":r")
return "./" .. test_dir
end
M.closest_test = function()
local package_name = get_package_name()
local test_case = get_closest_test()
local test_scope
if test_case then
test_scope = "testcase"
else
test_scope = "package"
end
return {
package = package_name,
name = test_case,
scope = test_scope,
}
end
M.get_root_dir = function()
local id, client = next(vim.lsp.buf_get_clients())
if id == nil then
error({ error_msg = "lsp client not attached" })
end
if not client.config.root_dir then
error({ error_msg = "lsp root_dir not defined" })
end
return client.config.root_dir
end
return M

161
lua/dot/commands.lua Normal file
View File

@@ -0,0 +1,161 @@
-- Yazi file manager
if vim.fn.executable("yazi") then
local PATH_CACHE = vim.fn.stdpath("cache")
local PATH_SELECTED_FILES = PATH_CACHE .. "/tfm_selected_files"
local function open_yazi(path_to_open, open_mode)
local file_to_focus = path_to_open or vim.fn.expand("%")
if file_to_focus ~= "" then
file_to_focus = string.format('"%s"', file_to_focus)
end
local buffers_for_existing_files = {}
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.fn.buflisted(buf) == 1 then
local buf_name = vim.fn.bufname(buf)
if vim.fn.filereadable(buf_name) == 1 then
table.insert(buffers_for_existing_files, buf_name)
end
end
end
-- Clean leftover files
vim.fn.delete(PATH_SELECTED_FILES)
local cmd = string.format("yazi --chooser-file %s %s", PATH_SELECTED_FILES, file_to_focus)
local last_win = vim.api.nvim_get_current_win()
-- Open window
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
border = "rounded",
style = "minimal",
height = vim.o.lines,
width = vim.o.columns,
row = 0.5 - 1,
col = 0.5,
})
vim.api.nvim_set_option_value("winhl", "NormalFloat:Normal", { win = win })
vim.api.nvim_set_option_value("filetype", "tfm", { buf = buf })
local group = vim.api.nvim_create_augroup("tfm_window", { clear = true })
vim.api.nvim_create_autocmd("VimResized", {
group = group,
buffer = buf,
callback = function()
vim.api.nvim_win_set_config(
win,
vim.tbl_deep_extend("force", vim.api.nvim_win_get_config(win), {
height = vim.o.lines,
width = vim.o.columns,
row = 0.5 - 1,
col = 0.5,
})
)
end,
})
local on_exit = function(_, code, _)
if code ~= 0 then
return
end
vim.api.nvim_win_close(0, true)
vim.api.nvim_set_current_win(last_win)
if vim.fn.filereadable(PATH_SELECTED_FILES) ~= 1 then
return
end
local selected_files = vim.fn.readfile(PATH_SELECTED_FILES)
local edit = open_mode or vim.cmd.edit
local directories = {}
for _, path in ipairs(selected_files) do
if vim.fn.isdirectory(path) == 1 then
table.insert(directories, path)
else
edit(path)
end
end
local _, first_dir = next(directories)
if first_dir ~= nil then
open_yazi(first_dir, open_mode)
end
-- Clean leftover files
vim.fn.delete(PATH_SELECTED_FILES)
-- Close empty buffers
for _, buf in ipairs(buffers_for_existing_files) do
if vim.fn.filereadable(buf) ~= 1 then
vim.cmd.bdelete(buf)
end
end
end
vim.fn.jobstart(cmd, {
term = true,
on_exit = on_exit,
})
vim.cmd.startinsert()
end
vim.api.nvim_create_user_command("Ex", function()
open_yazi()
end, {})
end
-- Grip markdown reader
---@type integer?
local grip_channel = nil
vim.api.nvim_create_user_command("GripStart", function()
if grip_channel then
return
end
local file = vim.api.nvim_buf_get_name(0)
local cmd = "go-grip -b false -H 0.0.0.0 " .. file
grip_channel = vim.fn.jobstart(cmd, {
on_stderr = function(_, err)
if grip_channel == nil then
return
end
vim.fn.jobstop(grip_channel)
local content = table.concat(err, "\n")
if #content > 0 then
vim.notify("Grip error: " .. content, vim.log.levels.ERROR, {})
end
end,
on_exit = function()
if grip_channel == nil then
return
end
vim.fn.chanclose(grip_channel)
grip_channel = nil
end,
stderr_buffered = true,
})
end, {})
vim.api.nvim_create_user_command("GripStop", function()
if grip_channel then
vim.fn.jobstop(grip_channel)
end
end, {})
vim.api.nvim_create_autocmd({ "QuitPre", "BufDelete" }, {
callback = function()
if grip_channel then
vim.fn.jobstop(grip_channel)
end
end,
})

22
lua/dot/debugger.lua Normal file
View File

@@ -0,0 +1,22 @@
local dap = require("dap")
local dapui = require("dapui")
dapui.setup()
dap.listeners.before.attach.dapui_config = function()
dapui.open()
end
dap.listeners.before.launch.dapui_config = function()
dapui.open()
end
dap.listeners.before.event_terminated.dapui_config = function()
dapui.close()
end
dap.listeners.before.event_exited.dapui_config = function()
dapui.close()
end
-- Languages
-- Go
require("dap-go").setup()

83
lua/dot/formatting.lua Normal file
View File

@@ -0,0 +1,83 @@
local conform = require("conform")
local prettier = { "prettierd", "prettier", stop_after_first = true }
local function javascript_formatters(bufnr)
local formatters = {}
if conform.get_formatter_info("deno_fmt", bufnr).available then
table.insert(formatters, "deno_fmt")
end
if conform.get_formatter_info("prettierd", bufnr).available then
table.insert(formatters, "prettierd")
elseif require("conform").get_formatter_info("prettier", bufnr).available then
table.insert(formatters, "prettier")
end
if conform.get_formatter_info("eslint_d", bufnr).available then
table.insert(formatters, "eslint_d")
end
return formatters
end
conform.setup({
formatters_by_ft = {
css = prettier,
gdscript = { "gdformat" },
go = function(bufnr)
local formatters = {}
if conform.get_formatter_info("gofumpt", bufnr).available then
table.insert(formatters, "gofumpt")
else
table.insert(formatters, "gofmt")
end
if conform.get_formatter_info("golines", bufnr).available then
table.insert(formatters, "golines")
end
if conform.get_formatter_info("goimports", bufnr).available then
table.insert(formatters, "gofmt")
end
if conform.get_formatter_info("golangci-lint").available then
table.insert(formatters, "golangci-lint")
end
return formatters
end,
html = prettier,
javascript = javascript_formatters,
javascriptreact = javascript_formatters,
typescript = javascript_formatters,
typescriptreact = javascript_formatters,
json = function(bufnr)
return #javascript_formatters(bufnr) and javascript_formatters(bufnr) or { "jq" }
end,
less = prettier,
lua = { "stylua" },
markdownn = { "mdfmt" },
nix = { "alejandra", stop_after_first = true }, -- TODO: Support nix fmt command when flake.nix formatter is enabled
rust = { "rustfmt", lsp_format = "fallback" },
scss = prettier,
sh = { "shellharden", "shfmt" },
templ = { "templ" },
yaml = prettier,
xhtml = { "xmllint", "xmltidy", stop_after_first = true },
xml = { "xmllint", "xmltidy", stop_after_first = true },
["*"] = { "codespell" },
["_"] = { "trim_whitespace" },
},
format_on_save = {
timeout_ms = 500,
lsp_format = "fallback",
},
formaters = {
mdfmt = { command = "mdfmt" },
xmltidy = { inherit = false, command = "tidy", args = { "-xml", "-indent", "yes", "2", "-wrap", "100", "-" } }, -- INFO: Uses HTML Tidy
},
})

228
lua/dot/init.lua Normal file
View File

@@ -0,0 +1,228 @@
vim.g.mapleader = " "
vim.g.maplocalleader = " "
-- Filetype plugins
vim.o.filetype = "on"
-- Terminal
vim.o.termguicolors = true -- True colors
vim.g.have_nerd_font = true
---- Appearance
-- Line numbers
vim.o.number = true
vim.o.relativenumber = true
vim.o.signcolumn = "yes"
vim.o.colorcolumn = "80"
-- Indentation
vim.o.expandtab = false
vim.o.tabstop = 4
vim.o.softtabstop = 4
vim.o.shiftwidth = 4
vim.o.breakindent = true
vim.o.list = true
vim.opt.listchars = { tab = "", trail = ".", nbsp = "" }
----
-- Mouse support
vim.o.mouse = "a"
-- Save undo history
vim.o.undofile = true
vim.o.ignorecase = true
vim.o.smartcase = true
vim.o.updatetime = 250
vim.o.timeoutlen = 300
vim.o.splitright = true
vim.o.splitbelow = true
vim.o.inccommand = "split"
vim.o.cursorline = true
vim.o.scrolloff = 10
vim.o.completeopt = "menuone,noselect"
-- Confirm on exit
vim.o.confirm = true
-- Diagnostics
vim.diagnostic.config({
severity_sort = true,
float = { border = "rounded", source = "if_many" },
underline = { severity = vim.diagnostic.severity.ERROR },
signs = vim.g.have_nerd_font and {
text = {
[vim.diagnostic.severity.ERROR] = "󰅚 ",
[vim.diagnostic.severity.WARN] = "󰀪 ",
[vim.diagnostic.severity.INFO] = "󰋽 ",
[vim.diagnostic.severity.HINT] = "󰌶 ",
},
} or {},
virtual_text = {
source = "if_many",
spacing = 2,
format = function(diagnostic)
local diagnostic_message = {
[vim.diagnostic.severity.ERROR] = diagnostic.message,
[vim.diagnostic.severity.WARN] = diagnostic.message,
[vim.diagnostic.severity.INFO] = diagnostic.message,
[vim.diagnostic.severity.HINT] = diagnostic.message,
}
return diagnostic_message[diagnostic.severity]
end,
},
})
---- Plugins
require("dot.plugins")
require("dot.commands")
require("dot.keymaps")
-- Theme
vim.cmd.colorscheme("catppuccin")
require("nvim-treesitter.configs").setup({
auto_install = false,
highlight = { enable = true },
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "<c-space>",
node_incremental = "<c-space>",
scope_incremental = "<c-s>",
node_decremental = "<M-space>",
},
},
textobjects = {
select = {
enable = true,
lookahead = true,
keymaps = {
["aa"] = "@parameter.outer",
["ia"] = "@parameter.inner",
["af"] = "@function.outer",
["if"] = "@function.inner",
["ac"] = "@class.outer",
["ic"] = "@class.inner",
},
},
move = {
enable = true,
set_jumps = true,
goto_next_start = {
["]m"] = "@function.outer",
["]]"] = "@class.outer",
},
goto_next_end = {
["]M"] = "@function.outer",
["]["] = "@class.outer",
},
goto_previous_start = {
["[m"] = "@function.outer",
["[["] = "@class.outer",
},
goto_previous_end = {
["[M"] = "@function.outer",
["[]"] = "@class.outer",
},
},
},
textsubjects = {
enable = true,
prev_selection = ",",
keymaps = {
["."] = "textsubjects-smart",
[";"] = "textsubjects-container-outer",
["i;"] = "textsubjects-container-inner",
},
},
swap = {
enable = true,
swap_next = {
["<leader>a"] = "@parameter.inner",
},
swap_previous = {
["<leader>A"] = "@parameter.inner",
},
},
playground = {
enable = true,
disable = {},
updatetime = 25,
persist_queries = false,
keybindings = {
toggle_query_editor = "o",
toggle_hl_groups = "i",
toggle_injected_languages = "t",
toggle_anonymous_nodes = "a",
toggle_language_display = "I",
focus_language = "f",
unfocus_language = "F",
update = "R",
goto_node = "<cr>",
show_help = "?",
},
},
query_linter = {
enable = true,
use_virtual_text = true,
lint_events = { "BugWrite", "CursorHold" },
},
})
vim.api.nvim_create_autocmd("TextYankPost", {
desc = "Highlight when yanking text",
group = vim.api.nvim_create_augroup("dot-highlight-yank", { clear = true }),
callback = function()
vim.hl.on_yank()
end,
})
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("dot-lsp-attach-autocmds", { clear = true }),
callback = function(e)
local client = vim.lsp.get_client_by_id(e.data.client_id)
-- Highlight references of word under cursor when it rests for a little while
if client and client:supports_method(vim.lsp.protocol.Methods.textDocument_documentHighlight, e.buf) then
local highlight_augroup = vim.api.nvim_create_augroup("dot-lsp-highlight", { clear = false })
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
buffer = e.buf,
callback = vim.lsp.buf.document_highlight,
group = highlight_augroup,
})
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
buffer = e.buf,
callback = vim.lsp.buf.clear_references,
group = highlight_augroup,
})
vim.api.nvim_create_autocmd("LspDetach", {
callback = function(e2)
vim.lsp.buf.clear_references()
vim.api.nvim_clear_autocmds({ group = "dot-lsp-attach-autocmds", buffer = e2.buf })
end,
group = vim.api.nvim_create_augroup("dot-lsp-detach-autocmds", { clear = true }),
})
end
-- Toggle inlay hints
if client and client:supports_method(vim.lsp.protocol.Methods.textDocument_inlayHint, e.buf) then
vim.keymap.set("n", "<leader>lh", function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = e.buf }))
end, { desc = "LSP: [T]oggle Inlay [H]ints" })
end
end,
})

81
lua/dot/keymaps.lua Normal file
View File

@@ -0,0 +1,81 @@
vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>")
-- Navigation
vim.keymap.set("n", "<C-h>", "<C-w><C-h>", { desc = "Move focus to the left window" })
vim.keymap.set("n", "<C-l>", "<C-w><C-l>", { desc = "Move focus to the right window" })
vim.keymap.set("n", "<C-j>", "<C-w><C-l>", { desc = "Move focus to the lower window" })
vim.keymap.set("n", "<C-k>", "<C-w><C-k>", { desc = "Move focus to the upper window" })
vim.keymap.set("n", "<leader>w", ":lua require('harpoon'):list():add()<cr>", { desc = "Harpoon: Add file to list" })
vim.keymap.set("n", "<C-p>", ":lua require('harpoon'):list():prev()<cr>", { desc = "Harpoon: Previous file" })
vim.keymap.set("n", "<C-n>", ":lua require('harpoon'):list():next()<cr>", { desc = "Harpoon: Next file" })
vim.keymap.set("n", "<leader>e", ":lua require('harpoon').ui:toggle_quick_menu(require('harpoon'):list())<cr>", {
desc = "Harpoon: Add file to list",
})
vim.keymap.set("n", "<C-e>", ":Ex<cr>", { desc = "Open file manager" })
-- Fuzzy find
vim.keymap.set("n", "ff", ":lua require('telescope.builtin').find_files()<cr>", { desc = "Telescope: [F]ind [F]iles" })
vim.keymap.set("n", "fw", ":lua require('telescope.builtin').live_grep()<cr>", { desc = "Telescope: [F]ind [W]ord" })
vim.keymap.set("n", "/", ":lua require('telescope.builtin').current_buffer_fuzzy_find()<cr>", {
desc = "Telescope: Find in current buffer",
})
-- Spelling
vim.keymap.set("n", "s=", "z=", { desc = "Suggest spelling currection" })
vim.keymap.set("n", "st", function()
vim.o.spell = not vim.o.spell
end, { desc = "Toggle spelling correction" })
-- Language Server Protocol & Actions
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" })
vim.keymap.set("n", "<leader>t", vim.diagnostic.open_float, { desc = "Open diagnostic" })
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(e)
---@param lhs string
---@param rhs string|function
---@param desc string
---@param mode string|string[]?
local function map(lhs, rhs, desc, mode)
vim.keymap.set(mode or "n", lhs, rhs, { buffer = e.buf, desc = "LSP: " .. desc })
end
map("gn", vim.lsp.buf.rename, "Re[n]ame")
map("ga", vim.lsp.buf.code_action, "[G]oto Code [A]ction", { "n", "x" })
map("gr", ":lua require('telescope.builtin').lsp_references()<cr>", "[G]oto [R]eferences")
map("gi", ":lua require('telescope.builtin').lsp_implementations()<cr>", "[G]oto [I]mplementation")
map("gd", ":lua require('telescope.builtin').lsp_definitions()<cr>", "[G]oto [D]efinition")
map("gt", ":lua require('telescope.builtin').lsp_type_definitions()<cr>", "[G]oto [T]ype Definition")
map("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration<cr>")
map("gO", ":lua require('telescope.builtin').lsp_document_symbols()<cr>", "[O]pen Document Symbols")
map("gW", ":lua require('telescope.builtin').lsp_dynamic_workspace_symbols()<cr>", "Open [W]orkspace Symbols")
end,
group = vim.api.nvim_create_augroup("dot-lsp-attach-keymaps", { clear = true }),
})
-- Debugger
vim.keymap.set("n", "<leader>b", ":lua require('dap').toggle_breakpoint()<cr>", {
desc = "Debugger: Toggle [B]reakpointn",
})
vim.keymap.set("n", "<F5>", ":lua require('dap').continue()<cr>", { desc = "Debugger: Continue debugger" })
vim.keymap.set("n", "<F8>", ":lua require('dap').terminate()<cr>", { desc = "Debugger: Terminate debugger" })
vim.keymap.set("n", "<leader>C", ":lua require('dap').clear_breakpoints()<cr>", {
desc = "Debugger: Clear all breakpoints",
})
vim.keymap.set("n", "<leader>xu", ":lua require('dapui').toggle()<cr>", { desc = "Debugger: Toggle debugger [U]I" })
vim.keymap.set("n", "<leader>K", ":lua require('dapui').eval(nil, { enter=true })<cr>", {
desc = "Debugger: Toggle debugger [U]I",
})
-- Tweaks
vim.keymap.set("n", "J", "mzJ`z") -- Move when highlighted
vim.keymap.set("n", "<C-d>", "<C-d>zz") -- Make cursor stay in place when jumping
vim.keymap.set("n", "<C-u>", "<C-u>zz")
vim.keymap.set("n", "<C-c>", "<Esc>")
vim.keymap.set("n", "Q", "<nop>")
vim.keymap.set({ "n", "v" }, "<Space>", "<Nop>", { silent = true })
vim.keymap.set("n", "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
vim.keymap.set("n", "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })

312
lua/dot/lsp.lua Normal file
View File

@@ -0,0 +1,312 @@
---@type lze.PluginSpec[] | { lsp: vim.lsp.Config }[]
return {
-- Language Server Providers
{
"cssls",
lsp = { filetypes = { "css", "scss", "less" } },
},
{
"denols",
lsp = {
filetypes = {
"javascript",
"javascriptreact",
"javascript.jsx",
"typescript",
"typescriptreact",
"typescript.tsx",
},
},
},
{
"emmet_language_server",
lsp = {
filetypes = {
"astro",
"css",
"eruby",
"html",
"htmlangular",
"htmldjango",
"javascriptreact",
"less",
"pug",
"sass",
"scss",
"svelte",
"templ",
"typescriptreact",
"vue",
},
},
},
{
"eslint",
lsp = {
filetypes = {
"javascript",
"javascriptreact",
"javascript.jsx",
"typescript",
"typescriptreact",
"typescript.tsx",
"vue",
"svelte",
"astro",
"htmlangular",
},
},
},
{
"golangci_lint_ls",
lsp = {
filetypes = { "go", "gomod" },
},
},
{
"gopls",
lsp = {
filetypes = { "go", "gomod", "gowork", "gotmpl" },
},
},
{
"html",
lsp = {
filetypes = { "html", "templ" },
},
},
{
"htmx",
filetypes = {
-- html
"aspnetcorerazor",
"astro",
"astro-markdown",
"blade",
"clojure",
"django-html",
"htmldjango",
"edge",
"eelixir", -- vim ft
"elixir",
"ejs",
"erb",
"eruby", -- vim ft
"gohtml",
"gohtmltmpl",
"haml",
"handlebars",
"hbs",
"html",
"htmlangular",
"html-eex",
"heex",
"jade",
"leaf",
"liquid",
"markdown",
"mdx",
"mustache",
"njk",
"nunjucks",
"php",
"razor",
"slim",
"twig",
-- js
"javascript",
"javascriptreact",
"reason",
"rescript",
"typescript",
"typescriptreact",
-- mixed
"vue",
"svelte",
"templ",
},
},
{
"jsonls",
lsp = {
filetypes = { "json", "jsonc" },
},
},
{
"lemminx",
lsp = {
filetypes = { "xml", "xsd", "xsl", "xslt", "svg", "xhtml" },
},
},
{
"lua_ls",
lsp = {
filetypes = { "lua" },
on_attach = function(client)
if client.workspace_folders then
local path = client.workspace_folders[1].name
if
path ~= vim.fn.stdpath("config") and vim.loop.fs_stat(path .. "/.luarc.json")
or vim.loop.fs_stat(path .. "/.luarc.jsonc")
then
return
end
end
client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, {
runtime = {
version = "LuaJIT",
path = {
"lua/?.lua",
"lua/?/init.lua",
},
},
workspace = {
checkThirdParty = false,
library = {
vim.env.VIMRUNTIME,
},
},
})
end,
settings = {
Lua = {
codeLens = { enable = true },
hint = { enable = true, semicolon = "Disable" },
telemetry = { enabled = false },
},
},
},
},
{
"marksman",
lsp = {
filetypes = { "markdown", "markdown.mdx" },
},
},
{
"nil_ls",
lsp = {
filetypes = { "nix" },
single_file_support = true,
},
},
{
"rust_analyzer",
lsp = {
filetypes = { "rust" },
settings = {
["rust_analyzer"] = {
diagnostics = {
enable = true,
},
},
},
},
},
{
"tailwindcss",
lsp = {
filetypes = {
-- html
"aspnetcorerazor",
"astro",
"astro-markdown",
"blade",
"clojure",
"django-html",
"htmldjango",
"edge",
"eelixir", -- vim ft
"elixir",
"ejs",
"erb",
"eruby", -- vim ft
"gohtml",
"gohtmltmpl",
"haml",
"handlebars",
"hbs",
"html",
"htmlangular",
"html-eex",
"heex",
"jade",
"leaf",
"liquid",
"markdown",
"mdx",
"mustache",
"njk",
"nunjucks",
"php",
"razor",
"slim",
"twig",
-- css
"css",
"less",
"postcss",
"sass",
"scss",
"stylus",
"sugarss",
-- js
"javascript",
"javascriptreact",
"reason",
"rescript",
"typescript",
"typescriptreact",
-- mixed
"vue",
"svelte",
"templ",
},
},
},
{
"ts_ls",
lsp = {
filetypes = {
"javascript",
"javascriptreact",
"javascript.jsx",
"typescript",
"typescriptreact",
"typescript.tsx",
},
},
},
}
--[[ local M = {}
M.opts = {
keymaps = require("dot.keymaps"),
augroup = vim.api.nvim_create_augroup("dot_group_lsp", {}),
}
function M.setup(opts)
M.opts = vim.tbl_extend("force", M.opts, opts or {})
local keymaps = M.opts.keymaps
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(e)
keymaps.mapn("<leader>r", vim.lsp.buf.rename, { desc = "(LSP) [r]ename", buffer = e.buf })
keymaps.mapn("<leader>a", vim.lsp.buf.code_action, { desc = "(LSP) Code [a]ction", buffer = e.buf })
keymaps.mapn("gd", vim.lsp.buf.definition, { desc = "(LSP) [g]o to [d]efinition", buffer = e.buf })
keymaps.mapn("gD", vim.lsp.buf.declaration, { desc = "(LSP) [g]o to [D]efinition", buffer = e.buf })
keymaps.mapn("gI", vim.lsp.buf.implementation, { desc = "(LSP) [g]o to [I]mplementation", buffer = e.buf })
keymaps.mapn("gt", vim.lsp.buf.type_definition, {
desc = "(LSP) [g]o to [t]ype definition",
buffer = e.buf,
})
end,
group = M.opts.augroup,
})
end
function M.setup(name) end ]]

264
lua/dot/plugins.lua Normal file
View File

@@ -0,0 +1,264 @@
-- Plugins
local lze = require("lze")
lze.register_handlers(require("lzextras").lsp)
lze.load({
{ "plenary.nvim", dep_of = { "harpoon", "telescope.nvim" } },
-- Language Server Protocol
{
"nvim-lspconfig",
dep_of = { "godotdev" },
---@param plugin lze.Plugin
lsp = function(plugin)
local config = plugin.lsp or {}
config["capabilities"] = require("blink.cmp").get_lsp_capabilities(config["capabilities"] or {})
vim.lsp.config(plugin.name, config)
vim.lsp.enable(plugin.name)
end,
},
{ "lazydev.nvim", on_require = "lazydev" },
{ import = "dot.lsp" },
-- Debugger
{
"nvim-dap",
after = function()
require("dot.debugger")
end,
dep_of = { "godotdev.nvim" },
on_require = { "dap", "dapui" },
},
{ "nvim-dap-ui", dep_of = "nvim-dap" },
{ "nvim-nio", dep_of = "nvim-dap-ui" },
-- Formatting
{
"conform.nvim",
after = function()
require("dot.formatting")
end,
event = { "InsertLeave", "TextChanged" },
on_require = "conform",
},
{
"guess-indent.nvim",
after = function()
require("guess-indent").setup()
end,
cmd = "GuessIndent",
event = "BufEnter",
},
-- Autocomplete
{
"blink-cmp",
after = function()
require("blink.cmp").setup({
completion = {
list = { selection = { preselect = true, auto_insert = true } },
menu = {
draw = {
padding = { 1, 0 },
columns = { { "label", "label_description", gap = 1 }, { "kind_icon", "kind" } },
components = {
kind_icon = { width = { fill = true } },
},
},
},
documentation = { auto_show = true },
},
fuzzy = { implementation = "prefer_rust" },
keymap = {
["<C-space>"] = { "show", "show_documentation", "hide_documentation" },
["<Left>"] = { "hide", "fallback" },
["<Right>"] = { "accept", "fallback" },
["<CR>"] = { "accept", "fallback" },
["<Up>"] = { "select_prev", "snippet_backward", "fallback" },
["<Down>"] = { "select_next", "snippet_forward", "fallback" },
["<C-Up>"] = { "scroll_documentation_up", "fallback" },
["<C-Down>"] = { "scroll_documentation_down", "fallback" },
},
sources = {
default = { "snippets", "lazydev", "lsp", "path", "buffer" },
providers = {
lazydev = {
name = "LazyDev",
module = "lazydev.integrations.blink",
score_offset = 100,
},
},
},
})
end,
cmd = "ConformInfo",
event = "InsertEnter",
on_require = "blink",
},
{ "friendly-snippets", dep_of = "blink-cmp" },
{
"nvim-autopairs",
after = function()
require("nvim-autopairs").setup()
end,
event = "InsertEnter",
},
-- Fuzzy Finding
{
"telescope.nvim",
after = function()
require("telescope").load_extension("zf-native")
end,
cmd = { "Telescope" },
on_require = "telescope",
},
{ "telescope-zf-native.nvim", dep_of = "telescope.nvim" },
-- Quick file switching
{
"harpoon2",
after = function()
require("harpoon"):setup()
end,
on_require = "harpoon",
},
-- Auto-saving
{
"auto-save.nvim",
after = function()
require("auto-save").setup({
condition = function(buf)
if vim.bo[buf].filetype == "harpoon" then
return false
end
return true
end,
})
end,
cmd = "ASToggle",
event = { "InsertLeave", "TextChanged" },
},
-- Session restore in git repos
{
"auto-session",
after = function()
require("auto-session").setup()
end,
cmd = {
"SessionSave",
"SessionRestore",
"SessionDelete",
"SessionDisableAutoSave",
"SessionToggleSave",
"SessionPurgeOrphaned",
"SessionSearch",
"Auutosession",
},
lazy = not (#(vim.fs.root(0, ".git") or {}) > 0),
},
-- Secrets hiding
{
"cloak.nvim",
after = function()
require("cloak").setup()
end,
cmd = {
"CloakDisable",
"CloakEnable",
"CloakToggle",
},
ft = { "sh" },
},
-- Treesitter (Syntax Highlighting)
{
"nvim-treesitter",
dep_of = { "godotdev", "indent-blankline.nvim" },
on_require = "nvim-treesitter",
},
{ "nvim-treesitter-textobjects", dep_of = "nvim-treesitter" },
{ "nvim-treesitter-textsubjects", dep_of = "nvim-treesitter" },
-- Appearance
{
"catppuccin-nvim",
after = function()
require("catppuccin").setup({
flavour = "mocha",
transparent_background = true,
})
end,
},
{
"indent-blankline.nvim",
after = function()
require("ibl").setup()
end,
event = "BufEnter",
},
-- Git
{
"gitsigns.nvim",
after = function()
require("gitsigns").setup({
signs = {
add = { text = "+" },
change = { text = "~" },
delete = { text = "+" },
topdelete = { text = "-" },
changedelete = { text = "~" },
},
current_line_blame = false,
current_line_blame_opts = {
delay = 0,
},
})
end,
cmd = "Gitsigns",
keys = {
{
"<leader>gt",
":Gitsigns toggle_current_line_blame<cr>",
desc = "[Git] Toggle line blame",
},
},
lazy = not (#(vim.fs.root(0, ".git") or {}) > 0),
},
-- Todo comments
{
"todo-comments.nvim",
after = function()
require("todo-comments").setup()
end,
},
-- Integrations
{
"aw-watcher.nvim",
after = function()
require("aw_watcher").setup({})
end,
},
{
"godotdev.nvim",
after = function()
require("godotdev").setup({
autostart_editor_server = true,
})
end,
cmd = { "GodotReconnectLSP", "GodotStartEditorServer" },
ft = { "gd", "gdscript", "gdshader", "gdscript3" },
on_require = "godotdev",
},
})

View File

@@ -1,40 +0,0 @@
local grip_channel = nil
vim.api.nvim_create_user_command("GripStart", function()
if grip_channel then
return
end
local file = vim.api.nvim_buf_get_name(0)
local cmd = "go-grip -b false -H 0.0.0.0 " .. file
grip_channel = vim.fn.jobstart(cmd, {
stderr_buffered = true,
on_stderr = function(_, err)
vim.fn.jobstop(grip_channel)
local content = table.concat(err, "\n")
if content:len() > 0 then
vim.api.nvim_notify("Grip error: " .. content, vim.log.levels.ERROR, {})
end
end,
on_exit = function()
vim.fn.chanclose(grip_channel)
grip_channel = nil
end,
})
end, {})
vim.api.nvim_create_user_command("GripStop", function()
if grip_channel then
vim.fn.jobstop(grip_channel)
end
end, {})
vim.api.nvim_create_autocmd({ "QuitPre", "BufDelete" }, {
callback = function()
if grip_channel then
vim.fn.jobstop(grip_channel)
end
end,
})

View File

@@ -1,14 +0,0 @@
require("dot013.options")
require("dot013.tweaks")
require("dot013.grip")
vim.g.lze = {
--@type fun(name: string)
load = vim.cmd.packadd,
--@type boolean
verbose = true,
}
require("lze").load("dot013.plugins")
require("dot013.keymap")

View File

@@ -1,35 +0,0 @@
vim.keymap.set("n", "<leader>d", '"_d', { desc = "Delete to void" })
vim.keymap.set("v", "<leader>d", '"_d', { desc = "Delete to void" })
vim.keymap.set("n", "<leader>v", "<cmd>:vsplit<cr>", { desc = "Split the windows vertically" })
vim.keymap.set("n", "<leader>h", "<cmd>:split<cr>", { desc = "Split the windows horizontally" })
vim.keymap.set("n", "s=", "z=", { desc = "Suggest spelling currection" })
vim.keymap.set("n", "st", function()
vim.o.spell = not vim.o.spell
end, { desc = "Toggle spelling correction" })
vim.keymap.set("n", "<leader>ee", vim.diagnostic.open_float, { desc = "Open diagnostics" })
vim.keymap.set({ "n", "v" }, "<leader>y", '"+y', { desc = "Copy to system's clipboard" })
vim.keymap.set({ "n", "v" }, "<leader>p", '"+p', { desc = "Paste from system's clipboard" })
-- ------
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(e)
vim.keymap.set("n", "<leader>r", vim.lsp.buf.rename, { desc = "[LSP] Rename", buffer = e.buf })
vim.keymap.set("n", "<leader>a", vim.lsp.buf.code_action, { desc = "[LSP] Code action", buffer = e.buf })
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { desc = "[LSP] Go to definition", buffer = e.buf })
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, { desc = "[LSP] Go to declaration", buffer = e.buf })
vim.keymap.set("n", "gI", vim.lsp.buf.implementation, { desc = "[LSP] Go to implementation", buffer = e.buf })
vim.keymap.set(
"n",
"<leader>D",
vim.lsp.buf.type_definition,
{ desc = "[LSP] Go to type definition", buffer = e.buf }
)
end,
group = vim.api.nvim_create_augroup("dot013_group", {}),
})

View File

@@ -1,57 +0,0 @@
vim.g.mapleader = " "
vim.g.maplocalleader = " "
-- vim.g.loaded_netrw = 1;
-- vim.g.loaded_netrwPlugin = 1;
vim.wo.number = true
vim.o.mouse = "a"
-- True colors
vim.o.termguicolors = true
-- Enable filetype plugins
vim.o.filetype = "on"
-- Enable spell checking by default
vim.o.spell = true
-- Set relative line numbers
vim.o.number = true
vim.o.relativenumber = true
vim.o.signcolumn = "number"
-- Set indentation
vim.o.expandtab = false
vim.o.tabstop = 4
vim.o.softtabstop = 4
vim.o.shiftwidth = 4
-- vim.o.expandtab = 4;
vim.o.breakindent = true
-- Scroll off
vim.o.scrolloff = 10
-- Line length column
vim.o.colorcolumn = "80"
-- Sync NeoVim and OS clipboards
vim.o.clipboard = ""
-- Highlight search
vim.o.hlsearch = false
vim.o.incsearch = true
-- Save undo history
vim.o.undofile = true
-- Case-insensitive search, unless \C or capital in search
vim.o.ignorecase = true
vim.o.smartcase = true
vim.wo.signcolumn = "yes"
vim.o.updatetime = 250
vim.o.timeoutlen = 300
vim.o.completeopt = "menuone,noselect"

View File

@@ -1,40 +0,0 @@
return {
-- Frappurccino/Catppuccin theme
{
"catppuccin-nvim",
priority = 1000,
after = function()
require("catppuccin").setup({
flavour = "mocha",
transparent_background = true,
})
vim.cmd.colorscheme("catppuccin")
end,
},
-- Status bar
{
"lualine.nvim",
priority = 1000,
after = function()
require("lualine").setup({
options = {
icons_enabled = false,
theme = "catppuccin",
component_separators = "|",
section_separators = "",
},
})
end,
},
{ "nvim-web-devicons", dep_of = { "lualine.nvim" } },
-- Visual indentation
{
"indent-blankline.nvim",
priority = 1000,
after = function()
require("ibl").setup()
end,
},
}

View File

@@ -1,72 +0,0 @@
return {
-- DAP Debugger support
{
"nvim-dap",
dap_of = {
"nvim-dap-ui",
"nvim-dap-virtual-text",
"nvim-dap-go",
},
keys = {
{ "<leader>b", ":lua require('dap').toggle_breakpoint()<cr>", "[Debugger] Toggle breakpoint" },
{ "<leader>x", ":lua require('dap').continue()<cr>", "[Debugger] Continue debugger" },
{ "<leader>X", ":lua require('dap').terminate()<cr>", "[Debugger] Terminate debugger" },
{ "<leader>C", ":lua require('dap').clear_breakpoints()<cr>", "[Debugger] Clear all breakpoints" },
-- UI
{ "<leader>xu", ":lua require('dapui').toggle()<cr>", "[Debugger] Toggle debugger UI" },
{
"<leader>K",
":lua require('dapui').eval(nil, { enter = true })<cr>",
"[Debugger] Eval var under cursor",
},
},
after = function()
local dap = require("dap")
local dapui = require("dapui")
dapui.setup()
local dapvt = require("nvim-dap-virtual-text")
dapvt.setup()
dap.listeners.before.attach.dapui_config = function()
dapui.open()
end
dap.listeners.before.launch.dapui_config = function()
dapui.open()
end
dap.listeners.before.event_terminated.dapui_config = function()
dapui.close()
end
dap.listeners.before.event_exited.dapui_config = function()
dapui.close()
end
-- Languages
local dapgo = require("dap-go")
dapgo.setup()
end,
},
-- Debugger UI
{
"nvim-dap-ui",
dep_of = { "nvim-dap" },
},
{
"nvim-nio",
dep_of = { "nvim-dap-ui" },
},
-- Debugger state hover
{
"nvim-dap-virtual-text",
dep_of = { "nvim-dap" },
},
-- Language specific debuggers
{
"nvim-dap-go",
dep_of = { "nvim-dap" },
},
}

View File

@@ -1,108 +0,0 @@
local function js_fmt(bufnr)
local f = {}
if require("conform").get_formatter_info("prettierd", bufnr).available then
table.insert(f, "prettierd")
elseif require("conform").get_formatter_info("prettier", bufnr).available then
table.insert(f, "prettier")
end
if require("conform").get_formatter_info("eslint_d", bufnr).available then
table.insert(f, "eslint_d")
end
if
require("conform").get_formatter_info("deno_fmt", bufnr).available
and (require("dot013.utils").is_in_cwd("deno.json") or require("dot013.utils").is_in_cwd("deno.jsonc"))
then
table.insert(f, "deno_fmt")
end
return f
end
return {
-- Formatters support
{
"conform.nvim",
event = { "InsertLeave", "TextChanged" },
after = function()
require("conform").setup({
formatters_by_ft = {
-- Simple formatters
lua = { "stylua" },
nix = { --[[ "nixcmdfmt", ]] "alejandra", stop_after_first = true },
rust = { "rustfmt", lsp_format = "fallback" },
sh = { "shellharden", "shfmt" },
xml = { "xmllint", "xmltidy" },
xhtml = { "xmllint", "xmltidy" },
markdown = { "mdfmt" },
html = { "prettierd", "prettier", stop_after_first = true },
css = { "prettierd", "prettier", stop_after_first = true },
yaml = { "prettierd", "prettier", stop_after_first = true },
-- Golang's formatters used by priority
go = function(bufnr)
local f = {}
if require("conform").get_formatter_info("gofumpt", bufnr).available then
table.insert(f, "gofumpt")
else
table.insert(f, "gofmt")
end
if require("conform").get_formatter_info("golines", bufnr).available then
table.insert(f, "golines")
elseif require("conform").get_formatter_info("goimports", bufnr).available then
table.insert(f, "goimports")
end
return f
end,
templ = { "templ" },
-- JavaScript's ecosystem
javascript = js_fmt,
javascriptreact = js_fmt,
typescript = js_fmt,
typescriptreact = js_fmt,
json = function(bufnr)
local fmts = js_fmt(bufnr)
if fmts then
return fmts
end
return { "jq" }
end,
-- Fallback for any filetype
["*"] = { "codespell" },
["_"] = { "trim_whitespace" },
},
format_on_save = {
timeout_ms = 500,
lsp_format = "fallback",
},
formatters = {
mdfmt = {
command = "mdfmt",
},
xmltidy = {
inherit = false,
-- Uses HTML Tidy
command = "tidy",
args = { "-xml", "-indent", "yes", "2", "-wrap", "100", "-" },
},
--[[ nixcmdfmt = {
inherit = false,
stdin = false,
cwd = require("conform.util").root_file({ "flake.nix" }),
require_cwd = true,
command = "nix",
args = { "fmt", "$FILENAME" },
}, ]]
},
})
end,
},
}

View File

@@ -1,225 +0,0 @@
return {
-- Auto saving on file save
{
"auto-save.nvim",
cmd = "ASToggle",
event = { "InsertLeave", "TextChanged" },
after = function()
require("auto-save").setup({
condition = function(buf)
if vim.bo[buf].filetype == "harpoon" then
return false
end
return true
end,
})
end,
},
-- Session restore, enabled automatically in git repos
{
"auto-session",
lazy = not require("dot013.utils").is_in_cwd(".git"),
cmd = {
"SessionSave",
"SessionRestore",
"SessionDelete",
"SessionDisableAutoSave",
"SessionToggleSave",
"SessionPurgeOrphaned",
"SessionSearch",
"Auutosession",
},
after = function()
require("auto-session").setup()
end,
},
-- Completion
{
"blink-cmp",
event = "InsertEnter",
dep_of = { "nvim-lspconfig" },
after = function()
require("blink.cmp").setup({
keymap = {
["<C-space>"] = { "show", "show_documentation", "hide_documentation" },
["<Left>"] = { "hide", "fallback" },
["<Right>"] = { "accept", "fallback" },
["<CR>"] = { "accept", "fallback" },
["<Up>"] = { "select_prev", "snippet_backward", "fallback" },
["<Down>"] = { "select_next", "snippet_forward", "fallback" },
["<C-Up>"] = { "scroll_documentation_up", "fallback" },
["<C-Down>"] = { "scroll_documentation_down", "fallback" },
},
snippets = {
expand = function(snippet)
require("luasnip").lsp_expand(snippet)
end,
active = function(filter)
if filter and filter.direction then
require("luasnip").jumpable(filter.direction)
end
return require("luasnip").in_snippet()
end,
jump = function(direction)
require("luasnip").jump(direction)
end,
},
sources = {
default = {
"snippets",
"lsp",
"path",
"buffer",
},
},
completion = {
list = {
selection = { preselect = true, auto_insert = true },
},
menu = {
draw = {
padding = { 1, 0 },
columns = { { "label", "label_description", gap = 1 }, { "kind_icon", "kind" } },
components = {
kind_icon = { width = { fill = true } },
},
},
},
documentation = {
auto_show = true,
},
},
fuzzy = { implementation = "prefer_rust" },
})
end,
},
{
"luasnip",
dep_of = { "blink-cmp" },
after = function()
require("luasnip.loaders.from_vscode").lazy_load()
require("luasnip").setup()
end,
},
{ "friendly-snippets", dep_of = { "luasnip" } },
-- Environment variables and secrets hidding
{
"cloak.nvim",
ft = { "sh" },
cmd = {
"CloakDisable",
"CloakEnable",
"CloakToggle",
},
after = function()
require("cloak").setup()
end,
},
-- Smart comments
{
"comment.nvim",
after = function()
require("Comment").setup({
mappings = {
basic = true,
extra = true,
},
})
end,
},
-- Git integration, enabled just in git repos
{
"gitsigns.nvim",
cmd = "Gitsigns",
keys = {
{
"<leader>gt",
":Gitsigns toggle_current_line_blame<cr>",
desc = "[Git] Toggle line blame",
},
},
enabled = require("dot013.utils").is_in_cwd(".git"),
lazy = not require("dot013.utils").is_in_cwd(".git"),
after = function()
require("gitsigns").setup({
signs = {
add = { text = "+" },
change = { text = "~" },
delete = { text = "+" },
topdelete = { text = "-" },
changedelete = { text = "~" },
},
current_line_blame = false,
current_line_blame_opts = {
delay = 0,
},
})
end,
},
-- Auto closing pairs
{
"nvim-autopairs",
event = "InsertEnter",
after = function()
require("nvim-autopairs").setup()
end,
},
-- Auto closing and renaming tags
{
"nvim-ts-autotag",
event = { "BufReadPre", "BufNewFile" },
after = function()
require("nvim-ts-autotag").setup({
opts = {
enable_close = true,
enable_rename = true,
enable_close_on_slash = false,
},
})
end,
},
-- Automatic buffer options and .editorconfig support
{
"vim-sleuth",
event = { "BufReadPre", "BufNewFile" },
},
-- Tailwind integration
{
"tailwind-tools.nvim",
after = function()
-- TODO: Fork the project to remove root_dir clauses in LSP config,
-- since Tailwind v4 doesn't use tailwind.config.js
require("tailwind-tools").setup()
end,
},
-- File explorer
{
-- (Probably can be replaced by local functions in the config)
"tfm.nvim",
enabled = vim.fn.executable("yazi"),
cmd = { "Ex", "Tfm", "TfmSplit", "TfmVsplit", "TfmTabedit" },
keys = {
{ "<C-e>", ":Tfm<cr>", desc = "[TFM] Open file manager" },
},
after = function()
require("tfm").setup({
file_manager = "yazi",
replace_netrw = true,
enable_cmds = true,
})
end,
},
}

View File

@@ -1,13 +0,0 @@
return {
{ import = "dot013.plugins.appearance" },
{ import = "dot013.plugins.debugger" },
{ import = "dot013.plugins.formatting" },
{ import = "dot013.plugins.ide" },
{ import = "dot013.plugins.integrations" },
{ import = "dot013.plugins.lsp" },
{ import = "dot013.plugins.navigation" },
{ import = "dot013.plugins.treesitter" },
-- Global Dependencies
{ "plenary.nvim", dep_of = { "telescope.nvim", "harpoon" } },
}

View File

@@ -1,8 +0,0 @@
return {
{
"aw-watcher.nvim",
after = function()
require("aw_watcher").setup({})
end,
},
}

View File

@@ -1,131 +0,0 @@
local lsps = {
["cssls"] = {},
["emmet_language_server"] = {
filetypes = require("lspconfig.configs.emmet_language_server").default_config.filetypes,
},
["eslint"] = {},
["denols"] = {},
["lemminx"] = {
filetypes = { "xml", "xsd", "xsl", "xslt", "svg", "xhtml" },
},
["lua_ls"] = {
on_init = function(client)
if client.workspace_folders then
local path = client.workspace_folders[1].name
if vim.loop.fs_stat(path .. "/.luarc.json") or vim.loop.fs_stat(path .. "/.luarc.jsonc") then
return
end
end
client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, {
runtime = {
version = "LuaJIT",
},
workspace = {
checkThirdParty = false,
library = {
vim.env.VIMRUNTIME,
},
},
})
end,
settings = {
Lua = {
workspace = { checkThirdParty = false },
telemetry = { enable = false },
},
},
},
["gopls"] = {},
["golangci_lint_ls"] = function()
if vim.fn.executable("golangci-list") == 1 then
return {}
else
return nil
end
end,
["html"] = {},
-- ["htmx"] = {}, # BORKED: blink.cmp stops working whtn htmx-lsp is attached https://github.com/Saghen/blink.cmp/issues/825
["jsonls"] = {},
["nil_ls"] = {
cmd = { "nil" },
filetypes = { "nix" },
single_file_support = true,
root_dir = nil,
},
["marksman"] = {},
["ts_ls"] = {},
["rust_analyzer"] = {},
}
return {
-- Language Server Protocol (LSP) configuration
{
"nvim-lspconfig",
after = function()
for k, v in pairs(lsps) do
if type(v) == "function" then
v = v()
end
if v == nil then
return
end
v.capabilities = require("blink.cmp").get_lsp_capabilities(v.capabilities)
vim.lsp.enable(k)
vim.lsp.config(k, v)
end
vim.diagnostic.config({
virtual_text = true,
})
end,
},
-- Emmet integration
{
"nvim-emmet",
ft = lsps["emmet_language_server"].filetypes,
keys = {
{
"<leader>we",
":lua require('nvim-emmet').wrap_with_abbreviation()<cr>",
desc = "[Emmet] Wrap with emmet abbreviation",
mode = { "n", "v" },
},
},
},
-- Quickfix list and diagnostics
{
"trouble.nvim",
cmd = { "Trouble" },
keys = {
{
"<leader>t",
"<cmd>Trouble diagnostics toggle severity=vim.diagnostic.severity.ERROR<cr>",
desc = "[Trouble] Buffer diagnostics",
},
{
"<leader>la",
"<cmd>Trouble lsp toggle focus=false win.position=right win.type=split<cr>",
desc = "[Trouble] All LSP Definitions & references",
},
{
"<leader>s",
"<cmd>Trouble symbols toggle focus=false win.position=right win.type=split<cr>",
desc = "[Trouble] Symbols",
},
{
"<leader>q",
"<cmd>Trouble qflist toggle<cr>",
desc = "[Trouble] Quickfix list",
},
},
after = function()
require("trouble").setup()
end,
},
}

View File

@@ -1,144 +0,0 @@
return {
-- File fuzzy finder
{
"telescope.nvim",
cmd = {
"Telescope",
},
dep_of = { "tailwind-tools.nvim" },
keys = {
{
"<leader><space>",
":lua require('telescope.builtin').buffers()<cr>",
desc = "[Telescope] Find existing buffers",
},
{
"/",
function()
return require("telescope.builtin").current_buffer_fuzzy_find(
require("telescope.themes").get_dropdown({
windblend = 10,
previewer = false,
})
)
end,
desc = "[Telescope] Find in current buffer",
},
{
"fr",
":lua require('telescope.builtin').oldfiles()<cr>",
desc = "[Telescope] Find recent files",
},
{
"ff",
function()
if require("dot013.utils").is_in_cwd(".git") then
return require("telescope.builtin").git_files()
else
return require("telescope.builtin").find_files()
end
end,
desc = "[Telescope] Git files",
},
{
"<leader>ff",
function()
require("telescope.builtin").find_files({ no_ignore = true, no_ignore_parent = true, hidden = true })
end,
desc = "[Telescope] Find files",
},
{ "fw", ":lua require('telescope.builtin').grep_string()<cr>", desc = "[Telescope] Find word" },
{
"<leader>fw",
"<cmd>Telescope live_grep<cr>",
desc = "[Telescope] Find word in all files",
},
{ "fs", ":lua require('telescope.builtin').resume()<cr>", desc = "[Telescope] Resume search" },
{ "<leader>u", "<cmd>Telescope undo<cr>", desc = "[Telescope] Undo history" },
},
after = function()
require("telescope").setup()
require("telescope").load_extension("zf-native")
require("telescope").load_extension("undo")
end,
},
{ "telescope-zf-native.nvim", dep_of = { "telescope.nvim" } },
{ "telescope-undo.nvim", dep_of = { "telescope.nvim" } },
-- File quick switching
{
"harpoon2",
keys = (function()
local h = nil
local function harpoon()
if h == nil then
h = require("harpoon")
h:setup()
end
return h
end
return {
{
"<leader>w",
function()
harpoon():list():add()
end,
desc = "[Harpoon] Append to list",
},
{
"<leader>e",
function()
harpoon().ui:toggle_quick_menu(harpoon():list())
end,
desc = "[Harpoon] Open quick menu",
},
{
"<leader>E",
function()
harpoon().ui:toggle_quick_menu(harpoon():list())
end,
desc = "[Harpoon] Open quick edit menu",
},
{
"<C-p>",
function()
harpoon():list():prev()
end,
desc = "[Harpoon] Jump to previous item",
},
{
"<C-n>",
function()
harpoon():list():next()
end,
desc = "[Harpoon] Jump to next item",
},
}
end)(),
},
-- Visual jump marks
{
"marks.nvim",
after = function()
require("marks").setup({
refresh_interval = 250,
})
end,
},
-- Tmux panel jumping
{
"tmux.nvim",
keys = {
{ "<C-h>", ":lua require('tmux').move_left()<cr>", desc = "[Tmux] Move to left pane" },
{ "<C-j>", ":lua require('tmux').move_bottom()<cr>", desc = "[Tmux] Move to bottom pane" },
{ "<C-k>", ":lua require('tmux').move_top()<cr>", desc = "[Tmux] Move to top pane" },
{ "<C-l>", ":lua require('tmux').move_right()<cr>", desc = "[Tmux] Move to right pane" },
},
after = function()
require("tmux").setup()
end,
},
}

View File

@@ -1,110 +0,0 @@
return {
-- Syntax highlight
{
"nvim-treesitter",
dep_of = { "indent-blankline.nvim" },
priority = 1000,
after = function()
require("nvim-treesitter.configs").setup({
auto_install = false,
highlight = { enable = true },
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "<c-space>",
node_incremental = "<c-space>",
scope_incremental = "<c-s>",
node_decremental = "<M-space>",
},
},
textobjects = {
select = {
enable = true,
lookahead = true,
keymaps = {
["aa"] = "@parameter.outer",
["ia"] = "@parameter.inner",
["af"] = "@function.outer",
["if"] = "@function.inner",
["ac"] = "@class.outer",
["ic"] = "@class.inner",
},
},
move = {
enable = true,
set_jumps = true,
goto_next_start = {
["]m"] = "@function.outer",
["]]"] = "@class.outer",
},
goto_next_end = {
["]M"] = "@function.outer",
["]["] = "@class.outer",
},
goto_previous_start = {
["[m"] = "@function.outer",
["[["] = "@class.outer",
},
goto_previous_end = {
["[M"] = "@function.outer",
["[]"] = "@class.outer",
},
},
},
textsubjects = {
enable = true,
prev_selection = ",",
keymaps = {
["."] = "textsubjects-smart",
[";"] = "textsubjects-container-outer",
["i;"] = "textsubjects-container-inner",
},
},
swap = {
enable = true,
swap_next = {
["<leader>a"] = "@parameter.inner",
},
swap_previous = {
["<leader>A"] = "@parameter.inner",
},
},
playground = {
enable = true,
disable = {},
updatetime = 25,
persist_queries = false,
keybindings = {
toggle_query_editor = "o",
toggle_hl_groups = "i",
toggle_injected_languages = "t",
toggle_anonymous_nodes = "a",
toggle_language_display = "I",
focus_language = "f",
unfocus_language = "F",
update = "R",
goto_node = "<cr>",
show_help = "?",
},
},
query_linter = {
enable = true,
use_virtual_text = true,
lint_events = { "BugWrite", "CursorHold" },
},
})
local LANGUAGE_ALIASES = {
{ from = "dataviewjs", to = "javascript" },
{ from = "js", to = "javascript" },
{ from = "ts", to = "typescript" },
}
for _, v in pairs(LANGUAGE_ALIASES) do
vim.treesitter.language.register(v.to, v.from)
end
end,
},
{ "nvim-treesitter-textobjects", dep_of = { "nvim-treesitter" } },
{ "nvim-treesitter-textsubjects", dep_of = { "nvim-treesitter" } },
}

View File

@@ -1,26 +0,0 @@
-- Highlight on yank
local highlight_group = vim.api.nvim_create_augroup("YankHighlight", { clear = true })
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function()
vim.highlight.on_yank()
end,
group = highlight_group,
pattern = "*",
})
-- Move when highlighted
vim.keymap.set("n", "J", "mzJ`z")
-- Make cursor stay in place when using J
vim.keymap.set("n", "<C-d>", "<C-d>zz")
vim.keymap.set("n", "<C-u>", "<C-u>zz")
-- Just to be sure
vim.keymap.set("n", "<C-c>", "<Esc>")
-- Don't press Q
vim.keymap.set("n", "Q", "<nop>")
vim.keymap.set({ "n", "v" }, "<Space>", "<Nop>", { desc = "Nop", silent = true })
vim.keymap.set("n", "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
vim.keymap.set("n", "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })

View File

@@ -1,23 +0,0 @@
local M = {}
M.is_in_cwd = function(name)
local cwd = vim.fn.getcwd()
local cwdContent = vim.split(vim.fn.glob(cwd .. "/*"), "\n", { trimempty = true })
local hiddenCwdContent = vim.split(vim.fn.glob(cwd .. "/.*"), "\n", { trimempty = true })
for _, f in pairs(hiddenCwdContent) do
table.insert(cwdContent, f)
end
local fullName = cwd .. "/" .. name
for _, f in pairs(cwdContent) do
if f == fullName then
return true
end
end
return false
end
return M

View File

@@ -1,34 +0,0 @@
{self}: {
config,
lib,
pkgs,
...
}: let
cfg = config.neovim;
in
with lib; {
options.neovim = {
enable = mkOption {
type = with types; bool;
default = true;
};
package = mkOption {
type = with types; package;
default = self.packages.${pkgs.system}.default;
readOnly = true;
};
defaultEditor = mkOption {
type = with types; bool;
default = true;
};
};
config = mkIf cfg.enable {
environment.variables = {
EDITOR = "nvim";
};
environment.systemPackages = [cfg.package];
# Disable NixOS's Neovim
programs.neovim.enable = mkForce false;
};
}

View File

@@ -2,129 +2,147 @@
pkgs,
lib,
neovim ? pkgs.neovim,
blink-cmp ? pkgs.vimPlugins.blink-cmp,
ripgrep ? pkgs.ripgrep,
mdfmt ? null,
go-grip ? null,
yazi ? pkgs.yazi,
godotdev ? (pkgs.vimUtils.buildVimPlugin {
pname = "godotdev.nvim";
version = "v0.2.3";
src = fetchGit {
url = "https://github.com/Mathijs-Bakker/godotdev.nvim";
rev = "79d9315988b7772c03a1cabb6f31f5287c849e2b";
};
}),
...
}: let
start =
(with pkgs.vimPlugins; [
catppuccin-nvim
indent-blankline-nvim
lze
nvim-lspconfig
nvim-treesitter.withAllGrammars
nvim-treesitter-textobjects
nvim-treesitter-textsubjects
(
(pkgs.vimUtils.buildVimPlugin {
name = "dot013.nvim";
src = ./.;
}).overrideAttrs
{doCheck = false;}
)
])
++ [
blink-cmp
];
opt = with pkgs.vimPlugins; [
auto-save-nvim
auto-session
cloak-nvim
conform-nvim
comment-nvim
friendly-snippets
gitsigns-nvim
harpoon2
lualine-nvim
luasnip
marks-nvim
nvim-autopairs
nvim-dap
nvim-dap-go
nvim-dap-ui
nvim-dap-virtual-text
nvim-nio
nvim-ts-autotag
nvim-web-devicons
tailwind-tools-nvim
telescope-nvim
telescope-zf-native-nvim
telescope-undo-nvim
trouble-nvim
tmux-nvim
vim-sleuth
(pkgs.vimUtils.buildVimPlugin {
pname = "aw-watcher.nvim";
version = "master";
src = fetchGit {
url = "https://github.com/lowitea/aw-watcher.nvim";
rev = "be7b03748f59b6602502baf08e7f7736cc7279a5";
};
})
(pkgs.vimUtils.buildVimPlugin {
pname = "nvim-emmet";
version = "v0.4.4";
src = fetchGit {
url = "https://github.com/olrtg/nvim-emmet";
rev = "cde4fb2968704aae5c18b7f8a9bc2508767bb78d";
};
})
# Probably can be replaced by local functions in the config
(pkgs.vimUtils.buildVimPlugin {
pname = "tfm.nvim";
version = "2024-04-23";
src = fetchGit {
url = "https://github.com/Rolv-Apneseth/tfm.nvim";
rev = "fb0de2c96bf303216ac5d91ce9bdb7f430030f8b";
};
})
];
languageServers = with pkgs; [
emmet-language-server
deno
gopls
golangci-lint-langserver
htmx-lsp
lemminx
lua-language-server
nil
marksman
tailwindcss-language-server
typescript-language-server
rust-analyzer
vscode-langservers-extracted
];
formatters = with pkgs; [
alejandra
jq
html-tidy
libxml2
mdfmt
prettierd
shellharden
shfmt
];
externalDependencies = [
ripgrep
go-grip
yazi
];
dot-nvim = pkgs.vimUtils.buildVimPlugin {
name = "dot.nvim";
src = lib.cleanSource ./.;
};
in
neovim.override {
viAlias = true;
vimAlias = true;
configure.packages.plugins = {inherit start opt;};
configure.packages.plugins = {
# Reference: ./lua/dot/plugins.lua
start = with pkgs.vimPlugins; [
lze
lzextras
# Language Server Protocol
nvim-lspconfig
# Autocomplete
blink-cmp
friendly-snippets # Snippets
# Treesitter (Syntax Highlighting)
nvim-treesitter.withAllGrammars
nvim-treesitter-textobjects # Dependency
nvim-treesitter-textsubjects # Dependency
(dot-nvim.overrideAttrs {doCheck = false;})
];
opt = with pkgs.vimPlugins; [
# Language Server Protocol
lazydev-nvim
# Debugger
nvim-dap
nvim-dap-ui
nvim-nio # Dependency
# Formatting
conform-nvim
guess-indent-nvim
# Auto Complete
nvim-autopairs
# Fuzzy Finding
telescope-nvim
telescope-zf-native-nvim # Dependency
# Quick file switching
harpoon2
# Auto saving
auto-save-nvim
# Session restore
auto-session
# Secrets hiding
cloak-nvim
# Appearance
catppuccin-nvim
indent-blankline-nvim
# Git
gitsigns-nvim
# Todo Comments
todo-comments-nvim
# Integrations
(pkgs.vimUtils.buildVimPlugin {
pname = "aw-watcher.nvim";
version = "master";
src = fetchGit {
url = "https://github.com/lowitea/aw-watcher.nvim";
rev = "be7b03748f59b6602502baf08e7f7736cc7279a5";
};
})
godotdev
];
# inherit start opt;
};
extraMakeWrapperArgs = let
binPath = lib.makeBinPath (languageServers ++ formatters ++ externalDependencies);
binPath = lib.makeBinPath (with pkgs;
[
# INFO: LSP Providers
# Reference: ./lua/dot/lsp.lua
vscode-langservers-extracted # cssls, eslint, html, jsonls, typescript
docker-language-server
emmet-language-server
golangci-lint-langserver
gopls
htmx-lsp
lemminx
lua-language-server
marksman
nil
rust-analyzer
tailwindcss-language-server
typescript-language-server
]
++ [
# INFO: Formatters
# Reference: ./lua/dot/formatting.lua
# TODO: Remove some formatters from Neovim's path and let them be provided
# by flake.nix in projects
alejandra
gdtoolkit_4
html-tidy
jq
libxml2
mdfmt
prettierd
shellharden
shfmt
]
++ [
# INFO: External dependencies
go-grip # Reference: ./lua/dot/commands.lua#Grip markdown reader
ripgrep # Reference ./lua/dot/plugins.lua#telescope.nvim
yazi # Reference ./lua/dot/commands.lua#Yazi file manager
zf # Reference ./lua/dot/plugins.lua#telescope-zf-native.nvim
]);
in "--suffix PATH : ${binPath}";
}

View File

@@ -1 +1 @@
require("dot013")
require("dot")

85
scripts/godot-neovim.sh Normal file
View File

@@ -0,0 +1,85 @@
#!/usr/bin/env bash
# Script provided by Mathijs Bakker's godotdev.nvim, licensed under the Apache
# License Version 2.0.
#
# A copy of the original script can be found at
# https://github.com/Mathijs-Bakker/godotdev.nvim/blob/79d9315988b7772c03a1cabb6f31f5287c849e2b/doc/neovim-external-editor-setup.md#installation
#
# A copy of the original license can be found at
# https://github.com/Mathijs-Bakker/godotdev.nvim/blob/79d9315988b7772c03a1cabb6f31f5287c849e2b/LICENSE
# Godot → Neovim launcher with GUI terminal focus
# Usage:
# godot-nvr.sh [terminal_name] +{line} {file} [--tab|--vsplit]
# -----------------------------
# Arguments
# -----------------------------
DEFAULT_TERMINAL="${DEFAULT_TERMINAL:=ghostty}"
ARG0="$1"
if [[ "$ARG0" == +* || "$ARG0" == --* || -f "$ARG0" ]]; then
# No terminal argument provided, use default
GODOT_TERMINAL="$DEFAULT_TERMINAL"
else
# First argument is terminal name
GODOT_TERMINAL="$ARG0"
shift
fi
SOCKET="${SOCKET:=/tmp/godot.nvim}" # Neovim socket path
OPEN_MODE="window"
LINE=""
FILE=""
# -----------------------------
# Parse remaining arguments
# -----------------------------
while [[ $# -gt 0 ]]; do
case "$1" in
--tab)
OPEN_MODE="tab"
shift
;;
--vsplit)
OPEN_MODE="vsplit"
shift
;;
+[0-9]*)
LINE="${1#+}"
shift
;;
*)
FILE="$1"
shift
;;
esac
done
[ "$FILE" = "" ] && exit 0
# -----------------------------
# Open file in Neovim or jump to buffer
# -----------------------------
if nvr --servername "$SOCKET" --remote-expr \
"bufexists(fnamemodify('$FILE', ':p'))" | grep -q 1; then
CMD=":buffer $(basename "$FILE")"
else
case "$OPEN_MODE" in
window) CMD=":e $FILE" ;;
tab) CMD=":tabedit $FILE" ;;
vsplit) CMD=":vsplit $FILE" ;;
esac
fi
[ "$LINE" != "" ] && CMD="$CMD | call cursor($LINE,1)"
CMD="$CMD | normal! zz"
nvr --servername "$SOCKET" --remote-send "<C-\\><C-N>${CMD}<CR>"
# -----------------------------
# Focus GUI terminal (Hyprland)
# -----------------------------
hyprctl dispatch focuswindow "class:$GODOT_TERMINAL"