├── .gitignore ├── Readme.md ├── git ├── gitconfig.user.symlink └── gitignore_global.symlink ├── node └── install.sh ├── npmrc.symlink ├── os └── install.sh ├── prettierrc.js.symlink ├── script ├── bootstrap.sh └── install ├── setup.sh ├── vim ├── install.sh ├── postinstall.sh └── vimrc.symlink └── zsh ├── install.sh ├── zsh.after.symlink ├── alias.zsh ├── antigen.config.zsh ├── path.zsh └── prompt.zsh └── zshrc.symlink /.gitignore: -------------------------------------------------------------------------------- 1 | # Common ignored files 2 | .git 3 | .vim 4 | CVS 5 | .svn 6 | .hg 7 | .lock-wscript 8 | .wafpickle-N 9 | *.swp 10 | .DS_Store 11 | ._* 12 | npm-debug.log 13 | *~ 14 | 15 | # Ignore vim plugins 16 | # We manage vim plugins using Plugged for Vim, which is set up by the installation scripts 17 | vim/**/plugged 18 | vim/**/plug.* 19 | vim/**/.netrwhist 20 | config.symlink/nvim 21 | 22 | # Ignore private config 23 | zprivate.symlink 24 | envvars.symlink 25 | 26 | # This symlink changes per-machine 27 | init.vim 28 | 29 | # Ignore vcs config in case it has per-machine settings 30 | git/gitconfig.symlink 31 | hg/hgrc.local.symlink 32 | 33 | # Ignore `curl`ed files 34 | antigen.zsh 35 | 36 | # Ignore generated/lockfiles 37 | # antigen.config.zsh.zwc 38 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Dotfiles: The Dan Eden Story 2 | 3 | I have no idea what I’m doing, but with any luck, that’ll change the more I use 4 | my own dotfiles. 5 | 6 | ## Installation 7 | 8 | 1. In your home folder (just type `cd` in terminal to get there, silly), run 9 | `git clone https://github.com/daneden/dotfiles .dotfiles` 10 | 2. Navigate to the cloned directory and run `./setup.sh` 11 | 3. Party. 12 | 13 | ## What's Inside? 14 | 15 | 1. A script that copies dotfiles to my home directory to configure things like 16 | git, vim, and zsh 17 | - This works by looking for files with a `.symlink` suffix 18 | 2. zsh configuration that provides a useful prompt and some aliases 19 | - The `prompt.zsh` file contains a lot of code copied from The Internet to 20 | get my git status to show in the prompt 21 | 3. git configuration that provides my own details and some aliases 22 | 4. vim configuration that provides some plugins and sets some preferences 23 | - To avoid bloating my dotfiles with overrides from e.g. oh-my-zsh, I've 24 | opted to write all my dotfiles using only built-in package managers and 25 | options. Vim is chief amongst examples of this, since my `.vimrc` is pretty 26 | long. 27 | 5. A Brewfile to install common apps and CLI tools I use frequently 28 | 6. Yarn/Node global package installation 29 | -------------------------------------------------------------------------------- /git/gitconfig.user.symlink: -------------------------------------------------------------------------------- 1 | [user] 2 | name = Daniel Eden 3 | email = dan.eden@me.com 4 | [core] 5 | editor = vim -c start 6 | excludesfile = ~/.gitignore_global 7 | [alias] 8 | # add 9 | aa = add . 10 | ap = add --patch 11 | 12 | # commit 13 | cm = commit -S 14 | 15 | # log 16 | lg = vlog --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%C(bold blue)<%an>%Creset' --abbrev-commit 17 | 18 | # push 19 | p = push 20 | 21 | # status 22 | s = status 23 | 24 | [diff] 25 | compactionHeuristic = true 26 | [pull] 27 | rebase = true 28 | [init] 29 | defaultBranch = main 30 | [filter "lfs"] 31 | clean = git-lfs clean -- %f 32 | smudge = git-lfs smudge -- %f 33 | process = git-lfs filter-process 34 | required = true 35 | [push] 36 | autoSetupRemote = true 37 | -------------------------------------------------------------------------------- /git/gitignore_global.symlink: -------------------------------------------------------------------------------- 1 | # Common ignored files 2 | .git 3 | CVS 4 | .svn 5 | .hg 6 | .lock-wscript 7 | .wafpickle-N 8 | *.swp 9 | .DS_Store 10 | ._* 11 | npm-debug.log 12 | *.un~ 13 | .sass-cache 14 | yarn-error.log 15 | -------------------------------------------------------------------------------- /node/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl https://get.volta.sh | bash 4 | 5 | volta install node typescript zx yarn -------------------------------------------------------------------------------- /npmrc.symlink: -------------------------------------------------------------------------------- 1 | init.author.name=Daniel Eden 2 | init.author.email=dan.eden@me.com 3 | init.author.url=https://daneden.me 4 | init.license=MIT 5 | init.version=0.0.1 6 | loglevel=silent 7 | allow-same-version=true 8 | -------------------------------------------------------------------------------- /os/install.sh: -------------------------------------------------------------------------------- 1 | if [ "$(uname)" == "Darwin" ]; then 2 | defaults write NSGlobalDomain KeyRepeat -int 1 3 | 4 | # Custom keyboard shortcuts 5 | # @: CMD 6 | # $: Shift 7 | # ~: Alt 8 | # ^: Ctrl 9 | TAB_KEY_SYMBOL="\\U21e5" # Note the backslash-escaped backslash. 10 | COMMAND_KEY_SYMBOL="@" 11 | SHIFT_KEY_SYMBOL="$" 12 | ENTER_KEY_SYMBOL="\\U21a9" 13 | defaults write com.apple.finder NSUserKeyEquivalents "{ 'Show Package Contents' = '${COMMAND_KEY_SYMBOL}${SHIFT_KEY_SYMBOL}O'; }" 14 | 15 | defaults write -g NSUserKeyEquivalents "{ 'Paste and Match Style' = '${COMMAND_KEY_SYMBOL}V'; }" 16 | defaults write -g NSUserKeyEquivalents "{ 'Zoom' = '${COMMAND_KEY_SYMBOL}${SHIFT_KEY_SYMBOL}M'; }" 17 | 18 | defaults write com.apple.Mail NSUserKeyEquivalents "{ 'Send' = '${COMMEND_KEY_SYMBOL}${ENTER_KEY_SYMBOL}'; }" 19 | defaults write com.apple.Mail NSUserKeyEquivalents "{ 'Archive' = '${COMMEND_KEY_SYMBOL}E'; }" 20 | fi 21 | -------------------------------------------------------------------------------- /prettierrc.js.symlink: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | singleQuote: false, 4 | tabWidth: 2, 5 | trailingComma: "es5", 6 | useTabs: false, 7 | proseWrap: "always", 8 | printWidth: 80, 9 | } 10 | -------------------------------------------------------------------------------- /script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # bootstrap installs things. 4 | 5 | while [[ $# > 1 ]] 6 | do 7 | key="$1" 8 | 9 | case $key in 10 | -u|--user) 11 | USER="$2" 12 | shift # past argument 13 | ;; 14 | *) 15 | # unknown option 16 | ;; 17 | esac 18 | shift # past argument or value 19 | done 20 | 21 | cd "$(dirname "$0")/.." 22 | DOTFILES_ROOT=$(pwd -P) 23 | 24 | echo '' 25 | 26 | info () { 27 | printf "\r [ \033[00;34m..\033[0m ] $1\n" 28 | } 29 | 30 | user () { 31 | printf "\r [ \033[0;33m??\033[0m ] $1\n" 32 | } 33 | 34 | success () { 35 | printf "\r\033[2K [ \033[00;32mOK\033[0m ] $1\n" 36 | } 37 | 38 | fail () { 39 | printf "\r\033[2K [\033[0;31mFAIL\033[0m] $1\n" 40 | echo '' 41 | exit 42 | } 43 | 44 | setup_gitconfig () { 45 | if ! [ -f "$DOTFILES_ROOT/git/gitconfig.user.symlink" ] 46 | then 47 | info 'setup gitconfig' 48 | 49 | git_credential='cache' 50 | if [ "$(uname -s)" == "Darwin" ] 51 | then 52 | git_credential='osxkeychain' 53 | fi 54 | 55 | user ' - What is your github author name?' 56 | read -e git_authorname 57 | user ' - What is your github author email?' 58 | read -e git_authoremail 59 | 60 | sed -e "s/AUTHORNAME/$git_authorname/g" -e "s/AUTHOREMAIL/$git_authoremail/g" -e "s/GIT_CREDENTIAL_HELPER/$git_credential/g" git/gitconfig.symlink.example > git/gitconfig.symlink 61 | 62 | success 'gitconfig' 63 | fi 64 | } 65 | 66 | 67 | link_file () { 68 | local src=$1 dst=$2 69 | 70 | local overwrite= backup= skip= 71 | local action= 72 | 73 | if [ -f "$dst" -o -d "$dst" -o -L "$dst" ] 74 | then 75 | 76 | if [ "$overwrite_all" == "false" ] && [ "$backup_all" == "false" ] && [ "$skip_all" == "false" ] 77 | then 78 | 79 | local currentSrc="$(readlink $dst)" 80 | 81 | if [ "$currentSrc" == "$src" ] 82 | then 83 | 84 | skip=true; 85 | 86 | else 87 | 88 | user "File already exists: $dst ($(basename "$src")), what do you want to do?\n\ 89 | [s]kip, [S]kip all, [o]verwrite, [O]verwrite all, [b]ackup, [B]ackup all?" 90 | read -n 1 action 91 | 92 | case "$action" in 93 | o ) 94 | overwrite=true;; 95 | O ) 96 | overwrite_all=true;; 97 | b ) 98 | backup=true;; 99 | B ) 100 | backup_all=true;; 101 | s ) 102 | skip=true;; 103 | S ) 104 | skip_all=true;; 105 | * ) 106 | ;; 107 | esac 108 | 109 | fi 110 | 111 | fi 112 | 113 | overwrite=${overwrite:-$overwrite_all} 114 | backup=${backup:-$backup_all} 115 | skip=${skip:-$skip_all} 116 | 117 | if [ "$overwrite" == "true" ] 118 | then 119 | rm -rf "$dst" 120 | success "removed $dst" 121 | fi 122 | 123 | if [ "$backup" == "true" ] 124 | then 125 | mv "$dst" "${dst}.backup" 126 | success "moved $dst to ${dst}.backup" 127 | fi 128 | 129 | if [ "$skip" == "true" ] 130 | then 131 | success "skipped $src" 132 | fi 133 | fi 134 | 135 | if [ "$skip" != "true" ] # "false" or empty 136 | then 137 | ln -s "$1" "$2" 138 | success "linked $1 to $2" 139 | fi 140 | } 141 | 142 | install_dotfiles () { 143 | info 'Installing dotfiles' 144 | 145 | local overwrite_all=false backup_all=false skip_all=false 146 | 147 | for src in $(find -H "$DOTFILES_ROOT" -maxdepth 2 -name '*.symlink' -not -path '*.git*') 148 | do 149 | dst="$HOME/.$(basename "${src%.*}")" 150 | link_file "$src" "$dst" 151 | done 152 | } 153 | 154 | setup_gitconfig 155 | install_dotfiles 156 | 157 | exit 158 | -------------------------------------------------------------------------------- /script/install: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # 3 | # Run all dotfiles installers. 4 | 5 | cd "$(dirname $0)"/.. 6 | 7 | echo "\n${WAITING}Running install scripts..." 8 | 9 | # find the installers and run them iteratively 10 | find . -name install.sh | while read installer ; do \ 11 | echo "${WAITING}Running ${installer}..."; \ 12 | ./"${installer}"; \ 13 | echo "${DONE}Finished ${installer}\n"; \ 14 | done 15 | 16 | echo "${DONE}Finished running install scripts\n" 17 | echo "${WAITING}Running postinstall scripts..." 18 | 19 | # find the post-installers and run them iteratively 20 | source ~/.zshrc 21 | find . -name postinstall.sh | while read installer ; do \ 22 | echo "${WAITING}Running ${installer}..."; \ 23 | ./"${installer}"; \ 24 | echo "${DONE}Finished ${installer}\n"; \ 25 | done 26 | 27 | echo "${DONE}Finished running postinstall scripts\n" 28 | 29 | echo "All done setting up dotfiles! Open a new shell to apply changes." 30 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Set up color escape codes 4 | export RED='\033[0;31m' 5 | export GREEN='\033[0;32m' 6 | export YELLOW='\033[1;33m' 7 | export NC='\033[0m' # No Color 8 | 9 | export WAITING="${YELLOW}○ ${NC}" 10 | export DONE="${GREEN}✓ ${NC}" 11 | 12 | # Setup gitconfig, customizations, and extensions 13 | echo "${WAITING}Bootstrapping... (copying dotfiles and creating directories)"; 14 | ./script/bootstrap.sh 15 | echo "${DONE}Done bootstrapping\n"; 16 | 17 | # Run package manager installation scripts 18 | ./script/install 19 | -------------------------------------------------------------------------------- /vim/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Create necessary directories for Vim 4 | dirs=( "$HOME/.vim.user/undo" ) 5 | i=0 6 | 7 | for dir in "${dirs[@]}" 8 | do 9 | if [ ! -d "$dir" ]; then 10 | mkdir -p $dir 11 | echo "Creating directory $dir" 12 | i=$((i+1)) 13 | fi 14 | 15 | done 16 | 17 | if [ $i -eq 0 ]; then 18 | echo "No new directories created" 19 | else 20 | echo "Created $i new directories" 21 | fi 22 | 23 | -------------------------------------------------------------------------------- /vim/postinstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | function clone_pull { 4 | DIRECTORY="$HOME/.vim/pack/$1/start/$1" 5 | if [ -d "$DIRECTORY" ]; then 6 | echo "${WAITING}Updating $1..." 7 | cd "$DIRECTORY" 8 | git pull --ff-only 9 | cd 10 | echo "${DONE}Updated $1\n" 11 | else 12 | echo "${WAITING}Installing $1..." 13 | git clone "https://github.com/$2" $DIRECTORY 14 | echo "${DONE}Installed $1\n" 15 | fi 16 | } 17 | 18 | clone_pull typescript-vim "leafgarland/typescript-vim.git" 19 | clone_pull vim-javascript "pangloss/vim-javascript.git" 20 | -------------------------------------------------------------------------------- /vim/vimrc.symlink: -------------------------------------------------------------------------------- 1 | " Custom vim configuration 2 | " Loaded after YADR's .vimrc 3 | 4 | syntax enable 5 | colorscheme peachpuff 6 | 7 | """""""""""""""""""""""""""" 8 | " GENERAL 9 | """""""""""""""""""""""""""" 10 | 11 | " Make sure we're using the expected shell 12 | if executable('zsh') 13 | set shell=zsh\ -l 14 | endif 15 | 16 | " Improve I/O by disabling swap/backup files 17 | " This is considered a Bad Idea (TM) by many, but I haven't (yet) had Vim 18 | " crash on me or anything. 19 | set nobackup 20 | set nowritebackup 21 | set noswapfile 22 | 23 | " Automatically :write before running commands 24 | set autowrite 25 | 26 | " Highlight the current cursor line 27 | set cursorline 28 | highlight CursorLineNr ctermfg=grey 29 | 30 | " Enable undofiles 31 | set undodir=~/.vim.user/undo 32 | set undofile 33 | 34 | " Enable mouse and system clipboard 35 | set mouse=a 36 | set clipboard=unnamed 37 | 38 | " Use relative numbers in normal mode, absolute numbers in insert 39 | set relativenumber 40 | set number 41 | autocmd InsertEnter * :set number norelativenumber 42 | autocmd InsertLeave * :set relativenumber 43 | highlight LineNr ctermfg=darkgrey 44 | 45 | " Reopen file buffers to the same location 46 | if has("autocmd") 47 | au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") 48 | \| exe "normal! g'\"" | endif 49 | endif 50 | 51 | " Set tab preferences 52 | filetype plugin indent on 53 | set tabstop=2 54 | set shiftwidth=2 55 | set expandtab 56 | 57 | " Status line 58 | function! GitBranch() 59 | return system("git rev-parse --abbrev-ref HEAD 2>/dev/null | tr -d '\n'") 60 | endfunction 61 | 62 | function! StatuslineGit() 63 | let l:branchname = GitBranch() 64 | return strlen(l:branchname) > 0?' '.l:branchname.' ':'' 65 | endfunction 66 | 67 | set laststatus=2 68 | set statusline= 69 | set statusline+=%#PmenuSel# 70 | set statusline+=%{StatuslineGit()} 71 | set statusline+=%#LineNr# 72 | set statusline+=\ %f 73 | set statusline+=%m\ 74 | set statusline+=%= 75 | set statusline+=%#CursorColumn# 76 | set statusline+=\ %y 77 | set statusline+=\ %{&fileencoding?&fileencoding:&encoding} 78 | set statusline+=\[%{&fileformat}\] 79 | set statusline+=\ %p%% 80 | set statusline+=\ %l:%c 81 | set statusline+=\ 82 | 83 | " Scroll margin 84 | set scrolloff=10 85 | 86 | """""""""""""""""""""""""""" 87 | " FILETYPE-SPECIFIC SETTINGS 88 | """""""""""""""""""""""""""" 89 | 90 | " Highlight lines that exceed 80 characters 91 | set colorcolumn=81 92 | highlight ColorColumn ctermfg=darkgrey 93 | 94 | " Force line-wrapping on markdown above 80 chars 95 | autocmd FileType markdown set textwidth=80 96 | 97 | " For git commits, shorten line length to 72 chars 98 | autocmd FileType gitcommit set colorcolumn=73 99 | autocmd FileType gitcommit set textwidth=72 100 | 101 | """""""""""""""""""""""""""" 102 | " KEY MAPPING 103 | """""""""""""""""""""""""""" 104 | 105 | " Open file explorer on '-' 106 | nnoremap - :Ex 107 | 108 | " Removes trailing spaces 109 | function! TrimWhiteSpace() 110 | %s/\s\+$//e 111 | endfunction 112 | 113 | nnoremap rts :call TrimWhiteSpace() 114 | 115 | " Automatically trim whitespace on save 116 | autocmd FileWritePre * :call TrimWhiteSpace() 117 | autocmd FileAppendPre * :call TrimWhiteSpace() 118 | autocmd FilterWritePre * :call TrimWhiteSpace() 119 | autocmd BufWritePre * :call TrimWhiteSpace() 120 | 121 | autocmd BufWritePre * :%s/\s\+$//e 122 | 123 | " Always use 'very magic' mode searching 124 | " This ensures that the expected perl-type regex character meanings are always 125 | " turned on 126 | nnoremap / /\v 127 | vnoremap / /\v 128 | cnoremap %s/ %smagic/ 129 | cnoremap \>s/ \>smagic/ 130 | nnoremap :g/ :g/\v 131 | nnoremap :g// :g// 132 | 133 | " HARD MODE 134 | nnoremap :echoe "Use h" 135 | nnoremap :echoe "Use l" 136 | nnoremap :echoe "Use k" 137 | nnoremap :echoe "Use j" 138 | -------------------------------------------------------------------------------- /zsh/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Downloading Antigen (zsh plugin manager)..." 4 | curl -L git.io/antigen > antigen.zsh 5 | -------------------------------------------------------------------------------- /zsh/zsh.after.symlink/alias.zsh: -------------------------------------------------------------------------------- 1 | # A handy utility for making and then cd-ing to a directory 2 | function __mkc { 3 | if [ "$1x" != "x" ]; then 4 | mkdir "$1" 5 | cd "$1" 6 | fi 7 | } 8 | 9 | alias mkc="__mkc" 10 | 11 | # Custom URL shortener 12 | # (Requires that I've git cloned the shortener repo locally) 13 | function __shorten { 14 | pushd ~/Repos/shortener; 15 | yarn shorten "$@"; 16 | popd; 17 | } 18 | 19 | alias shorten='__shorten' 20 | 21 | # A utility function to clone a GitHub repo and cd into it 22 | function __gcd { 23 | if [ "$1x" != "x" ]; then 24 | git clone "https://github.com/$1" --depth=10 --no-single-branch 25 | DIRNAME="$(cut -d'/' -f2 <<<$1)" 26 | cd "$DIRNAME" 27 | fi 28 | } 29 | 30 | # Clone a GitHub repo 31 | function __gc { 32 | if [ "$1x" != "x" ]; then 33 | git clone "https://github.com/$1" --depth=10 --no-single-branch 34 | fi 35 | } 36 | 37 | alias gcd='__gcd' 38 | alias gc='__gc' 39 | 40 | # Some convenience aliases 41 | alias pull="git pull" 42 | alias push="git push" 43 | 44 | # One-liner to fix Homebrew permissions 45 | alias fixbrew="sudo chown -R $(whoami) /usr/local/bin /usr/local/lib /usr/local/sbin && chmod u+w /usr/local/bin /usr/local/lib /usr/local/sbin" 46 | -------------------------------------------------------------------------------- /zsh/zsh.after.symlink/antigen.config.zsh: -------------------------------------------------------------------------------- 1 | source ${HOME}/.dotfiles/antigen.zsh 2 | 3 | # This initial apply is here to circumvent a caching bug 4 | antigen apply 5 | 6 | # Install plugins 7 | antigen bundle command-not-found 8 | antigen bundle zsh-users/zsh-syntax-highlighting 9 | antigen bundle zsh-users/zsh-history-substring-search 10 | 11 | # Chocks away 12 | antigen apply 13 | 14 | # Apply config specific to these packages 15 | 16 | ## History Substring Search 17 | bindkey '^[[A' history-substring-search-up 18 | bindkey '^[[B' history-substring-search-down 19 | -------------------------------------------------------------------------------- /zsh/zsh.after.symlink/path.zsh: -------------------------------------------------------------------------------- 1 | if [ -d "/usr/local/rvm" ]; then 2 | [[ -s "/usr/local/rvm/scripts/rvm" ]] && source "/usr/local/rvm/scripts/rvm" 3 | elif [ -d "$HOME/.rvm" ]; then 4 | [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" 5 | fi 6 | 7 | if [ -d "$HOME/.npm-modules" ]; then 8 | export PATH="$HOME/.npm-modules/bin:$PATH" 9 | fi 10 | 11 | if [ -d "$HOME/.yarn" ]; then 12 | export PATH="$HOME/.yarn/bin:$PATH" 13 | fi 14 | 15 | export PATH=/usr/local/bin:$PATH 16 | -------------------------------------------------------------------------------- /zsh/zsh.after.symlink/prompt.zsh: -------------------------------------------------------------------------------- 1 | # Git status in prompt 2 | setopt prompt_subst 3 | autoload -U colors && colors # Enable colors in prompt 4 | 5 | # Echoes a username/host string when connected over SSH (empty otherwise) 6 | ssh_info() { 7 | [[ "$SSH_CONNECTION" != '' ]] && echo '%(!.%{$fg[red]%}.%{$fg[yellow]%})%n%{$reset_color%}@%{$fg[green]%}%m%{$reset_color%}:' || echo '' 8 | } 9 | 10 | # Echoes information about Git repository status when inside a Git repository 11 | git_info() { 12 | 13 | # Exit if not inside a Git repository 14 | ! git rev-parse --is-inside-work-tree > /dev/null 2>&1 && return 15 | 16 | # Git branch/tag, or name-rev if on detached head 17 | local GIT_LOCATION=${$(git symbolic-ref -q HEAD || git name-rev --name-only --no-undefined --always HEAD)#(refs/heads/|tags/)} 18 | 19 | local AHEAD="%{$fg[red]%}⇡NUM%{$reset_color%}" 20 | local BEHIND="%{$fg[cyan]%}⇣NUM%{$reset_color%}" 21 | local MERGING="%{$fg[magenta]%}⚡︎%{$reset_color%}" 22 | local UNTRACKED="%{$fg[red]%}●%{$reset_color%}" 23 | local MODIFIED="%{$fg[yellow]%}●%{$reset_color%}" 24 | local STAGED="%{$fg[green]%}●%{$reset_color%}" 25 | 26 | local -a DIVERGENCES 27 | local -a FLAGS 28 | 29 | local NUM_AHEAD="$(git log --oneline @{u}.. 2> /dev/null | wc -l | tr -d ' ')" 30 | if [ "$NUM_AHEAD" -gt 0 ]; then 31 | DIVERGENCES+=( "${AHEAD//NUM/$NUM_AHEAD}" ) 32 | fi 33 | 34 | local NUM_BEHIND="$(git log --oneline ..@{u} 2> /dev/null | wc -l | tr -d ' ')" 35 | if [ "$NUM_BEHIND" -gt 0 ]; then 36 | DIVERGENCES+=( "${BEHIND//NUM/$NUM_BEHIND}" ) 37 | fi 38 | 39 | local GIT_DIR="$(git rev-parse --git-dir 2> /dev/null)" 40 | if [ -n $GIT_DIR ] && test -r $GIT_DIR/MERGE_HEAD; then 41 | FLAGS+=( "$MERGING" ) 42 | fi 43 | 44 | if [[ -n $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then 45 | FLAGS+=( "$UNTRACKED" ) 46 | fi 47 | 48 | if ! git diff --quiet 2> /dev/null; then 49 | FLAGS+=( "$MODIFIED" ) 50 | fi 51 | 52 | if ! git diff --cached --quiet 2> /dev/null; then 53 | FLAGS+=( "$STAGED" ) 54 | fi 55 | 56 | local -a GIT_INFO 57 | GIT_INFO+=( "\033[38;5;15m%F{245}±" ) 58 | [ -n "$GIT_STATUS" ] && GIT_INFO+=( "$GIT_STATUS" ) 59 | [[ ${#DIVERGENCES[@]} -ne 0 ]] && GIT_INFO+=( "${(j::)DIVERGENCES}" ) 60 | [[ ${#FLAGS[@]} -ne 0 ]] && GIT_INFO+=( "${(j::)FLAGS}" ) 61 | GIT_INFO+=( "\033[38;5;15m%F{245}$GIT_LOCATION%{$reset_color%}" ) 62 | echo "${(j: :)GIT_INFO}" 63 | 64 | } 65 | 66 | # Change the prompt character color if the last command had a nonzero exit code 67 | PS1=' 68 | $(ssh_info)%F{240}%~%u $(git_info) 69 | %(?.%{$fg[magenta]%}.%{$fg[red]%})%(!.#.λ)%{$reset_color%} ' 70 | 71 | -------------------------------------------------------------------------------- /zsh/zshrc.symlink: -------------------------------------------------------------------------------- 1 | #! /bin/zsh - 2 | # Set options 3 | # =========== 4 | # Docs: http://zsh.sourceforge.net/Doc/Release/Options.html#Options 5 | 6 | # Auto-cd when issuing a command that is a directory name 7 | setopt auto_cd 8 | 9 | # Case-insensitive globbing. This allows case-insensitive expansions 10 | # e.g. % ls ~/d* expands to % ls /Users/dte/Desktop /Users/dte/Documents 11 | setopt no_case_glob 12 | 13 | # Enable autocorrection on commands 14 | setopt correct 15 | setopt correct_all 16 | 17 | # Auto-completion 18 | autoload -Uz compinit && compinit 19 | 20 | # partial completion suggestions 21 | zstyle ':completion:*' list-suffixes 22 | zstyle ':completion:*' expand prefix suffix 23 | 24 | # Search history with up/down arrow keys 25 | autoload -U up-line-or-beginning-search 26 | autoload -U down-line-or-beginning-search 27 | zle -N up-line-or-beginning-search 28 | zle -N down-line-or-beginning-search 29 | bindkey "^[[A" up-line-or-beginning-search # Up 30 | bindkey "^[[B" down-line-or-beginning-search # Down 31 | 32 | # Vim mode 33 | bindkey -v 34 | 35 | # Better searching in command mode 36 | bindkey -M vicmd '?' history-incremental-search-backward 37 | bindkey -M vicmd '/' history-incremental-search-forward 38 | 39 | # Beginning search with arrow keys 40 | bindkey "^[OA" up-line-or-beginning-search 41 | bindkey "^[OB" down-line-or-beginning-search 42 | bindkey -M vicmd "k" up-line-or-beginning-search 43 | bindkey -M vicmd "j" down-line-or-beginning-search 44 | 45 | # Make Vi mode transitions faster (KEYTIMEOUT is in hundredths of a second) 46 | export KEYTIMEOUT=1 47 | 48 | # History options 49 | # =============== 50 | HISTFILE=${ZDOTDIR:-$HOME}/.zsh_history 51 | setopt extended_history 52 | SAVEHIST=5000 53 | HISTSIZE=2000 54 | 55 | # share history across multiple zsh sessions 56 | setopt SHARE_HISTORY 57 | # adds commands as they are typed, not at shell exit 58 | setopt INC_APPEND_HISTORY 59 | 60 | # expire duplicates first 61 | setopt HIST_EXPIRE_DUPS_FIRST 62 | # do not store duplications 63 | setopt HIST_IGNORE_DUPS 64 | #ignore duplicates when searching 65 | setopt HIST_FIND_NO_DUPS 66 | # removes blank lines from history 67 | setopt HIST_REDUCE_BLANKS 68 | 69 | # Source .after configs 70 | for f (~/.dotfiles/**/*.zsh(N.)) . $f 71 | 72 | export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" 73 | export VOLTA_HOME="$HOME/.volta" 74 | export PATH="$VOLTA_HOME/bin:$PATH" 75 | --------------------------------------------------------------------------------