├── tag-gpg ├── bash_profile.gpg ├── gnupg │ ├── gpg-agent.conf │ └── gpg.conf ├── gitconfig-gpg └── bin │ └── passp ├── tag-development ├── config │ └── nvim │ │ └── init.vim ├── bin │ ├── tmuxsend │ ├── git-pingu │ ├── git-todo │ ├── rails-schema-resolve │ ├── tmuxwidth │ ├── start │ ├── cssh │ └── git-completion.sh ├── vim │ └── ftplugin │ │ └── typescript.vim ├── gitshrc ├── ctags ├── gitignore ├── bash_profile.development ├── tmux.conf ├── gitconfig └── vimrc ├── host-boulder.local └── rcrc ├── host-shiro.local └── rcrc ├── tag-macos ├── gitconfig-macos ├── tmux.conf.local ├── bin │ ├── wifi │ ├── iterm │ ├── socks │ ├── battery │ ├── switch │ └── log └── bash_profile.local ├── bash_hosts ├── tag-email ├── bin │ ├── sync-email │ └── mutt-notmuch-py ├── mutt │ ├── config │ │ ├── account.georgebrock │ │ ├── account.gmail │ │ ├── pgp.muttrc │ │ └── mutt-colors-solarized-dark-256.muttrc │ ├── mailcap │ └── Equifax_Secure_CA.cert ├── msmtprc ├── mbsyncrc ├── muttrc └── notmuch-config ├── tag-linux └── tmux.conf.local ├── .gitignore ├── inputrc ├── tag-github ├── bash_profile.github └── vim │ └── local │ └── github.vimrc ├── host-coalface.local └── rcrc ├── codespaces-post-start ├── ssh └── config ├── bash_profile └── install.sh /tag-gpg/bash_profile.gpg: -------------------------------------------------------------------------------- 1 | export GPG_TTY=$(tty) 2 | -------------------------------------------------------------------------------- /tag-development/config/nvim/init.vim: -------------------------------------------------------------------------------- 1 | source ~/.vimrc 2 | -------------------------------------------------------------------------------- /host-boulder.local/rcrc: -------------------------------------------------------------------------------- 1 | TAGS="macos development email gpg" 2 | -------------------------------------------------------------------------------- /host-shiro.local/rcrc: -------------------------------------------------------------------------------- 1 | TAGS="macos development email gpg" 2 | -------------------------------------------------------------------------------- /tag-development/bin/tmuxsend: -------------------------------------------------------------------------------- 1 | tmux send-keys -t 0 "$@" C-m 2 | -------------------------------------------------------------------------------- /tag-macos/gitconfig-macos: -------------------------------------------------------------------------------- 1 | [credential] 2 | helper = osxkeychain 3 | -------------------------------------------------------------------------------- /bash_hosts: -------------------------------------------------------------------------------- 1 | $include /etc/hosts 2 | 3 | pingu 4 | yeti 5 | manfred.local 6 | -------------------------------------------------------------------------------- /tag-gpg/gnupg/gpg-agent.conf: -------------------------------------------------------------------------------- 1 | default-cache-ttl 600 2 | max-cache-ttl 7200 3 | -------------------------------------------------------------------------------- /tag-email/bin/sync-email: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | msmtp-queue -r && mbsync FASTMAIL 4 | -------------------------------------------------------------------------------- /tag-development/vim/ftplugin/typescript.vim: -------------------------------------------------------------------------------- 1 | noremap :ALEGoToDefinition 2 | -------------------------------------------------------------------------------- /tag-linux/tmux.conf.local: -------------------------------------------------------------------------------- 1 | set -g status-left ' ' 2 | set -g status-right ' %a %Y-%m-%d %H:%M ' 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | offlineimap/Account-* 2 | offlineimap/Repository-* 3 | offlineimap/pid 4 | tags.temp 5 | -------------------------------------------------------------------------------- /inputrc: -------------------------------------------------------------------------------- 1 | set expand-tilde on 2 | set bell-style visible 3 | 4 | "\C-n": menu-complete 5 | "\e3": "#" 6 | -------------------------------------------------------------------------------- /tag-development/gitshrc: -------------------------------------------------------------------------------- 1 | :set color.ui true 2 | 3 | :echo 4 | status 5 | :echo 6 | log --oneline -n 1 7 | -------------------------------------------------------------------------------- /tag-github/bash_profile.github: -------------------------------------------------------------------------------- 1 | export SRB_SKIP_GEM_RBIS=1 2 | export PATH="/workspaces/github/bin:$PATH" 3 | -------------------------------------------------------------------------------- /tag-gpg/gitconfig-gpg: -------------------------------------------------------------------------------- 1 | [user] 2 | signingkey = B51FFCFB 3 | [gpg] 4 | program = gpg 5 | [commit] 6 | gpgsign = true 7 | -------------------------------------------------------------------------------- /host-coalface.local/rcrc: -------------------------------------------------------------------------------- 1 | TAGS="macos development gpg github" 2 | DOTFILES_DIRS="/Users/georgebrock/.dotfiles /Users/georgebrock/.dotfiles-private" 3 | -------------------------------------------------------------------------------- /tag-development/ctags: -------------------------------------------------------------------------------- 1 | --regex-ruby=/([A-Z][A-Z0-9_]+)[ \t]*=/\1/C,constant/ 2 | --regex-ruby=/^[ \t]*attr_(reader|writer|accessor) (:[a-z0-9_]+, )*:([a-z0-9_]+)/\3/A,attr/ 3 | -------------------------------------------------------------------------------- /tag-development/gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | .DS_Store 4 | ._* 5 | tags 6 | tags.temp 7 | *.pyc 8 | bin/stubs 9 | .bundle 10 | .vagrant 11 | Session.vim 12 | .nvimlog 13 | -------------------------------------------------------------------------------- /tag-macos/tmux.conf.local: -------------------------------------------------------------------------------- 1 | set -g default-command 'reattach-to-user-namespace -l bash' 2 | set -g status-left ' ' 3 | set -g status-right-length 80 4 | set -g status-right 'WiFi: #(wifi) | Battery: #(battery) | %a %Y-%m-%d %H:%M ' 5 | -------------------------------------------------------------------------------- /codespaces-post-start: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Not general to all Codespaces: must be configured in the repo's .devcontainer 4 | # setup. 5 | 6 | if [[ -x /workspaces/github/bin/build-ctags ]]; then 7 | /workspaces/github/bin/build-ctags 8 | fi 9 | -------------------------------------------------------------------------------- /tag-github/vim/local/github.vimrc: -------------------------------------------------------------------------------- 1 | let g:ale_ruby_sorbet_executable = '/workspaces/github/bin/srb' 2 | let g:ale_ruby_ruby_executable = '/workspaces/github/vendor/ruby/current/bin/ruby' 3 | let g:ale_ruby_rubocop_executable = '/workspaces/github/bin/rubocop' 4 | -------------------------------------------------------------------------------- /tag-gpg/bin/passp: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | password_store="$HOME/.password-store" 4 | 5 | options () { 6 | find $password_store -type f -name *.gpg | \ 7 | sed "s|$password_store/||" | sed 's/\.gpg$//' 8 | } 9 | 10 | pass "$@" $(options | pick) 11 | -------------------------------------------------------------------------------- /tag-development/bin/git-pingu: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env gitsh 2 | 3 | :set pwd $(!pwd) 4 | :set repo "$(!basename $pwd).git" 5 | 6 | !ssh git@pingu.georgebrock.com "git init --bare $repo" 7 | remote add pingu git@pingu.georgebrock.com:$repo 8 | push -u --all pingu 9 | push --tags pingu 10 | -------------------------------------------------------------------------------- /tag-macos/bin/wifi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | data=$(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I) 4 | ssid=$(echo "$data" | grep -E '^\s+SSID' | sed -e 's/^[ \t]*SSID: //') 5 | if [ -z "$ssid" ]; then 6 | echo '(none)' 7 | else 8 | echo "$ssid" 9 | fi 10 | -------------------------------------------------------------------------------- /tag-macos/bin/iterm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env osascript 2 | 3 | on run argv 4 | tell application "iTerm" 5 | tell the first terminal 6 | set last_session to count of session 7 | tell session last_session 8 | write text argv as string 9 | end tell 10 | end tell 11 | end 12 | end run 13 | -------------------------------------------------------------------------------- /tag-development/bin/git-todo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | base=${1:-origin/HEAD} 4 | 5 | git diff "$base" | grep -E '^\+(\+\+|.*\bTODO\b)' | grep -B1 '^\+[^+]' | awk ' 6 | /^\+\+\+/ { sub(/^b\//, "", $2); print $2; next } 7 | /^--/ { print ""; next } 8 | { sub(/^.*TODO(: *)?/, "- ", $0); print $0 } 9 | ' 10 | -------------------------------------------------------------------------------- /tag-development/bin/rails-schema-resolve: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export RAILS_ENV=test 4 | git_dir=$(git rev-parse --git-dir) 5 | rebase_base=$(cat "$git_dir/rebase-apply/onto" || cat "$git_dir/rebase-merge/onto") 6 | 7 | git checkout "$rebase_base" -- db/schema.rb 8 | rake db:drop db:create db:schema:load 9 | rake db:migrate 10 | -------------------------------------------------------------------------------- /tag-development/bin/tmuxwidth: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | target_width=$1 4 | current_width=$(tmux list-panes | grep active | cut -d' ' -f2 | grep -Eo '[0-9]+' | head -1) 5 | delta=$(expr $current_width - $target_width) 6 | 7 | if [ $delta -lt 0 ]; then 8 | tmux resize-pane -R ${delta:1} 9 | elif [ $delta -gt 0 ]; then 10 | tmux resize-pane -L $delta 11 | fi 12 | -------------------------------------------------------------------------------- /tag-email/mutt/config/account.georgebrock: -------------------------------------------------------------------------------- 1 | set from = "george@georgebrock.com" 2 | set sendmail = "/opt/homebrew/bin/msmtpq -a fastmail" 3 | set spoolfile = "+INBOX" 4 | set postponed = "+drafts" 5 | set trash = "+archive" 6 | set record = "+sent" 7 | set reply_with_xorig = yes 8 | set reverse_name = yes 9 | macro index gi "+INBOX" "go to the INBOX" 10 | -------------------------------------------------------------------------------- /tag-development/bash_profile.development: -------------------------------------------------------------------------------- 1 | source ~/.bin/git-completion.sh 2 | 3 | alias g=git 4 | alias gc="git commit -v" 5 | alias gca="git commit --amend -v" 6 | alias gs="git status" 7 | alias gd="git diff" 8 | alias gds="git diff --stat" 9 | alias gdc="git diff --cached" 10 | alias ga="git add" 11 | alias gf="git fetch" 12 | alias gb="git branch" 13 | alias gg="git grep -En" 14 | -------------------------------------------------------------------------------- /tag-development/bin/start: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | tmux rename-window $(basename `pwd`) 4 | tmux split-window -hd 5 | tmux split-window -vd 6 | tmuxwidth 80 7 | tmux send-keys -t 1 'gitsh' C-m 8 | tmux send-keys -t 2 'vim -S' C-m 9 | tmux select-pane -t 2 10 | if [ -f Vagrantfile ]; then 11 | vagrant up 12 | vagrant ssh -- -t 'cd /vagrant; bash -l' 13 | elif [ -f ENV/bin/activate ]; then 14 | tmux send-keys -t 0 'source ENV/bin/activate' C-m 15 | fi 16 | -------------------------------------------------------------------------------- /tag-macos/bash_profile.local: -------------------------------------------------------------------------------- 1 | eval "$(/opt/homebrew/bin/brew shellenv)" 2 | 3 | export PATH="/opt/homebrew/bin:$PATH" 4 | export PATH="./.git/trust/../../bin:$PATH" 5 | 6 | test -f "$HOME/.asdf/asdf.sh" && source "$HOME/.asdf/asdf.sh" 7 | test -f "/opt/homebrew/opt/asdf/libexec/asdf.sh" && source "/opt/homebrew/opt/asdf/libexec/asdf.sh" 8 | 9 | export HOMEBREW_NO_EMOJI="get off my lawn" 10 | 11 | export TZ="$(defaults read "com.apple.ScreenTimeAgent" LastTimeZoneName)" 12 | -------------------------------------------------------------------------------- /tag-email/msmtprc: -------------------------------------------------------------------------------- 1 | defaults 2 | auth on 3 | tls on 4 | 5 | # Fastmail 6 | account fastmail 7 | host smtp.fastmail.com 8 | port 465 9 | protocol smtp 10 | from george@georgebrock.com 11 | user georgebrock@fastmail.com 12 | passwordeval security find-internet-password -r smtp -s smtp.fastmail.com -a georgebrock@fastmail.com -w 13 | tls_fingerprint FE:CF:B4:1C:41:E7:3D:FF:69:A4:00:0D:2C:13:B7:31:A3:71:90:3B:BE:88:BB:26:E8:19:26:66:2C:29:17:13 14 | tls_starttls off 15 | 16 | account default : fastmail 17 | -------------------------------------------------------------------------------- /tag-email/mutt/mailcap: -------------------------------------------------------------------------------- 1 | text/html; qlmanage -p %s; nametemplate=%s.html 2 | text/html; lynx -dump %s; nametemplate=%s.html; copiousoutput 3 | 4 | application/pdf; qlmanage -p %s; nametemplate=%s.pdf 5 | image/jpg; qlmanage -p %s; nametemplate=%s.jpg 6 | image/jpeg; qlmanage -p %s; nametemplate=%s.jpg 7 | image/pjpeg; qlmanage -p %s; nametemplate=%s.jpg 8 | image/png; qlmanage -p %s; nametemplate=%s.png 9 | image/gif; qlmanage -p %s; nametemplate=%s.gif 10 | 11 | text/*; open %s 12 | application/*; open %s 13 | -------------------------------------------------------------------------------- /ssh/config: -------------------------------------------------------------------------------- 1 | SendEnv TZ LC_* 2 | Include config.* 3 | 4 | Host github.com 5 | Hostname ssh.github.com 6 | Port 443 7 | User git 8 | 9 | Host *.dev 10 | ForwardAgent yes 11 | 12 | Host yeti yeti.georgebrock.com 13 | User georgebrock 14 | Hostname yeti.georgebrock.com 15 | 16 | Host pippin pippin.brock.network 17 | User pi 18 | Hostname pippin.brock.network 19 | ForwardAgent yes 20 | 21 | Host merry merry.brock.network 22 | User pi 23 | Hostname merry.brock.network 24 | ForwardAgent yes 25 | -------------------------------------------------------------------------------- /tag-email/mutt/config/account.gmail: -------------------------------------------------------------------------------- 1 | set from = "george@georgebrock.com" 2 | set sendmail = "/usr/local/bin/msmtp -a georgebrock" 3 | set spoolfile = "+george.brocklehurst-gmail.com/INBOX" 4 | set mbox = "+george.brocklehurst-gmail.com/archive" 5 | set postponed = "+george.brocklehurst-gmail.com/drafts" 6 | macro index gi "+george.brocklehurst-gmail.com/INBOX" "go to the INBOX" 7 | macro index gt "+thoughtbot/INBOX" "next account" 8 | macro index gT "+georgebrock.com/INBOX" "previous account" 9 | -------------------------------------------------------------------------------- /tag-macos/bin/socks: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # The name of the wireless network has changed between versions of OS X, so we 4 | # need to find the right name: 5 | service=`networksetup -listallnetworkservices | grep -Ei 'wi-fi|airport'` 6 | 7 | sudo networksetup -setsocksfirewallproxy $service localhost 9000 8 | sudo networksetup -setsocksfirewallproxystate $service on 9 | 10 | echo 'Connecting to proxy.' 11 | echo 'Press ctrl+c when you are done.' 12 | 13 | ssh -ND 9000 pingu.georgebrock.com 14 | 15 | echo 'Disconnecting.' 16 | 17 | sudo networksetup -setsocksfirewallproxystate $service off 18 | -------------------------------------------------------------------------------- /tag-development/tmux.conf: -------------------------------------------------------------------------------- 1 | set -g default-terminal 'screen-256color' 2 | 3 | unbind C-b 4 | set -g prefix M-a 5 | 6 | setw -g mode-keys vi 7 | 8 | # Recommended by neovim 9 | set -g escape-time 200 10 | set -g focus-events on 11 | 12 | unbind Left 13 | unbind Down 14 | unbind Up 15 | unbind Right 16 | bind h select-pane -L 17 | bind M-h select-pane -L 18 | bind j select-pane -D 19 | bind M-j select-pane -D 20 | bind k select-pane -U 21 | bind M-k select-pane -U 22 | bind l select-pane -R 23 | bind M-l select-pane -R 24 | 25 | bind '\' run-shell "tmuxwidth 80" 26 | 27 | source-file ~/.tmux.conf.local 28 | -------------------------------------------------------------------------------- /tag-development/bin/cssh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | codespace="$1" 4 | 5 | if ! ssh-add -l 2>&1 > /dev/null; then 6 | echo >&2 "$(basename "$0"): need to add private keys to the SSH agent" 7 | ssh-add 8 | fi 9 | 10 | if [[ $EUID -ne 0 ]]; then 11 | echo >&2 "$(basename "$0"): must run as root to forward port 80, re-running with sudo" 12 | exec sudo /bin/sh "$0" "$@" 13 | fi 14 | 15 | gh cs ports forward 80:80 3012:3012 2206:2206 -c "$codespace" & 16 | pid1=$! 17 | gh cs ports forward 6006:6006 3035:3035 -c "$codespace" & 18 | pid2=$! 19 | 20 | sleep 5 21 | gh cs ssh -c "$codespace" 22 | 23 | kill -s TERM "$pid1" 24 | kill -s TERM "$pid2" 25 | echo "Done." 26 | -------------------------------------------------------------------------------- /tag-macos/bin/battery: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | get_battery_variable() { 4 | name=$1 5 | data=$2 6 | echo $data | grep -Eo "\"$name\" = [^ ]+" | cut -d' ' -f3 7 | } 8 | 9 | data=$(ioreg -rc AppleSmartBattery) 10 | full=`get_battery_variable 'FullyCharged' "$data"` 11 | 12 | if [ $full == 'Yes' ]; then 13 | echo "Full" 14 | exit 0 15 | fi 16 | 17 | charging=`get_battery_variable 'IsCharging' "$data"` 18 | current=`get_battery_variable 'CurrentCapacity' "$data"` 19 | max=`get_battery_variable 'MaxCapacity' "$data"` 20 | percentage=$((current * 100 / max)) 21 | charging_message=`[ "$charging" == 'Yes' ] && echo ' (charging)'` 22 | 23 | echo "$percentage%$charging_message" 24 | -------------------------------------------------------------------------------- /bash_profile: -------------------------------------------------------------------------------- 1 | export PATH="$HOME/.bin:$PATH" 2 | 3 | short_codespace_name="$(echo "$CODESPACE_NAME" | sed -Ee 's/^georgebrock-(.+)-[^-]+$/\1/')" 4 | export PS1="\[\033[00;33m\]${short_codespace_name:-\h} \[\033[00;36m\]\W\[\033[31m\]\$ \[\033[0m\]" 5 | 6 | alias vim=nvim 7 | export EDITOR=nvim 8 | export VISUAL=nvim 9 | 10 | alias psg="ps auxwww | head -n 1 ; ps auxwww | grep -Ei" 11 | alias ll="ls -l" 12 | 13 | export HISTFILESIZE=10000 14 | export CLICOLOR=1 15 | export LSCOLORS=gxFxCxDxBxegedabagacad 16 | 17 | # Completion 18 | export hostname_completion_file=~/.bash_hosts 19 | complete -A hostname ssh 20 | 21 | for path in $(ls -a ~/.bash_profile.*); do 22 | source $path 23 | done 24 | -------------------------------------------------------------------------------- /tag-email/mbsyncrc: -------------------------------------------------------------------------------- 1 | IMAPAccount ACCT_FASTMAIL 2 | Host imap.fastmail.com 3 | User georgebrock@fastmail.com 4 | UseKeychain yes 5 | SSLType IMAPS 6 | SSLVersions TLSv1.2 7 | AuthMechs LOGIN 8 | 9 | IMAPStore STORE_FASTMAIL_REMOTE 10 | Account ACCT_FASTMAIL 11 | 12 | MaildirStore STORE_FASTMAIL_LOCAL 13 | Path ~/.mail/ 14 | Inbox ~/.mail/INBOX 15 | 16 | Channel CHAN_FASTMAIL_INBOX 17 | Far :STORE_FASTMAIL_REMOTE: 18 | Near :STORE_FASTMAIL_LOCAL: 19 | Sync All 20 | CopyArrivalDate yes 21 | 22 | Channel CHAN_FASTMAIL_ARCHIVE 23 | Far :STORE_FASTMAIL_REMOTE:Archive 24 | Near :STORE_FASTMAIL_LOCAL:archive 25 | Sync Push 26 | Remove None 27 | Expunge None 28 | MaxMessages 10 29 | CopyArrivalDate yes 30 | 31 | Channel CHAN_FASTMAIL_SENT 32 | Far :STORE_FASTMAIL_REMOTE:Sent 33 | Near :STORE_FASTMAIL_LOCAL:sent 34 | Sync Push 35 | Remove None 36 | Expunge None 37 | MaxMessages 10 38 | CopyArrivalDate yes 39 | 40 | Group FASTMAIL 41 | Channel CHAN_FASTMAIL_INBOX 42 | Channel CHAN_FASTMAIL_ARCHIVE 43 | Channel CHAN_FASTMAIL_SENT 44 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | exec > >(tee -i $HOME/dotfiles_install.log) 4 | exec 2>&1 5 | set -x 6 | 7 | 8 | if [[ "$CODESPACES" = "true" ]]; then 9 | rm ~/.bashrc 10 | sudo apt-get install -y rcm tmux universal-ctags 11 | rcup -f -v -d . -t linux -t development -t github 12 | 13 | if [[ -d /etc/ssh ]]; then 14 | echo 'AcceptEnv TZ LC_*' >> /etc/ssh/sshd_config 15 | fi 16 | 17 | elif [[ "$(uname)" = "Darwin" ]]; then 18 | brew install rcm 19 | rcup -v -t macos 20 | rcup -v 21 | else 22 | >&2 echo "error: Unknown system" 23 | exit 1 24 | fi 25 | 26 | if [[ ! -d "$HOME/.vim/bundle/Vundle.vim" ]]; then 27 | git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim 28 | fi 29 | 30 | vim +PluginInstall +qa 31 | 32 | if [[ "$CODESPACES" = "true" ]]; then 33 | # Vundle's pinned Git version support is broken, so work around it with 34 | # this hack. 35 | git --git-dir "$HOME/.vim/bundle/ale/.git" fetch --tags 36 | git --git-dir "$HOME/.vim/bundle/ale/.git" checkout v4.0.0 37 | 38 | git config --global url.https://github.com/.insteadOf git@github.com: 39 | git config --global gpg.program /.codespaces/bin/gh-gpgsign 40 | fi 41 | -------------------------------------------------------------------------------- /tag-development/gitconfig: -------------------------------------------------------------------------------- 1 | [user] 2 | name = George Brocklehurst 3 | email = george@georgebrock.com 4 | [core] 5 | excludesfile = ~/.gitignore 6 | [commit] 7 | verbose = true 8 | [push] 9 | default = current 10 | [rebase] 11 | autosquash = true 12 | [color] 13 | ui = true 14 | [alias] 15 | c-p = cherry-pick 16 | graph = log --all --graph --decorate --oneline -n30 17 | rgrep = !git grep 18 | cb = rev-parse --abbrev-ref --symbolic-full-name HEAD 19 | rb = rev-parse --abbrev-ref --symbolic-full-name HEAD@{u} 20 | sb = !git show-branch $(git cb) $(git rb) 21 | tig = !tig 22 | force = push --force-with-lease 23 | [mergetool "vimdiff"] 24 | cmd = vimdiff -f $LOCAL $MERGED $REMOTE 25 | [merge] 26 | tool = vimdiff 27 | [diff] 28 | tool = vimdiff 29 | guitool = vimdiff 30 | [difftool] 31 | prompt = false 32 | [mergetool] 33 | prompt = false 34 | keepBackup = false 35 | [blame] 36 | date = short 37 | [help] 38 | autocorrect = 1 39 | [grep] 40 | lineNumber = true 41 | patternType = extended 42 | [fetch] 43 | prune = true 44 | [gitsh] 45 | prompt = "%D %c%b%#%w" 46 | [include] 47 | path = ~/.gitconfig-gpg 48 | path = ~/.gitconfig-macos 49 | [init] 50 | defaultBranch = main 51 | -------------------------------------------------------------------------------- /tag-email/mutt/Equifax_Secure_CA.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE 3 | ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 4 | MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT 5 | B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB 6 | nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR 7 | fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW 8 | 8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG 9 | A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE 10 | CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG 11 | A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS 12 | spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB 13 | Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 14 | zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB 15 | BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 16 | 70+sB3c4 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /tag-email/mutt/config/pgp.muttrc: -------------------------------------------------------------------------------- 1 | set pgp_decode_command="gpg2 --no-verbose --batch --output - %f" 2 | set pgp_verify_command="gpg2 --no-verbose --batch --output - --verify %s %f" 3 | set pgp_decrypt_command="gpg2 --no-verbose --batch --output - %f" 4 | set pgp_sign_command="gpg2 --no-verbose --batch --output - --armor --detach-sign --textmode %?a?-u %a? %f" 5 | set pgp_clearsign_command="gpg2 --no-verbose --batch --output - --armor --textmode --clearsign %?a?-u %a? %f" 6 | set pgp_encrypt_only_command="pgpewrap gpg2 --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust --encrypt-to 0xB51FFCFB -- -r %r -- %f" 7 | set pgp_encrypt_sign_command="pgpewrap gpg2 --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust --encrypt-to 0xB51FFCFB -- -r %r -- %f" 8 | set pgp_import_command="gpg2 --no-verbose --import -v %f" 9 | set pgp_export_command="gpg2 --no-verbose --export --armor %r" 10 | set pgp_verify_key_command="gpg2 --no-verbose --batch --fingerprint --check-sigs %r" 11 | set pgp_list_pubring_command="gpg2 --no-verbose --batch --with-colons --list-keys %r" 12 | set pgp_list_secring_command="gpg2 --no-verbose --batch --with-colons --list-secret-keys %r" 13 | 14 | set pgp_use_gpg_agent=yes 15 | set pgp_sign_as=0xB51FFCFB 16 | set pgp_timeout=60 17 | set pgp_good_sign="^gpg: Good signature from" 18 | set pgp_autosign 19 | set pgp_replysign 20 | set pgp_autoencrypt=no 21 | set pgp_replyencrypt=no 22 | set pgp_replysignencrypted=yes 23 | set pgp_verify_sig=yes 24 | set pgp_auto_decode 25 | 26 | unignore X-PGP-Key: 27 | my_hdr X-PGP-Key: http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0xB51FFCFB 28 | -------------------------------------------------------------------------------- /tag-macos/bin/switch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # @raycast.schemaVersion 1 4 | # @raycast.title Switch Computer 5 | # @raycast.mode fullOutput 6 | # @raycast.packageName georgebrock 7 | # 8 | # @raycast.icon 💻 9 | # 10 | # Documentation: 11 | # @raycast.description Switch between computers 12 | # @raycast.author georgebrock 13 | # @raycast.authorURL https://georgebrock.com 14 | 15 | INPUT_DISPLAY_PORT_1=15 16 | INPUT_HDMI_1=17 17 | INPUT_HDMI_2=18 18 | 19 | machine="$1" 20 | if [[ -z "$machine" ]] && [[ "$(hostname -s)" == "boulder" ]]; then 21 | machine="coalface" 22 | elif [[ -z "$machine" ]] && [[ "$(hostname -s)" == "coalface" ]]; then 23 | machine="boulder" 24 | fi 25 | 26 | if [[ $# -gt 1 ]] || [[ -z "$machine" ]]; then 27 | echo >&2 "usage: $0 [machine]" 28 | exit 64 # EX_USAGE 29 | fi 30 | 31 | declare -A displays 32 | 33 | if [[ "$machine" = "coalface" ]]; then 34 | displays[U3421WE]="$INPUT_HDMI_1" 35 | displays[U2717D]="$INPUT_HDMI_1" 36 | hostname="coalface.local" 37 | elif [[ "$machine" = "boulder" ]]; then 38 | displays[1]="$INPUT_HDMI_2" 39 | displays[2]="$INPUT_DISPLAY_PORT_1" 40 | hostname="boulder.local" 41 | else 42 | echo >&2 "$0: unknown machine" 43 | exit 65 # EX_DATAERR 44 | fi 45 | 46 | if ! which -s lunar && ! which -s ddcctl; then 47 | echo >&2 "$0: cannot find lunar or ddcctl" 48 | exit 69 # EX_UNAVAILABLE 49 | fi 50 | 51 | if ! ssh-add -l; then 52 | ssh-add 53 | fi 54 | ssh "$hostname" caffeinate -u -t 1 & 55 | 56 | for display in "${!displays[@]}"; do 57 | if which -s lunar; then 58 | lunar ddc "$display" INPUT_SOURCE "${displays[$display]}" 59 | elif which -s ddcctl; then 60 | ddcctl -d "$display" -i "${displays[$display]}" 61 | fi 62 | done 63 | 64 | pmset displaysleepnow 65 | -------------------------------------------------------------------------------- /tag-macos/bin/log: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # @raycast.schemaVersion 1 4 | # @raycast.title Log 5 | # @raycast.mode fullOutput 6 | # @raycast.packageName georgebrock 7 | # 8 | # @raycast.icon 🪵 9 | # 10 | # Documentation: 11 | # @raycast.description Start daily work log 12 | # @raycast.author georgebrock 13 | # @raycast.authorURL https://georgebrock.com 14 | 15 | require "date" 16 | require "erb" 17 | 18 | START_WEEK = Date.new(2021, 6, 14) 19 | TODAY = Date.today 20 | 21 | class RoutineTask 22 | def initialize(title, only: []) 23 | only.each do |day_name| 24 | unless Date::DAYNAMES.include?(day_name) 25 | raise ArgumentError, "Invalid day name: #{day_name.inspect}" 26 | end 27 | end 28 | 29 | @title = title 30 | @only = only 31 | end 32 | 33 | def appropriate?(date) 34 | @only.empty? || @only.include?(Date::DAYNAMES[date.wday]) 35 | end 36 | 37 | def to_s 38 | @title 39 | end 40 | end 41 | 42 | TASKS = [ 43 | RoutineTask.new("📆 Check calendar"), 44 | RoutineTask.new("📝 Review OmniFocus projects", only: ["Monday"]), 45 | RoutineTask.new("⛳️ Flag important OmniFocus tasks for the day"), 46 | RoutineTask.new("💬 Share plan for the week with @danhodos & @jen-k", only: ["Monday"]), 47 | RoutineTask.new("📊 Check in on SLOs"), 48 | RoutineTask.new("💬 Read Slack"), 49 | RoutineTask.new("📥 Process inbox"), 50 | ] 51 | 52 | markdown = ERB.new(DATA.read).result_with_hash( 53 | week_no: ((TODAY - START_WEEK) / 7).to_i, 54 | day_no: TODAY.wday, 55 | tasks: TASKS.select { |t| t.appropriate?(TODAY) }, 56 | ) 57 | 58 | system("dayone2", "new", "-j", "Work Log", markdown) 59 | system("open", "-a", "Day One") 60 | 61 | __END__ 62 | # Week <%= week_no %>, day <%= day_no %> 63 | 64 | - ⏰ Morning routine 65 | <% tasks.each do |task| %> 66 | - [ ] <%= task %><% end %> 67 | - 🕰 Total time: … 68 | - … 69 | -------------------------------------------------------------------------------- /tag-email/muttrc: -------------------------------------------------------------------------------- 1 | set folder = ~/.mail 2 | set alias_file = ~/.mutt/alias 3 | set header_cache = ~/.mutt/cache/headers 4 | set message_cachedir = ~/.mutt/cache/bodies 5 | set certificate_file = ~/.mutt/certificates 6 | set mailcap_path = ~/.mutt/mailcap 7 | set tmpdir = ~/.mutt/temp 8 | set signature = ~/.mutt/sig 9 | 10 | set wait_key = no 11 | set mbox_type = Maildir 12 | set timeout = 3 13 | set mail_check = 0 14 | unset move 15 | set delete 16 | unset confirmappend 17 | set quit 18 | unset mark_old 19 | set pipe_decode 20 | set thorough_search 21 | 22 | set status_chars = " *%A" 23 | set status_format = "───[ Folder: %f ]───[%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]───%>─%?p?( %p postponed )?───" 24 | 25 | ignore * 26 | unignore subject: from: date: to: cc: 27 | unhdr_order * 28 | hdr_order subject: from: date: to: cc: 29 | 30 | mailboxes +INBOX 31 | alternates [^@]+@choosyosx\.com [^@]+@choosy\.app george@iconicosx\.com [^@]+@georgebrock\.com 32 | 33 | set date_format = "%Y-%m-%d" 34 | set index_format = "%4C %Z %D %-20.20F %s" 35 | set sort = threads 36 | set sort_aux = reverse-last-date-received 37 | 38 | macro index S "unset wait_keymutt-notmuch-py ~/.mail/temporary/search+temporary/search" "search mail using notmuch" 39 | bind index g noop 40 | bind index gg first-entry 41 | bind index G last-entry 42 | bind pager G bottom 43 | bind index \Cf next-page 44 | bind index \Cb previous-page 45 | bind pager \Cf next-page 46 | bind pager \Cb previous-page 47 | macro index o "sync-email" "sync local mail with server" 48 | macro pager \Cu "|urlview" "call urlview to open links" 49 | 50 | set pager_index_lines = 10 51 | set pager_stop 52 | set menu_scroll 53 | set tilde 54 | unset markers 55 | 56 | alternative_order text/plain text/enriched text/html 57 | auto_view text/html 58 | 59 | set realname = "George Brocklehurst" 60 | set envelope_from 61 | set sig_dashes 62 | set edit_headers 63 | set fast_reply 64 | set fcc_attach 65 | set mime_forward = no 66 | set mime_forward_rest 67 | set forward_format = "Fwd: %s" 68 | set forward_decode 69 | set reply_to 70 | set include 71 | set forward_quote 72 | 73 | set sendmail_wait = 0 74 | unset record 75 | 76 | set query_command = "contacts -Sf '%n <%e>' '%s' | grep -v '<>'" 77 | 78 | unignore List-Unsubscribe: 79 | 80 | source ~/.mutt/config/mutt-colors-solarized-dark-256.muttrc 81 | source ~/.mutt/config/account.georgebrock 82 | source ~/.mutt/config/pgp.muttrc 83 | -------------------------------------------------------------------------------- /tag-email/notmuch-config: -------------------------------------------------------------------------------- 1 | # .notmuch-config - Configuration file for the notmuch mail system 2 | # 3 | # For more information about notmuch, see http://notmuchmail.org 4 | 5 | # Database configuration 6 | # 7 | # The only value supported here is 'path' which should be the top-level 8 | # directory where your mail currently exists and to where mail will be 9 | # delivered in the future. Files should be individual email messages. 10 | # Notmuch will store its database within a sub-directory of the path 11 | # configured here named ".notmuch". 12 | # 13 | [database] 14 | path=/Users/georgebrocklehurst/.mail 15 | 16 | # User configuration 17 | # 18 | # Here is where you can let notmuch know how you would like to be 19 | # addressed. Valid settings are 20 | # 21 | # name Your full name. 22 | # primary_email Your primary email address. 23 | # other_email A list (separated by ';') of other email addresses 24 | # at which you receive email. 25 | # 26 | # Notmuch will use the various email addresses configured here when 27 | # formatting replies. It will avoid including your own addresses in the 28 | # recipient list of replies, and will set the From address based on the 29 | # address to which the original email was addressed. 30 | # 31 | [user] 32 | name=George Brocklehurst 33 | primary_email=george.brocklehurst@gmail.com 34 | other_email=george@choosyosx.com;george@iconicosx.com;george@georgebrock.com;george@thoughtbot.com; 35 | 36 | # Configuration for "notmuch new" 37 | # 38 | # The following options are supported here: 39 | # 40 | # tags A list (separated by ';') of the tags that will be 41 | # added to all messages incorporated by "notmuch new". 42 | # 43 | # ignore A list (separated by ';') of file and directory names 44 | # that will not be searched for messages by "notmuch new". 45 | # 46 | # NOTE: *Every* file/directory that goes by one of those 47 | # names will be ignored, independent of its depth/location 48 | # in the mail store. 49 | # 50 | [new] 51 | tags=unread;inbox; 52 | ignore= 53 | 54 | # Search configuration 55 | # 56 | # The following option is supported here: 57 | # 58 | # exclude_tags 59 | # A ;-separated list of tags that will be excluded from 60 | # search results by default. Using an excluded tag in a 61 | # query will override that exclusion. 62 | # 63 | [search] 64 | exclude_tags=deleted;spam; 65 | 66 | # Maildir compatibility configuration 67 | # 68 | # The following option is supported here: 69 | # 70 | # synchronize_flags Valid values are true and false. 71 | # 72 | # If true, then the following maildir flags (in message filenames) 73 | # will be synchronized with the corresponding notmuch tags: 74 | # 75 | # Flag Tag 76 | # ---- ------- 77 | # D draft 78 | # F flagged 79 | # P passed 80 | # R replied 81 | # S unread (added when 'S' flag is not present) 82 | # 83 | # The "notmuch new" command will notice flag changes in filenames 84 | # and update tags, while the "notmuch tag" and "notmuch restore" 85 | # commands will notice tag changes and update flags in filenames 86 | # 87 | [maildir] 88 | synchronize_flags=true 89 | -------------------------------------------------------------------------------- /tag-email/bin/mutt-notmuch-py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | mutt-notmuch-py 4 | 5 | This is a Gmail-only version of the original mutt-notmuch script. 6 | 7 | It will interactively ask you for a search query and then symlink the matching 8 | messages to $HOME/.cache/mutt_results. 9 | 10 | Add this to your muttrc. 11 | 12 | macro index / "unset wait_keymutt-notmuch-py~/.cache/mutt_results" \ 13 | "search mail (using notmuch)" 14 | 15 | This script overrides the $HOME/.cache/mutt_results each time you run a query. 16 | 17 | Install this by adding this file somewhere on your PATH. 18 | 19 | Only tested on OSX Lion. 20 | 21 | (c) 2012 - Honza Pokorny 22 | Licensed under BSD 23 | """ 24 | import hashlib, sys 25 | from commands import getoutput 26 | from mailbox import Maildir 27 | from optparse import OptionParser 28 | 29 | 30 | def digest(filename): 31 | try: 32 | with open(filename) as f: 33 | return hashlib.sha1(f.read()).hexdigest() 34 | except IOError: 35 | return None 36 | 37 | 38 | def pick_all_mail(messages): 39 | for m in messages: 40 | if 'archive' in m: 41 | return m 42 | return messages[0] 43 | 44 | 45 | def empty_dir(directory): 46 | box = Maildir(directory) 47 | box.clear() 48 | 49 | 50 | def command(cmd): 51 | return getoutput(cmd) 52 | 53 | 54 | def main(dest_box): 55 | query = raw_input('Query: ') 56 | 57 | command('mkdir -p %s' % dest_box) 58 | command('mkdir -p %s/cur' % dest_box) 59 | command('mkdir -p %s/new' % dest_box) 60 | 61 | empty_dir(dest_box) 62 | 63 | files = command('notmuch search --output=files %s' % query).split('\n') 64 | files = filter(None, files) 65 | 66 | data = {} 67 | messages = [] 68 | 69 | for f in files: 70 | sha = digest(f) 71 | if sha: 72 | if sha not in data.keys(): 73 | data[sha] = [f] 74 | else: 75 | data[sha].append(f) 76 | 77 | for sha in data.keys(): 78 | if is_gmail and len(data[sha]) > 1: 79 | messages.append(pick_all_mail(data[sha])) 80 | else: 81 | messages.append(data[sha][0]) 82 | 83 | for m in messages: 84 | command('ln -s "%s" %s/cur/' % (m, dest_box)) 85 | 86 | 87 | if __name__ == '__main__': 88 | global is_gmail 89 | 90 | p = OptionParser("usage: %prog [OPTIONS] [RESULTDIR]") 91 | p.add_option('-g', '--gmail', dest='gmail', 92 | action='store_true', default=True, 93 | help='gmail-specific behavior') 94 | p.add_option('-G', '--not-gmail', dest='gmail', 95 | action='store_false', 96 | help='gmail-specific behavior') 97 | (options, args) = p.parse_args() 98 | 99 | is_gmail = options.gmail 100 | 101 | if args: 102 | dest = args[0] 103 | else: 104 | dest = '~/.cache/mutt_results' 105 | 106 | main(dest.rstrip('/')) 107 | -------------------------------------------------------------------------------- /tag-development/vimrc: -------------------------------------------------------------------------------- 1 | syntax on 2 | 3 | set list " Shows invisible characters 4 | set listchars=tab:▸\ ,eol:¬ 5 | set expandtab " Use spaces, not tabs 6 | set tabstop=2 softtabstop=2 shiftwidth=2 " Default tab size 7 | set showcmd " Show the current command in the footer 8 | set ruler " Show line and col numbers in footer 9 | set modeline " Read modelines from files 10 | set laststatus=2 " Show status line (filename, etc.) always in all windows 11 | set number 12 | set relativenumber " Show line numbers 13 | set hlsearch " Highlight the current search term 14 | set incsearch " Incremental searching 15 | set colorcolumn=80 16 | set cursorline " Highlight the line the cursor is on 17 | set wildmode=longest,list 18 | set complete+=kspell " Autocomplete with dictionary words when spell check is on 19 | set splitright 20 | set splitbelow 21 | set nojoinspaces 22 | 23 | set wildignore+=*.pyc 24 | 25 | filetype plugin on 26 | filetype indent on 27 | 28 | augroup georgebrock 29 | autocmd! 30 | 31 | autocmd BufNewFile,BufRead *.ru setfiletype ruby 32 | autocmd BufNewFile,BufRead *.css.erb,*.spriter setfiletype css 33 | autocmd BufNewFile,BufRead *.mkd,*.md,*.markdown setfiletype markdown 34 | autocmd BufNewFile,BufRead *.json setfiletype javascript 35 | autocmd BufNewFile,BufRead *.ejs,*.hbs setfiletype html 36 | autocmd BufNewFile,BufRead *.go setfiletype go 37 | autocmd BufNewFile,BufRead *.slim setfiletype slim 38 | autocmd BufNewFile,BufRead *.ex,*.exs set filetype=elixir 39 | 40 | autocmd Filetype python setlocal tabstop=4 softtabstop=4 shiftwidth=4 41 | autocmd Filetype make,automake setlocal noexpandtab 42 | autocmd Filetype go setlocal noexpandtab 43 | 44 | autocmd Filetype markdown setlocal spell textwidth=80 45 | autocmd Filetype gitcommit,mail setlocal spell textwidth=76 colorcolumn=77 46 | augroup END 47 | 48 | if has('nvim') 49 | map! # 50 | nmap r r# 51 | map! – 52 | 53 | noremap :tabnext 1 54 | noremap :tabnext 2 55 | noremap :tabnext 3 56 | noremap :tabnext 4 57 | noremap :tabnext 5 58 | noremap :tabnext 6 59 | noremap :tabnext 7 60 | noremap :tabnext 8 61 | noremap :tablast 62 | else 63 | map! 3 # 64 | nmap r3 r# 65 | map! - – 66 | 67 | noremap 1 :tabnext 1 68 | noremap 2 :tabnext 2 69 | noremap 3 :tabnext 3 70 | noremap 4 :tabnext 4 71 | noremap 5 :tabnext 5 72 | noremap 6 :tabnext 6 73 | noremap 7 :tabnext 7 74 | noremap 8 :tabnext 8 75 | noremap 9 :tablast 76 | endif 77 | 78 | noremap :ALENext 79 | noremap :ALEPrevious 80 | 81 | set omnifunc=ale#completion#OmniFunc 82 | set updatetime=500 83 | 84 | let g:ale_fixers = { 85 | \ '*': ['trim_whitespace'], 86 | \ 'javascript': ['prettier'], 87 | \ 'typescript': ['prettier'], 88 | \ 'javascriptreact': ['prettier'], 89 | \ 'typescriptreact': ['prettier'], 90 | \} 91 | let g:ale_fix_on_save = 1 92 | 93 | set rtp+=~/.vim/bundle/Vundle.vim 94 | call vundle#begin() 95 | Plugin 'gmarik/vundle' 96 | Plugin 'tpope/vim-rails' 97 | Plugin 'kien/ctrlp.vim' 98 | Plugin 'tpope/vim-endwise' 99 | Plugin 'jnwhiteh/vim-golang' 100 | Plugin 'nono/vim-handlebars' 101 | Plugin 'ConradIrwin/vim-bracketed-paste' 102 | Plugin 'elixir-lang/vim-elixir' 103 | Plugin 'leafgarland/typescript-vim' 104 | Plugin 'tpope/vim-obsession' 105 | Plugin 'dense-analysis/ale' 106 | call vundle#end() 107 | 108 | set background=dark 109 | silent! colorscheme retrobox 110 | 111 | map g :silent !gitsh:redraw! 112 | map t :call ExecuteInShell("clear; ".TestCmd()) 113 | map T :call ExecuteInShell("clear; ".TestCmd().":".line(".")) 114 | map d :call ExecuteInShell("clear; ".DjangoTestCmd()) 115 | map r :call ExecuteInShell("clear; ".AllTestsCmd()) 116 | map M :call ExecuteInShell("clear; make") 117 | map :call RepeatInShell() 118 | map ct :silent !ctags -R .:redraw! 119 | map / :nohlsearch 120 | map m :silent !open -a Marked %:redraw! 121 | map e :e =expand("%:p:h") . "/" 122 | map b :call ToggleBackground() 123 | map 2 :setlocal tabstop=2 softtabstop=2 shiftwidth=2 124 | map 4 :setlocal tabstop=4 softtabstop=4 shiftwidth=4 125 | 126 | xnoremap . :normal . " . command in visual mode 127 | xnoremap @ :call ExecuteMacroOverVisualRange() 128 | 129 | function! ExecuteMacroOverVisualRange() 130 | echo "@".getcmdline() 131 | execute ":'<,'>normal @".nr2char(getchar()) 132 | endfunction 133 | 134 | command! -nargs=+ Shell :call ExecuteInShell() 135 | command! -nargs=+ Rake :call ExecuteInShell("rake ".) 136 | 137 | function! ExecuteInShell(cmd) 138 | let t:last_shell_cmd = a:cmd 139 | if (system("tmux list-panes | wc -l | grep -Eo '([0-9]+)'") > 1) 140 | execute(":silent !tmuxsend ' ".a:cmd."'") 141 | else 142 | execute(":!".a:cmd) 143 | endif 144 | redraw! 145 | endfunction 146 | 147 | function! RepeatInShell() 148 | if (exists("t:last_shell_cmd")) 149 | call ExecuteInShell(t:last_shell_cmd) 150 | else 151 | echo "ExecuteInShell hasn't been called yet, can't repeat it" 152 | endif 153 | endfunction 154 | 155 | function! TestCmd() 156 | let l:file = expand("%:.") 157 | if (match(l:file, ".feature$") != -1) 158 | return "cucumber ".l:file 159 | elseif (match(l:file, "_spec.rb$") != -1) 160 | return "rspec ".l:file 161 | elseif (match(l:file, "_test.rb$") != -1) 162 | return "./bin/rails test ".l:file 163 | elseif (match(l:file, ".py$") != -1) 164 | return "nosetests ".l:file 165 | elseif (match(l:file, ".exs") != -1) 166 | return "mix test ".l:file 167 | elseif (match(l:file, ".stories.tsx") != -1) 168 | return "./bin/npm run storybook:test -- ".l:file 169 | elseif (match(l:file, ".ts") != -1) 170 | let l:match = matchstrlist([l:file], '\(.\+/\)\?\(ui/packages/[^/]\+\)/\(.\+\)', #{submatches: v:true}) 171 | if len(l:match) != 1 172 | return "./bin/npm test ".l:file 173 | else 174 | let l:package = l:match[0].submatches[1] 175 | let l:rel_path = l:match[0].submatches[2] 176 | return "./bin/npm test -w ".l:package." ".l:rel_path 177 | endif 178 | endif 179 | endfunction 180 | 181 | function! DjangoTestCmd() 182 | let l:file = expand("%:.") 183 | let l:module = substitute(substitute(l:file, "/", ".", "g"), "\.py$", "", "") 184 | return "python manage.py test ".l:module 185 | endfunction 186 | 187 | function! AllTestsCmd() 188 | return SpringCmd("spring rake", "rake") 189 | endfunction 190 | 191 | function! SpringCmd(spring_version, default_version) 192 | return "$(if [[ -z `which spring` ]]; then echo \"".a:default_version."\"; else echo \"".a:spring_version."\"; fi)" 193 | endfunction 194 | 195 | function! ToggleBackground() 196 | if &background == "light" 197 | set background=dark 198 | else 199 | set background=light 200 | endif 201 | endfunction 202 | 203 | for f in split(glob("~/.vim/local/*"), "\n") 204 | exe "source" f 205 | endfor 206 | -------------------------------------------------------------------------------- /tag-gpg/gnupg/gpg.conf: -------------------------------------------------------------------------------- 1 | # Options for GnuPG 2 | # Copyright 1998, 1999, 2000, 2001, 2002, 2003, 3 | # 2010 Free Software Foundation, Inc. 4 | # 5 | # This file is free software; as a special exception the author gives 6 | # unlimited permission to copy and/or distribute it, with or without 7 | # modifications, as long as this notice is preserved. 8 | # 9 | # This file is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 11 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | # 13 | # Unless you specify which option file to use (with the command line 14 | # option "--options filename"), GnuPG uses the file ~/.gnupg/gpg.conf 15 | # by default. 16 | # 17 | # An options file can contain any long options which are available in 18 | # GnuPG. If the first non white space character of a line is a '#', 19 | # this line is ignored. Empty lines are also ignored. 20 | # 21 | # See the man page for a list of options. 22 | 23 | # Uncomment the following option to get rid of the copyright notice 24 | 25 | #no-greeting 26 | 27 | # If you have more than 1 secret key in your keyring, you may want to 28 | # uncomment the following option and set your preferred keyid. 29 | 30 | default-key B51FFCFB 31 | 32 | # If you do not pass a recipient to gpg, it will ask for one. Using 33 | # this option you can encrypt to a default key. Key validation will 34 | # not be done in this case. The second form uses the default key as 35 | # default recipient. 36 | 37 | #default-recipient some-user-id 38 | #default-recipient-self 39 | 40 | # Use --encrypt-to to add the specified key as a recipient to all 41 | # messages. This is useful, for example, when sending mail through a 42 | # mail client that does not automatically encrypt mail to your key. 43 | # In the example, this option allows you to read your local copy of 44 | # encrypted mail that you've sent to others. 45 | 46 | #encrypt-to some-key-id 47 | 48 | # By default GnuPG creates version 4 signatures for data files as 49 | # specified by OpenPGP. Some earlier (PGP 6, PGP 7) versions of PGP 50 | # require the older version 3 signatures. Setting this option forces 51 | # GnuPG to create version 3 signatures. 52 | 53 | #force-v3-sigs 54 | 55 | # Because some mailers change lines starting with "From " to ">From " 56 | # it is good to handle such lines in a special way when creating 57 | # cleartext signatures; all other PGP versions do it this way too. 58 | 59 | #no-escape-from-lines 60 | 61 | # If you do not use the Latin-1 (ISO-8859-1) charset, you should tell 62 | # GnuPG which is the native character set. Please check the man page 63 | # for supported character sets. This character set is only used for 64 | # metadata and not for the actual message which does not undergo any 65 | # translation. Note that future version of GnuPG will change to UTF-8 66 | # as default character set. In most cases this option is not required 67 | # as GnuPG is able to figure out the correct charset at runtime. 68 | 69 | charset utf-8 70 | 71 | # Group names may be defined like this: 72 | # group mynames = paige 0x12345678 joe patti 73 | # 74 | # Any time "mynames" is a recipient (-r or --recipient), it will be 75 | # expanded to the names "paige", "joe", and "patti", and the key ID 76 | # "0x12345678". Note there is only one level of expansion - you 77 | # cannot make an group that points to another group. Note also that 78 | # if there are spaces in the recipient name, this will appear as two 79 | # recipients. In these cases it is better to use the key ID. 80 | 81 | #group mynames = paige 0x12345678 joe patti 82 | 83 | # Lock the file only once for the lifetime of a process. If you do 84 | # not define this, the lock will be obtained and released every time 85 | # it is needed, which is usually preferable. 86 | 87 | #lock-once 88 | 89 | # GnuPG can send and receive keys to and from a keyserver. These 90 | # servers can be HKP, email, or LDAP (if GnuPG is built with LDAP 91 | # support). 92 | # 93 | # Example HKP keyserver: 94 | # hkp://keys.gnupg.net 95 | # hkp://subkeys.pgp.net 96 | # 97 | # Example email keyserver: 98 | # mailto:pgp-public-keys@keys.pgp.net 99 | # 100 | # Example LDAP keyservers: 101 | # ldap://keyserver.pgp.com 102 | # 103 | # Regular URL syntax applies, and you can set an alternate port 104 | # through the usual method: 105 | # hkp://keyserver.example.net:22742 106 | # 107 | # Most users just set the name and type of their preferred keyserver. 108 | # Note that most servers (with the notable exception of 109 | # ldap://keyserver.pgp.com) synchronize changes with each other. Note 110 | # also that a single server name may actually point to multiple 111 | # servers via DNS round-robin. hkp://keys.gnupg.net is an example of 112 | # such a "server", which spreads the load over a number of physical 113 | # servers. To see the IP address of the server actually used, you may use 114 | # the "--keyserver-options debug". 115 | 116 | keyserver hkp://keys.gnupg.net 117 | #keyserver mailto:pgp-public-keys@keys.nl.pgp.net 118 | #keyserver ldap://keyserver.pgp.com 119 | 120 | # Common options for keyserver functions: 121 | # 122 | # include-disabled : when searching, include keys marked as "disabled" 123 | # on the keyserver (not all keyservers support this). 124 | # 125 | # no-include-revoked : when searching, do not include keys marked as 126 | # "revoked" on the keyserver. 127 | # 128 | # verbose : show more information as the keys are fetched. 129 | # Can be used more than once to increase the amount 130 | # of information shown. 131 | # 132 | # use-temp-files : use temporary files instead of a pipe to talk to the 133 | # keyserver. Some platforms (Win32 for one) always 134 | # have this on. 135 | # 136 | # keep-temp-files : do not delete temporary files after using them 137 | # (really only useful for debugging) 138 | # 139 | # http-proxy="proxy" : set the proxy to use for HTTP and HKP keyservers. 140 | # This overrides the "http_proxy" environment variable, 141 | # if any. 142 | # 143 | # auto-key-retrieve : automatically fetch keys as needed from the keyserver 144 | # when verifying signatures or when importing keys that 145 | # have been revoked by a revocation key that is not 146 | # present on the keyring. 147 | # 148 | # no-include-attributes : do not include attribute IDs (aka "photo IDs") 149 | # when sending keys to the keyserver. 150 | 151 | keyserver-options auto-key-retrieve 152 | 153 | # Display photo user IDs in key listings 154 | 155 | # list-options show-photos 156 | 157 | # Display photo user IDs when a signature from a key with a photo is 158 | # verified 159 | 160 | # verify-options show-photos 161 | 162 | # Use this program to display photo user IDs 163 | # 164 | # %i is expanded to a temporary file that contains the photo. 165 | # %I is the same as %i, but the file isn't deleted afterwards by GnuPG. 166 | # %k is expanded to the key ID of the key. 167 | # %K is expanded to the long OpenPGP key ID of the key. 168 | # %t is expanded to the extension of the image (e.g. "jpg"). 169 | # %T is expanded to the MIME type of the image (e.g. "image/jpeg"). 170 | # %f is expanded to the fingerprint of the key. 171 | # %% is %, of course. 172 | # 173 | # If %i or %I are not present, then the photo is supplied to the 174 | # viewer on standard input. If your platform supports it, standard 175 | # input is the best way to do this as it avoids the time and effort in 176 | # generating and then cleaning up a secure temp file. 177 | # 178 | # If no photo-viewer is provided, GnuPG will look for xloadimage, eog, 179 | # or display (ImageMagick). On Mac OS X and Windows, the default is 180 | # to use your regular JPEG image viewer. 181 | # 182 | # Some other viewers: 183 | # photo-viewer "qiv %i" 184 | # photo-viewer "ee %i" 185 | # 186 | # This one saves a copy of the photo ID in your home directory: 187 | # photo-viewer "cat > ~/photoid-for-key-%k.%t" 188 | # 189 | # Use your MIME handler to view photos: 190 | # photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG" 191 | 192 | # Passphrase agent 193 | # 194 | # We support the old experimental passphrase agent protocol as well as 195 | # the new Assuan based one (currently available in the "newpg" package 196 | # at ftp.gnupg.org/gcrypt/alpha/aegypten/). To make use of the agent, 197 | # you have to run an agent as daemon and use the option 198 | # 199 | use-agent 200 | # 201 | # which tries to use the agent but will fallback to the regular mode 202 | # if there is a problem connecting to the agent. The normal way to 203 | # locate the agent is by looking at the environment variable 204 | # GPG_AGENT_INFO which should have been set during gpg-agent startup. 205 | # In certain situations the use of this variable is not possible, thus 206 | # the option 207 | # 208 | # --gpg-agent-info=::1 209 | # 210 | # may be used to override it. 211 | 212 | # Automatic key location 213 | # 214 | # GnuPG can automatically locate and retrieve keys as needed using the 215 | # auto-key-locate option. This happens when encrypting to an email 216 | # address (in the "user@example.com" form), and there are no 217 | # user@example.com keys on the local keyring. This option takes the 218 | # following arguments, in the order they are to be tried: 219 | # 220 | # cert = locate a key using DNS CERT, as specified in RFC-4398. 221 | # GnuPG can handle both the PGP (key) and IPGP (URL + fingerprint) 222 | # CERT methods. 223 | # 224 | # pka = locate a key using DNS PKA. 225 | # 226 | # ldap = locate a key using the PGP Universal method of checking 227 | # "ldap://keys.(thedomain)". For example, encrypting to 228 | # user@example.com will check ldap://keys.example.com. 229 | # 230 | # keyserver = locate a key using whatever keyserver is defined using 231 | # the keyserver option. 232 | # 233 | # You may also list arbitrary keyservers here by URL. 234 | # 235 | # Try CERT, then PKA, then LDAP, then hkp://subkeys.net: 236 | #auto-key-locate cert pka ldap hkp://subkeys.pgp.net 237 | 238 | ask-cert-level 239 | cert-policy-url http://www.georgebrock.com/pgp 240 | -------------------------------------------------------------------------------- /tag-email/mutt/config/mutt-colors-solarized-dark-256.muttrc: -------------------------------------------------------------------------------- 1 | # vim: filetype=muttrc 2 | 3 | # 4 | # 5 | # make sure that you are using mutt linked against slang, not ncurses, or 6 | # suffer the consequences of weird color issues. use "mutt -v" to check this. 7 | 8 | # custom body highlights ----------------------------------------------- 9 | # highlight my name and other personally relevant strings 10 | #color body color136 color234 "(ethan|schoonover)" 11 | # custom index highlights ---------------------------------------------- 12 | # messages which mention my name in the body 13 | #color index color136 color234 "~b \"phil(_g|\!| gregory| gold)|pgregory\" !~N !~T !~F !~p !~P" 14 | #color index J_cream color230 "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~N !~T !~F !~p !~P" 15 | #color index color136 color37 "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~T !~F !~p !~P" 16 | #color index color136 J_magent "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~F !~p !~P" 17 | ## messages which are in reference to my mails 18 | #color index J_magent color234 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P" 19 | #color index J_magent color230 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P" 20 | #color index J_magent color37 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P" 21 | #color index J_magent color160 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P" 22 | 23 | # for background in 16 color terminal, valid background colors include: 24 | # base03, bg, black, any of the non brights 25 | 26 | # basic colors --------------------------------------------------------- 27 | color normal color241 default 28 | color error color160 default 29 | color tilde color235 default 30 | color message color37 default 31 | color markers color160 color254 32 | color attachment color254 default 33 | color search color61 default 34 | #color status J_black J_status 35 | color status color241 color235 36 | color indicator color234 color136 37 | color tree color136 default # arrow in threads 38 | 39 | # basic monocolor screen 40 | mono bold bold 41 | mono underline underline 42 | mono indicator reverse 43 | mono error bold 44 | 45 | # index ---------------------------------------------------------------- 46 | 47 | #color index color160 default "~D(!~p|~p)" # deleted 48 | #color index color235 default ~F # flagged 49 | #color index color166 default ~= # duplicate messages 50 | #color index color240 default "~A!~N!~T!~p!~Q!~F!~D!~P" # the rest 51 | #color index J_base default "~A~N!~T!~p!~Q!~F!~D" # the rest, new 52 | color index color160 default "~A" # all messages 53 | color index color166 default "~E" # expired messages 54 | color index color33 default "~N" # new messages 55 | color index color33 default "~O" # old messages 56 | color index color61 default "~Q" # messages that have been replied to 57 | color index color240 default "~R" # read messages 58 | color index color33 default "~U" # unread messages 59 | color index color33 default "~U~$" # unread, unreferenced messages 60 | color index color241 default "~v" # messages part of a collapsed thread 61 | color index color241 default "~P" # messages from me 62 | color index color37 default "~p!~F" # messages to me 63 | color index color37 default "~N~p!~F" # new messages to me 64 | color index color37 default "~U~p!~F" # unread messages to me 65 | color index color240 default "~R~p!~F" # messages to me 66 | color index color160 default "~F" # flagged messages 67 | color index color160 default "~F~p" # flagged messages to me 68 | color index color160 default "~N~F" # new flagged messages 69 | color index color160 default "~N~F~p" # new flagged messages to me 70 | color index color160 default "~U~F~p" # new flagged messages to me 71 | color index color235 color160 "~D" # deleted messages 72 | color index color245 default "~v~(!~N)" # collapsed thread with no unread 73 | color index color136 default "~v~(~N)" # collapsed thread with some unread 74 | color index color64 default "~N~v~(~N)" # collapsed thread with unread parent 75 | # statusbg used to indicated flagged when foreground color shows other status 76 | # for collapsed thread 77 | color index color160 color235 "~v~(~F)!~N" # collapsed thread with flagged, no unread 78 | color index color136 color235 "~v~(~F~N)" # collapsed thread with some unread & flagged 79 | color index color64 color235 "~N~v~(~F~N)" # collapsed thread with unread parent & flagged 80 | color index color64 color235 "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged 81 | color index color37 color235 "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly 82 | color index color136 color160 "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial) 83 | #color index color136 default "~(~N)" # messages in threads with some unread 84 | #color index color64 default "~S" # superseded messages 85 | #color index color160 default "~T" # tagged messages 86 | #color index color166 color160 "~=" # duplicated messages 87 | 88 | # message headers ------------------------------------------------------ 89 | 90 | #color header color240 default "^" 91 | color hdrdefault color240 default 92 | color header color241 default "^(From)" 93 | color header color33 default "^(Subject)" 94 | 95 | # body ----------------------------------------------------------------- 96 | 97 | color quoted color33 default 98 | color quoted1 color37 default 99 | color quoted2 color136 default 100 | color quoted3 color160 default 101 | color quoted4 color166 default 102 | 103 | color signature color240 default 104 | color bold color235 default 105 | color underline color235 default 106 | color normal color244 default 107 | # 108 | color body color245 default "[;:][-o][)/(|]" # emoticons 109 | color body color245 default "[;:][)(|]" # emoticons 110 | color body color245 default "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\ 111 | |FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\ 112 | |IRL|RTFM|ROTFL|ROFL|YMMV)[*]?" 113 | color body color245 default "[ ][*][^*]*[*][ ]?" # more emoticon? 114 | color body color245 default "[ ]?[*][^*]*[*][ ]" # more emoticon? 115 | 116 | ## pgp 117 | 118 | color body color160 default "(BAD signature)" 119 | color body color37 default "(Good signature)" 120 | color body color234 default "^gpg: Good signature .*" 121 | color body color241 default "^gpg: " 122 | color body color241 color160 "^gpg: BAD signature from.*" 123 | mono body bold "^gpg: Good signature" 124 | mono body bold "^gpg: BAD signature from.*" 125 | 126 | # yes, an insance URL regex 127 | color body color160 default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]" 128 | # and a heavy handed email regex 129 | #color body J_magent default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])" 130 | 131 | # Various smilies and the like 132 | #color body color230 default "<[Gg]>" # 133 | #color body color230 default "<[Bb][Gg]>" # 134 | #color body color136 default " [;:]-*[})>{(<|]" # :-) etc... 135 | # *bold* 136 | #color body color33 default "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)" 137 | #mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)" 138 | # _underline_ 139 | #color body color33 default "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)" 140 | #mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)" 141 | # /italic/ (Sometimes gets directory names) 142 | #color body color33 default "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)" 143 | #mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)" 144 | 145 | # Border lines. 146 | #color body color33 default "( *[-+=#*~_]){6,}" 147 | 148 | #folder-hook . "color status J_black J_status " 149 | #folder-hook gmail/inbox "color status J_black color136 " 150 | #folder-hook gmail/important "color status J_black color136 " 151 | 152 | -------------------------------------------------------------------------------- /tag-development/bin/git-completion.sh: -------------------------------------------------------------------------------- 1 | # bash/zsh completion support for core Git. 2 | # 3 | # Copyright (C) 2006,2007 Shawn O. Pearce 4 | # Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/). 5 | # Distributed under the GNU General Public License, version 2.0. 6 | # 7 | # The contained completion routines provide support for completing: 8 | # 9 | # *) local and remote branch names 10 | # *) local and remote tag names 11 | # *) .git/remotes file names 12 | # *) git 'subcommands' 13 | # *) git email aliases for git-send-email 14 | # *) tree paths within 'ref:path/to/file' expressions 15 | # *) file paths within current working directory and index 16 | # *) common --long-options 17 | # 18 | # To use these routines: 19 | # 20 | # 1) Copy this file to somewhere (e.g. ~/.git-completion.bash). 21 | # 2) Add the following line to your .bashrc/.zshrc: 22 | # source ~/.git-completion.bash 23 | # 3) Consider changing your PS1 to also show the current branch, 24 | # see git-prompt.sh for details. 25 | # 26 | # If you use complex aliases of form '!f() { ... }; f', you can use the null 27 | # command ':' as the first command in the function body to declare the desired 28 | # completion style. For example '!f() { : git commit ; ... }; f' will 29 | # tell the completion to use commit completion. This also works with aliases 30 | # of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '". 31 | # 32 | # Compatible with bash 3.2.57. 33 | # 34 | # You can set the following environment variables to influence the behavior of 35 | # the completion routines: 36 | # 37 | # GIT_COMPLETION_CHECKOUT_NO_GUESS 38 | # 39 | # When set to "1", do not include "DWIM" suggestions in git-checkout 40 | # and git-switch completion (e.g., completing "foo" when "origin/foo" 41 | # exists). 42 | # 43 | # GIT_COMPLETION_SHOW_ALL 44 | # 45 | # When set to "1" suggest all options, including options which are 46 | # typically hidden (e.g. '--allow-empty' for 'git commit'). 47 | 48 | case "$COMP_WORDBREAKS" in 49 | *:*) : great ;; 50 | *) COMP_WORDBREAKS="$COMP_WORDBREAKS:" 51 | esac 52 | 53 | # Discovers the path to the git repository taking any '--git-dir=' and 54 | # '-C ' options into account and stores it in the $__git_repo_path 55 | # variable. 56 | __git_find_repo_path () 57 | { 58 | if [ -n "${__git_repo_path-}" ]; then 59 | # we already know where it is 60 | return 61 | fi 62 | 63 | if [ -n "${__git_C_args-}" ]; then 64 | __git_repo_path="$(git "${__git_C_args[@]}" \ 65 | ${__git_dir:+--git-dir="$__git_dir"} \ 66 | rev-parse --absolute-git-dir 2>/dev/null)" 67 | elif [ -n "${__git_dir-}" ]; then 68 | test -d "$__git_dir" && 69 | __git_repo_path="$__git_dir" 70 | elif [ -n "${GIT_DIR-}" ]; then 71 | test -d "${GIT_DIR-}" && 72 | __git_repo_path="$GIT_DIR" 73 | elif [ -d .git ]; then 74 | __git_repo_path=.git 75 | else 76 | __git_repo_path="$(git rev-parse --git-dir 2>/dev/null)" 77 | fi 78 | } 79 | 80 | # Deprecated: use __git_find_repo_path() and $__git_repo_path instead 81 | # __gitdir accepts 0 or 1 arguments (i.e., location) 82 | # returns location of .git repo 83 | __gitdir () 84 | { 85 | if [ -z "${1-}" ]; then 86 | __git_find_repo_path || return 1 87 | echo "$__git_repo_path" 88 | elif [ -d "$1/.git" ]; then 89 | echo "$1/.git" 90 | else 91 | echo "$1" 92 | fi 93 | } 94 | 95 | # Runs git with all the options given as argument, respecting any 96 | # '--git-dir=' and '-C ' options present on the command line 97 | __git () 98 | { 99 | git ${__git_C_args:+"${__git_C_args[@]}"} \ 100 | ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null 101 | } 102 | 103 | # Removes backslash escaping, single quotes and double quotes from a word, 104 | # stores the result in the variable $dequoted_word. 105 | # 1: The word to dequote. 106 | __git_dequote () 107 | { 108 | local rest="$1" len ch 109 | 110 | dequoted_word="" 111 | 112 | while test -n "$rest"; do 113 | len=${#dequoted_word} 114 | dequoted_word="$dequoted_word${rest%%[\\\'\"]*}" 115 | rest="${rest:$((${#dequoted_word}-$len))}" 116 | 117 | case "${rest:0:1}" in 118 | \\) 119 | ch="${rest:1:1}" 120 | case "$ch" in 121 | $'\n') 122 | ;; 123 | *) 124 | dequoted_word="$dequoted_word$ch" 125 | ;; 126 | esac 127 | rest="${rest:2}" 128 | ;; 129 | \') 130 | rest="${rest:1}" 131 | len=${#dequoted_word} 132 | dequoted_word="$dequoted_word${rest%%\'*}" 133 | rest="${rest:$((${#dequoted_word}-$len+1))}" 134 | ;; 135 | \") 136 | rest="${rest:1}" 137 | while test -n "$rest" ; do 138 | len=${#dequoted_word} 139 | dequoted_word="$dequoted_word${rest%%[\\\"]*}" 140 | rest="${rest:$((${#dequoted_word}-$len))}" 141 | case "${rest:0:1}" in 142 | \\) 143 | ch="${rest:1:1}" 144 | case "$ch" in 145 | \"|\\|\$|\`) 146 | dequoted_word="$dequoted_word$ch" 147 | ;; 148 | $'\n') 149 | ;; 150 | *) 151 | dequoted_word="$dequoted_word\\$ch" 152 | ;; 153 | esac 154 | rest="${rest:2}" 155 | ;; 156 | \") 157 | rest="${rest:1}" 158 | break 159 | ;; 160 | esac 161 | done 162 | ;; 163 | esac 164 | done 165 | } 166 | 167 | # The following function is based on code from: 168 | # 169 | # bash_completion - programmable completion functions for bash 3.2+ 170 | # 171 | # Copyright © 2006-2008, Ian Macdonald 172 | # © 2009-2010, Bash Completion Maintainers 173 | # 174 | # 175 | # This program is free software; you can redistribute it and/or modify 176 | # it under the terms of the GNU General Public License as published by 177 | # the Free Software Foundation; either version 2, or (at your option) 178 | # any later version. 179 | # 180 | # This program is distributed in the hope that it will be useful, 181 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 182 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 183 | # GNU General Public License for more details. 184 | # 185 | # You should have received a copy of the GNU General Public License 186 | # along with this program; if not, see . 187 | # 188 | # The latest version of this software can be obtained here: 189 | # 190 | # http://bash-completion.alioth.debian.org/ 191 | # 192 | # RELEASE: 2.x 193 | 194 | # This function can be used to access a tokenized list of words 195 | # on the command line: 196 | # 197 | # __git_reassemble_comp_words_by_ref '=:' 198 | # if test "${words_[cword_-1]}" = -w 199 | # then 200 | # ... 201 | # fi 202 | # 203 | # The argument should be a collection of characters from the list of 204 | # word completion separators (COMP_WORDBREAKS) to treat as ordinary 205 | # characters. 206 | # 207 | # This is roughly equivalent to going back in time and setting 208 | # COMP_WORDBREAKS to exclude those characters. The intent is to 209 | # make option types like --date= and : easy to 210 | # recognize by treating each shell word as a single token. 211 | # 212 | # It is best not to set COMP_WORDBREAKS directly because the value is 213 | # shared with other completion scripts. By the time the completion 214 | # function gets called, COMP_WORDS has already been populated so local 215 | # changes to COMP_WORDBREAKS have no effect. 216 | # 217 | # Output: words_, cword_, cur_. 218 | 219 | __git_reassemble_comp_words_by_ref() 220 | { 221 | local exclude i j first 222 | # Which word separators to exclude? 223 | exclude="${1//[^$COMP_WORDBREAKS]}" 224 | cword_=$COMP_CWORD 225 | if [ -z "$exclude" ]; then 226 | words_=("${COMP_WORDS[@]}") 227 | return 228 | fi 229 | # List of word completion separators has shrunk; 230 | # re-assemble words to complete. 231 | for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do 232 | # Append each nonempty word consisting of just 233 | # word separator characters to the current word. 234 | first=t 235 | while 236 | [ $i -gt 0 ] && 237 | [ -n "${COMP_WORDS[$i]}" ] && 238 | # word consists of excluded word separators 239 | [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] 240 | do 241 | # Attach to the previous token, 242 | # unless the previous token is the command name. 243 | if [ $j -ge 2 ] && [ -n "$first" ]; then 244 | ((j--)) 245 | fi 246 | first= 247 | words_[$j]=${words_[j]}${COMP_WORDS[i]} 248 | if [ $i = $COMP_CWORD ]; then 249 | cword_=$j 250 | fi 251 | if (($i < ${#COMP_WORDS[@]} - 1)); then 252 | ((i++)) 253 | else 254 | # Done. 255 | return 256 | fi 257 | done 258 | words_[$j]=${words_[j]}${COMP_WORDS[i]} 259 | if [ $i = $COMP_CWORD ]; then 260 | cword_=$j 261 | fi 262 | done 263 | } 264 | 265 | if ! type _get_comp_words_by_ref >/dev/null 2>&1; then 266 | _get_comp_words_by_ref () 267 | { 268 | local exclude cur_ words_ cword_ 269 | if [ "$1" = "-n" ]; then 270 | exclude=$2 271 | shift 2 272 | fi 273 | __git_reassemble_comp_words_by_ref "$exclude" 274 | cur_=${words_[cword_]} 275 | while [ $# -gt 0 ]; do 276 | case "$1" in 277 | cur) 278 | cur=$cur_ 279 | ;; 280 | prev) 281 | prev=${words_[$cword_-1]} 282 | ;; 283 | words) 284 | words=("${words_[@]}") 285 | ;; 286 | cword) 287 | cword=$cword_ 288 | ;; 289 | esac 290 | shift 291 | done 292 | } 293 | fi 294 | 295 | # Fills the COMPREPLY array with prefiltered words without any additional 296 | # processing. 297 | # Callers must take care of providing only words that match the current word 298 | # to be completed and adding any prefix and/or suffix (trailing space!), if 299 | # necessary. 300 | # 1: List of newline-separated matching completion words, complete with 301 | # prefix and suffix. 302 | __gitcomp_direct () 303 | { 304 | local IFS=$'\n' 305 | 306 | COMPREPLY=($1) 307 | } 308 | 309 | # Similar to __gitcomp_direct, but appends to COMPREPLY instead. 310 | # Callers must take care of providing only words that match the current word 311 | # to be completed and adding any prefix and/or suffix (trailing space!), if 312 | # necessary. 313 | # 1: List of newline-separated matching completion words, complete with 314 | # prefix and suffix. 315 | __gitcomp_direct_append () 316 | { 317 | local IFS=$'\n' 318 | 319 | COMPREPLY+=($1) 320 | } 321 | 322 | __gitcompappend () 323 | { 324 | local x i=${#COMPREPLY[@]} 325 | for x in $1; do 326 | if [[ "$x" == "$3"* ]]; then 327 | COMPREPLY[i++]="$2$x$4" 328 | fi 329 | done 330 | } 331 | 332 | __gitcompadd () 333 | { 334 | COMPREPLY=() 335 | __gitcompappend "$@" 336 | } 337 | 338 | # Generates completion reply, appending a space to possible completion words, 339 | # if necessary. 340 | # It accepts 1 to 4 arguments: 341 | # 1: List of possible completion words. 342 | # 2: A prefix to be added to each possible completion word (optional). 343 | # 3: Generate possible completion matches for this word (optional). 344 | # 4: A suffix to be appended to each possible completion word (optional). 345 | __gitcomp () 346 | { 347 | local cur_="${3-$cur}" 348 | 349 | case "$cur_" in 350 | --*=) 351 | ;; 352 | --no-*) 353 | local c i=0 IFS=$' \t\n' 354 | for c in $1; do 355 | if [[ $c == "--" ]]; then 356 | continue 357 | fi 358 | c="$c${4-}" 359 | if [[ $c == "$cur_"* ]]; then 360 | case $c in 361 | --*=|*.) ;; 362 | *) c="$c " ;; 363 | esac 364 | COMPREPLY[i++]="${2-}$c" 365 | fi 366 | done 367 | ;; 368 | *) 369 | local c i=0 IFS=$' \t\n' 370 | for c in $1; do 371 | if [[ $c == "--" ]]; then 372 | c="--no-...${4-}" 373 | if [[ $c == "$cur_"* ]]; then 374 | COMPREPLY[i++]="${2-}$c " 375 | fi 376 | break 377 | fi 378 | c="$c${4-}" 379 | if [[ $c == "$cur_"* ]]; then 380 | case $c in 381 | *=|*.) ;; 382 | *) c="$c " ;; 383 | esac 384 | COMPREPLY[i++]="${2-}$c" 385 | fi 386 | done 387 | ;; 388 | esac 389 | } 390 | 391 | # Clear the variables caching builtins' options when (re-)sourcing 392 | # the completion script. 393 | if [[ -n ${ZSH_VERSION-} ]]; then 394 | unset ${(M)${(k)parameters[@]}:#__gitcomp_builtin_*} 2>/dev/null 395 | else 396 | unset $(compgen -v __gitcomp_builtin_) 397 | fi 398 | 399 | # This function is equivalent to 400 | # 401 | # __gitcomp "$(git xxx --git-completion-helper) ..." 402 | # 403 | # except that the output is cached. Accept 1-3 arguments: 404 | # 1: the git command to execute, this is also the cache key 405 | # 2: extra options to be added on top (e.g. negative forms) 406 | # 3: options to be excluded 407 | __gitcomp_builtin () 408 | { 409 | # spaces must be replaced with underscore for multi-word 410 | # commands, e.g. "git remote add" becomes remote_add. 411 | local cmd="$1" 412 | local incl="${2-}" 413 | local excl="${3-}" 414 | 415 | local var=__gitcomp_builtin_"${cmd/-/_}" 416 | local options 417 | eval "options=\${$var-}" 418 | 419 | if [ -z "$options" ]; then 420 | local completion_helper 421 | if [ "$GIT_COMPLETION_SHOW_ALL" = "1" ]; then 422 | completion_helper="--git-completion-helper-all" 423 | else 424 | completion_helper="--git-completion-helper" 425 | fi 426 | # leading and trailing spaces are significant to make 427 | # option removal work correctly. 428 | options=" $incl $(__git ${cmd/_/ } $completion_helper) " || return 429 | 430 | for i in $excl; do 431 | options="${options/ $i / }" 432 | done 433 | eval "$var=\"$options\"" 434 | fi 435 | 436 | __gitcomp "$options" 437 | } 438 | 439 | # Variation of __gitcomp_nl () that appends to the existing list of 440 | # completion candidates, COMPREPLY. 441 | __gitcomp_nl_append () 442 | { 443 | local IFS=$'\n' 444 | __gitcompappend "$1" "${2-}" "${3-$cur}" "${4- }" 445 | } 446 | 447 | # Generates completion reply from newline-separated possible completion words 448 | # by appending a space to all of them. 449 | # It accepts 1 to 4 arguments: 450 | # 1: List of possible completion words, separated by a single newline. 451 | # 2: A prefix to be added to each possible completion word (optional). 452 | # 3: Generate possible completion matches for this word (optional). 453 | # 4: A suffix to be appended to each possible completion word instead of 454 | # the default space (optional). If specified but empty, nothing is 455 | # appended. 456 | __gitcomp_nl () 457 | { 458 | COMPREPLY=() 459 | __gitcomp_nl_append "$@" 460 | } 461 | 462 | # Fills the COMPREPLY array with prefiltered paths without any additional 463 | # processing. 464 | # Callers must take care of providing only paths that match the current path 465 | # to be completed and adding any prefix path components, if necessary. 466 | # 1: List of newline-separated matching paths, complete with all prefix 467 | # path components. 468 | __gitcomp_file_direct () 469 | { 470 | local IFS=$'\n' 471 | 472 | COMPREPLY=($1) 473 | 474 | # use a hack to enable file mode in bash < 4 475 | compopt -o filenames +o nospace 2>/dev/null || 476 | compgen -f /non-existing-dir/ >/dev/null || 477 | true 478 | } 479 | 480 | # Generates completion reply with compgen from newline-separated possible 481 | # completion filenames. 482 | # It accepts 1 to 3 arguments: 483 | # 1: List of possible completion filenames, separated by a single newline. 484 | # 2: A directory prefix to be added to each possible completion filename 485 | # (optional). 486 | # 3: Generate possible completion matches for this word (optional). 487 | __gitcomp_file () 488 | { 489 | local IFS=$'\n' 490 | 491 | # XXX does not work when the directory prefix contains a tilde, 492 | # since tilde expansion is not applied. 493 | # This means that COMPREPLY will be empty and Bash default 494 | # completion will be used. 495 | __gitcompadd "$1" "${2-}" "${3-$cur}" "" 496 | 497 | # use a hack to enable file mode in bash < 4 498 | compopt -o filenames +o nospace 2>/dev/null || 499 | compgen -f /non-existing-dir/ >/dev/null || 500 | true 501 | } 502 | 503 | # Execute 'git ls-files', unless the --committable option is specified, in 504 | # which case it runs 'git diff-index' to find out the files that can be 505 | # committed. It return paths relative to the directory specified in the first 506 | # argument, and using the options specified in the second argument. 507 | __git_ls_files_helper () 508 | { 509 | if [ "$2" == "--committable" ]; then 510 | __git -C "$1" -c core.quotePath=false diff-index \ 511 | --name-only --relative HEAD -- "${3//\\/\\\\}*" 512 | else 513 | # NOTE: $2 is not quoted in order to support multiple options 514 | __git -C "$1" -c core.quotePath=false ls-files \ 515 | --exclude-standard $2 -- "${3//\\/\\\\}*" 516 | fi 517 | } 518 | 519 | 520 | # __git_index_files accepts 1 or 2 arguments: 521 | # 1: Options to pass to ls-files (required). 522 | # 2: A directory path (optional). 523 | # If provided, only files within the specified directory are listed. 524 | # Sub directories are never recursed. Path must have a trailing 525 | # slash. 526 | # 3: List only paths matching this path component (optional). 527 | __git_index_files () 528 | { 529 | local root="$2" match="$3" 530 | 531 | __git_ls_files_helper "$root" "$1" "${match:-?}" | 532 | awk -F / -v pfx="${2//\\/\\\\}" '{ 533 | paths[$1] = 1 534 | } 535 | END { 536 | for (p in paths) { 537 | if (substr(p, 1, 1) != "\"") { 538 | # No special characters, easy! 539 | print pfx p 540 | continue 541 | } 542 | 543 | # The path is quoted. 544 | p = dequote(p) 545 | if (p == "") 546 | continue 547 | 548 | # Even when a directory name itself does not contain 549 | # any special characters, it will still be quoted if 550 | # any of its (stripped) trailing path components do. 551 | # Because of this we may have seen the same directory 552 | # both quoted and unquoted. 553 | if (p in paths) 554 | # We have seen the same directory unquoted, 555 | # skip it. 556 | continue 557 | else 558 | print pfx p 559 | } 560 | } 561 | function dequote(p, bs_idx, out, esc, esc_idx, dec) { 562 | # Skip opening double quote. 563 | p = substr(p, 2) 564 | 565 | # Interpret backslash escape sequences. 566 | while ((bs_idx = index(p, "\\")) != 0) { 567 | out = out substr(p, 1, bs_idx - 1) 568 | esc = substr(p, bs_idx + 1, 1) 569 | p = substr(p, bs_idx + 2) 570 | 571 | if ((esc_idx = index("abtvfr\"\\", esc)) != 0) { 572 | # C-style one-character escape sequence. 573 | out = out substr("\a\b\t\v\f\r\"\\", 574 | esc_idx, 1) 575 | } else if (esc == "n") { 576 | # Uh-oh, a newline character. 577 | # We cannot reliably put a pathname 578 | # containing a newline into COMPREPLY, 579 | # and the newline would create a mess. 580 | # Skip this path. 581 | return "" 582 | } else { 583 | # Must be a \nnn octal value, then. 584 | dec = esc * 64 + \ 585 | substr(p, 1, 1) * 8 + \ 586 | substr(p, 2, 1) 587 | out = out sprintf("%c", dec) 588 | p = substr(p, 3) 589 | } 590 | } 591 | # Drop closing double quote, if there is one. 592 | # (There is not any if this is a directory, as it was 593 | # already stripped with the trailing path components.) 594 | if (substr(p, length(p), 1) == "\"") 595 | out = out substr(p, 1, length(p) - 1) 596 | else 597 | out = out p 598 | 599 | return out 600 | }' 601 | } 602 | 603 | # __git_complete_index_file requires 1 argument: 604 | # 1: the options to pass to ls-file 605 | # 606 | # The exception is --committable, which finds the files appropriate commit. 607 | __git_complete_index_file () 608 | { 609 | local dequoted_word pfx="" cur_ 610 | 611 | __git_dequote "$cur" 612 | 613 | case "$dequoted_word" in 614 | ?*/*) 615 | pfx="${dequoted_word%/*}/" 616 | cur_="${dequoted_word##*/}" 617 | ;; 618 | *) 619 | cur_="$dequoted_word" 620 | esac 621 | 622 | __gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")" 623 | } 624 | 625 | # Lists branches from the local repository. 626 | # 1: A prefix to be added to each listed branch (optional). 627 | # 2: List only branches matching this word (optional; list all branches if 628 | # unset or empty). 629 | # 3: A suffix to be appended to each listed branch (optional). 630 | __git_heads () 631 | { 632 | local pfx="${1-}" cur_="${2-}" sfx="${3-}" 633 | 634 | __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \ 635 | "refs/heads/$cur_*" "refs/heads/$cur_*/**" 636 | } 637 | 638 | # Lists branches from remote repositories. 639 | # 1: A prefix to be added to each listed branch (optional). 640 | # 2: List only branches matching this word (optional; list all branches if 641 | # unset or empty). 642 | # 3: A suffix to be appended to each listed branch (optional). 643 | __git_remote_heads () 644 | { 645 | local pfx="${1-}" cur_="${2-}" sfx="${3-}" 646 | 647 | __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \ 648 | "refs/remotes/$cur_*" "refs/remotes/$cur_*/**" 649 | } 650 | 651 | # Lists tags from the local repository. 652 | # Accepts the same positional parameters as __git_heads() above. 653 | __git_tags () 654 | { 655 | local pfx="${1-}" cur_="${2-}" sfx="${3-}" 656 | 657 | __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \ 658 | "refs/tags/$cur_*" "refs/tags/$cur_*/**" 659 | } 660 | 661 | # List unique branches from refs/remotes used for 'git checkout' and 'git 662 | # switch' tracking DWIMery. 663 | # 1: A prefix to be added to each listed branch (optional) 664 | # 2: List only branches matching this word (optional; list all branches if 665 | # unset or empty). 666 | # 3: A suffix to be appended to each listed branch (optional). 667 | __git_dwim_remote_heads () 668 | { 669 | local pfx="${1-}" cur_="${2-}" sfx="${3-}" 670 | local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers 671 | 672 | # employ the heuristic used by git checkout and git switch 673 | # Try to find a remote branch that cur_es the completion word 674 | # but only output if the branch name is unique 675 | __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ 676 | --sort="refname:strip=3" \ 677 | "refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \ 678 | uniq -u 679 | } 680 | 681 | # Lists refs from the local (by default) or from a remote repository. 682 | # It accepts 0, 1 or 2 arguments: 683 | # 1: The remote to list refs from (optional; ignored, if set but empty). 684 | # Can be the name of a configured remote, a path, or a URL. 685 | # 2: In addition to local refs, list unique branches from refs/remotes/ for 686 | # 'git checkout's tracking DWIMery (optional; ignored, if set but empty). 687 | # 3: A prefix to be added to each listed ref (optional). 688 | # 4: List only refs matching this word (optional; list all refs if unset or 689 | # empty). 690 | # 5: A suffix to be appended to each listed ref (optional; ignored, if set 691 | # but empty). 692 | # 693 | # Use __git_complete_refs() instead. 694 | __git_refs () 695 | { 696 | local i hash dir track="${2-}" 697 | local list_refs_from=path remote="${1-}" 698 | local format refs 699 | local pfx="${3-}" cur_="${4-$cur}" sfx="${5-}" 700 | local match="${4-}" 701 | local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers 702 | 703 | __git_find_repo_path 704 | dir="$__git_repo_path" 705 | 706 | if [ -z "$remote" ]; then 707 | if [ -z "$dir" ]; then 708 | return 709 | fi 710 | else 711 | if __git_is_configured_remote "$remote"; then 712 | # configured remote takes precedence over a 713 | # local directory with the same name 714 | list_refs_from=remote 715 | elif [ -d "$remote/.git" ]; then 716 | dir="$remote/.git" 717 | elif [ -d "$remote" ]; then 718 | dir="$remote" 719 | else 720 | list_refs_from=url 721 | fi 722 | fi 723 | 724 | if [ "$list_refs_from" = path ]; then 725 | if [[ "$cur_" == ^* ]]; then 726 | pfx="$pfx^" 727 | fer_pfx="$fer_pfx^" 728 | cur_=${cur_#^} 729 | match=${match#^} 730 | fi 731 | case "$cur_" in 732 | refs|refs/*) 733 | format="refname" 734 | refs=("$match*" "$match*/**") 735 | track="" 736 | ;; 737 | *) 738 | for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD; do 739 | case "$i" in 740 | $match*) 741 | if [ -e "$dir/$i" ]; then 742 | echo "$pfx$i$sfx" 743 | fi 744 | ;; 745 | esac 746 | done 747 | format="refname:strip=2" 748 | refs=("refs/tags/$match*" "refs/tags/$match*/**" 749 | "refs/heads/$match*" "refs/heads/$match*/**" 750 | "refs/remotes/$match*" "refs/remotes/$match*/**") 751 | ;; 752 | esac 753 | __git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \ 754 | "${refs[@]}" 755 | if [ -n "$track" ]; then 756 | __git_dwim_remote_heads "$pfx" "$match" "$sfx" 757 | fi 758 | return 759 | fi 760 | case "$cur_" in 761 | refs|refs/*) 762 | __git ls-remote "$remote" "$match*" | \ 763 | while read -r hash i; do 764 | case "$i" in 765 | *^{}) ;; 766 | *) echo "$pfx$i$sfx" ;; 767 | esac 768 | done 769 | ;; 770 | *) 771 | if [ "$list_refs_from" = remote ]; then 772 | case "HEAD" in 773 | $match*) echo "${pfx}HEAD$sfx" ;; 774 | esac 775 | __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ 776 | "refs/remotes/$remote/$match*" \ 777 | "refs/remotes/$remote/$match*/**" 778 | else 779 | local query_symref 780 | case "HEAD" in 781 | $match*) query_symref="HEAD" ;; 782 | esac 783 | __git ls-remote "$remote" $query_symref \ 784 | "refs/tags/$match*" "refs/heads/$match*" \ 785 | "refs/remotes/$match*" | 786 | while read -r hash i; do 787 | case "$i" in 788 | *^{}) ;; 789 | refs/*) echo "$pfx${i#refs/*/}$sfx" ;; 790 | *) echo "$pfx$i$sfx" ;; # symbolic refs 791 | esac 792 | done 793 | fi 794 | ;; 795 | esac 796 | } 797 | 798 | # Completes refs, short and long, local and remote, symbolic and pseudo. 799 | # 800 | # Usage: __git_complete_refs [