Compare commits

...

19 Commits

Author SHA1 Message Date
2e6c687a7c feat(plugins,nix): godot integration 2025-12-14 21:59:29 -03:00
1c1cd0ca52 feat(nix): provide home-manager and nixos modules directly in flake.nix 2025-12-14 21:59:29 -03:00
b71abaec7a feat(package): missing ripgrep depenndency for telescope 2025-12-14 21:59:29 -03:00
144b5cdde9 feat(plugins): nvim-autopairs 2025-12-14 21:59:29 -03:00
c00702d1cb feat(nix): reorganize plugins in neovim package for nix 2025-12-14 21:59:28 -03:00
aa88049fab chore(deps): update flakes 2025-12-14 21:59:28 -03:00
4d7aa88641 feat(plugins,formatters): move formatters to dedicated file 2025-12-14 21:59:28 -03:00
e8e109babb feat(keymaps): tweaks to keymaps 2025-12-14 21:59:28 -03:00
196da5309e feat(keymap): spellingn toggle and correction 2025-12-14 21:59:28 -03:00
be99745640 feat(debugger): golang adapter for dap 2025-12-14 21:59:27 -03:00
a9a59ec260 feat(debugger,keymaps): dap and dapui debugging configuration 2025-12-14 21:59:27 -03:00
1fdc7ec7fe fixup! feat(keymaps,plugins): navigation and keymaps with telescope and harpoon 2025-12-14 21:59:27 -03:00
7fc1d34a1c feat(commands): replace Ex command for yazi 2025-12-14 21:59:27 -03:00
a68a167264 feat(commands): grip command for markdown preview 2025-12-14 21:59:27 -03:00
526a626136 feat: file managing with yazi 2025-12-14 21:59:26 -03:00
8b935a5760 feat(plugins): secret hidding with cloak.nvim 2025-12-14 21:59:26 -03:00
eaf3ff77e9 feat(plugins): appearance settings and theme 2025-12-14 21:59:26 -03:00
430fefba32 fixup! feat(plugins): auto-formatting with conform.nvim 2025-12-14 21:59:26 -03:00
fb5ea210ba feat(plugins): auto-saving and auto-sessions 2025-12-14 21:59:26 -03:00
15 changed files with 1317 additions and 355 deletions

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": {

118
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,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;
};
};

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
},
})

View File

@@ -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)

View File

@@ -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 })

View File

@@ -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",
},
})

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

@@ -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"