This commit is contained in:
root 2026-03-16 12:19:11 -03:00
commit 73ff9ee8ee
No known key found for this signature in database
31 changed files with 4906 additions and 0 deletions

416
home/nvim/default.nix Normal file
View file

@ -0,0 +1,416 @@
{
config,
pkgs,
lib,
...
}:
with lib;
let
cfg = config.custom.neovim;
in
{
options.custom.neovim = {
enable = mkEnableOption "Custom Neovim";
colorscheme = mkOption {
type = types.str;
default = "unokai";
};
hostname = mkOption {
type = types.str;
};
};
config = mkIf cfg.enable {
programs.neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = false;
vimdiffAlias = true;
plugins = with pkgs.vimPlugins; [
{
plugin = auto-session;
type = "lua";
config = ''
require("auto-session").setup({
cwd_change_handling = true,
suppressed_dirs = { "$HOME", "/etc/nixos", "$HOME/tmp" },
})
'';
}
{
plugin = blink-cmp;
type = "lua";
config = ''
require("blink.cmp").setup({
completion = {
documentation = {
auto_show = true
},
},
keymap = {
preset = "default",
["<C-y>"] = { "snippet_forward", "fallback" },
["<C-s>"] = { "select_and_accept", "snippet_forward", "fallback" },
["<C-S-y>"] = { "snippet_backward", "fallback" },
},
})
'';
}
{
plugin = comment-nvim;
type = "lua";
config = ''
require('Comment').setup()
'';
}
{
plugin = conform-nvim;
type = "lua";
config = ''
require("conform").setup({
formatters_by_ft = {
c = { "clang-format" },
cpp = { "clang-format" },
lua = { "stylua" },
javascript = { "prettierd" },
nix = { "nixfmt" },
python = { "black" },
php = { "php_cs_fixer" },
zig = { "zigfmt" },
css = { "prettierd" },
scss = { "prettierd" },
less = { "prettierd" },
blade = { "blade-formatter" },
go = { "gofmt" },
wgsl = { "wgsl_fmt" },
},
})
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*",
callback = function(args)
require("conform").format({ bufnr = args.buf })
end,
})
vim.keymap.set("n", "<leader>rf", function()
require("conform").format({
lsp_fallback = true,
async = true,
timeout_ms = 500,
})
end, { desc = "conform format" })
'';
}
leap-nvim
{
plugin = lsp_lines-nvim;
type = "lua";
config = ''
require("lsp_lines").setup()
vim.keymap.set("n", "<localleader>i", require("lsp_lines").toggle, { desc = "Toggle LSP lines" })
'';
}
{
plugin = mini-icons;
type = "lua";
config = ''require("mini.icons").setup()'';
}
{
plugin = neotest;
type = "lua";
config = ''
require('neotest').setup({
output = {
open_on_run = true
},
adapters = {
require('neotest-pest'),
}
})
vim.keymap.set('n', '<localleader>pn', function() require('neotest').run.run() end, { desc = "test nearest" })
vim.keymap.set('n', '<localleader>pe', function() require('neotest').run.run(vim.fn.expand('%')) end, { desc = "test file" })
'';
}
{
plugin = neotest-pest;
type = "lua";
}
# {
# plugin = nvim-autopairs;
# type = "lua";
# config = ''
# require('nvim-autopairs').setup()
# '';
# }
{
plugin = nvim-dap;
type = "lua";
config = ''
local dap = require("dap")
dap.adapters.php = {
type = 'executable',
command = '${pkgs.nodejs}/bin/node',
args = { '${pkgs.vscode-extensions.xdebug.php-debug}/share/vscode/extensions/xdebug.php-debug/out/phpDebug.js' },
}
dap.configurations.php = {
{
type = 'php',
request = 'launch',
name = 'listen for xdebug',
port = 9003,
}
}
'';
}
{
plugin = nvim-dap-ui;
type = "lua";
config = ''
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
'';
}
nvim-nio
{
plugin = nvim-treesitter.withAllGrammars;
type = "lua";
config = ''
local treesitter = require("nvim-treesitter")
treesitter.setup()
vim.api.nvim_create_autocmd('FileType', {
pattern = {
'c', 'lua', 'vim', 'vimdoc', 'query', 'elixir', 'heex', 'javascript', 'typescript',
'html', 'yaml', 'blade', 'php', 'scss', 'comment', 'cmake' , 'dockerfile', 'fish',
'fsharp', 'git_config', 'git_rebase', 'gitignore', 'glsl', 'go', 'gomod', 'graphql',
'haskell', 'hlsl', 'http', 'ini', 'javadoc', 'jq', 'jsdoc', 'json', 'json5', 'kitty',
'latex', 'markdown', 'nginx', 'nix', 'php', 'php_only', 'phpdoc', 'regex', 'rust', 'sql',
'ssh_config', 'tmux', 'vim', 'wgsl', 'yaml', 'zig', 'ols',
},
callback = function()
vim.treesitter.start()
end,
})
'';
}
{
plugin = nvim-treesitter-context;
type = "lua";
config = ''require("treesitter-context").setup()'';
}
# {
# plugin = nvim-treesitter-textobjectse
# type = "lua";
# config = ''
# vim.g.no_plugin_maps = true
# require("treesitter-textobjects").setup()
# '';
# }
nvim-lspconfig
nvim-nio
{
plugin = nvim-surround;
type = "lua";
config = ''require("nvim-surround").setup()'';
}
{
plugin = nvim-web-devicons;
type = "lua";
config = ''require("nvim-web-devicons").setup()'';
}
{
plugin = oil-nvim;
type = "lua";
config = ''
require("oil").setup()
vim.keymap.set("n", "<leader>o", "<cmd>Oil<cr>", { desc = "Oil" })
'';
}
{
plugin = opencode-nvim;
type = "lua";
config = ''
vim.o.autoread = true
-- Recommended/example keymaps.
vim.keymap.set({ "n", "x" }, "<C-a>", function() require("opencode").ask("@this: ", { submit = true }) end, { desc = "Ask opencode" })
vim.keymap.set({ "n", "x" }, "<C-x>", function() require("opencode").select() end, { desc = "Execute opencode action" })
vim.keymap.set({ "n", "t" }, "<C-.>", function() require("opencode").toggle() end, { desc = "Toggle opencode" })
vim.keymap.set({ "n", "x" }, "go", function() return require("opencode").operator("@this ") end, { desc = "Add range to opencode", expr = true })
vim.keymap.set("n", "goo", function() return require("opencode").operator("@this ") .. "_" end, { desc = "Add line to opencode", expr = true })
vim.keymap.set("n", "<S-C-u>", function() require("opencode").command("session.half.page.up") end, { desc = "Scroll opencode up" })
vim.keymap.set("n", "<S-C-d>", function() require("opencode").command("session.half.page.down") end, { desc = "Scroll opencode down" })
-- You may want these if you stick with the opinionated "<C-a>" and "<C-x>" above otherwise consider "<leader>o".
vim.keymap.set("n", "+", "<C-a>", { desc = "Increment under cursor", noremap = true })
vim.keymap.set("n", "-", "<C-x>", { desc = "Decrement under cursor", noremap = true })
'';
}
phpactor
plenary-nvim
{
plugin = render-markdown-nvim;
type = "lua";
config = ''require("render-markdown").setup()'';
}
{
plugin = snacks-nvim;
type = "lua";
config = ''
local snacks = require("snacks")
snacks.setup({
bigfile = {},
dim = {},
image = {},
indent = {},
lazygit = {},
picker = {
win = {
input = {
keys = {
["<Esc>"] = { "close", mode = { "n", "i" } },
},
},
},
},
quickfile = {},
notifier = {},
})
vim.keymap.set({ "n" }, "<localleader>t", snacks.picker.grep, { desc = "grep picker" })
vim.keymap.set({ "n" }, "<localleader>r", snacks.picker.buffers, { desc = "buffer picker" })
vim.keymap.set({ "n" }, "<localleader>s", snacks.picker.files, { desc = "file picker" })
vim.keymap.set({ "n" }, "<localleader>ln", snacks.picker.lsp_references, { desc = "lsp references" })
vim.keymap.set("n", "<localleader>le", snacks.picker.lsp_implementations, { desc = "lsp implementations" })
-- vim.keymap.set("n", "<leader>lg", function() snacks.lazygit() end , { desc = "lazygit" })
'';
}
rose-pine
{
plugin = rustaceanvim;
type = "lua";
config = ''
vim.keymap.set("n", "<leader>da", function() vim.cmd.RustLsp('codeAction') end, { silent = true, buffer = bufnr })
vim.keymap.set("n", "K", function() vim.cmd.RustLsp({'hover', 'actions'}) end, { silent = true, buffer = bufnr })
'';
}
{
plugin = tabby-nvim;
type = "lua";
config = ''
require("tabby").setup({
preset = "active_wins_at_tail",
options = {
theme = {
fill = "TabLineFill",
head = "TabLine",
current_tab = "TabLineSel",
tab = "TabLine",
win = "TabLine",
tail = "TabLine",
},
nerdfont = true,
lualine_theme = nil,
tab_name = {
name_fallback = function(tabid)
return tabid
end,
},
buf_name = { mode = "unique", },
},
})
vim.keymap.set("n", "<leader>to", "<cmd>Tabby jump_to_tab<cr>", { desc = "Jump to tab" })
vim.keymap.set("n", "<leader>tf", "<cmd>Tabby pick_window<cr>", { desc = "Search tab" })
'';
}
{
plugin = ts-autotag-nvim;
type = "lua";
config = ''
require("ts-autotag").setup()
'';
}
# {
# plugin = toggleterm-nvim;
# type = "lua";
# config = ''
# require("toggleterm").setup()
# vim.keymap.set("n", "<leader>nt", "<cmd>ToggleTerm size=120 direction=tab name=ttermh<cr>", { desc = "Toggle tterm tab" })
# vim.keymap.set("n", "<leader>ns", "<cmd>ToggleTerm direction=vertical name=ttermv<cr>", { desc = "Toggle tterm vertical" })
# vim.keymap.set("n", "<C-n>", "<cmd>ToggleTerm direction=float name=ttermf<cr>", { desc = "Toggle tterm float" })
# '';
# }
{
plugin = trouble-nvim;
type = "lua";
config = ''
require("trouble").setup({})
vim.keymap.set("n", "<localleader>id", "<cmd>Trouble diagnostics toggle<cr>", { desc = "Trouble project" })
-- vim.keymap.set("n", "<localleader>io", "<cmd>Trouble diagnostics toggle filter.buf=0<cr>", { desc = "Trouble buffer" })
'';
}
{
plugin = undotree;
type = "lua";
config = ''vim.keymap.set("n", "<leader>u", vim.cmd.UndotreeToggle, { desc = "undotree" })'';
}
vim-repeat
{
plugin = vimtex;
type = "lua";
config = ''
vim.g.vimtex_view_method = "zathura"
vim.g.vimtex_compiler_method = "latexmk"
'';
}
{
plugin = which-key-nvim;
type = "lua";
config = ''
local wk = require("which-key")
wk.setup({
preset = "helix",
win = { row = 0, col = 0.5 },
triggers = {
{ "<leader>", mode = { "n", "v" } },
{ "<localleader>", mode = { "n", "v" } },
}
})
wk.add({
{ "<leader>s", group = "Search..." },
{ "<leader>l", group = "Launch..." },
{ "<leader>t", group = "Tab..." },
{ "<leader>g", group = "Go..." },
{ "<leader>r", group = "Run..." },
{ "<leader>n", group = "term..." },
})
-- vim.keymap.set({"t"}, "<C-/>", wk.show, { desc = "Show which key in terminal mode" })
'';
}
vim-fugitive
];
extraConfig = ''
colorscheme ${cfg.colorscheme}
'';
extraLuaConfig = ''
${builtins.readFile ./settings.lua}
${builtins.replaceStrings [ "@HOSTNAME@" ] [ cfg.hostname ] (builtins.readFile ./plugins.lua)}
require("custom")
'';
};
};
}

161
home/nvim/plugins.lua Normal file
View file

@ -0,0 +1,161 @@
local hostname = "@HOSTNAME@"
local servers = {
clangd = {},
textlab = {},
lua_ls = {
settings = {
Lua = {
runtime = {
version = "LuaJIT",
},
diagnostics = {
globals = { "vim" },
},
workspace = {
library = vim.api.nvim_get_runtime_file("", true),
checkThirdParty = false,
},
telemetry = {
enable = false,
},
},
},
},
nixd = {
nixpkgs = {
expr = 'import (builtins.getFlake "/etc/nixos").inputs.nixpkgs {}',
},
formatting = { command = { "nixfmt" } },
options = {
nixos = {
expr = '(builtins.getFlake "/etc/nixos").nixosConfigurations.' .. hostname .. ".options",
},
home_manager = {
expr = '(builtins.getFlake "/etc/nixos").homeConfigurations.' .. hostname .. ".options",
},
},
},
phpactor = {},
zls = {
settings = {
zls = {
enable_build_on_save = true,
semantic_tokens = "partial",
},
},
},
css = {},
scss = {},
less = {},
blade = {},
html = { filetypes = { "html", "blade" } },
htmx = { filetypes = { "html", "blade" } },
gopls = {},
ols = {},
wgsl_analyzer = {},
}
for server, config in pairs(servers) do
vim.lsp.config(server, config)
vim.lsp.enable(server)
end
-- vim.api.nvim_create_autocmd("LspAttach", {
-- group = vim.api.nvim_create_augroup("UserConfigLsp", {}),
-- callback = function(ev)
vim.keymap.set("n", "gn", vim.lsp.buf.declaration, { desc = "go to declaration" })
vim.keymap.set("n", "ge", vim.lsp.buf.definition, { desc = "go to definition" })
-- vim.keymap.set("n", "gi", vim.lsp.buf.implementaion, { desc = "go to implementation" })
vim.keymap.set("n", "<leader>rr", vim.lsp.buf.rename, { desc = "lsp rename" })
vim.keymap.set("n", "<leader>ra", vim.lsp.buf.code_action, { desc = "code action" })
vim.keymap.set({ "n", "i" }, "<C-k>", vim.lsp.buf.signature_help, { desc = "signature help" })
vim.keymap.set("n", "gr", vim.lsp.buf.references, { desc = "references" })
-- end,
-- })
local leap = require("leap")
leap.opts.preview = function(ch0, ch1, ch2)
return not (ch1:match("%s") or (ch0:match("%a") and ch1:match("%a") and ch2:match("%a")))
end
leap.opts.equivalence_classes = {
" \t\r\n",
"([{",
")]}",
"'\"`",
}
vim.api.nvim_set_hl(0, "LeapBackdrop", { link = "Comment" })
do
-- Return an argument table for `leap()`, tailored for f/t-motions.
local function as_ft(key_specific_args)
local common_args = {
inputlen = 1,
inclusive = true,
-- To limit search scope to the current line:
-- pattern = function (pat) return '\\%.l'..pat end,
opts = {
labels = "", -- force autojump
safe_labels = vim.fn.mode(1):match("[no]") and "" or nil, -- [1]
},
}
return vim.tbl_deep_extend("keep", common_args, key_specific_args)
end
local clever = require("leap.user").with_traversal_keys -- [2]
local clever_f = clever("f", "F")
local clever_t = clever("t", "T")
for key, key_specific_args in pairs({
f = { opts = clever_f },
F = { backward = true, opts = clever_f },
t = { offset = -1, opts = clever_t },
T = { backward = true, offset = 1, opts = clever_t },
}) do
vim.keymap.set({ "n", "x", "o" }, key, function()
require("leap").leap(as_ft(key_specific_args))
end)
end
end
vim.api.nvim_create_autocmd("CmdlineLeave", {
group = vim.api.nvim_create_augroup("LeapOnSearch", {}),
callback = function()
local ev = vim.v.event
local is_search_cmd = (ev.cmdtype == "/") or (ev.cmdtype == "?")
local cnt = vim.fn.searchcount().total
if is_search_cmd and not ev.abort and (cnt > 1) then
-- Allow CmdLineLeave-related chores to be completed before
-- invoking Leap.
vim.schedule(function()
-- We want "safe" labels, but no auto-jump (as the search
-- command already does that), so just use `safe_labels`
-- as `labels`, with n/N removed.
local labels = require("leap").opts.safe_labels:gsub("[nN]", "")
-- For `pattern` search, we never need to adjust conceallevel
-- (no user input). We cannot merge `nil` from a table, but
-- using the option's current value has the same effect.
local vim_opts = { ["wo.conceallevel"] = vim.wo.conceallevel }
require("leap").leap({
pattern = vim.fn.getreg("/"), -- last search pattern
windows = { vim.fn.win_getid() },
opts = { safe_labels = "", labels = labels, vim_opts = vim_opts },
})
end)
end
end,
})
vim.keymap.set({ "n", "x", "o" }, "s", "<Plug>(leap)", { desc = "leap" })
vim.keymap.set({ "n", "x", "o" }, "S", "<Plug>(leap-from-window)", { desc = "leap across window" })
require("neotest").setup({
adapters = {
require("neotest-pest"),
},
})
vim.keymap.set("n", "<localleader>pn", function()
require("neotest").run.run()
end, { desc = "test nearest" })
vim.keymap.set("n", "<localleader>pe", function()
require("neotest").run.run(vim.fn.expand("%"))
end, { desc = "test file" })

147
home/nvim/settings.lua Normal file
View file

@ -0,0 +1,147 @@
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.cursorline = true
vim.opt.wrap = false
vim.opt.scrolloff = 10
vim.opt.sidescrolloff = 8
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.softtabstop = 4
vim.opt.expandtab = true
vim.opt.smartindent = true
vim.opt.autoindent = true
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.hlsearch = false
vim.opt.incsearch = true
vim.opt.termguicolors = true
vim.opt.signcolumn = "yes"
vim.opt.colorcolumn = "120"
vim.opt.showmatch = false
--- vim.opt.matchtime = 2
vim.opt.conceallevel = 0
vim.opt.concealcursor = ""
vim.opt.synmaxcol = 1000
vim.opt.isfname:append("@-@")
vim.opt.backup = false
vim.opt.writebackup = false
vim.opt.swapfile = false
vim.opt.undofile = true
vim.opt.undodir = vim.fn.expand("~/.cache/vim/undodir")
vim.opt.updatetime = 100
vim.opt.timeoutlen = 500
vim.opt.ttimeoutlen = 0
vim.opt.autoread = true
vim.opt.autowrite = false
vim.opt.hidden = true
--- vim.opt.errorbells = false
vim.opt.backspace = "indent,eol,start"
vim.opt.autochdir = false
vim.opt.path:append("**")
vim.opt.selection = "exclusive"
vim.opt.mouse = "a"
vim.opt.modifiable = true
vim.opt.encoding = "UTF-8"
-- Split behavior
vim.opt.splitbelow = true
vim.opt.splitright = true
vim.g.mapleader = " "
vim.g.maplocalleader = vim.api.nvim_replace_termcodes("<BS>", false, false, true)
vim.o.exrc = true
vim.o.showtabline = 2
vim.cmd("set title")
vim.cmd("set ic")
-- Delete without yanking
vim.keymap.set({ "n", "v" }, "<localleader>d", '"_d', { desc = "Delete without yanking" })
vim.keymap.set({ "n", "v" }, "<C-c>", '"+y', { desc = "Copy to clipboard" })
vim.keymap.set("x", "<localleader>p", '"_dP', { desc = "Replace without yanking" })
-- Wayland clipboard mappings
vim.keymap.set({ "n", "v" }, "<leader>y", '"+y', { desc = "Yank to system clipboard" })
vim.keymap.set("n", "<leader>Y", '"+Y', { desc = "Yank line to system clipboard" })
vim.keymap.set({ "n", "v" }, "<leader>p", '"+p', { desc = "Paste from system clipboard" })
vim.keymap.set({ "n", "v" }, "<leader>P", '"+P', { desc = "Paste from system clipboard before cursor" })
-- Better J behavior
vim.keymap.set("n", "J", "mzJ`z", { desc = "Join lines and keep cursor position" })
--- center when jumping
vim.keymap.set("n", "n", "nzzzv", { desc = "Next search result (centered)" })
vim.keymap.set("n", "N", "Nzzzv", { desc = "Previous search result (centered)" })
vim.keymap.set("n", "<C-d>", "<C-d>zz", { desc = "Half page down (centered)" })
vim.keymap.set("n", "<C-u>", "<C-u>zz", { desc = "Half page up (centered)" })
--- window navigation
vim.keymap.set("n", "<C-w>Left", "<C-w>h", { desc = "Move to left window" })
vim.keymap.set("n", "<C-w>Right", "<C-w>l", { desc = "Move to right window" })
vim.keymap.set("n", "<C-w>Top", "<C-w>k", { desc = "Move to top window" })
vim.keymap.set("n", "<C-w>Down", "<C-w>j", { desc = "Move to bottom window" })
vim.keymap.set("t", "<S-Esc>", "<C-\\><C-n>", { desc = "Exit terminal mode" })
vim.keymap.set("n", "<leader>tn", "<cmd>$tabnew<cr>", { desc = "create tab" })
vim.keymap.set("n", "<leader>n", function()
vim.cmd("tabnext 1")
end, { desc = "Go to tab 1" })
vim.keymap.set("n", "<leader>e", function()
vim.cmd("tabnext 2")
end, { desc = "Go to tab 2" })
vim.keymap.set("n", "<leader>i", function()
vim.cmd("tabnext 3")
end, { desc = "Go to tab 3" })
vim.keymap.set("n", "<leader>a", function()
vim.cmd("tabnext 4")
end, { desc = "Go to tab 4" })
vim.keymap.set({ "n", "t" }, "<C-H>", function()
vim.cmd("tabnext #")
end, { desc = "Go to previous tab" })
vim.keymap.set({ "n", "t" }, "<C-Space>", "<C-w>p", { desc = "Go to previous pane" })
vim.keymap.set("n", "<localleader>v", "<cmd>vsplit<cr>", { desc = "split (vertical line)" })
vim.keymap.set("n", "<leader>h", "<cmd>split<cr>", { desc = "split (horizontal line)" })
vim.keymap.set("n", "<localleader><localleader>", "<cmd>w<cr>", { desc = "save buffer" })
vim.diagnostic.config({
virtual_text = false,
virtual_lines = true,
signs = true,
underline = true,
update_in_insert = false,
severity_sort = true,
})
-- Highlight yanked text
vim.api.nvim_create_autocmd("TextYankPost", {
group = augroup,
callback = function()
vim.highlight.on_yank()
end,
})
--- return to last edit position when opening files
vim.api.nvim_create_autocmd("BufReadPost", {
group = augroup,
callback = function()
local mark = vim.api.nvim_buf_get_mark(0, '"')
local lcount = vim.api.nvim_buf_line_count(0)
if mark[1] > 0 and mark[1] <= lcount then
pcall(vim.api.nvim_win_set_cursor, 0, mark)
end
end,
})
--- command line completion
vim.opt.wildmenu = true
vim.opt.wildmode = "longest:full,full"
vim.opt.wildignore:append({ "*.o", "*.obj", "*.pyc", "*.class", "*.jar", "*.lock" })