1
0

add changes made in work workstation

This commit is contained in:
2026-03-15 18:19:17 +01:00
parent f100cffb79
commit 07258cd68a
16 changed files with 401 additions and 50 deletions

View File

@@ -33,10 +33,10 @@ dotfiles/
- **Terminal**: [Alacritty](https://github.com/alacritty/alacritty)
- **Shell**: [ZSH](https://www.zsh.org/)
- [zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting)
- [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions)
- [zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting)
- [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions)
(submodule)
- [zsh-completions](https://github.com/zsh-users/zsh-completions)
- [zsh-completions](https://github.com/zsh-users/zsh-completions)
(submodule)
- **Package Manager**: [Homebrew/Linuxbrew](https://brew.sh/)
- **Dotfile Management**: [GNU Stow](https://www.gnu.org/software/stow/)
@@ -50,8 +50,12 @@ dotfiles/
[tmux-plugin-manager](https://github.com/tmux-plugins/tpm)
- [Terraform](https://www.terraform.io/)
- python3-libtmux
- Installed via `apt` in Debian. Remember to run `brew unlink python3` to
- 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
- reattach-to-user-namespace (macOS only)
### Language Servers & Linters
@@ -79,13 +83,22 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup component add rust-analyzer
```
2. **Install Homebrew**
1. **Install Homebrew**
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
3. **Install tmux-plugin-manager**
1. **Install Cursor agent binary**
Install the [Cursor](https://www.cursor.com/) `agent` binary to
`~/.local/bin/agent` (used by avante.nvim for ACP). Then authenticate:
```bash
~/.local/bin/agent login
```
1. **Install tmux-plugin-manager**
```bash
mkdir -p ~/.tmux/plugins
@@ -104,7 +117,7 @@ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashi
sudo apt update && sudo apt install terraform
```
2. **Install Dependencies**
1. **Install Dependencies**
```bash
# System packages
@@ -142,24 +155,24 @@ git clone --recurse-submodules https://github.com/yourusername/dotfiles.git ~/do
cd ~/dotfiles
```
2. **Deploy configurations using Stow**:
1. **Deploy configurations using Stow**:
```bash
stow zsh tmux git nvim curl alacritty wallpaper
```
3. Change the default shell
1. Change the default shell
```bash
chsh -s /bin/zsh
```
4. **Set up tmux plugins**:
1. **Set up tmux plugins**:
- Start a tmux session
- Press `C-b I` to install plugins
5. **Git configuration**:
2. **Git configuration**:
- Create a `~/.gitconfig.local` file with personal config
- See `~/.gitconfig.local.example` for reference

View File

@@ -19,3 +19,9 @@ style = "Regular"
[general]
import = ["~/.config/alacritty/colors/rose-pine.toml"]
# Key bindings
[keyboard]
bindings = [
{ key = "V", mods = "Control|Shift", action = "Paste" },
]

141
nvim/.config/nvim/README.md Normal file
View File

@@ -0,0 +1,141 @@
# Neovim Configuration
Keybinds reference for autocompletion, LSP, linting, diagnostics, and AI
features. Leader key is `<Space>`.
## Autocompletion (blink.cmp)
| Keybind | Mode | Description |
| --------- | ------- | --------------------------------- |
| `C-y` | Insert | Accept completion |
| `C-space` | Insert | Open menu or toggle docs |
| `C-n` | Insert | Select next item |
| `C-p` | Insert | Select previous item |
| `C-e` | Insert | Dismiss completion menu |
| `C-k` | Insert | Toggle signature help |
| `Tab` | Command | Show and accept cmdline completion|
Completion is disabled in Avante's input buffer.
### Snippets (LuaSnip)
Snippets are available for Lua, Rust, Bash, Python, and Terraform. Type a
snippet prefix and accept it from the completion menu (`C-y`).
## LSP
### Code Actions & Refactoring
| Keybind | Mode | Description |
| ------------ | ------ | ---------------------------------------- |
| `<leader>ca` | Normal | Code action menu |
| `<leader>ca` | Visual | Code action (quickfix for selection) |
| `<leader>cf` | Normal | Apply quickfix at cursor |
| `<leader>ci` | Normal | Organize imports |
### Navigation (Neovim 0.11+ built-ins)
| Keybind | Mode | Description |
| ------- | ------ | -------------------- |
| `K` | Normal | Hover documentation |
| `gd` | Normal | Go to definition |
| `gD` | Normal | Go to declaration |
| `grr` | Normal | Go to references |
| `gri` | Normal | Go to implementation |
| `grn` | Normal | Rename symbol |
### Inlay Hints
Inlay hints are enabled automatically for any LSP that supports them.
## Linting & Diagnostics
| Keybind | Mode | Description |
| ------------ | ------------- | ---------------------------------- |
| `<leader>l` | Normal | Trigger linting for current file |
| `<leader>d` | Normal | Toggle inline diagnostics |
| `<leader>sd` | Normal | Search all diagnostics (Telescope) |
Linting runs automatically on `BufEnter`, `BufWritePost`, and `InsertLeave`.
### Configured Linters
| Language | Linter |
| ---------- | ---------------- |
| Lua | luacheck |
| Bash / sh | shellcheck |
| Terraform | tflint |
| Markdown | markdownlint-cli2|
| Go | golangci-lint |
## Formatting
| Keybind | Mode | Description |
| ------------ | ------------- | --------------------------------- |
| `<leader>mp` | Normal/Visual | Format file or range |
| `<leader>sn` | Normal | Save without formatting |
Format on save is enabled by default.
### Configured Formatters
| Language | Formatter |
| --------------- | --------------- |
| Lua | stylua |
| Rust | rustfmt |
| Go | gofumpt |
| Python | ruff |
| Bash / sh / zsh | shfmt |
| JSON | prettier |
| YAML | yamlfmt |
| Markdown | markdownlint-cli2|
| Terraform | terraform_fmt |
## AI (Avante)
Provider is selected automatically: **Cursor ACP** when `~/.local/bin/agent`
exists, otherwise **Gemini API** (requires `GEMINI_API_KEY`).
All tool calls require explicit approval (`auto_approve_tool_permissions = false`).
### Global Keybinds
| Keybind | Mode | Description |
| ------------ | ---------------- | --------------------- |
| `<C-\>` | Normal/Visual/Insert | Toggle Avante sidebar |
| `<leader>aa` | Normal | Avante Ask |
| `<leader>ae` | Normal | Avante Edit |
| `<leader>ar` | Normal | Avante Refresh |
### Sidebar (defaults)
| Keybind | Description |
| --------- | ------------------------------- |
| `A` | Apply all suggestions |
| `a` | Apply suggestion at cursor |
| `r` | Retry user request |
| `e` | Edit user request |
| `<Tab>` | Switch windows in sidebar |
| `<S-Tab>` | Reverse switch windows |
| `@` | Add file to context |
| `d` | Remove file from context |
| `q` | Close sidebar |
### Diff Review
When changes are proposed and applied, a conflict-style diff appears in the
buffer. Use these keybinds to accept or reject hunks:
| Keybind | Description |
| ----------- | ------------------------ |
| `co` | Choose ours (original) |
| `ct` | Choose theirs (suggested)|
| `ca` | Accept all theirs |
| `cb` | Choose both |
| `cc` | Choose at cursor |
| `]x` / `[x` | Next / previous diff hunk |
### Input Buffer
The Avante input prompt auto-resizes to fit your text (up to 20 lines) and
shrinks back after sending.

View File

@@ -6,8 +6,13 @@ return {
gopls = {
completeUnimported = true,
usePlaceholders = true,
["completion.matcher"] = "fuzzy",
["completion.completeFunctionCalls"] = true,
analyses = {
unusedparams = true,
staticcheck = true,
unusedwrite = true,
shadow = true,
},
["ui.inlayhint.hints"] = {
compositeLiteralFields = true,

View File

@@ -9,8 +9,15 @@ return {
loadOutDirsFromCheck = true,
runBuildScripts = true,
},
-- Add clippy lints for Rust
checkOnSave = true,
completion = {
autoself = { enable = true },
snippets = { enable = true },
},
diagnostics = {
enable = true,
experimental = { enable = true },
},
procMacro = {
enable = true,
ignored = {

View File

@@ -15,12 +15,6 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then
end
vim.opt.rtp:prepend(lazypath)
-- Make sure to setup `mapleader` and `maplocalleader` before
-- loading lazy.nvim so that mappings are correct.
-- This is also a good place to setup other settings (vim.opt)
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
-- Setup lazy.nvim
require("lazy").setup({
spec = {

View File

@@ -18,6 +18,7 @@ vim.opt.backup = false -- creates a backup file
-- if a file is being edited by another program (or was written to file while editing with another program), it is not
-- allowed to be edited
vim.opt.writebackup = false
vim.opt.autoread = true -- reload files changed outside of neovim
vim.o.completeopt = "menuone,noinsert,popup,fuzzy"
vim.opt.termguicolors = true -- set termguicolors to enable highlight groups
vim.opt.whichwrap = "bs<>[]hl" -- which "horizontal" keys are allowed to travel to prev/next line
@@ -62,13 +63,22 @@ vim.opt.fillchars:append({ fold = ">" })
vim.opt.incsearch = true -- search as characters are entered
-- remove trailing whitespace
-- Auto-reload buffers when files change on disk (e.g. from external tools or AI agents)
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold" }, {
callback = function()
if vim.fn.getcmdwintype() == "" then
vim.cmd("checktime")
end
end,
})
-- remove trailing whitespace (keeppatterns avoids adding to search history)
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
pattern = { "*" },
callback = function()
local save_cursor = vim.fn.getpos(".")
pcall(function()
vim.cmd([[%s/\s\+$//e]])
vim.cmd([[keeppatterns %s/\s\+$//e]])
end)
vim.fn.setpos(".", save_cursor)
end,
@@ -79,8 +89,7 @@ vim.keymap.set("n", "<leader>w", function()
vim.opt.wrap:toggle()
end, { desc = "Toggle line wrapping" })
-- local uv = vim.uv
local uv = vim.loop
local uv = vim.uv
vim.api.nvim_create_autocmd({ "VimEnter", "VimLeave" }, {
callback = function()
@@ -94,13 +103,27 @@ vim.api.nvim_create_autocmd({ "VimEnter", "VimLeave" }, {
local spell_types = { "text", "plaintex", "typst", "gitcommit", "markdown" }
-- add gotmpl filetypes for blueprint repos
-- *.ext.tmpl files use the filetype of ext (e.g. foo.json.tmpl -> json, bar.sh.tmpl -> bash)
vim.filetype.add({
extension = {
gotmpl = "gotmpl",
},
pattern = {
[".*/recipes/.*%.ya?ml"] = "gotmpl",
[".*%.sh.tmpl"] = "bash",
[".*%.tmpl$"] = function(path)
local name = vim.fn.fnamemodify(path, ":t")
local base = name:match("^(.+)%.tmpl$")
if base then
local ext = base:match("%.(%w+)$")
if ext then
if ext == "sh" then
return "bash"
end
return ext
end
end
return nil
end,
},
})

View File

@@ -25,7 +25,7 @@ vim.api.nvim_create_autocmd("LspAttach", {
if client ~= nil then
if client:supports_method("textDocument/foldingRange") then
local win = vim.api.nvim_get_current_win()
vim.wo[win][0].foldexpr = "v:lua.vim.lsp.foldexpr()"
vim.wo[win].foldexpr = "v:lua.vim.lsp.foldexpr()"
end
end
end,
@@ -41,3 +41,30 @@ vim.api.nvim_create_autocmd("LspAttach", {
end
end,
})
-- [[CODE ACTIONS
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
local bufnr = args.data.bufnr
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, { buffer = bufnr, desc = "Code action (menu)" })
vim.keymap.set("v", "<leader>ca", function()
vim.lsp.buf.code_action({ context = { only = { "quickfix" } } })
end, { buffer = bufnr, desc = "Code action (selection)" })
-- Quickfix at cursor: apply single fix without menu when only one available
vim.keymap.set("n", "<leader>cf", function()
vim.lsp.buf.code_action({
context = { only = { "quickfix" } },
apply = true,
})
end, { buffer = bufnr, desc = "Apply fix at cursor" })
-- Organize imports (Rust: source.organizeImports.rust, Go: source.organizeImports)
vim.keymap.set("n", "<leader>ci", function()
vim.lsp.buf.code_action({
context = {
only = { "source.organizeImports.rust", "source.organizeImports" },
},
apply = true,
})
end, { buffer = bufnr, desc = "Organize imports" })
end,
})

View File

@@ -2,7 +2,7 @@
-- loading lazy.nvim so that mappings are correct.
-- This is also a good place to setup other settings (vim.opt)
vim.g.mapleader = " "
vim.g.maplocalleader = " "
vim.g.maplocalleader = "\\"
-- (mode, key, command)
vim.keymap.set({ "n", "v" }, "<Space>", "<Nop>", { silent = true })
-- vim.keymap.set("n", "<leader>pv", vim.cmd.Ex, { desc = "Open current directory" })

View File

@@ -0,0 +1,98 @@
-- Avante.nvim: uses Cursor ACP when the agent binary is available,
-- otherwise falls back to the Gemini API (requires GEMINI_API_KEY).
local agent_path = os.getenv("HOME") .. "/.local/bin/agent"
local has_cursor_agent = vim.uv.fs_stat(agent_path) ~= nil
local provider = has_cursor_agent and "cursor" or "gemini"
return {
{
"yetone/avante.nvim",
event = "VeryLazy",
version = false,
build = "make",
opts = {
provider = provider,
mode = "agentic",
behaviour = {
auto_approve_tool_permissions = {
"web_search",
"fetch",
"view",
"ls",
"glob",
"grep",
"get_diagnostics",
"think",
"read_todos",
"read_file_toplevel_symbols",
"read_definitions",
},
auto_apply_diff_after_generation = false,
enable_fastapply = false,
},
acp_providers = {
cursor = {
command = agent_path,
args = { "acp" },
auth_method = "cursor_login",
env = {
HOME = os.getenv("HOME"),
PATH = os.getenv("PATH"),
},
},
},
providers = {
gemini = {
model = "gemini-2.5-flash",
},
},
},
config = function(_, opts)
require("avante").setup(opts)
vim.api.nvim_create_autocmd("FileType", {
pattern = "AvanteInput",
callback = function(args)
local buf = args.buf
local min_height = 5
local max_height = 20
local function resize_input()
local win = vim.fn.bufwinid(buf)
if win == -1 or not vim.api.nvim_win_is_valid(win) then
return
end
local lines = vim.api.nvim_buf_line_count(buf)
local height = math.max(min_height, math.min(lines + 1, max_height))
vim.api.nvim_win_set_height(win, height)
end
vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI" }, {
buffer = buf,
callback = resize_input,
})
resize_input()
end,
})
end,
keys = {
{ "<C-\\>", "<cmd>AvanteToggle<cr>", mode = { "n", "v", "i" }, desc = "Toggle Avante Chat" },
{ "<leader>aa", "<cmd>AvanteAsk<cr>", desc = "Avante Ask" },
{ "<leader>ae", "<cmd>AvanteEdit<cr>", desc = "Avante Edit" },
{ "<leader>ar", "<cmd>AvanteRefresh<cr>", desc = "Avante Refresh" },
},
dependencies = {
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
"nvim-tree/nvim-web-devicons",
{
"MeanderingProgrammer/render-markdown.nvim",
opts = {
file_types = { "markdown", "Avante" },
},
ft = { "markdown", "Avante" },
},
},
},
}

View File

@@ -36,6 +36,9 @@ return {
---@module 'blink.cmp'
---@type blink.cmp.Config
opts = {
enabled = function()
return vim.bo.filetype ~= "AvanteInput"
end,
-- 'default' (recommended) for mappings similar to built-in completions (C-y to accept)
-- 'super-tab' for mappings similar to vscode (tab to accept)
-- 'enter' for enter to accept

View File

@@ -9,7 +9,7 @@ set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
bind r source-file ~/.tmux.conf \; display "Reloaded!" # Reload with ctrl-r
bind r source-file ~/.tmux.conf \; display "Reloaded!"
set -sg escape-time 1 # quicker responses
set -g base-index 1 # Numbering of windows
@@ -64,18 +64,26 @@ set -g @rose_pine_variant 'main' # Options are 'main', 'moon' or 'dawn'
set -g @rose_pine_date_time '%Y-%m-%d %H:%M '
set -g @rose_pine_directory 'on'
set -g @rose_pine_disable_active_window_menu 'on'
set -g @rose_pine_disable_active_window_menu 'off'
#set -g @rose_pine_left_separator ' > ' # The strings to use as separators are 1-space padded
#set -g @rose_pine_right_separator ' < ' # Accepts both normal chars & nerdfont icons
#set -g @rose_pine_field_separator ' ' # Default is two-space-padded, but can be set to anything
set -g @plugin 'MunifTanjim/tmux-mode-indicator'
set -g @rose_pine_status_left_prepend_section '#{tmux_mode_indicator}'
set -g @rose_pine_status_left_prepend_section '#{tmux_mode_indicator} '
# bind F5 to theme switch
bind-key . run-shell "$DOTFILES/scripts/hcf/rose_pine_switch"
bind-key . run-shell 'zsh -c "$DOTFILES/scripts/hcf/rose_pine_switch"'
set -g @plugin 'ofirgall/tmux-window-name'
set -g @tmux_window_name_substitute_sets "[('.+bash', 'bash'), ('cbonsai.+', 'cbonsai')]"
set -g @tmux_window_name_shells "['bash', 'fish', 'sh', 'zsh']"
# Replace login shell argv (-l/--login) so window name shows directory instead of "--login"
set -g @tmux_window_name_substitute_sets "[('.+bash', 'bash'), ('cbonsai.+', 'cbonsai'), (r'^(-l|--login)$', '')]"
# Include Homebrew zsh path so the plugin recognizes it as a shell (otherwise it shows full path or '-')
set -g @tmux_window_name_shells "['bash', 'fish', 'sh', 'zsh', '/opt/homebrew/bin/zsh', '/usr/local/bin/zsh']"
# When pane_current_path is unset tmux may show '-'; show '~' instead
set -g @tmux_window_name_dir_substitute_sets "[(r'^-$', '~'), (r'^\\.$', '~')]"
set -g @tmux_window_dir_programs "['nvim', 'vim', 'vi', 'git', 'cbonsai']"
set -g @tmux_window_name_use_tilde "True"
set -g @tmux_window_name_max_name_len "100"
@@ -125,7 +133,8 @@ set -g @resurrect-strategy-nvim 'session'
if-shell "uname | grep -q Darwin" {
# macOS specific settings
set -g @continuum-boot-options 'alacritty,fullscreen'
set -g default-command "reattach-to-user-namespace -l $SHELL"
# 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'

View File

@@ -1,15 +1,2 @@
export PATH=~/.local/bin:$PATH
export PATH=$DOTFILES/scripts/hcf/:$PATH
case "$(uname -s)" in
Linux*) {
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
} ;;
Darwin*) {
eval "$(/opt/homebrew/bin/brew shellenv)"
export PATH="/opt/homebrew/bin/bash/bin:$PATH"
} ;;
*) ;;
esac
export PATH="$(go env GOPATH)/bin:$PATH"
# PATH/brew/go are set in .zshenv for interactive shells (including login).
# .zprofile is only for login; .zshenv already runs first and sets PATH when -t 0.

View File

@@ -22,4 +22,27 @@ export GOPRIVATE="gitlab.feedzai.com,git.hcf.zone"
. "$HOME/.cargo/env"
# Interactive shells (e.g. new tmux windows): set PATH so we don't need a login shell.
# Tmux uses non-login shell by default; this avoids slow .zprofile on every new window.
if [[ -t 0 ]]; then
export PATH=~/.local/bin:$PATH
export PATH=~/.dotnet:$PATH
export PATH=$DOTFILES/scripts/hcf/:$PATH
case "$(uname -s)" in
Linux*) eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" ;;
Darwin*)
eval "$(/opt/homebrew/bin/brew shellenv)"
export PATH="/opt/homebrew/bin/bash/bin:$PATH"
;;
esac
if [[ -f "${HOME}/.cache/zsh/go-gopath" ]]; then
export PATH="$(cat "${HOME}/.cache/zsh/go-gopath")/bin:$PATH"
else
export PATH="$(go env GOPATH)/bin:$PATH"
mkdir -p "${HOME}/.cache/zsh" && go env GOPATH >"${HOME}/.cache/zsh/go-gopath" 2>/dev/null
fi
# Tell tmux our cwd early so tmux-window-name plugin can show the directory (not "-")
[[ -n "$TMUX" ]] && printf '\e]7;file://%s\a' "$(pwd)"
fi
export PATH

View File

@@ -36,9 +36,10 @@ case "$(uname -s)" in
fi
} ;;
Darwin*) {
source "$(brew --prefix)/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
# Use HOMEBREW_PREFIX (set in .zshenv) to avoid slow brew --prefix subprocess on every new shell
source "${HOMEBREW_PREFIX}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
# make less more friendly for non-text input files, see lesspipe(1)
export LESSOPEN="|$(brew --prefix)/bin/lesspipe.sh %s"
export LESSOPEN="|${HOMEBREW_PREFIX}/bin/lesspipe.sh %s"
} ;;
*) ;;
esac
@@ -86,6 +87,9 @@ function preexec() {
}
precmd() {
# Tell tmux our cwd (for pane_current_path) so tmux-window-name can show the directory
[[ -n "$TMUX" ]] && printf '\e]7;file://%s\a' "$(pwd)"
if [[ $__GIT_COMMAND_EXECUTED -eq 1 ]]; then
zstyle ':vcs_info:git*:*' cache-ttl 0
__GIT_COMMAND_EXECUTED=0
@@ -133,3 +137,11 @@ function +vi-git-extra() {
fi
fi
}
# Kiro CLI post block. Keep at the bottom of this file.
[[ -f "${HOME}/Library/Application Support/kiro-cli/shell/zshrc.post.zsh" ]] && builtin source "${HOME}/Library/Application Support/kiro-cli/shell/zshrc.post.zsh"
### MANAGED BY RANCHER DESKTOP START (DO NOT EDIT)
export PATH="/Users/inaki.dominguez/.rd/bin:$PATH"
### MANAGED BY RANCHER DESKTOP END (DO NOT EDIT)

View File

@@ -1,7 +1,10 @@
# Should be called before compinit
zmodload zsh/complist
autoload -U compinit; compinit
# Use a dump file and skip security check for much faster startup (compinit is a major bottleneck)
mkdir -p "${HOME}/.cache/zsh"
autoload -U compinit
compinit -C -d "${HOME}/.cache/zsh/.zcompdump"
_comp_options+=(globdots) # With hidden files
# +---------+