From 7cc34cbda4efa7fa6c845f9f808fb0c32e767694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Dom=C3=ADnguez=20Ochoa?= Date: Mon, 13 Apr 2026 19:29:57 +0200 Subject: [PATCH] add changes from work workstation --- README.md | 9 +- nvim/.config/nvim/README.md | 19 +++ nvim/.config/nvim/lua/ink/init.lua | 8 +- nvim/.config/nvim/lua/ink/remap.lua | 2 +- nvim/.config/nvim/lua/ink/tabline.lua | 38 ++++- nvim/.config/nvim/lua/plugins/basic/init.lua | 31 +++- .../nvim/lua/plugins/debugging/init.lua | 158 ++++++++++++++++++ nvim/.config/nvim/lua/plugins/init.lua | 1 + nvim/.config/nvim/lua/plugins/ui/init.lua | 59 +++++-- nvim/.config/nvim/nvim-pack-lock.json | 4 + tmux/.tmux.conf | 29 ++-- zsh/.zshenv | 2 +- zsh/.zshrc | 10 +- 13 files changed, 319 insertions(+), 51 deletions(-) create mode 100644 nvim/.config/nvim/lua/plugins/debugging/init.lua diff --git a/README.md b/README.md index ec14f8d..b597a06 100644 --- a/README.md +++ b/README.md @@ -52,10 +52,7 @@ dotfiles/ - python3-libtmux - Installed via `apt` in Debian. Remember to run `brew unlink python3` to prevent conflicting Python environments. -- [Cursor](https://www.cursor.com/) CLI (`agent` binary at `~/.local/bin/agent`) - - Required by [avante.nvim](https://github.com/yetone/avante.nvim) for - AI-assisted coding via ACP (Agent Communication Protocol) - - Run `agent login` once to authenticate +- gdb - reattach-to-user-namespace (macOS only) ### Language Servers & Linters @@ -129,7 +126,7 @@ sudo apt update && sudo apt install terraform ```bash # System packages -sudo apt install alacritty zsh tmux stow zsh-syntax-highlighting less python3-libtmux cbonsai shfmt shellcheck lua-check libsecret-tools wl-clipboard podman qemu-system-x86 qemu-utils virtiofsd gvproxy +sudo apt install alacritty zsh tmux stow zsh-syntax-highlighting less python3-libtmux cbonsai shfmt shellcheck lua-check libsecret-tools wl-clipboard podman qemu-system-x86 qemu-utils virtiofsd gvproxy gdb # Homebrew packages brew install neovim stylua lua-language-server bash-language-server prettier terraform-ls tflint ruff markdownlint-cli2 fzf tree-sitter-cli @@ -148,7 +145,7 @@ brew unlink python3 brew install curl git alacritty zsh tmux stow zsh-syntax-highlighting lesspipe cbonsai reattach-to-user-namespace # Development tools -brew install neovim stylua lua-language-server bash-language-server prettier terraform-ls tflint ruff fzf tree-sitter-cli podman +brew install neovim stylua lua-language-server bash-language-server prettier terraform-ls tflint ruff fzf tree-sitter-cli podman gdb # Node packages npm install --save-dev prettier prettier-plugin-go-template diff --git a/nvim/.config/nvim/README.md b/nvim/.config/nvim/README.md index ad4e961..a28effd 100644 --- a/nvim/.config/nvim/README.md +++ b/nvim/.config/nvim/README.md @@ -95,6 +95,25 @@ Linting runs automatically on `BufEnter`, `BufWritePost`, and `InsertLeave`. | ------------ | ------------- | --------------------------------- | | `mp` | Normal/Visual | Format file or range | +## Debugging (nvim-dap) + +Supports C, C++, Rust (via gdb/rust-gdb) and Go (via delve). + +| Keybind | Mode | Description | +| ------------- | ------------- | --------------------------------- | +| `gdc` | Normal | Continue / Launch | +| `gdb` | Normal | Toggle breakpoint | +| `gdB` | Normal | Set conditional breakpoint | +| `gds` | Normal | Step over | +| `gdi` | Normal | Step into | +| `gdo` | Normal | Step out | +| `gdh` | Normal/Visual | Hover variable under cursor | +| `gdS` | Normal | Show scopes (all variables) | +| `gdF` | Normal | Show call stack frames | +| `gdr` | Normal | Open REPL | +| `gdl` | Normal | Re-run last debug session | +| `gdt` | Normal | Terminate session | + ## AI (CodeCompanion) | Keybind | Mode | Description | diff --git a/nvim/.config/nvim/lua/ink/init.lua b/nvim/.config/nvim/lua/ink/init.lua index c73cf02..22053f9 100644 --- a/nvim/.config/nvim/lua/ink/init.lua +++ b/nvim/.config/nvim/lua/ink/init.lua @@ -7,7 +7,7 @@ vim.opt.smartcase = true -- but make it case sensitive if an uppercase is entere vim.wo.number = true vim.opt.relativenumber = true -vim.w.signcolumn = "yes" -- Keep signcolumn on by default +vim.wo.signcolumn = "yes" -- Keep signcolumn on by default vim.opt.swapfile = false -- creates a swapfile vim.opt.undofile = true -- Save undo history @@ -39,10 +39,8 @@ vim.o.completeopt = "menuone,noinsert,popup,fuzzy" vim.opt.wildmode = "longest:full,full" vim.opt.wildoptions = { "pum", "fuzzy" } -- Use a popup menu for cmdline with fuzzy matching --- vim.keymap.set("i", "", "", { desc = "Trigger LSP completion" }) --- Toggle signature help natively with in insert mode (Neovim 0.11+ default) - vim.opt.cursorline = true +vim.opt.termguicolors = true vim.opt.splitbelow = true -- open new vertical split bottom vim.opt.splitright = true -- open new horizontal splits right @@ -86,7 +84,7 @@ vim.api.nvim_create_autocmd({ "BufWritePre" }, { -- -- Set a keymap to toggle the 'wrap' option vim.keymap.set("n", "w", function() - vim.opt.wrap:toggle() + vim.opt.wrap = not vim.opt.wrap:get() end, { desc = "Toggle line wrapping" }) local uv = vim.uv diff --git a/nvim/.config/nvim/lua/ink/remap.lua b/nvim/.config/nvim/lua/ink/remap.lua index 36e4248..ba3f8f7 100644 --- a/nvim/.config/nvim/lua/ink/remap.lua +++ b/nvim/.config/nvim/lua/ink/remap.lua @@ -22,7 +22,7 @@ map("n", "N", "Nzzzv", { desc = "Find previous occurence of search" }) map("n", "", ":bnext", { desc = "Switch to next buffer" }) map("n", "", ":bprev", { desc = "Switch to previous buffer" }) -map("n", "x", ":bdelete!", { desc = "Close buffer" }) +map("n", "xb", ":bdelete!", { desc = "Close buffer" }) map("n", "b", " enew ", { desc = "Open new buffer" }) map("n", "v", "v", { desc = "Split vertical" }) diff --git a/nvim/.config/nvim/lua/ink/tabline.lua b/nvim/.config/nvim/lua/ink/tabline.lua index a6ae584..245072f 100644 --- a/nvim/.config/nvim/lua/ink/tabline.lua +++ b/nvim/.config/nvim/lua/ink/tabline.lua @@ -1,3 +1,36 @@ +local git_root_cache = {} + +local function get_git_root(path) + local dir = vim.fn.fnamemodify(path, ":h") + if git_root_cache[dir] then + return git_root_cache[dir] + end + local root = vim.fn.systemlist("git -C " .. vim.fn.shellescape(dir) .. " rev-parse --show-toplevel 2>/dev/null")[1] + if vim.v.shell_error ~= 0 or not root or root == "" then + root = false + end + git_root_cache[dir] = root + return root +end + +local function git_relative_path(abs_path) + if abs_path == "" then + return "[No Name]" + end + local root = get_git_root(abs_path) + if root then + local rel = abs_path:sub(#root + 2) -- strip root + trailing / + return rel ~= "" and rel or abs_path + end + return abs_path +end + +vim.api.nvim_create_autocmd("DirChanged", { + callback = function() + git_root_cache = {} + end, +}) + local mru_bufs = {} -- Initialize with currently listed buffers @@ -61,10 +94,7 @@ function _G.TabLine() for _, bufnr in ipairs(valid_bufs) do local is_current = (bufnr == current_buf) - local name = vim.api.nvim_buf_get_name(bufnr) - if name == "" then - name = "[No Name]" - end + local name = git_relative_path(vim.api.nvim_buf_get_name(bufnr)) local hl = is_current and "%#WildMenu#" or "%#TabLine#" diff --git a/nvim/.config/nvim/lua/plugins/basic/init.lua b/nvim/.config/nvim/lua/plugins/basic/init.lua index 2a5c8dc..24f0287 100644 --- a/nvim/.config/nvim/lua/plugins/basic/init.lua +++ b/nvim/.config/nvim/lua/plugins/basic/init.lua @@ -17,9 +17,38 @@ require("oil").setup({ view_options = { show_hidden = true, }, + preview = { + max_width = 0.9, + min_width = { 40, 0.4 }, + max_height = 0.9, + min_height = { 5, 0.1 }, + }, + float = { + max_width = math.floor(vim.o.columns * 0.66), + max_height = math.floor(vim.o.lines * 0.66), + }, + keymaps = { + [""] = { "actions.close", mode = "n" }, + }, }) -vim.keymap.set("n", "pv", "Oil", { desc = "Open current directory" }) +vim.api.nvim_create_autocmd("User", { + pattern = "OilEnter", + callback = vim.schedule_wrap(function(args) + local oil = require("oil") + if vim.api.nvim_get_current_buf() == args.data.buf and oil.get_current_dir() then + require("oil.actions").preview.callback() + end + end), +}) + +vim.keymap.set("n", "pv", function() + if vim.o.lines >= 40 and vim.o.columns >= 120 then + require("oil").open_float() + else + require("oil").open() + end +end, { desc = "Open file explorer" }) vim.keymap.set({ "n", "x", "o" }, "f", require("jump").start, {}) local function get_project_root() diff --git a/nvim/.config/nvim/lua/plugins/debugging/init.lua b/nvim/.config/nvim/lua/plugins/debugging/init.lua new file mode 100644 index 0000000..7cd7846 --- /dev/null +++ b/nvim/.config/nvim/lua/plugins/debugging/init.lua @@ -0,0 +1,158 @@ +vim.pack.add({ + { src = "https://codeberg.org/mfussenegger/nvim-dap" }, +}) + +local dap = require("dap") + +-- GDB adapter for C/C++ (requires gdb 14.0+) +dap.adapters.gdb = { + type = "executable", + command = "gdb", + args = { "--interpreter=dap", "--eval-command", "set print pretty on" }, +} + +-- Rust-specific adapter using rust-gdb for pretty-printing Rust types +dap.adapters["rust-gdb"] = { + type = "executable", + command = "rust-gdb", + args = { "--interpreter=dap", "--eval-command", "set print pretty on" }, +} + +-- Delve adapter for Go (uses delve's built-in DAP mode) +dap.adapters.delve = function(callback, config) + if config.mode == "remote" and config.request == "attach" then + callback({ + type = "server", + host = config.host or "127.0.0.1", + port = config.port or "38697", + }) + else + callback({ + type = "server", + port = "${port}", + executable = { + command = "dlv", + args = { "dap", "-l", "127.0.0.1:${port}", "--log", "--log-output=dap" }, + detached = vim.fn.has("win32") == 0, + }, + }) + end +end + +-- C configurations +dap.configurations.c = { + { + name = "Launch", + type = "gdb", + request = "launch", + program = function() + return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file") + end, + args = function() + local input = vim.fn.input("Arguments: ") + return vim.split(input, " ", { trimempty = true }) + end, + cwd = "${workspaceFolder}", + stopAtBeginningOfMainSubprogram = false, + }, + { + name = "Attach to process", + type = "gdb", + request = "attach", + program = function() + return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file") + end, + pid = function() + local name = vim.fn.input("Executable name (filter): ") + return require("dap.utils").pick_process({ filter = name }) + end, + cwd = "${workspaceFolder}", + }, +} + +dap.configurations.cpp = dap.configurations.c + +-- Rust configurations (using rust-gdb for pretty-printed types) +dap.configurations.rust = { + { + name = "Launch", + type = "rust-gdb", + request = "launch", + program = function() + return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/target/debug/", "file") + end, + args = function() + local input = vim.fn.input("Arguments: ") + return vim.split(input, " ", { trimempty = true }) + end, + cwd = "${workspaceFolder}", + stopAtBeginningOfMainSubprogram = false, + }, + { + name = "Attach to process", + type = "rust-gdb", + request = "attach", + program = function() + return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/target/debug/", "file") + end, + pid = function() + local name = vim.fn.input("Executable name (filter): ") + return require("dap.utils").pick_process({ filter = name }) + end, + cwd = "${workspaceFolder}", + }, +} + +-- Go configurations (using delve) +dap.configurations.go = { + { + type = "delve", + name = "Debug", + request = "launch", + program = "${file}", + }, + { + type = "delve", + name = "Debug test", + request = "launch", + mode = "test", + program = "${file}", + }, + { + type = "delve", + name = "Debug test (go.mod)", + request = "launch", + mode = "test", + program = "./${relativeFileDirname}", + }, +} + +-- Breakpoint signs +vim.fn.sign_define("DapBreakpoint", { text = "●", texthl = "DapBreakpoint", linehl = "", numhl = "" }) +vim.fn.sign_define("DapBreakpointCondition", { text = "◆", texthl = "DapBreakpoint", linehl = "", numhl = "" }) +vim.fn.sign_define("DapStopped", { text = "▶", texthl = "DapStopped", linehl = "DapStopped", numhl = "" }) + +-- Keybindings +vim.keymap.set("n", "gdb", dap.toggle_breakpoint, { desc = "Toggle breakpoint" }) +vim.keymap.set("n", "gdB", function() + dap.set_breakpoint(vim.fn.input("Breakpoint condition: ")) +end, { desc = "Conditional breakpoint" }) +vim.keymap.set("n", "gdc", dap.continue, { desc = "Continue / Launch" }) +vim.keymap.set("n", "gds", dap.step_over, { desc = "Step over" }) +vim.keymap.set("n", "gdi", dap.step_into, { desc = "Step into" }) +vim.keymap.set("n", "gdo", dap.step_out, { desc = "Step out" }) +vim.keymap.set("n", "gdr", dap.repl.open, { desc = "Open REPL" }) +vim.keymap.set("n", "gdl", dap.run_last, { desc = "Run last" }) +vim.keymap.set("n", "gdt", dap.terminate, { desc = "Terminate" }) +vim.keymap.set("n", "gdh", function() + require("dap.ui.widgets").hover() +end, { desc = "Hover variable" }) +vim.keymap.set("v", "gdh", function() + require("dap.ui.widgets").hover() +end, { desc = "Hover selection" }) +vim.keymap.set("n", "gdF", function() + require("dap.ui.widgets").centered_float(require("dap.ui.widgets").frames) +end, { desc = "Show frames" }) +vim.keymap.set("n", "gdS", function() + require("dap.ui.widgets").centered_float(require("dap.ui.widgets").scopes) +end, { desc = "Show scopes" }) diff --git a/nvim/.config/nvim/lua/plugins/init.lua b/nvim/.config/nvim/lua/plugins/init.lua index 297401f..b80a203 100644 --- a/nvim/.config/nvim/lua/plugins/init.lua +++ b/nvim/.config/nvim/lua/plugins/init.lua @@ -3,4 +3,5 @@ require("plugins.tmux") require("plugins.ui") require("plugins.formatting") require("plugins.linting") +require("plugins.debugging") require("plugins.ai") diff --git a/nvim/.config/nvim/lua/plugins/ui/init.lua b/nvim/.config/nvim/lua/plugins/ui/init.lua index 4d75450..b78e027 100644 --- a/nvim/.config/nvim/lua/plugins/ui/init.lua +++ b/nvim/.config/nvim/lua/plugins/ui/init.lua @@ -6,24 +6,59 @@ vim.opt.cmdheight = 2 -- more space in the neovim command line for displaying me vim.pack.add({ { src = "https://github.com/rose-pine/neovim" }, - { src = "https://github.com/zaldih/themery.nvim" }, { src = "https://github.com/brenoprata10/nvim-highlight-colors" }, }) -require("themery").setup({ - -- add the config here - themes = { "rose-pine-dawn", "rose-pine-main" }, -- Your list of installed colorschemes. - livePreview = true, -- Apply theme while picking. Default to true. -}) +-- Sync background with tmux rose-pine variant +if vim.env.TMUX then + local variant = vim.fn.system("tmux show-option -gqv @rose_pine_variant"):gsub("%s+", "") + vim.o.background = variant == "dawn" and "light" or "dark" +else + vim.o.background = "dark" +end + +vim.cmd.colorscheme("rose-pine") + vim.keymap.set("n", "tt", function() - local themery = require("themery") - local currentTheme = themery.getCurrentTheme() - if currentTheme and currentTheme.name == "rose-pine-dawn" then - themery.setThemeByName("rose-pine-main", true) + vim.o.background = vim.o.background == "dark" and "light" or "dark" +end, { desc = "Alternate between light and dark mode" }) + +-- Insert-mode cursor: extmark overlay for full fg+bg control (terminal ignores fg on cursor hl groups) +local function set_icursor_hl() + if vim.o.background == "light" then + vim.api.nvim_set_hl(0, "iCursorChar", { fg = "#fffaf3", bg = "#b4637a" }) -- dawn: surface / love else - themery.setThemeByName("rose-pine-dawn", true) + vim.api.nvim_set_hl(0, "iCursorChar", { fg = "#1f1d2e", bg = "#eb6f92" }) -- main: surface / love end -end, { noremap = true, desc = "Alternate between light and dark mode" }) +end + +set_icursor_hl() +vim.api.nvim_create_autocmd({ "ColorScheme", "OptionSet" }, { + pattern = { "*", "background" }, + callback = set_icursor_hl, +}) + +local icursor_ns = vim.api.nvim_create_namespace("icursor") + +local function update_icursor() + vim.api.nvim_buf_clear_namespace(0, icursor_ns, 0, -1) + local r, c = unpack(vim.api.nvim_win_get_cursor(0)) + local line = vim.api.nvim_get_current_line() + local char = c < #line and line:sub(c + 1, c + 1) or " " + vim.api.nvim_buf_set_extmark(0, icursor_ns, r - 1, c, { + virt_text = { { char, "iCursorChar" } }, + virt_text_pos = "overlay", + }) +end + +vim.api.nvim_create_autocmd("ModeChanged", { pattern = "*:i*", callback = update_icursor }) +vim.api.nvim_create_autocmd("CursorMovedI", { callback = update_icursor }) +vim.api.nvim_create_autocmd("ModeChanged", { + pattern = "i*:*", + callback = function() + vim.api.nvim_buf_clear_namespace(0, icursor_ns, 0, -1) + end, +}) require("nvim-highlight-colors").setup() diff --git a/nvim/.config/nvim/nvim-pack-lock.json b/nvim/.config/nvim/nvim-pack-lock.json index ba6d531..623b75a 100644 --- a/nvim/.config/nvim/nvim-pack-lock.json +++ b/nvim/.config/nvim/nvim-pack-lock.json @@ -50,6 +50,10 @@ "rev": "cf2a288696b03d0934da713d66c6d71557b5c997", "src": "https://github.com/rose-pine/neovim" }, + "nvim-dap": { + "rev": "45a69eba683a2c448dd9ecfc4de89511f0646b5f", + "src": "https://codeberg.org/mfussenegger/nvim-dap" + }, "nvim-highlight-colors": { "rev": "e2cb22089cc2358b2b995c09578224f142de6039", "src": "https://github.com/brenoprata10/nvim-highlight-colors" diff --git a/tmux/.tmux.conf b/tmux/.tmux.conf index d34d48b..abfad1e 100644 --- a/tmux/.tmux.conf +++ b/tmux/.tmux.conf @@ -25,7 +25,14 @@ bind '"' split-window -v -c "#{pane_current_path}" bind % split-window -h -c "#{pane_current_path}" ### set-environment -g PATH "$HOMEBREW_PREFIX/bin:$PATH" -bind o popup -E -E -d "#{pane_current_path}" -w 66% -h 66% +bind o run-shell '\ + SID="scratch-#{window_id}"; \ + if ! tmux has-session -t "$SID" 2>/dev/null; then \ + tmux new-session -d -s "$SID" -c "#{pane_current_path}"; \ + fi; \ + tmux popup -d "#{pane_current_path}" -w 66% -h 66% -E "tmux attach-session -t \"$SID\""' + +# set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q' bind-key -n C-S-Down next-window bind-key -n C-S-Up previous-window @@ -34,7 +41,7 @@ bind-key -n C-S-Right swap-window -t +1\; select-window -t +1 setw -g mode-keys vi bind-key -T copy-mode-vi v send-keys -X begin-selection -bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel +bind-key -T copy-mode-vi y send-keys -X copy-selection set -g set-clipboard on set -g focus-events on @@ -51,7 +58,12 @@ set-option -g allow-rename off set-option -sa terminal-features ',alacritty:RGB' set-option -ga terminal-features ",alacritty:usstyle" set-option -ga terminal-overrides ',alacritty:Tc' -set -g default-terminal "alacritty" + +if-shell 'infocmp tmux-256color >/dev/null 2>&1' { + set -g default-terminal "tmux-256color" +} { + set -g default-terminal "tmux" +} ############################################################################### ############################################################################### @@ -107,17 +119,6 @@ set-option -g @ssh-split-r-key "R" set -g @plugin 'Morantron/tmux-fingers' -# Platform-specific settings -if-shell "uname | grep -q Darwin" { - # macOS specific settings - set -g @continuum-boot-options 'alacritty,fullscreen' - # Don't use -l (login shell): avoids slow .zprofile on every new window; env is set in .zshenv - set -g default-command "reattach-to-user-namespace $SHELL" -} { - # Linux specific settings - set -g @continuum-boot-options 'alacritty,fullscreen' -} - ############################################################################### ############################################################################### ### Nvim-tmux-navigation setup ### diff --git a/zsh/.zshenv b/zsh/.zshenv index e8ee8a0..c6d86c3 100644 --- a/zsh/.zshenv +++ b/zsh/.zshenv @@ -49,4 +49,4 @@ if [[ -t 0 ]]; then [[ -n "$TMUX" ]] && printf '\e]7;file://%s\a' "$(pwd)" fi -export PATH +typeset -U path diff --git a/zsh/.zshrc b/zsh/.zshrc index 10417cc..23976c3 100644 --- a/zsh/.zshrc +++ b/zsh/.zshrc @@ -47,10 +47,6 @@ fpath=("$DOTFILES/zsh/zsh-completions/src" $fpath) source "$DOTFILES/zsh/completion.zsh" source "$DOTFILES/zsh/zsh-autosuggestions/zsh-autosuggestions.zsh" -# export starship_precmd_user_func="set_win_title" -# -# eval "$(starship init zsh)" - autoload -Uz vcs_info setopt prompt_subst @@ -118,9 +114,9 @@ function +vi-git-extra() { # Check if upstream exists before trying to get ahead/behind counts if git rev-parse --verify ${hook_com[branch]}@{upstream} >/dev/null 2>&1; then local ahead_behind=$(git rev-list --left-right --count HEAD...${hook_com[branch]}@{upstream} 2>/dev/null) - local ahead=$(echo $ahead_behind | awk '{print $1}') - local behind=$(echo $ahead_behind | awk '{print $2}') - + local split=($=ahead_behind) + local ahead=$split[1] + local behind=$split[2] [[ $ahead -gt 0 ]] && hook_com[misc]+="+"${ahead} [[ $behind -gt 0 ]] && hook_com[misc]+=${hook_com[misc]:+"/"}"-"${behind} fi