Compare commits

...

26 Commits

Author SHA1 Message Date
9a1dff2525 feat(plugins,nix): godot integration 2025-12-14 20:53:41 -03:00
d2b9cc3808 feat(nix): provide home-manager and nixos modules directly in flake.nix 2025-12-14 20:53:41 -03:00
3a0df8e527 feat(package): missing ripgrep depenndency for telescope 2025-12-14 20:53:41 -03:00
4cd90e887c feat(plugins): nvim-autopairs 2025-12-14 20:53:41 -03:00
68560f5b9a feat(nix): reorganize plugins in neovim package for nix 2025-12-14 20:53:40 -03:00
5c81a42ab9 chore(deps): update flakes 2025-12-14 20:53:40 -03:00
01e5cde50e feat(plugins,formatters): move formatters to dedicated file 2025-12-14 20:53:40 -03:00
e81d290f32 feat(keymaps): tweaks to keymaps 2025-12-14 20:53:40 -03:00
6155583139 feat(keymap): spellingn toggle and correction 2025-12-14 20:53:40 -03:00
017cc5ab53 feat(debugger): golang adapter for dap 2025-12-14 20:53:39 -03:00
d4106e2eee feat(debugger,keymaps): dap and dapui debugging configuration 2025-12-14 20:53:39 -03:00
11efcf9ee9 fixup! feat(keymaps,plugins): navigation and keymaps with telescope and harpoon 2025-12-14 20:53:39 -03:00
43a9be8024 feat(commands): replace Ex command for yazi 2025-12-14 20:53:39 -03:00
e4ac5c4ebc feat(commands): grip command for markdown preview 2025-12-14 20:53:39 -03:00
7efbf2ad17 feat: file managing with yazi 2025-12-14 20:53:39 -03:00
41f3c4a603 feat(plugins): secret hidding with cloak.nvim 2025-12-14 20:53:38 -03:00
eaf72c703c feat(plugins): appearance settings and theme 2025-12-14 20:53:38 -03:00
9a2d1f2f74 fixup! feat(plugins): auto-formatting with conform.nvim 2025-12-14 20:53:38 -03:00
e0ef613032 feat(plugins): auto-saving and auto-sessions 2025-12-14 20:53:38 -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
33 changed files with 1954 additions and 1274 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)

6
flake.lock generated
View File

@@ -18,11 +18,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1762844143,
"narHash": "sha256-SlybxLZ1/e4T2lb1czEtWVzDCVSTvk9WLwGhmxFmBxI=",
"lastModified": 1765186076,
"narHash": "sha256-hM20uyap1a0M9d344I692r+ik4gTMyj60cQWO+hAYP8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9da7f1cf7f8a6e2a7cb3001b048546c92a8258b4",
"rev": "addf7cf5f383a3101ecfba091b98d0a1263dc9b8",
"type": "github"
},
"original": {

115
flake.nix
View File

@@ -28,6 +28,7 @@
inherit (pkgs) lib stdenv;
}
);
neovim-pkgs = system: import nixpkgs {inherit system;};
in {
formatter = forAllSystems ({pkgs, ...}: pkgs.alejandra);
@@ -39,14 +40,20 @@
...
}: {
neovim = pkgs.callPackage ./package.nix {
mdfmt = self.packages.${stdenv.hostPlatform.system}.mdfmt;
mdfmt = self.packages.${pkgs.system}.mdfmt;
};
godot-neovim = pkgs.writeShellApplication {
name = "godot-neovim";
runtimeInputs = with pkgs; [neovim-remote];
text = builtins.readFile ./scripts/godot-neovim.sh;
};
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 (
@@ -60,11 +67,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 = " "
---- Plugins
require("dot.plugins")
-- 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 = "" }
-- Theme
vim.cmd.colorscheme("catppuccin")
----
-- 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,
},
})
require("dot.commands")
require("dot.keymaps")
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,
})

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

@@ -0,0 +1,79 @@
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", "<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("grn", vim.lsp.buf.rename, "[R]e[n]ame")
map("gra", vim.lsp.buf.code_action, "[G]oto Code [A]ction", { "n", "x" })
map("grr", ":lua require('telescope.builtin').lsp_references<cr>", "[G]oto [R]eferences")
map("gri", ":lua require('telescope.builtin').lsp_implementations<cr>", "[G]oto [I]mplementation")
map("grd", ":lua require('telescope.builtin').lsp_definitions", "[G]oto [D]efinition")
map("grt", ":lua require('telescope.builtin').lsp_type_definitions", "[G]oto [T]ype Definition")
map("grD", vim.lsp.buf.declaration, "[G]oto [D]eclaration")
map("gO", ":lua require('telescope.builtin').lsp_document_symbols", "[O]pen Document Symbols")
map("gW", ":lua require('telescope.builtin').lsp_dynamic_workspace_symbols", "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", "<leader>x", ":lua require('dap').continue()<cr>", { desc = "Debugger: Continue debugger" })
vim.keymap.set("n", "<leader>X", ":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") > 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") > 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,113 +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 },
scss = { "prettierd", "prettier", stop_after_first = true },
less = { "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,233 +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,
},
-- Todo comments explorer
{
"todo-comments.nvim",
after = function()
require("todo-comments").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,16 +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 = { "harpoon", "telescope.nvim", "todo-comments.nvim" },
},
}

View File

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

View File

@@ -1,142 +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
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, semicolin = "Disable" },
telemetry = { enable = false },
},
},
},
["gopls"] = {},
["golangci_lint_ls"] = function()
if vim.fn.executable("golangci-list") == 1 then
return {}
else
return nil
end
end,
["html"] = {},
["htmx"] = {},
["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()
local blink = require("blink.cmp")
for server, config in pairs(lsps) do
if type(config) == "function" then
config = config()
end
if config == nil then
return
end
-- config.capabilities = blink.get_lsp_capabilities(config.capabilities)
vim.lsp.enable(server)
if next(config) ~= nil then
vim.lsp.config(server, config)
end
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,130 +2,144 @@
pkgs,
lib,
neovim ? pkgs.neovim,
blink-cmp ? pkgs.vimPlugins.blink-cmp,
ripgrep ? pkgs.ripgrep,
mdfmt ? null,
go-grip ? pkgs.go-grip,
yazi ? pkgs.yazi,
...
}: 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
todo-comments-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";
};
})
(pkgs.vimUtils.buildVimPlugin {
pname = "godotdev.nvim";
version = "v0.2.3";
src = fetchGit {
url = "https://github.com/Mathijs-Bakker/godotdev.nvim";
rev = "79d9315988b7772c03a1cabb6f31f5287c849e2b";
};
})
];
# 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
emmet-language-server
golangci-lint-langserver
gopls
htmx-lsp
lemminx
lua-language-server
marksman
nil
rust-analyzer
tailwindcss-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"