Compare commits
19 Commits
9a1dff2525
...
2e6c687a7c
| Author | SHA1 | Date | |
|---|---|---|---|
|
2e6c687a7c
|
|||
|
1c1cd0ca52
|
|||
|
b71abaec7a
|
|||
|
144b5cdde9
|
|||
|
c00702d1cb
|
|||
|
aa88049fab
|
|||
|
4d7aa88641
|
|||
|
e8e109babb
|
|||
|
196da5309e
|
|||
|
be99745640
|
|||
|
a9a59ec260
|
|||
|
1fdc7ec7fe
|
|||
|
7fc1d34a1c
|
|||
|
a68a167264
|
|||
|
526a626136
|
|||
|
8b935a5760
|
|||
|
eaf3ff77e9
|
|||
|
430fefba32
|
|||
|
fb5ea210ba
|
6
flake.lock
generated
6
flake.lock
generated
@@ -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": {
|
||||
|
||||
118
flake.nix
118
flake.nix
@@ -28,6 +28,7 @@
|
||||
inherit (pkgs) lib stdenv;
|
||||
}
|
||||
);
|
||||
neovim-pkgs = system: import nixpkgs {inherit system;};
|
||||
in {
|
||||
formatter = forAllSystems ({pkgs, ...}: pkgs.alejandra);
|
||||
|
||||
@@ -39,17 +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;
|
||||
};
|
||||
godot-neovim = pkgs.writeShellApplication {
|
||||
name = "godot-neovim";
|
||||
};
|
||||
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 (
|
||||
@@ -63,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;
|
||||
};
|
||||
};
|
||||
|
||||
42
home.nix
42
home.nix
@@ -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
27
lua/dap-go/COPYRIGHT
Normal 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
272
lua/dap-go/init.lua
Normal 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
175
lua/dap-go/ts.lua
Normal 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
161
lua/dot/commands.lua
Normal 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
22
lua/dot/debugger.lua
Normal 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
83
lua/dot/formatting.lua
Normal 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
|
||||
},
|
||||
})
|
||||
101
lua/dot/init.lua
101
lua/dot/init.lua
@@ -28,6 +28,9 @@ vim.o.breakindent = true
|
||||
vim.o.list = true
|
||||
vim.opt.listchars = { tab = "│ ", trail = ".", nbsp = "␣" }
|
||||
|
||||
-- Theme
|
||||
vim.cmd.colorscheme("catppuccin")
|
||||
|
||||
----
|
||||
|
||||
-- Mouse support
|
||||
@@ -84,8 +87,99 @@ vim.diagnostic.config({
|
||||
},
|
||||
})
|
||||
|
||||
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 }),
|
||||
@@ -94,13 +188,6 @@ vim.api.nvim_create_autocmd("TextYankPost", {
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||
pattern = "*",
|
||||
callback = function(e)
|
||||
require("conform").format({ bufnr = e.buf })
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
group = vim.api.nvim_create_augroup("dot-lsp-attach-autocmds", { clear = true }),
|
||||
callback = function(e)
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
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" })
|
||||
@@ -27,27 +54,26 @@ vim.api.nvim_create_autocmd("LspAttach", {
|
||||
group = vim.api.nvim_create_augroup("dot-lsp-attach-keymaps", { clear = true }),
|
||||
})
|
||||
|
||||
-- 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",
|
||||
-- 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",
|
||||
})
|
||||
|
||||
vim.keymap.set(
|
||||
"n",
|
||||
"<C-e>",
|
||||
vim.fn.executable("yazi") and require("dot.tfm").open or ":Ex",
|
||||
{ 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",
|
||||
})
|
||||
-- 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 })
|
||||
|
||||
@@ -8,6 +8,7 @@ lze.load({
|
||||
-- Language Server Protocol
|
||||
{
|
||||
"nvim-lspconfig",
|
||||
dep_of = { "godotdev" },
|
||||
---@param plugin lze.Plugin
|
||||
lsp = function(plugin)
|
||||
local config = plugin.lsp or {}
|
||||
@@ -21,117 +22,35 @@ lze.load({
|
||||
{ "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()
|
||||
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
|
||||
require("conform").setup({
|
||||
formatters_by_ft = {
|
||||
-- Simple formatters
|
||||
lua = { "stylua" },
|
||||
nix = { "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 },
|
||||
|
||||
gdscript = { "gdformat" },
|
||||
-- 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" },
|
||||
}, ]]
|
||||
},
|
||||
})
|
||||
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
|
||||
{
|
||||
@@ -182,6 +101,13 @@ lze.load({
|
||||
on_require = "blink",
|
||||
},
|
||||
{ "friendly-snippets", dep_of = "blink-cmp" },
|
||||
{
|
||||
"nvim-autopairs",
|
||||
after = function()
|
||||
require("nvim-autopairs").setup()
|
||||
end,
|
||||
event = "InsertEnter",
|
||||
},
|
||||
|
||||
-- Fuzzy Finding
|
||||
{
|
||||
@@ -194,7 +120,7 @@ lze.load({
|
||||
},
|
||||
{ "telescope-zf-native.nvim", dep_of = "telescope.nvim" },
|
||||
|
||||
-- File quick switching
|
||||
-- Quick file switching
|
||||
{
|
||||
"harpoon2",
|
||||
after = function()
|
||||
@@ -204,4 +130,135 @@ lze.load({
|
||||
},
|
||||
|
||||
-- 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) > 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",
|
||||
},
|
||||
})
|
||||
|
||||
34
nixos.nix
34
nixos.nix
@@ -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;
|
||||
};
|
||||
}
|
||||
246
package.nix
246
package.nix
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
# 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
|
||||
# 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
|
||||
# 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
|
||||
@@ -28,8 +28,7 @@ else
|
||||
shift
|
||||
fi
|
||||
|
||||
SOCKET="${SOCKET:=/tmp/godot.pipe}" # Neovim socket path
|
||||
NVR="${NVR:=/Library/Frameworks/Python.framework/Versions/3.8/bin/nvr}"
|
||||
SOCKET="${SOCKET:=/tmp/godot.nvim}" # Neovim socket path
|
||||
|
||||
OPEN_MODE="window"
|
||||
LINE=""
|
||||
@@ -40,36 +39,47 @@ FILE=""
|
||||
# -----------------------------
|
||||
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 ;;
|
||||
--tab)
|
||||
OPEN_MODE="tab"
|
||||
shift
|
||||
;;
|
||||
--vsplit)
|
||||
OPEN_MODE="vsplit"
|
||||
shift
|
||||
;;
|
||||
+[0-9]*)
|
||||
LINE="${1#+}"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
FILE="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -z "$FILE" ] && exit 0
|
||||
[ "$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")"
|
||||
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" ;;
|
||||
window) CMD=":e $FILE" ;;
|
||||
tab) CMD=":tabedit $FILE" ;;
|
||||
vsplit) CMD=":vsplit $FILE" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
[ -n "$LINE" ] && CMD="$CMD | call cursor($LINE,1)"
|
||||
[ "$LINE" != "" ] && CMD="$CMD | call cursor($LINE,1)"
|
||||
CMD="$CMD | normal! zz"
|
||||
|
||||
$NVR --servername "$SOCKET" --remote-send "<C-\\><C-N>${CMD}<CR>"
|
||||
nvr --servername "$SOCKET" --remote-send "<C-\\><C-N>${CMD}<CR>"
|
||||
|
||||
# -----------------------------
|
||||
# Focus GUI terminal (Hyprland)
|
||||
# -----------------------------
|
||||
hyprctl dispatch focuswindow class:$GODOT_TERMINAL
|
||||
|
||||
hyprctl dispatch focuswindow "class:$GODOT_TERMINAL"
|
||||
|
||||
Reference in New Issue
Block a user