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

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