Last active
January 20, 2026 18:45
-
-
Save shawndumas/8810f160d6f71eed6328ad2df3f16ec1 to your computer and use it in GitHub Desktop.
dotfiles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [user] | |
| email = me@shawndumas.com | |
| name = Shawn Dumas | |
| [help] | |
| autocorrect = 5 | |
| [push] | |
| default = current | |
| autoSetupRemote = true | |
| [color] | |
| status = auto | |
| branch = auto | |
| ui = auto | |
| [core] | |
| excludesfile = /Users/shawndumas/.gitignore_global | |
| trustctime = false | |
| [alias] | |
| lg = log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %an)%Creset' --abbrev-commit --date=relative --graph | |
| s = status -s | |
| st = status | |
| ci = commit | |
| cp = cherry-pick | |
| br = branch | |
| co = checkout | |
| rc = rebase --continue | |
| dc = diff --cached | |
| prune-all = !git remote | xargs -n 1 git remote prune | |
| edit-unmerged = "!f() { git diff --name-status --diff-filter=U | cut -f2 ; }; vim `f`" | |
| add-unmerged = "!f() { git diff --name-status --diff-filter=U | cut -f2 ; }; git add `f`" | |
| hotspots = "!sh -c 'git log --pretty=format: --name-only | sort | uniq -c | sort -rg | head -50'" | |
| alias = "!sh -c '[ $# = 2 ] && git config --global alias.\"$1\" \"$2\"' && exit 0 || echo \"usage: git alias <new alias>\"" | |
| aliases = !git config --get-regexp 'alias.*' | colrm 1 6 | sed 's/[ ]/ = /' | |
| unmerge = reset --merge ORIG_HEAD | |
| stash-unapply = !git stash show -p | git apply -R | |
| purge = !git fetch --all && git remote prune origin | |
| find-in-reflog = "!f() { git reflog --all | while read commit rest; do git ls-tree -r $commit 2>/dev/null | grep \"$1\" && echo \"Found in: $commit\"; done; }; f" | |
| wt-add = worktree add | |
| wt-ls = worktree list | |
| wt-l = worktree lock | |
| wt-mv = worktree move | |
| wt-p = worktree prune | |
| wt-rm = worktree remove | |
| wt-r = worktree repair | |
| wt-ul = worktree unlock | |
| rm-gone = !git branch -vv | grep \": gone]\" | awk \"{print \\$1}\" | xargs -r git branch -D | |
| ls-gone = !git branch -vv | grep \": gone]\" | |
| base-main = !git merge-base HEAD main | |
| wip = !git add -A && git commit -m \"wip: $(date)\" | |
| undo = reset --soft HEAD~1 | |
| squash= "!f() { target=${1:-main}; git reset --soft $(git merge-base HEAD $target); echo 'Ready to commit squashed changes.'; }; f" | |
| pf = push --force-with-lease | |
| dm = diff main...HEAD | |
| [rerere] | |
| enabled = 1 | |
| [pull] | |
| ff = only | |
| rebase = true | |
| [diff] | |
| tool = gitkraken | |
| [difftool] | |
| prompt = false | |
| [difftool "gitkraken"] | |
| cmd = open -a GitKraken | |
| [merge] | |
| tool = gitkraken | |
| [mergetool] | |
| prompt = false | |
| keepBackup = false | |
| [mergetool "gitkraken"] | |
| cmd = "/Applications/GitKraken.app/Contents/Resources/app.asar.unpacked/src/js/redux/domain/InterApp/cli.js" merge "$LOCAL" "$REMOTE" "$BASE" "$MERGED" | |
| trustExitCode = true | |
| [filter "lfs"] | |
| process = git-lfs filter-process | |
| required = true | |
| clean = git-lfs clean -- %f | |
| smudge = git-lfs smudge -- %f |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| " Auto-install vim-plug if missing | |
| if empty(glob('~/.vim/autoload/plug.vim')) | |
| silent !mkdir -p ~/.vim/autoload | |
| silent !curl -fLo ~/.vim/autoload/plug.vim | |
| \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim | |
| autocmd VimEnter * PlugInstall --sync | source $MYVIMRC | |
| endif | |
| " Plugins | |
| " ------- | |
| call plug#begin('~/.vim/plugged') | |
| " Navigation & Movement | |
| Plug 'justinmk/vim-sneak' | |
| " Editing Enhancements (tpope collection) | |
| Plug 'tpope/vim-commentary' " gc to comment | |
| Plug 'tpope/vim-surround' " cs, ds, ys for surrounding text | |
| Plug 'tpope/vim-repeat' " Make . work with plugins | |
| Plug 'tpope/vim-abolish' " Smart substitution & abbreviations | |
| Plug 'tpope/vim-unimpaired' " Bracket mappings ]b, [b, etc. | |
| Plug 'tpope/vim-eunuch' " Unix commands (:Rename, :Move, etc.) | |
| " Git Integration | |
| Plug 'tpope/vim-fugitive' " Git commands & workflow | |
| call plug#end() | |
| " Basic Settings | |
| " -------------- | |
| syntax enable | |
| set nocompatible | |
| filetype plugin indent on | |
| let mapleader = ' ' | |
| let maplocalleader = ' ' | |
| " Editor Behavior | |
| set autoindent | |
| set autoread | |
| set backspace=indent,eol,start | |
| set complete=.,w,b,u,t,i,kspell | |
| set directory=$HOME/.vim/swaps//,~/tmp,/var/tmp,/tmp | |
| set expandtab | |
| set hidden | |
| set hlsearch | |
| set ignorecase | |
| set incsearch | |
| set laststatus=2 | |
| set listchars=tab:⇒\ ,eol:↩︎,trail:•,nbsp:• | |
| set mouse=a | |
| set nobackup | |
| set nofoldenable | |
| set nolist | |
| set noshowmode | |
| set nowritebackup | |
| set nrformats= | |
| set number | |
| set ruler | |
| set scrolloff=3 | |
| set shiftwidth=2 | |
| set showbreak=⤿ | |
| set showcmd | |
| set showmatch | |
| set smartcase | |
| set smarttab | |
| set softtabstop=2 | |
| set nospell | |
| set spelllang=en_us | |
| set splitbelow | |
| set splitright | |
| set tabstop=2 | |
| set title | |
| set ttimeout | |
| set ttimeoutlen=50 | |
| set ttyfast | |
| set visualbell | |
| set wildignorecase | |
| set wildignore=log/**,node_modules/**,target/**,tmp/**,*.pyc,*.o,*.swp | |
| set wildmenu | |
| set wildmode=longest,list,full | |
| set nowrap | |
| " Appearance | |
| set background=dark | |
| try | |
| colorscheme habamax | |
| catch | |
| colorscheme default | |
| endtry | |
| " Persistent Undo | |
| if has('persistent_undo') | |
| set undodir=~/.vim/undo// | |
| set undofile | |
| set undolevels=1000 | |
| set undoreload=10000 | |
| if !isdirectory(&undodir) | |
| call mkdir(&undodir, "p", 0700) | |
| endif | |
| endif | |
| " Status Line | |
| set statusline=%f\ %m%=%y\ %{&fileencoding?&fileencoding:&encoding}\ [%{&fileformat}]\ %p%%\ %l:%c | |
| " Highlight trailing whitespace | |
| highlight ExtraWhitespace ctermbg=red guibg=red | |
| match ExtraWhitespace /\s\+$/ | |
| " Core Key Mappings | |
| " ----------------- | |
| " Better navigation for wrapped lines | |
| nnoremap j gj | |
| nnoremap k gk | |
| " Yank to end of line (consistent with C and D) | |
| nnoremap Y y$ | |
| " Keep search matches centered | |
| nnoremap n nzz | |
| nnoremap N Nzz | |
| nnoremap * *zz | |
| nnoremap # #zz | |
| nnoremap G Gzz | |
| nnoremap } }zz | |
| nnoremap { {zz | |
| " Clear search highlighting | |
| nnoremap <silent> <F5> :nohlsearch<CR><C-l> | |
| " Search with very magic mode by default | |
| nnoremap / /\v | |
| vnoremap / /\v | |
| " Visual mode keeps selection after indent | |
| xnoremap > >gv | |
| xnoremap < <gv | |
| " Quick save and quit | |
| nnoremap <leader>w :w<CR> | |
| nnoremap <leader>q :q<CR> | |
| " Buffer navigation | |
| nnoremap <leader>b :ls<CR>:b<space> | |
| nnoremap <leader>] :bnext<CR> | |
| nnoremap <leader>[ :bprevious<CR> | |
| " Window management | |
| nnoremap <C-h> <C-w>h | |
| nnoremap <C-j> <C-w>j | |
| nnoremap <C-k> <C-w>k | |
| nnoremap <C-l> <C-w>l | |
| " Toggle settings | |
| nnoremap <leader>ow :set wrap!<CR> | |
| nnoremap <leader>ol :set list!<CR> | |
| nnoremap <leader>os :set spell!<CR> | |
| " Git Mappings (Fugitive) | |
| " ----------------------- | |
| nnoremap <leader>gb :Git blame<CR> | |
| nnoremap <leader>gc :Git commit<CR> | |
| nnoremap <leader>gd :Gdiff<CR> | |
| nnoremap <leader>gl :Git log<CR> | |
| nnoremap <leader>gp :Git push<CR> | |
| nnoremap <leader>gs :Git status -sb<CR> | |
| nnoremap <leader>gw :Gwrite<CR> | |
| nnoremap <leader>gr :Gread<CR> | |
| " Vim-Sneak Configuration | |
| " ----------------------- | |
| " Use \ and | for sneak (your old mappings) | |
| nmap \ <Plug>Sneak_s | |
| nmap <bar> <Plug>Sneak_S | |
| xmap \ <Plug>Sneak_s | |
| xmap <bar> <Plug>Sneak_S | |
| omap \ <Plug>Sneak_s | |
| omap <bar> <Plug>Sneak_S | |
| " Special Functions | |
| " ----------------- | |
| " Search current selection in visual mode | |
| function! s:VSetSearch() | |
| let temp = @s | |
| norm! gv"sy | |
| let @/ = '\V' . substitute(escape(@s, '/\'), '\n', '\\n', 'g') | |
| let @s = temp | |
| normal `` | |
| endfunction | |
| xnoremap * :<C-u>call <SID>VSetSearch()<CR>/<C-R>=@/<CR><CR> | |
| xnoremap # :<C-u>call <SID>VSetSearch()<CR>?<C-R>=@/<CR><CR> | |
| " Execute macro over visual selection | |
| xnoremap @ :<C-u>call ExecuteMacroOverVisualRange()<CR> | |
| function! ExecuteMacroOverVisualRange() | |
| echo "@".getcmdline() | |
| execute ":'<,'>normal @".nr2char(getchar()) | |
| endfunction | |
| " Remove fancy Unicode characters | |
| function! RemoveFancyCharacters() | |
| let typo = {} | |
| let typo["""] = '"' | |
| let typo["""] = '"' | |
| let typo["'"] = "'" | |
| let typo["'"] = "'" | |
| let typo["–"] = '--' | |
| let typo["—"] = '---' | |
| let typo["…"] = '...' | |
| :exe ":%s/".join(keys(typo), '\|').'/\=typo[submatch(0)]/ge' | |
| endfunction | |
| command! RemoveFancyCharacters :call RemoveFancyCharacters() | |
| " Search with ripgrep or ag if available | |
| if executable('rg') | |
| set grepprg=rg\ --vimgrep\ --smart-case\ --follow | |
| elseif executable('ag') | |
| set grepprg=ag\ --vimgrep | |
| endif | |
| " Auto Commands | |
| " ------------- | |
| augroup vimrc | |
| autocmd! | |
| " Cursorline only in active window | |
| autocmd WinEnter * set cursorline | |
| autocmd WinLeave * set nocursorline | |
| " Auto-resize windows when Vim is resized | |
| autocmd VimResized * :wincmd = | |
| " Return to last edit position when opening files | |
| autocmd BufReadPost * | |
| \ if line("'\"") > 0 && line("'\"") <= line("$") | | |
| \ exe "normal! g'\"" | | |
| \ endif | |
| " Auto-save when focus is lost | |
| autocmd FocusLost * silent! wa | |
| " File type specific settings | |
| autocmd FileType python setlocal shiftwidth=4 tabstop=4 | |
| autocmd FileType go setlocal noexpandtab | |
| autocmd FileType markdown setlocal wrap linebreak spell | |
| autocmd FileType gitcommit setlocal spell | |
| augroup END | |
| " Quick Edit Vimrc | |
| nnoremap <leader>ev :vsplit $MYVIMRC<CR> | |
| nnoremap <leader>sv :source $MYVIMRC<CR> | |
| " Performance | |
| set lazyredraw | |
| set synmaxcol=200 | |
| " Better file finding | |
| set path+=** | |
| " Security | |
| set exrc | |
| set secure | |
| " vim: set ft=vim: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ------------------------------- | |
| # Terminal Settings | |
| # ------------------------------- | |
| # Disable mouse tracking to prevent scroll issues in TUI apps | |
| printf '\e[?1000l\e[?1002l\e[?1003l\e[?1006l' | |
| # ------------------------------- | |
| # Shell Options | |
| # ------------------------------- | |
| setopt autocd | |
| setopt correct | |
| setopt checkjobs | |
| setopt hist_ignore_dups | |
| setopt hist_find_no_dups | |
| setopt append_history | |
| setopt inc_append_history | |
| setopt prompt_subst | |
| # ------------------------------- | |
| # History Settings | |
| # ------------------------------- | |
| export HISTFILE=~/.zsh_eternal_history | |
| export HISTSIZE=100000 | |
| export SAVEHIST=100000 | |
| export HISTTIMEFORMAT="[%F %T] " | |
| # ------------------------------- | |
| # Default Editor | |
| # ------------------------------- | |
| export GIT_EDITOR=vim | |
| export VISUAL=vim | |
| export EDITOR=vim | |
| # ------------------------------- | |
| # Aliases | |
| # ------------------------------- | |
| alias t='git ' | |
| alias rm='rm -i' | |
| alias cp='cp -i' | |
| alias mv='mv -i' | |
| alias ls='ls -G' | |
| alias fn='find . -name' | |
| alias c='ncal -A 1 -B 1' | |
| # ------------------------------- | |
| # Vi Mode and Key Bindings | |
| # ------------------------------- | |
| bindkey -v | |
| export KEYTIMEOUT=1 | |
| ZSH_VI_MODE=insert # Initialize vi mode state | |
| # Enable edit-command-line (press 'v' in normal mode to open vim) | |
| autoload -Uz edit-command-line | |
| zle -N edit-command-line | |
| bindkey -M vicmd 'v' edit-command-line | |
| # History search with arrow keys | |
| autoload -Uz up-line-or-beginning-search down-line-or-beginning-search | |
| zle -N up-line-or-beginning-search | |
| zle -N down-line-or-beginning-search | |
| bindkey '^[[A' up-line-or-beginning-search | |
| bindkey '^[[B' down-line-or-beginning-search | |
| # vi-insert mode keybindings | |
| bindkey -M viins '^A' beginning-of-line | |
| bindkey -M viins '^E' end-of-line | |
| bindkey -M viins '^K' kill-line | |
| bindkey -M viins '^L' clear-screen | |
| bindkey -M viins '^Y' insert-last-word | |
| # vi-command mode keybindings | |
| bindkey -M vicmd '^A' beginning-of-line | |
| bindkey -M vicmd '^E' end-of-line | |
| bindkey -M vicmd '^K' kill-line | |
| bindkey -M vicmd '^L' clear-screen | |
| bindkey -M viins '^Y' insert-last-word | |
| # Magic space (expands aliases and history) | |
| bindkey ' ' magic-space | |
| # ------------------------------- | |
| # Prompt: clean, color-coded, fast | |
| # ------------------------------- | |
| # Current directory, shortened like ~/proj/dir | |
| function prompt_dir { | |
| print -P "%F{cyan}%~%f" | |
| } | |
| # Git branch + dirty indicator | |
| function prompt_git { | |
| local branch git_status dirty | |
| if command git rev-parse --is-inside-work-tree &>/dev/null; then | |
| branch=$(git symbolic-ref --short HEAD 2>/dev/null || git describe --tags --exact-match 2>/dev/null) | |
| # Check for changes | |
| git_status=$(git status --porcelain 2>/dev/null) | |
| if [[ -n "$git_status" ]]; then | |
| # Staged changes | |
| if echo "$git_status" | grep -q '^[MARCD]'; then dirty+=" %F{green}+%f"; fi | |
| # Unstaged changes | |
| if echo "$git_status" | grep -q '^[ MARCD]M'; then dirty+=" %F{yellow}*%f"; fi | |
| # Untracked files | |
| if echo "$git_status" | grep -q '??'; then dirty+=" %F{red}?%f"; fi | |
| fi | |
| # Check for ahead/behind remote | |
| local ahead behind | |
| ahead=$(git rev-list --count @{u}..HEAD 2>/dev/null) | |
| behind=$(git rev-list --count HEAD..@{u} 2>/dev/null) | |
| if [[ "$ahead" -gt 0 ]]; then dirty+=" %F{yellow}↑$ahead%f"; fi | |
| if [[ "$behind" -gt 0 ]]; then dirty+=" %F{cyan}↓$behind%f"; fi | |
| print -P " %F{white}git:($branch$dirty)%f" | |
| fi | |
| } | |
| # Exit code (only shown if non-zero) | |
| function prompt_status { | |
| [[ $? -ne 0 ]] && print -P "%F{red}✘%?%f" | |
| } | |
| # Vi mode indicator | |
| function prompt_vi_mode { | |
| if [[ ${ZSH_VI_MODE:-insert} == 'command' ]]; then | |
| print -P "%F{magenta}[N]%f" | |
| else | |
| print -P "%F{green}[I]%f" | |
| fi | |
| } | |
| # Full prompt builder | |
| function build_prompt { | |
| PROMPT='$(prompt_status) $(prompt_vi_mode) $(prompt_dir) $(prompt_git) | |
| %F{yellow}❯%f ' | |
| } | |
| # ------------------------------- | |
| # Vi-mode switch detection (ZLE-safe) | |
| # ------------------------------- | |
| function zle-keymap-select { | |
| if [[ $KEYMAP == vicmd ]]; then | |
| ZSH_VI_MODE=command | |
| else | |
| ZSH_VI_MODE=insert | |
| fi | |
| zle reset-prompt | |
| } | |
| zle -N zle-keymap-select | |
| # ------------------------------- | |
| # Hook into prompt events | |
| # ------------------------------- | |
| if [[ -o interactive ]]; then | |
| autoload -Uz add-zsh-hook | |
| add-zsh-hook precmd build_prompt | |
| fi | |
| git-wt-co() { | |
| local branch_name | |
| local no_cd=false | |
| # --- Argument Parsing --- | |
| # Loop through all arguments to find the flag and the branch name. | |
| for arg in "$@"; do | |
| case "$arg" in | |
| --no-cd) | |
| no_cd=true | |
| ;; | |
| *) | |
| # Assume the first non-flag argument is the branch name. | |
| if [ -z "$branch_name" ]; then | |
| branch_name="$arg" | |
| fi | |
| ;; | |
| esac | |
| done | |
| # --- Validation --- | |
| if [ -z "$branch_name" ]; then | |
| echo "Usage: git-wt-co <branch-name> [--no-cd]" | |
| return 1 | |
| fi | |
| # --- Worktree Creation --- | |
| local repo_name=$(basename "$(git rev-parse --show-toplevel)") | |
| local target_path="$HOME/wt/$repo_name/$branch_name" | |
| # Tries to create from remote; if that fails, creates a new local branch. | |
| if git worktree add -b "$branch_name" "$target_path" "origin/$branch_name" 2>/dev/null || git worktree add -b "$branch_name" "$target_path"; then | |
| if [ "$no_cd" = false ]; then | |
| cd "$target_path" | |
| else | |
| echo "[SUCCESS]: Worktree created at $target_path" | |
| fi | |
| else | |
| echo "[ERROR]: Worktree creation failed for $branch_name" | |
| return 1 | |
| fi | |
| } | |
| export PATH="/opt/homebrew/opt/ruby/bin:$PATH" | |
| export LDFLAGS="-L/opt/homebrew/opt/ruby/lib" | |
| export CPPFLAGS="-I/opt/homebrew/opt/ruby/include" | |
| # ------------------------------- | |
| # Confirmation | |
| # ------------------------------- | |
| echo ".zshrc loaded: $(date)" | |
| eval "$(/opt/homebrew/bin/brew shellenv)" | |
| # Fuzzy Finder (fzf) | |
| [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh | |
| export PATH="$HOME/.local/bin:$PATH" | |
| # Reddio Reddit CLI aliases | |
| alias reddio='~/.local/bin/reddio' # Base reddio command | |
| alias rhot='~/.local/bin/reddio print -l 10' # Hot posts | |
| alias rtop='~/.local/bin/reddio print -t day -l 10' # Top posts of the day | |
| alias rweek='~/.local/bin/reddio print -t week -l 10' # Top posts of the week | |
| alias rfront='~/.local/bin/reddio print -l 25 /' # Your frontpage | |
| alias rinbox='~/.local/bin/reddio print message/unread' # Unread messages | |
| alias rsaved='~/.local/bin/reddio print user/-nom-de-guerre-/saved' # Your saved posts | |
| alias rprofile='~/.local/bin/reddio print user/-nom-de-guerre-/about' # Your profile | |
| alias rsubmitted='~/.local/bin/reddio print user/-nom-de-guerre-/submitted' # Your posts | |
| alias rcommented='~/.local/bin/reddio print user/-nom-de-guerre-/comments' # Your comments | |
| # Use the rcomments function below instead of rread alias | |
| # Quick subreddit access | |
| alias rsd='~/.local/bin/reddio print -l 20 r/shadowdark' | |
| alias rfl='~/.local/bin/reddio print -l 20 r/flashlight' | |
| alias rsrpg='~/.local/bin/reddio print -l 20 r/Solo_Roleplaying' | |
| rprint() { | |
| ~/.local/bin/reddio print r/"$1" | |
| } | |
| # Functions for interactive use | |
| rcomments() { | |
| if [ -z "$1" ]; then | |
| echo "Usage: rcomments <post-id or url>" | |
| else | |
| ~/.local/bin/reddio print comments/"$1" | |
| fi | |
| } | |
| # Alternative name for reading posts | |
| rr() { | |
| if [ -z "$1" ]; then | |
| echo "Usage: rr <post-id or url>" | |
| else | |
| ~/.local/bin/reddio print comments/"$1" | |
| fi | |
| } | |
| rsearch() { | |
| if [ -z "$2" ]; then | |
| echo "Usage: rsearch <subreddit> <query>" | |
| else | |
| ~/.local/bin/reddio print -q "$2" "r/$1" | |
| fi | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment