This repo contains my dotfile configuration
I manage the various configuration files in this repo using GNU Stow. This allows me to set up symlinks for all of my dotfiles using a single command:
stow -t ~ zsh
stow -t ~ config
stow -t ~ oh-my-zsh-custom
stow -t ~ binOptional: one-shot bootstrap (clones Oh My Zsh if missing + runs stow):
./script/bootstrapFull install (recommended on new machines): installs packages (macOS/Homebrew or Linux/apt), installs opencode, then runs bootstrap:
./script/installCommon options:
# core CLI only
./script/install --minimal
# skip GUI apps
./script/install --no-gui
# skip installing one of the AI tools
./script/install --no-opencode
./script/install --no-claude
# install a specific version
OPENCODE_VERSION=1.1.50 ./script/install
./script/install --claude-version 2.1.72- Custom theme lives in
$ZSH_CUSTOM(default:~/.config/oh-my-zsh), soomz updateworks. - Optional extras installed by `./script/bootstrap`:
- zsh-autosuggestions
- fast-syntax-highlighting
- fzf-tab
- History is shared across shells and stored under XDG state (default:
~/.local/state/zsh/history).
Quick examples:
# Update Oh My Zsh
omz update
# Run dotfiles health checks
./script/doctor
# fzf helper (defined in zsh/.zshrc)
feKeyboard hints:
- autosuggestions: accept suggestion with Right Arrow
- fzf-tab: use TAB completion then pick in the fzf UI
Terminal tip:
- Ctrl-S is enabled for Neovim/Kitty (XON/XOFF disabled via `stty -ixon` in `zsh/.zshrc`).
Key cheatsheet (from `config/.config/kitty/kitty.conf`):
splits:
Ctrl+Alt+Shift+Right vertical split (cwd=current)
Ctrl+Alt+Shift+Down horizontal split (cwd=current)
focus split:
Ctrl+Alt+Arrow keys
resize:
Ctrl+Alt+r resize mode
tabs:
Ctrl+Alt+t new tab (cwd=current)
Ctrl+Tab next tab
Ctrl+Shift+Tab previous tab
Ctrl+Alt+w close tab
zoom:
Ctrl+Alt+z toggle stack layout
selection (rectangle mode, respects pane boundaries):
Ctrl+Alt+left drag select text in opencode without crossing to nvim
Quick session helpers (defined in `zsh/.zshrc`):
# Open the static, curated kitty session (tabs + splits)
marvin_session
# Open a dynamic session with one tab per repo under ~/Documents/github/perso
# - Tabs are sorted by most recent commit
# - Inside kitty: uses remote control to populate current window
# - Outside kitty: spawns a new kitty window using a generated session file
# (written to XDG state: ~/.local/state/kitty/github-session.conf)
# - Each tab starts in nvim, then drops you into a shell when you quit nvim
github-session- This repo commits `config/.config/nvim/lazy-lock.json` so plugin versions are reproducible across machines.
- By default, `./script/bootstrap` will not overwrite an existing
~/.config/nvim/lazy-lock.json. - Recent edits are briefly highlighted (10s) so you can spot changes from tools like opencode.
- File explorer (LazyVim / neo-tree) opens by default on startup (disable with `NVIM_NO_EXPLORER=1`).
Use the repo lockfile on a machine that already has a local one:
mv ~/.config/nvim/lazy-lock.json ~/.config/nvim/lazy-lock.json.bak
./script/bootstrapScripts utilitaires stowés dans ~/.local/bin via le package bin.
hide-celluloid— toggle minimize/restore de Celluloid (lecteur vidéo). Utile comme “panic button” pour cacher rapidement une vidéo en cours de lecture, même si la fenêtre n’a pas le focus. Dépend dexdotooletxprop(X11).
Raccourci clavier (Cinnamon, non versionné car dans dconf) — à rejouer une fois sur une nouvelle machine :
# Libère la touche Calculatrice (par défaut: lance la calculette)
dconf write /org/cinnamon/desktop/keybindings/media-keys/calculator "@as []"
# Associe la touche Calculatrice au toggle Celluloid
dconf write /org/cinnamon/desktop/keybindings/custom-keybindings/custom0/name "'Hide Celluloid'"
dconf write /org/cinnamon/desktop/keybindings/custom-keybindings/custom0/command "'/home/$USER/.local/bin/hide-celluloid'"
dconf write /org/cinnamon/desktop/keybindings/custom-keybindings/custom0/binding "['XF86Calculator']"
dconf write /org/cinnamon/desktop/keybindings/custom-list "['custom0']"This dotfiles supports two AI coding assistants running in parallel:
- **OpenCode** (primary) - For general coding tasks
- **Claude Code** (secondary) - For complex reasoning with Claude 4.6 Sonnet
They are independent tools — OpenCode runs a local server, Claude Code is a direct CLI authenticated via browser (Claude Pro/Max subscription).
This repo ships a small, safe subset of opencode state as templates:
- UI preferences: `opencode-state/.local/state/opencode/kv.json`
- Recent models: `opencode-state/.local/state/opencode/model.json` (deepseek, GPT-5)
- System prompt: `opencode-state/.local/state/opencode/system_prompt.md`
- Configuration: `opencode-state/.config/opencode/opencode.json`
- TUI settings: `opencode-state/.config/opencode/tui.json`
- Environment optimizations: `opencode-state/.config/opencode/env.sh`
Claude Code stores sessions under ~/.claude/ (managed by the CLI itself).
This repo tracks only:
- Global system prompt:
claude-state/CLAUDE.md→ deployed to~/.claude/CLAUDE.md - Settings:
claude-state/settings.json→ deployed to~/.claude.json
Auth is browser-based — no API key needed (requires Claude Pro/Max subscription):
claude --login- Prompts templates: `shared-prompts/` (code-review, documentation, etc.)
- Shell aliases: `zsh/.zshrc.d/{opencode,claude}.zsh`
Both intentionally do not sync:
- prompt history (`prompt-history.jsonl`)
- usage/frecency stats (`frecency.jsonl`)
If you already have local state on a machine and want to adopt the repo defaults:
mv ~/.local/state/opencode/kv.json ~/.local/state/opencode/kv.json.bak
mv ~/.local/state/opencode/model.json ~/.local/state/opencode/model.json.bak
./script/bootstrapIf you want to explicitly sync your current (safe) local state back into the repo templates:
./script/opencode sync pushBoth assistants have unified management scripts:
# Show unified help
./script/opencode help
# Check overall status
./script/opencode status
# Run health checks
./script/opencode doctor
# Shell aliases (added by zsh/.zshrc.d/opencode.zsh):
oc help # Show help
oc status # Check status
oc doctor # Run health checks
ocsetup # Apply optimizations
ocmem # Monitor memory
ocpush # Save config to dotfiles
ocpull # Apply templates# Show help
./script/claude help
# Check status
./script/claude status
# Run health checks
./script/claude doctor
# Sync system prompt / settings to/from dotfiles
./script/claude sync push # Save ~/.claude/CLAUDE.md to repo
./script/claude sync pull # Apply repo templates to ~/.claude/
# Shell aliases (added by zsh/.zshrc.d/claude.zsh):
ccstatus # Check status
ccdoctor # Run health checks
ccpush # Save config to dotfiles
ccpull # Apply templates| Feature | OpenCode | Claude Code |
|---|---|---|
| **Default Model** | user-chosen (model.json) | claude-4.6-sonnet (direct) |
| **Auth** | API key / OpenRouter | Browser login (Claude Pro/Max) |
| **Architecture** | Local server (long-running) | CLI tool (per-invocation) |
| **Neovim Prefix** | <leader>a | <leader>z |
| **Shell Aliases** | oc* | cc* |
Common prompt templates available in shared-prompts/:
code-review.md— comprehensive code review checklistdocumentation.md— API and code documentation generator
These work with both assistants.
Quick setup on a new machine:
# Install both tools
cd ~/Documents/github/perso/dotfiles
./script/install # Installs opencode + claude CLI
# Authenticate Claude Code (browser-based, one-time)
claude --login
# Apply repo config templates
./script/opencode sync pull # Apply opencode templates
./script/claude sync pull # Apply CLAUDE.md system prompt
# Verify
./script/opencode status
./script/claude statusBoth assistants run as right-side terminal splits:
OpenCode (prefix: <leader>a) Claude Code (prefix: <leader>z)
================================ ================================
<leader>at Toggle split <leader>zt Toggle split
<leader>aa Ask (@this) <leader>za Ask (input/selection)
<leader>abb Send current buffer <leader>zb Send buffer
<leader>zp Paste selection (visual)
<leader>zh Focus split (insert)
Operators (OpenCode only):
go<motion> Send range to opencode (e.g. goip, gow)
# Quick start commands
ocpush && ccpush # Sync both to dotfiles
ocpull && ccpull # Apply templates on new machine
# AI assistant summary
ai-summary # Shows side-by-side overviewKey cheatsheet (custom additions in this repo):
save:
à (insert) save + exit insert
à (normal) save
<C-s> save (layout-agnostic)
<leader>w save (layout-agnostic)
telescope:
<leader>« fuzzy find in current buffer
<leader>sb fuzzy find in current buffer (layout-agnostic)
codeium (ghost text):
<C-l> accept suggestion (Codeium)
<M-Right> next suggestion
<M-Left> previous suggestion
<M-Down> clear suggestion
opencode.nvim (<leader>a menu):
Session management:
<leader>aa Ask (@this)
<leader>an New session
<leader>au Undo last action
<leader>ar Redo
<leader>ac Compact session
<leader>as Select session
<leader>aS Share session
<leader>at Toggle opencode
<leader>ax Execute action
Prompts (<leader>ap):
<leader>ape Explain @this
<leader>apf Fix @diagnostics
<leader>apr Review @this
<leader>apd Document @this
<leader>apo Optimize @this
<leader>apt Add tests
Context/Buffers (<leader>ab):
<leader>abb Send current buffer
<leader>aba Send all buffers
<leader>abv Send visible text
<leader>abd Send diagnostics
Navigation:
<S-C-u> Half page up
<S-C-d> Half page down
Operator (go + motion):
go<motion> Send range (ex: goip, gow, go$)
goo Send current line
Troubleshooting / Performance:
- Memory issues: Use `./script/opencode memory monitor` to check usage
- High memory: Run `./script/opencode memory cleanup` to clear cache
- Stuck models: Check timeout settings in `opencode-state/.config/opencode/opencode.json`
- Context limits: 200K tokens max, 200 messages per session
claude.lua (<leader>z):
<leader>zt Toggle Claude split
<leader>zh Focus Claude split (insert mode)
<leader>za Ask Claude (input prompt / visual selection)
<leader>zb Send current buffer to Claude
<leader>zp Paste visual selection as code block
<Esc> Interrupt Claude (Ctrl-C) in terminal mode
<C-w>p Return to code window from Claude terminal
poetry runner (Python projects):
<leader>pr Run current Python file via poetry in toggleterm
:PoetryRun Execute current file (auto-detects project root from pyproject.toml)
ToggleTerm (terminal management):
<C-t> Toggle terminal (from any mode, including terminal insert)
<leader>tt Toggle terminal (float)
<Esc> Exit terminal insert mode (then use <leader>tt or <C-t>)
<leader>tf Floating terminal
<leader>th Horizontal terminal
<leader>tv Vertical terminal
<leader>t1 Terminal 1
<leader>t2 Terminal 2
<leader>t3 Terminal 3
<leader>ts Select terminal
<leader>tg Lazygit
nvim-dap (Node.js debugging in Docker):
Prerequisites:
- Docker container with Node.js running in debug mode (port 567xx)
- Auto-detection scans ports 56700-56800
Debug controls:
<leader>dc Start/Continue debugging (auto-detects port or shows menu)
<leader>db Toggle breakpoint on current line
<leader>ds Step over (execute current line, move to next)
<leader>di Step into (enter function call)
<leader>do Step out (exit current function)
<leader>dx Stop debugging session
<leader>dr Open REPL console
<leader>dl Run last debug configuration
<leader>dt Toggle DAP UI (scopes, stack, watches)
Workflow:
1. Start Docker container with Node.js debug port exposed (e.g., 56745)
2. In nvim, place breakpoint: <leader>db on desired line
3. Start debugging: <leader>dc (auto-detects port or asks)
4. Navigate: <leader>ds (step over), <leader>di (step into)
5. Inspect: Hover variables or toggle UI with <leader>dt
6. Stop: <leader>dx when done
Features:
- Virtual text: Variable values displayed inline
- Auto-detection: Scans for Node.js debug ports automatically
- Port selection: Menu when multiple containers detected
- Manual input: Enter port if auto-detection fails
- Scopes panel: View all variables in current context
- Call stack: Navigate through function calls
- REPL: Execute JavaScript expressions during debug
New plugins (diffview, dadbod, lazydocker, markdown-preview, undotree):
diffview (git diff viewer):
<leader>gd Open diff view (compare working tree)
<leader>gh Open file history
<leader>gq Close diff view
<tab> Select next entry
<s-tab> Select previous entry
s Stage/unstage file
S Stage all files
U Unstage all files
X Restore entry
gf Go to file
vim-dadbod (database client):
UI (db explorer):
<leader>mu Toggle DB UI
<leader>mf Find DB buffer
<leader>mr Rename DB buffer
<leader>ml Show last query info
DBUI navigation:
<CR>/o Open/expand (table helpers, buffers, etc.)
S Open in vertical split
R Redraw
H Toggle connection details
Results navigation (wide tables):
zl/zh Scroll right/left
zL/zH Scroll right/left faster
Shift+wheel Scroll right/left (in db output)
Marvin SQL workflow (project-specific auto-connection + runner):
<leader>ms Execute SQL statement under cursor
<leader>mS Execute whole buffer
<leader>mo Toggle results output (bottom split)
Connection auto-resolution:
- Applies for files under app/entrypoints/postgres/clients/**/<client>/sql/**/*.sql
- Default dbname = <client> extracted from the path
- Optional override: first line "-- dbname: xxx"
- Credentials come from the shell / project .env (no secrets committed)
Vars (local): POSTGRES_LOCAL_USERNAME/PASSWORD/HOST/PORT
Vars (prod): POSTGRES_USERNAME/PASSWORD/HOST/PORT
- Password is URL-encoded when building the DSN
Switch env without restarting:
:MarvinDbMode local
:MarvinDbMode prod
lazydocker (Docker TUI in terminal):
<leader>td Open LazyDocker (floating terminal)
Note: Requires lazydocker installed on system
markdown-preview (live preview in browser):
<leader>mp Toggle markdown preview
Note: Opens in default browser, auto-updates on edit
undotree (visual undo history):
<leader>tu Toggle undotree panel
j/k Navigate history tree
u Undo to selected state
<CR> Revert to selected state
Search/replace tips:
in file:
:%s/old/new/gc replace with confirmation
fast iterative replace:
/pattern
cgn change match
n + . next + repeat
UI replace:
<leader>sr opens grug-far (if installed)
IDE-like workflow tips (LazyVim):
discover keymaps:
<leader> shows which-key menu
common LSP:
K hover docs
gd go to definition
gr references
<leader>rn rename
<leader>ca code action
diagnostics:
<leader>xx diagnostics list (Trouble)
eza (modern ls replacement with icons):
ls List files with icons and colors
ll List files in long format with icons
la List all files including hidden
lt List files as a tree
llt List files in long format as a tree
zoxide (smart cd command):
cd <dir> Navigate to directory (with fuzzy matching)
cdi Interactive directory selection with fzf
z <pattern> Jump to directory matching pattern
zi Interactive directory selection
delta (syntax-highlighting pager for git):
git diff Shows colored side-by-side diff
git log Shows colored log output
git show Shows colored commit/diff output
bottom (modern system monitor):
btm Launch interactive system monitor
top Alias for btm
htop Alias for btm
This repo does not stow into ~/.oh-my-zsh anymore.
- Keep
~/.oh-my-zshas a clean git checkout soomz updateworks. - Put custom themes/plugins under
$ZSH_CUSTOM(defaults to~/.config/oh-my-zshinzsh/.zshrc).
Install Oh My Zsh (git clone):
git clone https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zshCustom theme is shipped by this repo here:
- `oh-my-zsh-custom/.config/oh-my-zsh/themes/adrien-agnoster.zsh-theme`
If you need machine-specific paths or secrets, put them in ~/.zshrc.local.
Example template:
- `zsh/.zshrc.local.example`
If you previously overrode the theme inside ~/.oh-my-zsh, remove that symlink so OMZ can update.
Typical fix:
rm -f ~/.oh-my-zsh/themes/agnoster.zsh-theme
cd ~/.oh-my-zsh && git checkout -- themes/agnoster.zsh-theme