Compare commits
10 Commits
ed1cc8eedf
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 7eac65fadc | |||
| 7cc34cbda4 | |||
| 298e81add0 | |||
| b141b21d0f | |||
| 414602c66a | |||
| eb8c484c45 | |||
| 6808f8a148 | |||
| 2bbfd4ab95 | |||
| 214efb0e8a | |||
| 2afffb0488 |
14
README.md
14
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
|
||||
@@ -70,6 +67,11 @@ dotfiles/
|
||||
|
||||
### Extras
|
||||
|
||||
- pipx
|
||||
- awsume
|
||||
- podman
|
||||
- wl-clipboard (Debian only)
|
||||
- secret-tool (Debian only)
|
||||
- fzf
|
||||
- tree-sitter-cli
|
||||
- lesspipe
|
||||
@@ -124,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
|
||||
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
|
||||
@@ -143,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
|
||||
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
|
||||
|
||||
@@ -1,141 +1,126 @@
|
||||
# Neovim Configuration
|
||||
|
||||
Keybinds reference for autocompletion, LSP, linting, diagnostics, and AI
|
||||
features. Leader key is `<Space>`.
|
||||
Keybinds reference for window management, file navigation, autocompletion, LSP,
|
||||
linting, formatting, and AI features. Leader key is `<Space>`. Local leader is `\`.
|
||||
|
||||
## General & Window Management
|
||||
|
||||
| Keybind | Mode | Description |
|
||||
| ------------ | ------ | ---------------------------------------- |
|
||||
| `<leader>sn` | Normal | Save without formatting |
|
||||
| `<leader>w` | Normal | Toggle line wrapping |
|
||||
| `<leader>tt` | Normal | Alternate light/dark theme (Themery) |
|
||||
| `x` | Nor/Vis| Remove char under cursor without yank |
|
||||
| `p` | Visual | Paste without yanking underlying text |
|
||||
| `<` / `>` | Visual | Indent left / right |
|
||||
| `gl` | Normal | Jump to last change |
|
||||
| `<C-up/down>`| Nor/Vis| Move screen up / down one line |
|
||||
|
||||
## Buffer Management
|
||||
|
||||
| Keybind | Mode | Description |
|
||||
| ------------ | ------ | ---------------------------------------- |
|
||||
| `<Tab>` | Normal | Switch to next buffer |
|
||||
| `<S-Tab>` | Normal | Switch to previous buffer |
|
||||
| `<leader>x` | Normal | Close buffer |
|
||||
| `<leader>b` | Normal | Open new buffer |
|
||||
|
||||
## Splits & Navigation (Tmux Integrated)
|
||||
|
||||
| Keybind | Mode | Description |
|
||||
| ------------ | ------ | ---------------------------------------- |
|
||||
| `<leader>v` | Normal | Split vertical |
|
||||
| `<leader>h` | Normal | Split horizontal |
|
||||
| `<leader>xs` | Normal | Close split |
|
||||
| `<leader>se` | Normal | Reset split sizes |
|
||||
| `<S-up>` | Normal | Move to split above |
|
||||
| `<S-down>` | Normal | Move to split below |
|
||||
| `<S-left>` | Normal | Move to split left |
|
||||
| `<S-right>` | Normal | Move to split right |
|
||||
| `<C-\>` | Normal | Move to last active split |
|
||||
| `<C-Space>` | Normal | Move to next split |
|
||||
|
||||
## File Explorer & Fuzzy Finding (Fzf-Lua / Oil)
|
||||
|
||||
| Keybind | Mode | Description |
|
||||
| ---------------- | ------ | ------------------------------------ |
|
||||
| `<leader>pv` | Normal | Open file explorer (Oil) |
|
||||
| `<leader>pf` | Normal | Fuzzy find project files |
|
||||
| `<leader>ps` | Normal | Live grep project text |
|
||||
| `<leader><space>`| Normal | Fuzzy find open buffers |
|
||||
| `<leader>gf` | Normal | Fuzzy find tracked Git files |
|
||||
| `<leader>f` | N/X/O | Jump to label |
|
||||
|
||||
## Git Integration
|
||||
|
||||
| Keybind | Mode | Description |
|
||||
| ------------ | ------ | ---------------------------------------- |
|
||||
| `<leader>gs` | Normal | Open Git status (Fugitive) |
|
||||
| `<leader>gk` | Normal | Toggle inline Git blame |
|
||||
|
||||
## 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|
|
||||
| --------- | ------- | ------------------------------------------ |
|
||||
| `Tab` | Command | Show and accept cmdline completion |
|
||||
|
||||
Completion is disabled in Avante's input buffer.
|
||||
Completion is handled natively via Blink and Neovim 0.11+ built-in
|
||||
`vim.snippet`. CodeCompanion and LSP provide the completion sources.
|
||||
|
||||
### 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
|
||||
## LSP & Navigation
|
||||
|
||||
| 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 definition (Fzf-Lua) |
|
||||
| `gD` | Normal | Go to declaration |
|
||||
| `grr` | Normal | Go to references |
|
||||
| `gri` | Normal | Go to implementation |
|
||||
| `grn` | Normal | Rename symbol |
|
||||
| `gr` | Normal | Go to references (Fzf-Lua) |
|
||||
| `gI` | Normal | Go to implementation (Fzf-Lua) |
|
||||
| `<leader>th` | Normal | Toggle Inlay Hints |
|
||||
|
||||
### Inlay Hints
|
||||
|
||||
Inlay hints are enabled automatically for any LSP that supports them.
|
||||
|
||||
## Linting & Diagnostics
|
||||
## Linting, Diagnostics & Code Actions
|
||||
|
||||
| Keybind | Mode | Description |
|
||||
| ------------ | ------------- | ---------------------------------- |
|
||||
| ------------ | ------ | ---------------------------------------- |
|
||||
| `<leader>cf` | Normal | Apply quickfix at cursor |
|
||||
| `<leader>l` | Normal | Trigger linting for current file |
|
||||
| `<leader>d` | Normal | Toggle inline diagnostics |
|
||||
| `<leader>sd` | Normal | Search all diagnostics (Telescope) |
|
||||
| `<leader>cd` | Normal | Copy diagnostic to clipboard |
|
||||
|
||||
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.
|
||||
## Debugging (nvim-dap)
|
||||
|
||||
### 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
|
||||
Supports C, C++, Rust (via gdb/rust-gdb) and Go (via delve).
|
||||
|
||||
| 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 |
|
||||
| ------------- | ------------- | --------------------------------- |
|
||||
| `<leader>gdc` | Normal | Continue / Launch |
|
||||
| `<leader>gdb` | Normal | Toggle breakpoint |
|
||||
| `<leader>gdB` | Normal | Set conditional breakpoint |
|
||||
| `<leader>gds` | Normal | Step over |
|
||||
| `<leader>gdi` | Normal | Step into |
|
||||
| `<leader>gdo` | Normal | Step out |
|
||||
| `<leader>gdh` | Normal/Visual | Hover variable under cursor |
|
||||
| `<leader>gdS` | Normal | Show scopes (all variables) |
|
||||
| `<leader>gdF` | Normal | Show call stack frames |
|
||||
| `<leader>gdr` | Normal | Open REPL |
|
||||
| `<leader>gdl` | Normal | Re-run last debug session |
|
||||
| `<leader>gdt` | Normal | Terminate session |
|
||||
|
||||
### Sidebar (defaults)
|
||||
## AI (CodeCompanion)
|
||||
|
||||
| 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 |
|
||||
| Keybind | Mode | Description |
|
||||
| ------------ | ------------- | --------------------------------- |
|
||||
| `<leader>a` | Normal/Visual | Toggle CodeCompanion Chat |
|
||||
| `<leader>ca` | Visual | Add visual selection to Chat |
|
||||
| `<leader>ci` | Normal/Visual | Open inline prompt |
|
||||
| `<leader>cp` | Normal/Visual | Open Action Palette |
|
||||
|
||||
### 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.
|
||||
Active provider is automatically selected: **Gemini** (if `GEMINI_API_KEY` is set) or **Kiro** (local model).
|
||||
|
||||
@@ -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,15 +39,12 @@ 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", "<C-Space>", "<C-x><C-o>", { desc = "Trigger LSP completion" })
|
||||
-- Toggle signature help natively with <C-s> 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
|
||||
|
||||
vim.opt.showtabline = 2 -- always show tabs
|
||||
vim.opt.pumheight = 10 -- pop up menu height
|
||||
|
||||
vim.opt.shortmess:append("c") -- don't give |ins-completion-menu| messages
|
||||
@@ -87,7 +84,7 @@ vim.api.nvim_create_autocmd({ "BufWritePre" }, {
|
||||
--
|
||||
-- Set a keymap to toggle the 'wrap' option
|
||||
vim.keymap.set("n", "<leader>w", function()
|
||||
vim.opt.wrap:toggle()
|
||||
vim.opt.wrap = not vim.opt.wrap:get()
|
||||
end, { desc = "Toggle line wrapping" })
|
||||
|
||||
local uv = vim.uv
|
||||
@@ -102,3 +99,44 @@ vim.api.nvim_create_autocmd({ "VimEnter", "VimLeave" }, {
|
||||
--
|
||||
-- Filetypes to enable spellcheck
|
||||
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",
|
||||
[".*%.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,
|
||||
},
|
||||
})
|
||||
|
||||
-- Set global spell option to false initially to disable it for all file types
|
||||
vim.opt.spell = false
|
||||
|
||||
-- Create an augroup for spellcheck to group related autocommands
|
||||
vim.api.nvim_create_augroup("Spellcheck", { clear = true })
|
||||
|
||||
-- Create an autocommand to enable spellcheck for specified file types
|
||||
vim.api.nvim_create_autocmd({ "FileType" }, {
|
||||
group = "Spellcheck", -- Grouping the command for easier management
|
||||
pattern = spell_types, -- Only apply to these file types
|
||||
callback = function()
|
||||
vim.opt_local.spell = true -- Enable spellcheck for these file types
|
||||
end,
|
||||
desc = "Enable spellcheck for defined filetypes", -- Description for clarity
|
||||
})
|
||||
|
||||
@@ -81,15 +81,6 @@ vim.api.nvim_create_autocmd("LspAttach", {
|
||||
apply = true,
|
||||
})
|
||||
end, { buffer = bufnr, desc = "Apply fix at cursor" })
|
||||
|
||||
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,
|
||||
})
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ map("n", "N", "Nzzzv", { desc = "Find previous occurence of search" })
|
||||
|
||||
map("n", "<Tab>", ":bnext<CR>", { desc = "Switch to next buffer" })
|
||||
map("n", "<S-Tab>", ":bprev<CR>", { desc = "Switch to previous buffer" })
|
||||
map("n", "<leader>x", ":bdelete!<CR>", { desc = "Close buffer" })
|
||||
map("n", "<leader>xb", ":bdelete!<CR>", { desc = "Close buffer" })
|
||||
map("n", "<leader>b", "<cmd> enew <CR>", { desc = "Open new buffer" })
|
||||
|
||||
map("n", "<leader>v", "<C-w>v", { desc = "Split vertical" })
|
||||
|
||||
@@ -1,26 +1,132 @@
|
||||
local function tab_info()
|
||||
local fname = vim.fn.expand("%:p")
|
||||
if fname == "" then
|
||||
return ""
|
||||
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
|
||||
return "%#WildMenu# " .. fname .. " %*"
|
||||
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
|
||||
|
||||
--- @return string
|
||||
local function filestatus()
|
||||
if vim.bo.modified == true then
|
||||
return "%#Error# ● %*"
|
||||
local function git_relative_path(abs_path)
|
||||
if abs_path == "" then
|
||||
return "[No Name]"
|
||||
end
|
||||
if vim.bo.readonly == true then
|
||||
return "%#Error# %*"
|
||||
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 ""
|
||||
return abs_path
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd("DirChanged", {
|
||||
callback = function()
|
||||
git_root_cache = {}
|
||||
end,
|
||||
})
|
||||
|
||||
local mru_bufs = {}
|
||||
|
||||
-- Initialize with currently listed buffers
|
||||
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.bo[bufnr].buflisted then
|
||||
table.insert(mru_bufs, bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
local augroup = vim.api.nvim_create_augroup("MRU_Buffers", { clear = true })
|
||||
|
||||
vim.api.nvim_create_autocmd("BufEnter", {
|
||||
group = augroup,
|
||||
callback = function(args)
|
||||
local bufnr = args.buf
|
||||
if vim.bo[bufnr].buflisted then
|
||||
for i, b in ipairs(mru_bufs) do
|
||||
if b == bufnr then
|
||||
table.remove(mru_bufs, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
table.insert(mru_bufs, 1, bufnr)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("BufDelete", {
|
||||
group = augroup,
|
||||
callback = function(args)
|
||||
local bufnr = args.buf
|
||||
for i, b in ipairs(mru_bufs) do
|
||||
if b == bufnr then
|
||||
table.remove(mru_bufs, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
function _G.TabLine()
|
||||
return table.concat({
|
||||
tab_info(),
|
||||
filestatus(),
|
||||
})
|
||||
local current_buf = vim.api.nvim_get_current_buf()
|
||||
local available_width = vim.o.columns
|
||||
local used_width = 0
|
||||
local tabline = ""
|
||||
local ellipsis = "%#TabLineFill# ..."
|
||||
|
||||
local valid_bufs = {}
|
||||
|
||||
-- 1. Always place the current buffer first
|
||||
if vim.bo[current_buf].buflisted then
|
||||
table.insert(valid_bufs, current_buf)
|
||||
end
|
||||
|
||||
-- 2. Add the rest of the buffers in native ID order (matches :bnext)
|
||||
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if bufnr ~= current_buf and vim.api.nvim_buf_is_valid(bufnr) and vim.bo[bufnr].buflisted then
|
||||
table.insert(valid_bufs, bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
for _, bufnr in ipairs(valid_bufs) do
|
||||
local is_current = (bufnr == current_buf)
|
||||
local name = git_relative_path(vim.api.nvim_buf_get_name(bufnr))
|
||||
|
||||
local hl = is_current and "%#WildMenu#" or "%#TabLine#"
|
||||
|
||||
local status_raw = ""
|
||||
local status_hl = ""
|
||||
if vim.bo[bufnr].modified then
|
||||
status_raw = status_raw .. "● "
|
||||
status_hl = status_hl .. "%#Error#● " .. hl
|
||||
end
|
||||
if vim.bo[bufnr].readonly then
|
||||
status_raw = status_raw .. " "
|
||||
status_hl = status_hl .. "%#Error# " .. hl
|
||||
end
|
||||
|
||||
local text_to_measure = string.format(" %s %s", name, status_raw)
|
||||
local display_width = vim.api.nvim_strwidth(text_to_measure)
|
||||
|
||||
if used_width + display_width > available_width - 4 then
|
||||
tabline = tabline .. ellipsis
|
||||
break
|
||||
end
|
||||
|
||||
local segment = string.format("%s %s %s", hl, name, status_hl)
|
||||
tabline = tabline .. segment
|
||||
used_width = used_width + display_width
|
||||
end
|
||||
|
||||
return tabline .. "%#TabLineFill#"
|
||||
end
|
||||
|
||||
vim.opt.tabline = "%!v:lua.TabLine()"
|
||||
vim.opt.showtabline = 2 -- always show tabs
|
||||
|
||||
-- Adds the buffer name to the top of each window
|
||||
vim.opt.winbar = " %t %m"
|
||||
|
||||
@@ -8,21 +8,28 @@ vim.pack.add({
|
||||
})
|
||||
|
||||
local codecompanion = require("codecompanion")
|
||||
-- Dynamically choose the adapter based on the environment variable
|
||||
local active_adapter = os.getenv("GEMINI_API_KEY") and "gemini" or "kiro"
|
||||
local has_gemini = os.getenv("GEMINI_API_KEY")
|
||||
|
||||
codecompanion.setup({
|
||||
strategies = {
|
||||
chat = { adapter = active_adapter },
|
||||
inline = { adapter = active_adapter },
|
||||
agent = { adapter = active_adapter },
|
||||
interactions = {
|
||||
chat = {
|
||||
adapter = has_gemini and "gemini" or "kiro",
|
||||
tools = {
|
||||
["web_search"] = {
|
||||
opts = { require_approval_before = false },
|
||||
},
|
||||
["fetch_webpage"] = {
|
||||
opts = { require_approval_before = false },
|
||||
},
|
||||
},
|
||||
},
|
||||
inline = { adapter = has_gemini and "gemini" or nil },
|
||||
},
|
||||
adapters = {
|
||||
http = {
|
||||
gemini = function()
|
||||
return require("codecompanion.adapters").extend("gemini", {
|
||||
env = {
|
||||
-- We read the API key from the environment variable.
|
||||
-- You can also use "cmd:pass show gemini/api_key" or "cmd:cat ~/.gemini_api_key"
|
||||
api_key = os.getenv("GEMINI_API_KEY") or "cmd:cat ~/.gemini_api_key",
|
||||
},
|
||||
schema = {
|
||||
@@ -32,22 +39,27 @@ codecompanion.setup({
|
||||
},
|
||||
})
|
||||
end,
|
||||
-- If 'kiro' is a custom CLI or local LLM, you must define it here.
|
||||
-- This is a generic custom adapter stub for CodeCompanion:
|
||||
},
|
||||
acp = {
|
||||
kiro = function()
|
||||
return require("codecompanion.adapters").extend("openai_compatible", {
|
||||
name = "kiro",
|
||||
env = {
|
||||
url = "http://localhost:11434", -- Example endpoint
|
||||
-- api_key = "...",
|
||||
return require("codecompanion.adapters").extend("kiro", {
|
||||
defaults = {
|
||||
model = "kiro_default",
|
||||
},
|
||||
})
|
||||
end,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- Optional: Keymaps for CodeCompanion
|
||||
vim.keymap.set({ "n", "v" }, "<leader>a", "<cmd>CodeCompanionChat Toggle<cr>", { noremap = true, silent = true })
|
||||
-- Inline prompt for buffer modifications (Generates diffs)
|
||||
vim.keymap.set({ "n", "v" }, "<leader>ci", "<cmd>CodeCompanion <cr>", { noremap = true, silent = true })
|
||||
-- Add visual selection to chat
|
||||
vim.keymap.set("v", "<leader>ca", "<cmd>CodeCompanionChat Add<cr>", { noremap = true, silent = true })
|
||||
-- Action palette (Use this to Accept/Reject inline diffs)
|
||||
vim.keymap.set({ "n", "v" }, "<leader>cp", "<cmd>CodeCompanionActions<cr>", { noremap = true, silent = true })
|
||||
vim.cmd([[cab cc CodeCompanion]])
|
||||
|
||||
vim.cmd("packadd blink.cmp")
|
||||
@@ -58,6 +70,7 @@ blink.setup({
|
||||
completion = {
|
||||
menu = { border = "rounded" },
|
||||
documentation = { auto_show = true, window = { border = "rounded" } },
|
||||
ghost_text = { enabled = true }, -- Enables ghost text in insert mode
|
||||
},
|
||||
|
||||
cmdline = {
|
||||
@@ -85,6 +98,8 @@ blink.setup({
|
||||
name = "CodeCompanion",
|
||||
module = "codecompanion.providers.completion.blink",
|
||||
enabled = true,
|
||||
score_offset = 100, -- Boosts priority so AI suggestions appear first in ghost text
|
||||
async = true, -- Ensures AI fetching doesn't block the UI
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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 = {
|
||||
["<Esc><Esc>"] = { "actions.close", mode = "n" },
|
||||
},
|
||||
})
|
||||
|
||||
vim.keymap.set("n", "<leader>pv", "<cmd>Oil<cr>", { 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", "<leader>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" }, "<leader>f", require("jump").start, {})
|
||||
|
||||
local function get_project_root()
|
||||
@@ -45,12 +74,46 @@ local function get_project_root()
|
||||
return tf_root or nvim_root or git_root or lang_root or vim.fn.getcwd()
|
||||
end
|
||||
|
||||
local function get_submodule_excludes()
|
||||
local git_root = vim.fs.root(0, ".git")
|
||||
if not git_root then
|
||||
return {}
|
||||
end
|
||||
local handle =
|
||||
io.popen("git -C " .. vim.fn.shellescape(git_root) .. " submodule --quiet foreach 'echo $sm_path' 2>/dev/null")
|
||||
if not handle then
|
||||
return {}
|
||||
end
|
||||
local excludes = {}
|
||||
for line in handle:lines() do
|
||||
table.insert(excludes, line)
|
||||
end
|
||||
handle:close()
|
||||
return excludes
|
||||
end
|
||||
|
||||
vim.keymap.set("n", "<leader>pf", function()
|
||||
require("fzf-lua").files({ cwd = get_project_root() })
|
||||
local fzf = require("fzf-lua")
|
||||
local defaults = fzf.defaults.files
|
||||
local fd_opts = defaults.fd_opts
|
||||
local rg_opts = defaults.rg_opts
|
||||
for _, sub in ipairs(get_submodule_excludes()) do
|
||||
fd_opts = fd_opts .. " --exclude " .. vim.fn.shellescape(sub)
|
||||
rg_opts = "-g '!" .. sub .. "' " .. rg_opts
|
||||
end
|
||||
rg_opts = "--hidden " .. rg_opts
|
||||
fzf.files({ cwd = get_project_root(), fd_opts = fd_opts, rg_opts = rg_opts })
|
||||
end, { desc = "Fuzzy find project files" })
|
||||
|
||||
vim.keymap.set("n", "<leader>ps", function()
|
||||
require("fzf-lua").live_grep({ cwd = get_project_root() })
|
||||
local fzf = require("fzf-lua")
|
||||
local defaults = fzf.defaults.grep
|
||||
local rg_opts = defaults.rg_opts
|
||||
for _, sub in ipairs(get_submodule_excludes()) do
|
||||
rg_opts = "-g '!" .. sub .. "' " .. rg_opts
|
||||
end
|
||||
rg_opts = "--hidden " .. rg_opts
|
||||
fzf.live_grep({ cwd = get_project_root(), rg_opts = rg_opts })
|
||||
end, { desc = "Live grep project text" })
|
||||
|
||||
vim.keymap.set("n", "<leader><space>", function()
|
||||
@@ -58,7 +121,12 @@ vim.keymap.set("n", "<leader><space>", function()
|
||||
end, { desc = "Fuzzy find open files" })
|
||||
|
||||
vim.keymap.set("n", "<leader>gf", function()
|
||||
require("fzf-lua").git_files()
|
||||
local excludes = get_submodule_excludes()
|
||||
local pathspecs = {}
|
||||
for _, sub in ipairs(excludes) do
|
||||
table.insert(pathspecs, ":(exclude)" .. sub)
|
||||
end
|
||||
require("fzf-lua").git_files({ cmd = "git ls-files --exclude-standard -- . " .. table.concat(pathspecs, " ") })
|
||||
end, { desc = "Fuzzy find tracked Git files" })
|
||||
|
||||
vim.api.nvim_create_autocmd("BufEnter", {
|
||||
|
||||
158
nvim/.config/nvim/lua/plugins/debugging/init.lua
Normal file
158
nvim/.config/nvim/lua/plugins/debugging/init.lua
Normal file
@@ -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", "<leader>gdb", dap.toggle_breakpoint, { desc = "Toggle breakpoint" })
|
||||
vim.keymap.set("n", "<leader>gdB", function()
|
||||
dap.set_breakpoint(vim.fn.input("Breakpoint condition: "))
|
||||
end, { desc = "Conditional breakpoint" })
|
||||
vim.keymap.set("n", "<leader>gdc", dap.continue, { desc = "Continue / Launch" })
|
||||
vim.keymap.set("n", "<leader>gds", dap.step_over, { desc = "Step over" })
|
||||
vim.keymap.set("n", "<leader>gdi", dap.step_into, { desc = "Step into" })
|
||||
vim.keymap.set("n", "<leader>gdo", dap.step_out, { desc = "Step out" })
|
||||
vim.keymap.set("n", "<leader>gdr", dap.repl.open, { desc = "Open REPL" })
|
||||
vim.keymap.set("n", "<leader>gdl", dap.run_last, { desc = "Run last" })
|
||||
vim.keymap.set("n", "<leader>gdt", dap.terminate, { desc = "Terminate" })
|
||||
vim.keymap.set("n", "<leader>gdh", function()
|
||||
require("dap.ui.widgets").hover()
|
||||
end, { desc = "Hover variable" })
|
||||
vim.keymap.set("v", "<leader>gdh", function()
|
||||
require("dap.ui.widgets").hover()
|
||||
end, { desc = "Hover selection" })
|
||||
vim.keymap.set("n", "<leader>gdF", function()
|
||||
require("dap.ui.widgets").centered_float(require("dap.ui.widgets").frames)
|
||||
end, { desc = "Show frames" })
|
||||
vim.keymap.set("n", "<leader>gdS", function()
|
||||
require("dap.ui.widgets").centered_float(require("dap.ui.widgets").scopes)
|
||||
end, { desc = "Show scopes" })
|
||||
@@ -19,6 +19,12 @@ require("nvim-treesitter").install({
|
||||
"yaml",
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
callback = function()
|
||||
pcall(vim.treesitter.start)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Default to treesitter folding
|
||||
vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()"
|
||||
vim.opt.foldmethod = "expr"
|
||||
@@ -60,6 +66,9 @@ vim.api.nvim_create_autocmd({ "BufReadPre", "BufNewFile" }, {
|
||||
ruff = {
|
||||
prepend_args = { "--extend-select", "I" },
|
||||
},
|
||||
yamlfmt = {
|
||||
prepend_args = { "-formatter", "max_line_length=0,retain_document_start=true" },
|
||||
},
|
||||
},
|
||||
format_on_save = {
|
||||
lsp_fallback = true,
|
||||
|
||||
@@ -3,4 +3,5 @@ require("plugins.tmux")
|
||||
require("plugins.ui")
|
||||
require("plugins.formatting")
|
||||
require("plugins.linting")
|
||||
require("plugins.debugging")
|
||||
require("plugins.ai")
|
||||
|
||||
@@ -6,24 +6,56 @@ 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", "<leader>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)
|
||||
else
|
||||
themery.setThemeByName("rose-pine-dawn", true)
|
||||
end
|
||||
end, { noremap = true, desc = "Alternate between light and dark mode" })
|
||||
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()
|
||||
local palette = require("rose-pine.palette")
|
||||
vim.api.nvim_set_hl(0, "iCursorChar", { fg = palette.surface, bg = palette.love })
|
||||
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()
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
103
scripts/hcf/podman_setup
Executable file
103
scripts/hcf/podman_setup
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to configure podman for the local environment
|
||||
#
|
||||
# ./podman_setup
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if ! command -v podman &>/dev/null; then
|
||||
echo "Error: podman is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$(uname -s)" == Linux* ]]; then
|
||||
if ! command -v gvproxy &>/dev/null; then
|
||||
echo "Error: gvproxy is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v qemu-img &>/dev/null; then
|
||||
echo "Error: qemu-img is not installed (usually provided by the qemu-utils package)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v qemu-system-x86 &>/dev/null && ! command -v qemu-system-x86_64 &>/dev/null; then
|
||||
echo "Error: qemu-system-x86 is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f /usr/libexec/virtiofsd ]]; then
|
||||
echo "Error: virtiofsd is not installed in /usr/libexec/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -e /usr/local/bin/virtiofsd ]]; then
|
||||
echo "Linking virtiofsd to /usr/local/bin (requires sudo)..."
|
||||
sudo ln -s /usr/libexec/virtiofsd /usr/local/bin/virtiofsd
|
||||
fi
|
||||
|
||||
if [[ ! -e /usr/local/libexec/podman/gvproxy ]]; then
|
||||
echo "Setting up gvproxy in /usr/local/libexec/podman (requires sudo)..."
|
||||
sudo mkdir -p /usr/local/libexec/podman
|
||||
sudo ln -s "$(command -v gvproxy)" /usr/local/libexec/podman/gvproxy
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$(uname -s)" in
|
||||
Darwin*) memory=12288 ;;
|
||||
Linux*) memory=8192 ;;
|
||||
*)
|
||||
echo "Unsupported platform"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$(uname -s)" == Darwin* ]]; then
|
||||
helper_plist="/Library/LaunchDaemons/com.github.containers.podman.helper-$(whoami).plist"
|
||||
if [[ ! -f "$helper_plist" ]]; then
|
||||
echo "Installing podman-mac-helper (requires sudo)..."
|
||||
sudo podman-mac-helper install
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! podman machine inspect &>/dev/null; then
|
||||
echo "Initializing podman machine with 4 CPUs and $((memory / 1024))GB RAM..."
|
||||
podman machine init --rootful --cpus 4 --memory "$memory"
|
||||
fi
|
||||
|
||||
if [[ "$(uname -s)" == Darwin* ]]; then
|
||||
rosetta=$(podman machine inspect --format '{{.Rosetta}}')
|
||||
if [[ "$rosetta" != "true" ]]; then
|
||||
echo "Warning: Rosetta translation is not enabled on this podman machine."
|
||||
fi
|
||||
fi
|
||||
|
||||
state=$(podman machine inspect --format '{{.State}}')
|
||||
case "$state" in
|
||||
running)
|
||||
echo "Podman machine is already running."
|
||||
;;
|
||||
stopped)
|
||||
echo "Starting podman machine..."
|
||||
podman machine start
|
||||
;;
|
||||
*)
|
||||
echo "Error: podman machine is in unexpected state: $state"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$(uname -s)" in
|
||||
Darwin*) resolved_ip=$(dscacheutil -q host -a name host.docker.internal 2>/dev/null | awk '/^ip_address:/{print $2; exit}') ;;
|
||||
*) resolved_ip=$(getent hosts host.docker.internal 2>/dev/null | awk '{print $1}' || true) ;;
|
||||
esac
|
||||
if [[ -z "$resolved_ip" ]] || ! echo "$resolved_ip" | grep -qE '^(127\.|::1$)'; then
|
||||
echo "Adding host.docker.internal to /etc/hosts (requires sudo)..."
|
||||
echo "127.0.0.1 host.docker.internal" | sudo tee -a /etc/hosts >/dev/null
|
||||
fi
|
||||
|
||||
if [[ ! -e /usr/local/bin/docker ]]; then
|
||||
echo "Creating docker symlink to avoid issues with projects that do not inherit aliases (requires sudo)..."
|
||||
sudo ln -s "$(command -v podman)" /usr/local/bin/docker
|
||||
fi
|
||||
@@ -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 C-o popup -E -E -d "#{pane_current_path}" -w 90% -h 90% "opencode"
|
||||
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,39 +119,6 @@ set-option -g @ssh-split-r-key "R"
|
||||
|
||||
set -g @plugin 'Morantron/tmux-fingers'
|
||||
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
### tmux-continuum ###
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
|
||||
set -g @plugin 'tmux-plugins/tmux-resurrect'
|
||||
set -g @plugin 'tmux-plugins/tmux-continuum'
|
||||
|
||||
set -g @resurrect-capture-pane-contents 'on'
|
||||
set -g @resurrect-dir '~/.tmux/resurrect/'
|
||||
|
||||
set -g @continuum-save-interval '15'
|
||||
set -g @continuum-restore 'on'
|
||||
set -g @continuum-boot 'on'
|
||||
|
||||
### tmux-resurrect
|
||||
set -g @resurrect-save 'S' # prefix + Shift-s - save
|
||||
set -g @resurrect-restore 'R' # prefix + Shift-r - restore
|
||||
# for neovim
|
||||
set -g @resurrect-strategy-nvim 'session'
|
||||
|
||||
# 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 ###
|
||||
|
||||
134
zsh/.zsh_aliases
134
zsh/.zsh_aliases
@@ -7,22 +7,111 @@ alias tmux_secondary_win='tmux new-session -t main -s secondary'
|
||||
# enable color support of ls and also add handy aliases
|
||||
alias ls='ls --color=auto'
|
||||
alias grep='grep --color=auto'
|
||||
alias fgrep='fgrep --color=auto'
|
||||
alias egrep='egrep --color=auto'
|
||||
alias fgrep='grep -F --color=auto'
|
||||
alias egrep='grep -E --color=auto'
|
||||
|
||||
alias docker=podman
|
||||
|
||||
alias d='dirs -v'
|
||||
# shfmt needs to ignore this because it is a zsh specific syntax
|
||||
# shfmt:ignore:start
|
||||
for index ({1..9}) alias "c$index"="cd +${index}"; unset index
|
||||
# shfmt:ignore:end
|
||||
for index in 1 2 3 4 5 6 7 8 9; do alias "c$index"="cd +${index}"; done; unset index
|
||||
|
||||
alias kpget="keepassxc-cli show -a Password ${KEEPASS_DB}"
|
||||
alias kptotp="keepassxc-cli show -t ${KEEPASS_DB}"
|
||||
|
||||
# --- KeePassXC cached session (password stored in OS keychain) ---
|
||||
# macOS: security (Keychain)
|
||||
# Linux: secret-tool (GNOME Keyring via libsecret-tools)
|
||||
_KP_KEYCHAIN_SVC="keepassxc-cli-cache"
|
||||
_KP_KEYCHAIN_ACCT="master-password"
|
||||
|
||||
_kp_pw_store() {
|
||||
case "$UNAME_STRING" in
|
||||
Darwin)
|
||||
security add-generic-password -U \
|
||||
-s "$_KP_KEYCHAIN_SVC" -a "$_KP_KEYCHAIN_ACCT" -w "$1"
|
||||
;;
|
||||
Linux)
|
||||
echo -n "$1" | secret-tool store --label="$_KP_KEYCHAIN_SVC" \
|
||||
service "$_KP_KEYCHAIN_SVC" account "$_KP_KEYCHAIN_ACCT"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_kp_pw_get() {
|
||||
case "$UNAME_STRING" in
|
||||
Darwin)
|
||||
security find-generic-password \
|
||||
-s "$_KP_KEYCHAIN_SVC" -a "$_KP_KEYCHAIN_ACCT" -w 2>/dev/null
|
||||
;;
|
||||
Linux)
|
||||
secret-tool lookup \
|
||||
service "$_KP_KEYCHAIN_SVC" account "$_KP_KEYCHAIN_ACCT" 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_kp_pw_clear() {
|
||||
case "$UNAME_STRING" in
|
||||
Darwin)
|
||||
security delete-generic-password \
|
||||
-s "$_KP_KEYCHAIN_SVC" -a "$_KP_KEYCHAIN_ACCT" &>/dev/null
|
||||
;;
|
||||
Linux)
|
||||
secret-tool clear \
|
||||
service "$_KP_KEYCHAIN_SVC" account "$_KP_KEYCHAIN_ACCT" 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_kp_run() {
|
||||
local pw stderr_redir="/dev/null"
|
||||
[[ -n "$KP_DEBUG" ]] && stderr_redir="/dev/stderr"
|
||||
pw=$(_kp_pw_get)
|
||||
if [[ -z "$pw" ]]; then
|
||||
read -rs "pw?KeePassXC master password: " </dev/tty && echo
|
||||
_kp_pw_store "$pw" || return 1
|
||||
fi
|
||||
echo "$pw" | keepassxc-cli "$@" 2>"$stderr_redir"
|
||||
}
|
||||
|
||||
kpclose() { _kp_pw_clear && echo "KeePassXC session cleared."; }
|
||||
|
||||
kpgets() { _kp_run show -sa Password "$KEEPASS_DB" "$1"; }
|
||||
kptotps() { _kp_run show -st "$KEEPASS_DB" "$1"; }
|
||||
|
||||
# run with KP_DEBUG=1 to troubleshoot if needed
|
||||
function load_gemini() {
|
||||
export GEMINI_API_KEY=$(kpget "Gemini API Key")
|
||||
export GEMINI_API_KEY=$(kpgets "Gemini API Key")
|
||||
echo "Gemini API Key loaded into environment!"
|
||||
}
|
||||
|
||||
function totp() {
|
||||
local clip=false
|
||||
[[ "$1" == "-c" ]] && clip=true && shift
|
||||
|
||||
local code
|
||||
case "$1" in
|
||||
hcf) code=$(kptotps "personal/Dev/AWS Console") ;;
|
||||
aws) code=$(kptotps "work/Own/AWS console") ;;
|
||||
pci) code=$(kptotps "work/Own/PCI/AWS Workspaces") ;;
|
||||
*) echo "Usage: totp [-c] {hcf|aws|pci}" >&2; return 1 ;;
|
||||
esac
|
||||
|
||||
echo "$code"
|
||||
if $clip; then
|
||||
case "$UNAME_STRING" in
|
||||
Darwin) echo -n "$code" | pbcopy ;;
|
||||
Linux) if [[ "$XDG_SESSION_TYPE" == "wayland" ]]; then
|
||||
echo -n "$code" | wl-copy
|
||||
else
|
||||
echo -n "$code" | xclip -selection clipboard
|
||||
fi ;;
|
||||
|
||||
esac
|
||||
echo "(copied to clipboard)"
|
||||
fi
|
||||
}
|
||||
|
||||
_get_aws_config_path() {
|
||||
local config_path="${AWS_CONFIG_FILE:-$HOME/.aws/config}"
|
||||
echo "$config_path"
|
||||
@@ -75,16 +164,23 @@ _awsume_cmd() {
|
||||
|
||||
alias asm="_awsume_cmd"
|
||||
|
||||
alias tf="terraform"
|
||||
alias tfi="tf init"
|
||||
alias tfp="tf plan -lock=false"
|
||||
alias tfa="tf apply"
|
||||
alias tfu="tf get -update"
|
||||
alias tg="terragrunt"
|
||||
alias tgi="tg init"
|
||||
alias tgp="tg plan -lock=false"
|
||||
alias tga="tg apply"
|
||||
alias tgu="tg get -update"
|
||||
_ensure_awsume() {
|
||||
if [[ -z "$AWSUME_PROFILE" ]]; then
|
||||
echo "No awsume session found. Starting one..."
|
||||
_awsume_cmd || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
tf() { _ensure_awsume && terraform "$@"; }
|
||||
tfi() { _ensure_awsume && terraform init "$@"; }
|
||||
tfp() { _ensure_awsume && terraform plan -lock=false "$@"; }
|
||||
tfa() { _ensure_awsume && terraform apply "$@"; }
|
||||
tfu() { _ensure_awsume && terraform get -update "$@"; }
|
||||
tg() { _ensure_awsume && terragrunt "$@"; }
|
||||
tgi() { _ensure_awsume && terragrunt init "$@"; }
|
||||
tgp() { _ensure_awsume && terragrunt plan -lock=false "$@"; }
|
||||
tga() { _ensure_awsume && terragrunt apply "$@"; }
|
||||
tgu() { _ensure_awsume && terragrunt get -update "$@"; }
|
||||
|
||||
alias curltime="curl -w \"@$HOME/.curl-format.txt\" -o /dev/null -s "
|
||||
|
||||
@@ -124,7 +220,7 @@ git_push() {
|
||||
local branch
|
||||
branch=$(git branch --show-current)
|
||||
|
||||
git push origin "$branch" $@
|
||||
git push origin "$branch" "$@"
|
||||
}
|
||||
|
||||
alias gpush="git_push"
|
||||
@@ -132,7 +228,7 @@ alias gpush="git_push"
|
||||
passgen() {
|
||||
length=${1:-"12"}
|
||||
if [[ "$length" == <-> ]]; then
|
||||
echo $(cat /dev/urandom| base64 | head -c "$length")
|
||||
echo $(cat /dev/urandom| base64 -w0 | head -c "$length")
|
||||
else
|
||||
echo "passgen() takes a positive integer as first argument"
|
||||
echo "got $length"
|
||||
|
||||
@@ -22,6 +22,8 @@ export SSH_ENV="$HOME/.ssh/agent-environment"
|
||||
|
||||
export GOPRIVATE="gitlab.feedzai.com,git.hcf.zone"
|
||||
|
||||
export UNAME_STRING=$(uname -s)
|
||||
|
||||
. "$HOME/.cargo/env"
|
||||
|
||||
# Interactive shells (e.g. new tmux windows): set PATH so we don't need a login shell.
|
||||
@@ -30,7 +32,7 @@ if [[ -t 0 ]]; then
|
||||
export PATH=~/.local/bin:$PATH
|
||||
export PATH=~/.dotnet:$PATH
|
||||
export PATH=$DOTFILES/scripts/hcf/:$PATH
|
||||
case "$(uname -s)" in
|
||||
case "$UNAME_STRING" in
|
||||
Linux*) eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" ;;
|
||||
Darwin*)
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
@@ -47,4 +49,4 @@ if [[ -t 0 ]]; then
|
||||
[[ -n "$TMUX" ]] && printf '\e]7;file://%s\a' "$(pwd)"
|
||||
fi
|
||||
|
||||
export PATH
|
||||
typeset -U path
|
||||
|
||||
25
zsh/.zshrc
25
zsh/.zshrc
@@ -1,11 +1,8 @@
|
||||
setopt INC_APPEND_HISTORY
|
||||
setopt EXTENDED_HISTORY # Write the history file in the ':start:elapsed;command' format.
|
||||
setopt HIST_EXPIRE_DUPS_FIRST # Expire a duplicate event first when trimming history.
|
||||
setopt HIST_FIND_NO_DUPS # Do not display a previously found event.
|
||||
setopt HIST_IGNORE_ALL_DUPS # Delete an old recorded event if a new event is a duplicate.
|
||||
setopt HIST_IGNORE_DUPS # Do not record an event that was just recorded again.
|
||||
setopt HIST_IGNORE_SPACE # Do not record an event starting with a space.
|
||||
unsetopt HIST_SAVE_NO_DUPS # Do not write a duplicate event to the history file.
|
||||
setopt SHARE_HISTORY # Share history between all sessions.
|
||||
|
||||
bindkey -e
|
||||
@@ -25,15 +22,11 @@ setopt PUSHD_SILENT # Do not print the directory stack after pushd or popd.
|
||||
DISABLE_AUTO_TITLE="true"
|
||||
|
||||
# install zsh-syntax-highlighting
|
||||
case "$(uname -s)" in
|
||||
case "$UNAME_STRING" in
|
||||
Linux*) {
|
||||
source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
||||
# make less more friendly for non-text input files, see lesspipe(1)
|
||||
local lesspipe_bin_location
|
||||
lesspipe_bin_location=$(which lesspipe)
|
||||
if [ $? -eq 0 ]; then
|
||||
[ -x $lesspipe_bin_location ] && eval "$(lesspipe)"
|
||||
fi
|
||||
(($+commands[lesspipe])) && eval "$(lesspipe)"
|
||||
} ;;
|
||||
Darwin*) {
|
||||
# Use HOMEBREW_PREFIX (set in .zshenv) to avoid slow brew --prefix subprocess on every new shell
|
||||
@@ -54,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
|
||||
|
||||
@@ -125,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
|
||||
@@ -137,7 +126,3 @@ function +vi-git-extra() {
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
### MANAGED BY RANCHER DESKTOP START (DO NOT EDIT)
|
||||
export PATH="/Users/inaki.dominguez/.rd/bin:$PATH"
|
||||
### MANAGED BY RANCHER DESKTOP END (DO NOT EDIT)
|
||||
|
||||
Submodule zsh/zsh-completions updated: 922abfe707...8b97eaf521
Reference in New Issue
Block a user