├── home ├── fish_config │ ├── conf.d │ │ └── rustup.fish │ ├── config.fish │ ├── functions │ │ └── fish_prompt.fish │ └── fish_variables ├── .gitignore ├── .zshenv ├── .zshrc ├── .config │ └── nvim │ │ └── init.lua ├── .gitconfig └── .tmux.conf ├── playbooks ├── inventory ├── osx.yml ├── ubuntu.yml └── roles │ ├── common │ └── tasks │ │ └── main.yml │ ├── osx │ └── tasks │ │ └── main.yml │ └── ubuntu │ └── tasks │ └── main.yml ├── .gitignore ├── launch ├── zshrc ├── prompt.zsh ├── key-bindings.zsh ├── aliases.zsh ├── zinit.zsh └── configs.zsh ├── LICENSE ├── README.md └── CLAUDE.md /home/fish_config/conf.d/rustup.fish: -------------------------------------------------------------------------------- 1 | source "$HOME/.cargo/env.fish" 2 | -------------------------------------------------------------------------------- /playbooks/inventory: -------------------------------------------------------------------------------- 1 | [local] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /home/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.pyc 3 | .codeintel/config 4 | .pylintrc 5 | venv 6 | nmvg/ 7 | a.out -------------------------------------------------------------------------------- /playbooks/osx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: local 3 | roles: 4 | - role: osx 5 | - role: common 6 | -------------------------------------------------------------------------------- /playbooks/ubuntu.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: local 3 | roles: 4 | - role: ubuntu 5 | - role: common 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # do not leak internal company details 2 | home/fish_config/config_local.fish 3 | 4 | # Claude Code workspace files 5 | .claude/ 6 | -------------------------------------------------------------------------------- /launch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $(uname) == 'Linux' ]]; then 4 | ansible-playbook -i playbooks/inventory playbooks/ubuntu.yml --ask-become-pass 5 | else 6 | ansible-playbook -i playbooks/inventory playbooks/osx.yml 7 | fi 8 | -------------------------------------------------------------------------------- /zshrc/prompt.zsh: -------------------------------------------------------------------------------- 1 | # Do a custom prompt stolen from steeeef theme 2 | setopt prompt_subst 3 | 4 | turquoise="%F{cyan}" 5 | orange="%F{yellow}" 6 | purple="%F{magenta}" 7 | limegreen="%F{green}" 8 | PR_RST="%f" 9 | 10 | PROMPT=$' 11 | %{$purple%}%n${PR_RST} at %{$orange%}%m${PR_RST} in %{$limegreen%}%~${PR_RST} 12 | $ ' 13 | -------------------------------------------------------------------------------- /home/.zshenv: -------------------------------------------------------------------------------- 1 | # 2 | # Defines environment variables. 3 | # 4 | # Authors: 5 | # Sorin Ionescu 6 | # 7 | 8 | # Ensure that a non-login, non-interactive shell has a defined environment. 9 | if [[ ( "$SHLVL" -eq 1 && ! -o LOGIN ) && -s "${ZDOTDIR:-$HOME}/.zprofile" ]]; then 10 | source "${ZDOTDIR:-$HOME}/.zprofile" 11 | fi 12 | . "$HOME/.cargo/env" 13 | -------------------------------------------------------------------------------- /zshrc/key-bindings.zsh: -------------------------------------------------------------------------------- 1 | # alt-left and alt-right for switching words in terminal 2 | # taken from https://github.com/solnic/dotfiles/blob/master/home/zsh/key-bindings.zsh 3 | bindkey -e 4 | 5 | bindkey '^H' delete-word # iterm 6 | bindkey '^[[3~' delete-char # tmux 7 | 8 | bindkey '^[[1;9D' backward-word # iterm 9 | bindkey '^[^[[D' backward-word # tmux os x 10 | bindkey '^[[1;3D' backward-word # tmux ubuntu 11 | 12 | bindkey '^[[1;9C' forward-word # iterm 13 | bindkey '^[^[[C' forward-word # tmux os x 14 | bindkey '^[[1;3C' forward-word # tmux ubuntu 15 | -------------------------------------------------------------------------------- /playbooks/roles/common/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Symlink my dotfiles 3 | file: src=~/dotfiles/home/{{ item }} 4 | dest=~/{{ item }} 5 | state=link 6 | force=yes 7 | with_items: 8 | - .zshrc 9 | - .zshenv 10 | - .gitignore 11 | - .gitconfig 12 | - .tmux.conf 13 | - .config/nvim 14 | 15 | 16 | - name: Clone tmux plugins 17 | git: repo=https://github.com/tmux-plugins/tpm dest=~/.tmux/plugins/tpm 18 | 19 | 20 | - name: Install/update tmux plugins 21 | command: ~/.tmux/plugins/tpm/bin/update_plugins all 22 | 23 | - name: Install/update VIM plugins 24 | command: vim +PluginInstall! +qall 25 | -------------------------------------------------------------------------------- /home/.zshrc: -------------------------------------------------------------------------------- 1 | source "$HOME/dotfiles/zshrc/aliases.zsh" 2 | source "$HOME/dotfiles/zshrc/configs.zsh" 3 | source "$HOME/dotfiles/zshrc/key-bindings.zsh" 4 | source "$HOME/dotfiles/zshrc/prompt.zsh" 5 | source "$HOME/dotfiles/zshrc/zinit.zsh" 6 | 7 | # Source configuration for local machine if it exists 8 | [ -f ~/.zshrc.local ] && source "$HOME/.zshrc.local" 9 | 10 | # The next line updates PATH for the Google Cloud SDK. 11 | if [ -f '/opt/homebrew/share/google-cloud-sdk/path.zsh.inc' ]; then . '/opt/homebrew/share/google-cloud-sdk/path.zsh.inc'; fi 12 | 13 | # The next line enables shell command completion for gcloud. 14 | if [ -f '/opt/homebrew/share/google-cloud-sdk/completion.zsh.inc' ]; then . '/opt/homebrew/share/google-cloud-sdk/completion.zsh.inc'; fi 15 | -------------------------------------------------------------------------------- /home/fish_config/config.fish: -------------------------------------------------------------------------------- 1 | # Disable fish greeting message 2 | set -g fish_greeting 3 | 4 | if status is-interactive 5 | # Replace core utils 6 | alias cat='bat' 7 | alias diff='delta' 8 | alias find='fd' 9 | alias ls='eza' 10 | 11 | # Make core utils better 12 | export TIME_STYLE=long-iso # makes YYYY-MM-DD in the ls output 13 | export BLOCK_SIZE="'1" # makes 1,000,000 for big sizes 14 | 15 | # Common commands 16 | alias reload='source ~/.config/fish/config.fish' 17 | alias netest='ping 8.8.8.8' 18 | 19 | # Shorthands 20 | alias e="exit" 21 | alias h='history -t -500' 22 | end 23 | 24 | # Load local machine config 25 | if test -f ~/.config/fish/config_local.fish 26 | source ~/.config/fish/config_local.fish 27 | end 28 | -------------------------------------------------------------------------------- /playbooks/roles/osx/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - community.general.homebrew: 3 | update_homebrew: true 4 | upgrade_all: true 5 | name: 6 | - ack 7 | - bat 8 | - curl 9 | - eza 10 | - fish 11 | - git 12 | - jq 13 | - nmap 14 | - node 15 | - python 16 | - readline 17 | - ssh-copy-id 18 | - vim 19 | - wget 20 | - zsh 21 | - httpie 22 | - tree 23 | - openssl 24 | - coreutils 25 | - findutils 26 | - mosh 27 | - htop 28 | - tmux 29 | - ripgrep 30 | - fd 31 | - sd 32 | - delta 33 | - gh 34 | 35 | - name: Cleanup Brew packages 36 | command: brew cleanup 37 | 38 | - name: 'Save screenshots to Downloads' 39 | shell: defaults write com.apple.screencapture location ~/Downloads 40 | -------------------------------------------------------------------------------- /home/.config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | -- Minimal Neovim configuration in Lua 2 | 3 | -- Hide splash screen 4 | vim.opt.shortmess:append("I") 5 | 6 | -- Essential settings 7 | vim.opt.number = true -- Show line numbers 8 | vim.opt.mouse = 'a' -- Enable mouse 9 | vim.opt.expandtab = true -- Use spaces instead of tabs 10 | vim.opt.tabstop = 2 -- 2 spaces for tab 11 | vim.opt.shiftwidth = 2 -- 2 spaces for indentation 12 | vim.opt.ignorecase = true -- Case insensitive search 13 | vim.opt.smartcase = true -- Unless capital letters are used 14 | vim.opt.hlsearch = true -- Highlight search results 15 | vim.opt.incsearch = true -- Search as you type 16 | 17 | -- Leader key 18 | vim.g.mapleader = "," 19 | 20 | -- Clipboard integration with macOS 21 | vim.keymap.set({"n", "v"}, "y", '"+y') 22 | vim.keymap.set("n", "yy", '"+yy') 23 | 24 | -- Keep search results centered with context 25 | vim.opt.scrolloff = 8 26 | -------------------------------------------------------------------------------- /playbooks/roles/ubuntu/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Update repositories cache 3 | become: true 4 | ansible.builtin.apt: 5 | update_cache: yes 6 | 7 | - name: Install libraries using apt 8 | become: true 9 | ansible.builtin.apt: 10 | name: 11 | - ack-grep 12 | - bash 13 | - bat 14 | - curl 15 | - fd-find 16 | - fish 17 | - git 18 | - htop 19 | - nmap 20 | - nodejs 21 | - mosh 22 | - most 23 | - ripgrep 24 | - vim 25 | - tmux 26 | - wget 27 | - zsh 28 | - jq 29 | - delta 30 | - gh 31 | 32 | - name: Remove useless packages from the cache 33 | become: true 34 | ansible.builtin.apt: 35 | autoclean: yes 36 | 37 | - name: Remove dependencies that are no longer required and purge their configuration files 38 | become: true 39 | ansible.builtin.apt: 40 | autoremove: yes 41 | purge: true 42 | 43 | - name: Run "apt clean" 44 | become: true 45 | ansible.builtin.command: apt-get clean 46 | -------------------------------------------------------------------------------- /zshrc/aliases.zsh: -------------------------------------------------------------------------------- 1 | # Replace core utils with modern alternatives (matching Fish config) 2 | alias cat='bat' 3 | alias diff='delta' 4 | alias ls='eza' 5 | 6 | # Use Neovim instead of Vim 7 | alias vim='nvim' 8 | alias vi='nvim' 9 | 10 | # Make core utils better 11 | export TIME_STYLE=long-iso # makes YYYY-MM-DD in the ls output 12 | export BLOCK_SIZE="'1" # makes 1,000,000 for big sizes 13 | 14 | # Common commands 15 | alias reload='source ~/.zshrc' 16 | alias netest='ping 8.8.8.8' 17 | alias simple='python2 -m SimpleHTTPServer' 18 | alias hgrep='history -fd 0 | grep' 19 | 20 | # Important files 21 | alias zshrc="vim ~/.zshrc" 22 | alias vimrc="vim ~/.vimrc" 23 | 24 | # Shorthands 25 | alias e="exit" 26 | alias h='history -fd -500' 27 | 28 | # Analyze history data 29 | analyze_history(){ 30 | cut -f2 -d";" ~/.zsh_history | sort | uniq -c | sort -nr | head -n 30 31 | } 32 | analyze_commands(){ 33 | cut -f2 -d";" ~/.zsh_history | cut -d' ' -f1 | sort | uniq -c | sort -nr | head -n 30 34 | } 35 | 36 | # Suffix aliases 37 | alias -s log=less 38 | alias -s html=open 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Alex Palcuie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /home/fish_config/functions/fish_prompt.fish: -------------------------------------------------------------------------------- 1 | function fish_prompt --description 'Write out the prompt' 2 | set -l last_status $status 3 | set -l normal (set_color normal) 4 | set -l status_color (set_color brgreen) 5 | set -l cwd_color (set_color $fish_color_cwd) 6 | set -l vcs_color (set_color brpurple) 7 | set -l prompt_status "" 8 | 9 | # Since we display the prompt on a new line allow the directory names to be longer. 10 | set -q fish_prompt_pwd_dir_length 11 | or set -lx fish_prompt_pwd_dir_length 0 12 | 13 | # Color the prompt differently when we're root 14 | set -l suffix '❯' 15 | if functions -q fish_is_root_user; and fish_is_root_user 16 | if set -q fish_color_cwd_root 17 | set cwd_color (set_color $fish_color_cwd_root) 18 | end 19 | set suffix '#' 20 | end 21 | 22 | # Color the prompt in red on error 23 | if test $last_status -ne 0 24 | set status_color (set_color $fish_color_error) 25 | set prompt_status $status_color "[" $last_status "]" $normal 26 | end 27 | 28 | echo -s (prompt_login) ' ' $cwd_color (prompt_pwd) $vcs_color (fish_vcs_prompt) $normal ' ' $prompt_status 29 | echo -n -s $status_color $suffix ' ' $normal 30 | end 31 | -------------------------------------------------------------------------------- /home/fish_config/fish_variables: -------------------------------------------------------------------------------- 1 | # This file contains fish universal variable definitions. 2 | # VERSION: 3.0 3 | SETUVAR __fish_initialized:3400 4 | SETUVAR fish_color_autosuggestion:brblack 5 | SETUVAR fish_color_cancel:\x2dr 6 | SETUVAR fish_color_command:blue 7 | SETUVAR fish_color_comment:red 8 | SETUVAR fish_color_cwd:green 9 | SETUVAR fish_color_cwd_root:red 10 | SETUVAR fish_color_end:green 11 | SETUVAR fish_color_error:brred 12 | SETUVAR fish_color_escape:brcyan 13 | SETUVAR fish_color_history_current:\x2d\x2dbold 14 | SETUVAR fish_color_host:normal 15 | SETUVAR fish_color_host_remote:yellow 16 | SETUVAR fish_color_normal:normal 17 | SETUVAR fish_color_operator:brcyan 18 | SETUVAR fish_color_param:cyan 19 | SETUVAR fish_color_quote:yellow 20 | SETUVAR fish_color_redirection:cyan\x1e\x2d\x2dbold 21 | SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack 22 | SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack 23 | SETUVAR fish_color_status:red 24 | SETUVAR fish_color_user:brgreen 25 | SETUVAR fish_color_valid_path:\x2d\x2dunderline 26 | SETUVAR fish_key_bindings:fish_default_key_bindings 27 | SETUVAR fish_pager_color_completion:normal 28 | SETUVAR fish_pager_color_description:yellow\x1e\x2di 29 | SETUVAR fish_pager_color_prefix:normal\x1e\x2d\x2dbold\x1e\x2d\x2dunderline 30 | SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan 31 | SETUVAR fish_pager_color_selected_background:\x2dr 32 | SETUVAR fish_user_paths:/opt/homebrew/bin 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dotfiles by Alex Palcuie 2 | 3 | Hacking like a geek: 4 | 5 | * the `playbooks` folder contains Ansible that provisions a machine with apps and configs 6 | * the `launch` script auto-detects OS and runs the appropriate playbook 7 | * **Shell preferences**: 8 | * **Mac**: Zsh with Zinit plugin manager (syntax highlighting, autosuggestions, z jumping) 9 | * **Ubuntu/Debian**: Fish (primary shell) 10 | * my main machine is a Mac, I have a work dev Debian machine, and my server is running Ubuntu 11 | * Neovim as primary editor (aliased to vim) 12 | * Modern CLI tools: `bat` (better cat), `eza` (better ls), `fd` (better find), `rg` (better grep) 13 | 14 | ## Setup for a new Mac machine 15 | 16 | 1. Install XCode tools using `xcode-select --install` 17 | 2. Install [Brew](http://brew.sh/) 18 | 3. Install Ansible using Brew `brew install ansible` 19 | 4. As a convention `~/dotfiles` should be this repo 20 | 21 | ```bash 22 | git clone https://github.com/palcu/dotfiles.git ~/dotfiles 23 | ``` 24 | 5. Install [XQuartz](https://xquartz.macosforge.org/landing/) 25 | 6. Run the Ansible playbook for Mac 26 | 27 | ```bash 28 | ./launch 29 | ``` 30 | 31 | ## Setup for a new Linux machine 32 | 33 | We need a version of Ansible greater than 2.0. 34 | 35 | ```bash 36 | sudo apt-add-repository ppa:ansible/ansible 37 | sudo apt-get update 38 | sudo apt-get install ansible software-properties-common git 39 | git clone https://github.com/palcu/dotfiles.git ~/dotfiles 40 | cd ~/dotfiles 41 | ./launch 42 | ``` 43 | 44 | ## Sources of inspiration 45 | 46 | Thank you for all the people who've published their useful configs. 47 | 48 | * http://dotfiles.github.io 49 | * https://github.com/holman/dotfiles 50 | * https://github.com/mgax/dotfiles 51 | * https://github.com/razvand/snippets 52 | * https://github.com/pivotal/vim-config 53 | * https://github.com/pivotal/dotfiles 54 | -------------------------------------------------------------------------------- /home/.gitconfig: -------------------------------------------------------------------------------- 1 | [user] 2 | name = Alex Palcuie 3 | email = alex.palcuie@gmail.com 4 | signingKey = key::ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBA3aYoDA0xhWQAYZZFQL8JHoIQKT+558Gl8ySChIjlBy0HeT5HjegclrUH4FBp0WRM+B/URhg8T5zzzjgAkW0m0= ecdsa-sha2-nistp256 5 | [core] 6 | editor = vim 7 | excludesfile = ~/.gitignore 8 | attributesfile = ~/.gitattributes 9 | [web] 10 | browser = google-chrome 11 | [merge] 12 | tool = vimdiff 13 | [color] 14 | ui = auto 15 | interactive = auto 16 | [push] 17 | default = current 18 | [alias] 19 | co = checkout 20 | cm = commit 21 | st = status -sb 22 | br = branch 23 | undo = reset --hard HEAD 24 | amend = commit --amend -a 25 | graph = log --graph 26 | ignore = update-index --assume-unchanged 27 | unignore = update-index --no-assume-unchanged 28 | ignored = !git ls-files -v | grep "^[[:lower:]]" 29 | sweep = !git fsck && git gc && git remote update --prune && git stash clear 30 | update = !git checkout master && git checkout - && git merge master 31 | recent = !git branch --sort=-committerdate | head 32 | [log] 33 | abbrevCommit = true 34 | decorate = true 35 | [format] 36 | pretty = %C(yellow)%h%C(white)%d%Creset %s %C(cyan)(%cr) %C(bold blue)<%an>%Creset 37 | [filter "media"] 38 | required = true 39 | clean = git media clean %f 40 | smudge = git media smudge %f 41 | [diff] 42 | algorithm = patience 43 | [help] 44 | autocorrect = 1 45 | [branch "master"] 46 | remote = origin 47 | merge = refs/heads/master 48 | [filter "hawser"] 49 | clean = git hawser clean %f 50 | smudge = git hawser smudge %f 51 | required = true 52 | [filter "lfs"] 53 | clean = git-lfs clean -- %f 54 | smudge = git-lfs smudge -- %f 55 | process = git-lfs filter-process 56 | required = true 57 | [include] 58 | path = ~/.gitconfiglocal 59 | [gpg] 60 | format = ssh 61 | [commit] 62 | gpgsign = true 63 | [gpg "ssh"] 64 | defaultKeyCommand = ssh-add -L 65 | [fetch] 66 | prune = true 67 | -------------------------------------------------------------------------------- /zshrc/zinit.zsh: -------------------------------------------------------------------------------- 1 | ### Zinit Plugin Manager ### 2 | 3 | # Install Zinit if not present 4 | if [[ ! -f $HOME/.local/share/zinit/zinit.git/zinit.zsh ]]; then 5 | print -P "%F{33} %F{220}Installing %F{33}ZDHARMA-CONTINUUM%F{220} Initiative Plugin Manager (%F{33}zdharma-continuum/zinit%F{220})…%f" 6 | command mkdir -p "$HOME/.local/share/zinit" && command chmod g-rwX "$HOME/.local/share/zinit" 7 | command git clone https://github.com/zdharma-continuum/zinit "$HOME/.local/share/zinit/zinit.git" && \ 8 | print -P "%F{33} %F{34}Installation successful.%f%b" || \ 9 | print -P "%F{160} The clone has failed.%f%b" 10 | fi 11 | 12 | source "$HOME/.local/share/zinit/zinit.git/zinit.zsh" 13 | autoload -Uz _zinit 14 | (( ${+_comps} )) && _comps[zinit]=_zinit 15 | 16 | # Load a few important annexes, without Turbo 17 | # (this is currently required for annexes) 18 | zinit light-mode for \ 19 | zdharma-continuum/zinit-annex-as-monitor \ 20 | zdharma-continuum/zinit-annex-bin-gem-node \ 21 | zdharma-continuum/zinit-annex-patch-dl \ 22 | zdharma-continuum/zinit-annex-rust 23 | 24 | # Zinit plugins 25 | # Load syntax highlighting with turbo mode (after prompt) 26 | zinit wait lucid for \ 27 | light-mode zsh-users/zsh-syntax-highlighting 28 | 29 | # Load these immediately (needed for interactive use) 30 | zinit light zsh-users/zsh-autosuggestions 31 | zinit light zsh-users/zsh-completions 32 | 33 | # Z - Jump to frequently used directories 34 | zinit light agkozak/zsh-z 35 | 36 | # FZF-tab - Use fzf for tab completion (the nice scrolly thing) 37 | zinit light Aloxaf/fzf-tab 38 | 39 | # iTerm2 Shell Integration 40 | zinit snippet "https://iterm2.com/shell_integration/zsh" 41 | 42 | # FZF - Fuzzy Finder (better Ctrl+R and more) 43 | zinit ice from"gh-r" as"program" 44 | zinit light junegunn/fzf 45 | 46 | # FZF shell integration for key bindings and completion 47 | zinit snippet "https://github.com/junegunn/fzf/raw/master/shell/key-bindings.zsh" 48 | zinit snippet "https://github.com/junegunn/fzf/raw/master/shell/completion.zsh" 49 | 50 | # Skip compinit here if already initialized elsewhere 51 | # This avoids duplicate initialization and speeds up startup 52 | 53 | # Zinit completions compilation 54 | # Only run if compinit has been called 55 | (( ${+_comps} )) && zinit cdreplay -q -------------------------------------------------------------------------------- /home/.tmux.conf: -------------------------------------------------------------------------------- 1 | ### Settings 2 | 3 | # Start windows from 1, because that is my layout on the keyboard 4 | set -g base-index 1 5 | 6 | ### Bindings 7 | 8 | # Set prefix as in the old screen 9 | set -g prefix C-a 10 | bind-key C-a send-prefix 11 | unbind-key C-b 12 | # Fast switching between the previous windows with C-a-a-a-a 13 | bind-key C-a last-window 14 | # I can C-c C-c to create a new window 15 | bind-key C-c neww 16 | 17 | # Reload tmux config 18 | bind r source-file ~/.tmux.conf 19 | 20 | ### Status Bar - Custom Modern Theme 21 | # Status bar positioning and general settings 22 | set -g status-position bottom 23 | set -g status-justify left 24 | set -g status-style 'bg=#1e1e2e fg=#cdd6f4' 25 | set -g status-left-length 100 26 | set -g status-right-length 100 27 | 28 | # Left side: Session name with icon 29 | set -g status-left '#[fg=#1e1e2e,bg=#89b4fa,bold] ❐ #S #[fg=#89b4fa,bg=#313244] ' 30 | 31 | # Right side: Git branch, directory, time, and date 32 | set -g status-right '#[fg=#f38ba8,bg=#313244] %H:%M #[fg=#1e1e2e,bg=#f38ba8] %d %b ' 33 | 34 | # Window status formats 35 | set-window-option -g window-status-format '#[fg=#6c7086,bg=#313244] #I:#W ' 36 | set-window-option -g window-status-current-format '#[fg=#1e1e2e,bg=#a6e3a1,bold] #I:#W ' 37 | set-window-option -g window-status-separator '' 38 | 39 | # Pane borders 40 | set -g pane-border-style 'fg=#313244' 41 | set -g pane-active-border-style 'fg=#89b4fa' 42 | 43 | # Message style 44 | set -g message-style 'fg=#cdd6f4 bg=#313244' 45 | 46 | ### Mouse 47 | set-option -g mouse on 48 | 49 | ### Plugins 50 | set -g @plugin 'tmux-plugins/tpm' 51 | # Default sensible configs that I do not have to specify 52 | set -g @plugin 'tmux-plugins/tmux-sensible' 53 | # Navigate between panes wih hjkl and create them with - and | 54 | set -g @plugin 'tmux-plugins/tmux-pain-control' 55 | # Persistent sessions even on restart 56 | set -g @plugin 'tmux-plugins/tmux-resurrect' 57 | set -g @plugin 'tmux-plugins/tmux-continuum' 58 | # C-/ will search for something on my screen 59 | set -g @plugin 'tmux-plugins/tmux-copycat' 60 | # In copy mode I can press o and it will open that URL/file 61 | set -g @plugin 'tmux-plugins/tmux-open' 62 | 63 | 64 | # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) 65 | run '~/.tmux/plugins/tpm/tpm' 66 | -------------------------------------------------------------------------------- /zshrc/configs.zsh: -------------------------------------------------------------------------------- 1 | export EDITOR="nvim" 2 | export LC_ALL="en_US.UTF-8" 3 | export LANG="en_US.UTF-8" 4 | export PATH=$PATH:$HOME/dotfiles/scripts 5 | export TERM='xterm-256color' 6 | 7 | # Remove annoying ZSH messages and beeping 8 | unsetopt correctall 9 | unsetopt BEEP # No bell on error 10 | unsetopt LIST_BEEP # No bell on ambiguous completion 11 | unsetopt HIST_BEEP # No bell on history errors 12 | 13 | # allow # in a comment 14 | setopt interactivecomments 15 | 16 | # Directory navigation improvements 17 | setopt AUTO_CD # Type directory name to cd into it 18 | setopt AUTO_PUSHD # Make cd push old directory onto stack 19 | setopt PUSHD_IGNORE_DUPS # No duplicates in directory stack 20 | setopt CDABLE_VARS # cd to variable values 21 | 22 | # make the autosuggestions work with solarized 23 | ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=value' 24 | 25 | # Use completion-based suggestions instead of history 26 | ZSH_AUTOSUGGEST_STRATEGY=(completion) 27 | # Only show suggestions when buffer has at least 2 characters 28 | ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=50 29 | ZSH_AUTOSUGGEST_COMPLETION_IGNORE="?(#c0,1)" # Ignore patterns with 0-1 characters 30 | 31 | # History configuration 32 | export HISTFILE="$HOME/.zsh_history" 33 | export HISTSIZE=1000000 # Number of commands to keep in memory 34 | export SAVEHIST=1000000 # Number of commands to save to disk 35 | export HISTFILESIZE=2000000 # Maximum number of lines in history file 36 | 37 | # History options for better syncing 38 | setopt EXTENDED_HISTORY # Save timestamp and duration 39 | setopt INC_APPEND_HISTORY # Write to history file immediately, not when shell exits 40 | setopt SHARE_HISTORY # Share history between all sessions 41 | setopt HIST_EXPIRE_DUPS_FIRST # Expire duplicate entries first when trimming history 42 | setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again 43 | setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate 44 | 45 | # Completion system customization 46 | zstyle ':completion:*' menu select # Interactive menu selection 47 | zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' # Case insensitive matching 48 | zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} # Colored completion list 49 | zstyle ':completion:*:descriptions' format '' # Hide group descriptions 50 | zstyle ':completion:*:warnings' format 'No matches for: %d' # Warning for no matches 51 | zstyle ':completion:*' group-name '' # Group results by type 52 | -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | # CLAUDE.md 2 | 3 | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. 4 | 5 | ## Repository Overview 6 | 7 | This is a personal dotfiles repository that uses Ansible to automate the provisioning of development machines (Mac, Ubuntu, and Debian). The repository manages shell configurations, Neovim setup, tmux configuration, and various development tools. 8 | 9 | ### Shell Preferences 10 | - **Mac**: Zsh is the primary shell 11 | - **Ubuntu/Debian**: Zsh is the primary shell 12 | 13 | ## Key Commands 14 | 15 | ### Provisioning a Machine 16 | ```bash 17 | # Run from the repository root 18 | ./launch 19 | 20 | # Or manually for specific OS: 21 | # Mac: 22 | ansible-playbook -i playbooks/inventory playbooks/osx.yml 23 | 24 | # Linux: 25 | ansible-playbook -i playbooks/inventory playbooks/ubuntu.yml --ask-become-pass 26 | ``` 27 | 28 | ### Common Tasks 29 | - **Reload shell config**: 30 | - Zsh (Mac/Ubuntu/Debian): `source ~/.zshrc` 31 | - **Neovim**: No plugins currently configured (minimal setup) 32 | - **Update tmux plugins**: `~/.tmux/plugins/tpm/bin/update_plugins all` 33 | 34 | ## Architecture 35 | 36 | ### Directory Structure 37 | - `playbooks/` - Ansible playbooks and roles for provisioning 38 | - `roles/common/` - Tasks for all platforms (dotfile symlinks, VIM/tmux setup) 39 | - `roles/osx/` - Mac-specific configurations 40 | - `roles/ubuntu/` - Ubuntu/Linux-specific configurations 41 | - `home/` - Dotfiles that get symlinked to the home directory 42 | - `.config/nvim/` - Neovim configuration 43 | - `fish_config/` - Fish shell configuration (symlinked to `~/.config/fish`) 44 | - Various dotfiles (.tmux.conf, .gitconfig, .zshrc, etc.) 45 | - `zshrc/` - Modular Zsh configuration files (aliases, configs, key-bindings, prompt) 46 | 47 | ### Key Design Decisions 48 | 1. **Symlink Strategy**: All dotfiles remain in the repository and are symlinked to their expected locations using Ansible's `file` module with `state=link` and `force=yes` 49 | 2. **Shell Support**: 50 | - **Mac/Ubuntu/Debian**: Zsh as primary shell with Zinit plugin manager (includes syntax highlighting, autosuggestions, z jumping, and fzf) 51 | - Zsh configured with modern CLI replacements (bat→cat, eza→ls, rg→grep, fd→find, delta→diff, sd→sed) 52 | 3. **Plugin Management**: 53 | - Neovim uses minimal config with no plugins (by design) 54 | - Zsh uses Zinit for plugin management 55 | - tmux uses TPM (Tmux Plugin Manager) 56 | 4. **Local Overrides**: 57 | - Zsh: Machine-specific settings via `~/.zshrclocal` 58 | - Fish (legacy): Machine-specific settings via `~/.config/fish/config_local.fish` 59 | 60 | ### Important Implementation Details 61 | - The `launch` script auto-detects the OS and runs the appropriate playbook 62 | - Zsh config replaces core utilities with modern alternatives (bat, eza, ripgrep, fd, delta, sd) 63 | - VIM configuration includes NERDTree (F2 key), CtrlP for file search, and vim-go for Go development 64 | - All configurations are designed to be idempotent - safe to run multiple times --------------------------------------------------------------------------------