Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b5e8850
fix(nvim): flatten gopls double-nested settings
chagui Feb 9, 2026
59a43e9
fix(nvim): wire up blink-cmp LSP capabilities
chagui Feb 9, 2026
919c63e
fix(nvim): scope FileType options to buffer instead of global
chagui Feb 9, 2026
2e834f3
fix(nvim): extract LspDetach autocmd from LspAttach callback
chagui Feb 9, 2026
8f4aeb6
fix(nvim): correct grepformat pattern for ripgrep
chagui Feb 9, 2026
7e7c805
feat(nvim): add missing treesitter parsers
chagui Feb 9, 2026
ec6e8bf
feat(nvim): add format-on-save for Go files
chagui Feb 9, 2026
e74429c
chore(nvim): remove dead LazyVim reference from lazydev config
chagui Feb 9, 2026
3254ef0
feat(nvim): add LSP keymaps for common operations
chagui Feb 9, 2026
22c9b74
refactor(nvim): replace synchronous chezmoi apply with async job
chagui Feb 9, 2026
534a75e
fix(nvim): guard python3_host_prog against missing env var
chagui Feb 19, 2026
08d5766
chore(nvim): remove non-functional Caps_Lock mapping
chagui Feb 9, 2026
ac01a9f
refactor(nvim): replace vim-smoothie with native smoothscroll
chagui Feb 9, 2026
20308ac
fix(nvim): use HTTPS URL for lazy.nvim bootstrap
chagui Feb 9, 2026
a97d468
docs(nvim): add comments for recent config changes
chagui Feb 9, 2026
43cf733
fix(zsh): use uv tool install for argcomplete and avoid modifying she…
chagui Feb 19, 2026
c0b1fea
refactor(nvim): slim down editor profile for Claude Code usage
chagui Feb 21, 2026
ed5ec0f
feat(claude): add bazel and opentelemetry to WebFetch allow list
chagui Feb 21, 2026
bb961ee
feat(claude): expand WebFetch allow list and sort all sections
chagui Feb 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/bin/bash

echo "🐍 Installing Python"
curl -LsSf https://astral.sh/uv/install.sh | sh
if ! command -v uv &>/dev/null; then
UV_NO_MODIFY_PATH=1 curl -LsSf https://astral.sh/uv/install.sh | sh
fi
# install the latest Python version
uv python install

: "${XDG_DATA_HOME:=$HOME/.local/share}"
uv generate-shell-completion zsh >"${XDG_DATA_HOME}/zsh/completions/_uv"
uvx --generate-shell-completion zsh >"$XDG_DATA_HOME/zsh/completions/_uvx"

uv pip install argcomplete
activate-global-python-argcomplete
uv tool install argcomplete
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dot_kube/ → Kubernetes config
dot_cargo/ → Cargo (Rust) config
dot_cache/ → cached files
dot_local/ → local binaries/share
dot_claude/ → ~/.claude/ (Claude Code settings, skills, permissions)
Library/ → macOS Library preferences
gui/ → GUI app configs (not managed by chezmoi)
```
Expand Down
18 changes: 17 additions & 1 deletion dot_claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
"Bash(find:*)",
"Bash(grep:*)",
"Bash(head:*)",
"Bash(sort:*)",
"Bash(ls:*)",
"Bash(mkdir:*)",
"Bash(pwd:*)",
"Bash(rg:*)",
"Bash(sort:*)",
"Bash(tail:*)",
"Bash(tree:*)",
"Bash(wc:*)",
Expand Down Expand Up @@ -104,32 +104,48 @@
"WebFetch(domain:*.githubusercontent.com)",
"WebFetch(domain:*.readthedocs.io)",
"WebFetch(domain:about.gitlab.com)",
"WebFetch(domain:alacritty.org)",
"WebFetch(domain:bazel.build)",
"WebFetch(domain:www.gnu.org)",
"WebFetch(domain:developer.hashicorp.com)",
"WebFetch(domain:developers.raycast.com)",
"WebFetch(domain:doc.rust-lang.org)",
"WebFetch(domain:docs.ansible.com)",
"WebFetch(domain:docs.anthropic.com)",
"WebFetch(domain:docs.astral.sh)",
"WebFetch(domain:docs.aws.amazon.com)",
"WebFetch(domain:docs.claude.com)",
"WebFetch(domain:docs.datadoghq.com)",
"WebFetch(domain:docs.docker.com)",
"WebFetch(domain:docs.github.com)",
"WebFetch(domain:docs.gitlab.com)",
"WebFetch(domain:docs.python.org)",
"WebFetch(domain:docs.rs)",
"WebFetch(domain:github.com)",
"WebFetch(domain:gitlab.com)",
"WebFetch(domain:go.dev)",
"WebFetch(domain:grafana.com)",
"WebFetch(domain:graphite.dev)",
"WebFetch(domain:handbook.gitlab.com)",
"WebFetch(domain:helm.sh)",
"WebFetch(domain:katacontainers.io)",
"WebFetch(domain:kernel.org)",
"WebFetch(domain:kubernetes.io)",
"WebFetch(domain:man7.org)",
"WebFetch(domain:mypy.readthedocs.io)",
"WebFetch(domain:neovim.io)",
"WebFetch(domain:nginx.org)",
"WebFetch(domain:opentelemetry.io)",
"WebFetch(domain:pkg.go.dev)",
"WebFetch(domain:platform.openai.com)",
"WebFetch(domain:prometheus.io)",
"WebFetch(domain:pypi.org)",
"WebFetch(domain:registry.terraform.io)",
"WebFetch(domain:stackoverflow.com)",
"WebFetch(domain:support.anthropic.com)",
"WebFetch(domain:www.jetbrains.com)",
"WebFetch(domain:www.lua.org)",
"WebFetch(domain:zed.dev)",

"mcp__atlassian__atlassianUserInfo",
"mcp__atlassian__fetch",
Expand Down
2 changes: 2 additions & 0 deletions dot_config/nvim/after/plugin/blink-cmp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ capabilities = vim.tbl_deep_extend("force", capabilities, {
},
},
})

vim.lsp.config("*", { capabilities = capabilities })
5 changes: 5 additions & 0 deletions dot_config/nvim/after/plugin/treesitter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ end

configs.setup({
ensure_installed = {
"bash",
"c",
"cmake",
"dockerfile",
"dot",
"go",
"hcl",
"json",
"lua",
"make",
"python",
"rust",
"terraform",
"toml",
"yaml",
},
sync_install = false,
autopairs = {
Expand Down
22 changes: 11 additions & 11 deletions dot_config/nvim/filetype.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,27 @@ vim.filetype.add({

local augroups = require("user.augroups")
local autocmd = vim.api.nvim_create_autocmd
local set = vim.opt
-- Use vim.bo (buffer-local) not vim.opt (global) to avoid leaking settings across buffers
-- https://neovim.io/doc/user/api.html#nvim_create_autocmd()
autocmd({ "FileType" }, {
group = augroups.filetype,
pattern = { "terraform", "hcl", "json", "yaml" },
callback = function()
set.tabstop = 2
set.shiftwidth = 2
set.softtabstop = 2
set.expandtab = true
callback = function(event)
vim.bo[event.buf].tabstop = 2
vim.bo[event.buf].shiftwidth = 2
vim.bo[event.buf].softtabstop = 2
vim.bo[event.buf].expandtab = true
end,
})

autocmd({ "FileType" }, {
group = augroups.filetype,
pattern = { "go", "make" },
callback = function()
set.expandtab = false
set.tabstop = 4
set.shiftwidth = 4
set.softtabstop = 4
callback = function(event)
vim.bo[event.buf].expandtab = false
vim.bo[event.buf].tabstop = 4
vim.bo[event.buf].shiftwidth = 4
vim.bo[event.buf].softtabstop = 4
end,
})

Expand Down
26 changes: 23 additions & 3 deletions dot_config/nvim/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,33 @@ else
-- automatically hide and show the command line
vim.o.ch = 0

-- Run `chezmoi apply` whenever its configuration is modified.
-- Run `chezmoi apply` asynchronously whenever its source files are saved.
-- Uses jobstart to avoid blocking the UI; errors are reported via vim.notify.
local augroups = require("user.augroups")
vim.api.nvim_create_autocmd("BufWritePost", {
group = augroups.chezmoi,
pattern = vim.fn.expand("~") .. "/.local/share/chezmoi/*",
command = "silent! !chezmoi apply --no-tty --force --source-path '%'",
callback = function(event)
local source_path = vim.api.nvim_buf_get_name(event.buf)
vim.fn.jobstart({ "chezmoi", "apply", "--no-tty", "--force", "--source-path", source_path }, {
on_exit = function(_, code)
if code ~= 0 then
vim.schedule(function()
vim.notify("chezmoi apply failed (exit " .. code .. ")", vim.log.levels.ERROR)
end)
end
end,
})
end,
})

-- Python
local xdg_data = os.getenv("XDG_DATA_HOME") or (os.getenv("HOME") .. "/.local/share")
local python3 = xdg_data .. "/pyenv/versions/neovim/bin/python3"
if vim.uv.fs_stat(python3) then
vim.g.python3_host_prog = python3
end

-- Files to ignore
-- Python
vim.opt.wildignore:append("*.pyc,*.pyo,*/__pycache__/*")
Expand All @@ -39,7 +58,8 @@ else
-- Use ripgrep when available
if vim.fn.executable("rg") == 1 then
vim.o.grepprg = "rg --no-heading --vimgrep"
vim.o.grepformat = "f:%l:%c:%m"
-- https://neovim.io/doc/user/quickfix.html#errorformat
vim.o.grepformat = "%f:%l:%c:%m"
end
end

Expand Down
20 changes: 8 additions & 12 deletions dot_config/nvim/lsp/gopls.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@ return {
cmd = { "gopls" },
filetypes = { "go", "gomod", "gowork", "gotmpl", "gosum" },
root_markers = { "go.mod", "go.work", ".git" },
init_options = {
usePlaceholders = true,
},
settings = {
gopls = {
settings = {
gopls = {
experimentalPostfixCompletions = true,
analyses = {
unusedparams = true,
shadow = true,
},
staticcheck = true,
},
},
init_options = {
usePlaceholders = true,
experimentalPostfixCompletions = true,
analyses = {
unusedparams = true,
shadow = true,
},
staticcheck = true,
},
},
}
14 changes: 5 additions & 9 deletions dot_config/nvim/lua/plugins/code.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ return {
cond = profile.active("default"),
ft = "lua", -- only load on lua files
opts = {
-- It can also be a table with trigger words / mods
-- Only load luvit types when the `vim.uv` word is found
{ path = "${3rd}/luv/library", words = { "vim%.uv" } },
-- Only load the lazyvim library when the `LazyVim` global is found
{ path = "LazyVim", words = { "LazyVim" } },
library = {
-- Only load luvit types when the `vim.uv` word is found
{ path = "${3rd}/luv/library", words = { "vim%.uv" } },
},
},
},

Expand Down Expand Up @@ -55,10 +54,7 @@ return {
{ "<leader>mm", "<Cmd>Mason<CR>", desc = "Packages" },
},
},
{
"neovim/nvim-lspconfig",
dependencies = { "saghen/blink.cmp" },
},
{ "neovim/nvim-lspconfig" },
},
},

Expand Down
4 changes: 3 additions & 1 deletion dot_config/nvim/lua/plugins/editor.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
local profile = require("user.profile")

---@type LazySpec
return {
"psliwka/vim-smoothie",
{
"lewis6991/gitsigns.nvim",
cond = profile.active("default"),
dependencies = { "nvim-lua/plenary.nvim" },
},
-- Flash enhances the built-in search functionality by showing labels
Expand Down
3 changes: 3 additions & 0 deletions dot_config/nvim/lua/plugins/linux/telescope-media-files.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
local profile = require("user.profile")

---@type LazySpec
return {
{
"nvim-telescope/telescope-media-files.nvim",
cond = profile.active("default"),
dependencies = {
"nvim-telescope/telescope.nvim",
"nvim-lua/popup.nvim",
Expand Down
5 changes: 1 addition & 4 deletions dot_config/nvim/lua/plugins/ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ return {
end,
dependencies = { "kkharji/sqlite.lua" },
},
{
"nvim-lualine/lualine.nvim",
dependencies = { "kyazdani42/nvim-web-devicons" },
},
{ "nvim-lualine/lualine.nvim" },
{ "akinsho/toggleterm.nvim", cond = profile.active("default") },
}
1 change: 0 additions & 1 deletion dot_config/nvim/lua/user/keymaps.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ utils.nmap("<leader>s", "<Cmd>w<CR>")
-- Navigation hotkeys
utils.nmap("<C-c>", "<Cmd>q<CR>")
utils.nmap("<C-q>", "<Cmd>q!<CR>")
utils.inoremap("<Caps_Lock>", "<Esc>")
utils.inoremap("jk", "<Esc>")
utils.inoremap("kj", "<Esc>")

Expand Down
40 changes: 29 additions & 11 deletions dot_config/nvim/lua/user/lsp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ local augroups = require("user.augroups")
-- Format on save
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroups.lsp,
-- todo: use file types? pattern = { "terraform", "go" },
pattern = { "*.tf", "*.tfvars" },
pattern = { "*.tf", "*.tfvars", "*.go" },
callback = vim.lsp.buf.format,
})

Expand All @@ -41,7 +40,22 @@ local utils = require("user.utils")
vim.api.nvim_create_autocmd("LspAttach", {
group = augroups.lsp,
callback = function(attach)
utils.nmap("<leader>fb", vim.lsp.buf.format, { buffer = true, desc = "[F]ormat [B]uffer" })
-- Buffer-scoped keymaps: only active while an LSP client is attached
local buf_opts = { buffer = attach.buf }
utils.nmap("<leader>fb", vim.lsp.buf.format, vim.tbl_extend("force", buf_opts, { desc = "[F]ormat [B]uffer" }))
utils.nmap("gd", vim.lsp.buf.definition, vim.tbl_extend("force", buf_opts, { desc = "[G]oto [D]efinition" }))
utils.nmap("gD", vim.lsp.buf.declaration, vim.tbl_extend("force", buf_opts, { desc = "[G]oto [D]eclaration" }))
utils.nmap(
"<leader>ca",
vim.lsp.buf.code_action,
vim.tbl_extend("force", buf_opts, { desc = "[C]ode [A]ction" })
)
utils.nmap("<leader>rn", vim.lsp.buf.rename, vim.tbl_extend("force", buf_opts, { desc = "[R]e[n]ame" }))
utils.nmap(
"<leader>D",
vim.lsp.buf.type_definition,
vim.tbl_extend("force", buf_opts, { desc = "Type [D]efinition" })
)

local client = assert(vim.lsp.get_client_by_id(attach.data.client_id))
if client:supports_method(vim.lsp.protocol.Methods.textDocument_documentHighlight) then
Expand All @@ -57,15 +71,19 @@ vim.api.nvim_create_autocmd("LspAttach", {
group = augroups.lsp,
callback = vim.lsp.buf.clear_references,
})
end
end,
})

-- When LSP detaches: Clears the highlighting
vim.api.nvim_create_autocmd("LspDetach", {
group = augroups.lsp,
callback = function(detach)
vim.lsp.buf.clear_references()
vim.api.nvim_clear_autocmds({ group = augroups.lsp, buffer = detach.buf })
end,
})
-- Top-level (not inside LspAttach) to avoid registering a new handler on every attach.
-- Only clears buffer autocmds when no LSP clients remain.
vim.api.nvim_create_autocmd("LspDetach", {
group = augroups.lsp,
callback = function(detach)
vim.lsp.buf.clear_references()
local remaining = vim.lsp.get_clients({ bufnr = detach.buf })
if #remaining == 0 then
vim.api.nvim_clear_autocmds({ group = augroups.lsp, buffer = detach.buf })
end
end,
})
1 change: 1 addition & 0 deletions dot_config/nvim/lua/user/options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ local options = {
autoindent = true,

-- Navigation
smoothscroll = true,
title = true,
number = true,
relativenumber = true,
Expand Down
2 changes: 1 addition & 1 deletion dot_config/nvim/lua/user/plugin_manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if not vim.uv.fs_stat(lazypath) then
"git",
"clone",
"--filter=blob:none",
"gh:folke/lazy.nvim.git",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
Expand Down
5 changes: 3 additions & 2 deletions dot_config/zsh/dot_zshrc.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,10 @@ autoload -Uz tldr-fzf
{{- if eq .chezmoi.os "darwin" }}
fpath+="$(brew --prefix)/share/zsh/site-functions"
{{ end }}
fpath+="$HOME/.rustup/toolchains/stable-x86_64-apple-darwin/share/zsh/site-functions"
fpath+="$HOME/.docker/completions"
fpath+=($HOME/.rustup/toolchains/stable-x86_64-apple-darwin/share/zsh/site-functions(N/))
fpath+=($HOME/.docker/completions(N/))
fpath+="$XDG_DATA_HOME/zsh/completions"
fpath+=($XDG_DATA_HOME/uv/tools/argcomplete/lib/python*/site-packages/argcomplete/bash_completion.d(N))

autoload -Uz compinit && compinit
autoload -Uz select-word-style && select-word-style bash
Expand Down