From 8e4d61fb77ed68f896b6fe3dc0bbbcd078668ede Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Tue, 13 Aug 2019 23:33:32 -0400 Subject: zsh: adopt --- templates/.zsh/aliases.zsh | 42 ++++++++++++++++ templates/.zsh/completion.zsh | 16 ++++++ templates/.zsh/config.zsh | 47 ++++++++++++++++++ templates/.zsh/env.zsh | 17 +++++++ templates/.zsh/functions/dirty.zsh | 24 +++++++++ templates/.zsh/functions/ebdeploy.zsh | 3 ++ templates/.zsh/functions/ec2.zsh | 6 +++ templates/.zsh/functions/ghclone.zsh | 19 ++++++++ templates/.zsh/functions/git-branches.zsh | 23 +++++++++ templates/.zsh/functions/prs.zsh | 3 ++ templates/.zsh/functions/rfc.zsh | 0 templates/.zsh/functions/rp.zsh | 7 +++ templates/.zsh/functions/sheb.zsh | 22 +++++++++ templates/.zsh/functions/track.zsh | 81 +++++++++++++++++++++++++++++++ templates/.zsh/path.zsh | 13 +++++ templates/.zsh/prompt.zsh | 23 +++++++++ templates/.zsh/window.zsh | 19 ++++++++ templates/.zshenv | 1 + templates/.zshrc | 41 ++++++++++++++++ vars.toml | 11 +++++ 20 files changed, 418 insertions(+) create mode 100644 templates/.zsh/aliases.zsh create mode 100644 templates/.zsh/completion.zsh create mode 100644 templates/.zsh/config.zsh create mode 100644 templates/.zsh/env.zsh create mode 100644 templates/.zsh/functions/dirty.zsh create mode 100644 templates/.zsh/functions/ebdeploy.zsh create mode 100644 templates/.zsh/functions/ec2.zsh create mode 100644 templates/.zsh/functions/ghclone.zsh create mode 100644 templates/.zsh/functions/git-branches.zsh create mode 100644 templates/.zsh/functions/prs.zsh create mode 100644 templates/.zsh/functions/rfc.zsh create mode 100644 templates/.zsh/functions/rp.zsh create mode 100644 templates/.zsh/functions/sheb.zsh create mode 100644 templates/.zsh/functions/track.zsh create mode 100644 templates/.zsh/path.zsh create mode 100644 templates/.zsh/prompt.zsh create mode 100644 templates/.zsh/window.zsh create mode 100644 templates/.zshenv create mode 100644 templates/.zshrc diff --git a/templates/.zsh/aliases.zsh b/templates/.zsh/aliases.zsh new file mode 100644 index 0000000..f9207fa --- /dev/null +++ b/templates/.zsh/aliases.zsh @@ -0,0 +1,42 @@ +# navigation shortcuts +alias ..="cd .." +alias ...="cd ../.." +alias ....="cd ../../.." +alias .....="cd ../../../.." +if [[ $(uname) == "Darwin" || $(uname) == "FreeBSD" ]]; then + alias l="ls -lAhG" + alias la="ls -lAGh" + alias ll="ls -lGh" + alias ls="ls -Gh" +else + alias l="ls -lah --color" + alias la="ls -la --color" + alias ll="ls -l --color" + alias ls="ls --color" +fi + +# git +alias ga="git add" +alias gb="git branch" +alias gc="git commit" +alias gcb="git checkout -b" +alias gco="git checkout" +alias gd="git diff" +alias gds="git diff --staged" +alias gl="git pull" +alias gm="git merge" +alias gp="git push" +alias gs="git status" +alias gt="git tag" + +# docker-compose +alias dc="docker-compose" +alias dcd="docker-compose down" +alias dcud="docker-compose up -d" + +# edit +alias e="nvim" + +# pass +alias pc="pass --clip" +alias poc="pass otp --clip" diff --git a/templates/.zsh/completion.zsh b/templates/.zsh/completion.zsh new file mode 100644 index 0000000..016c655 --- /dev/null +++ b/templates/.zsh/completion.zsh @@ -0,0 +1,16 @@ +# matches case insensitive for lowercase +zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' + +# pasting with tabs doesn't perform completion +zstyle ':completion:*' insert-tab pending + +# gulp task completion +function gulpTasks() { + compls=$(grep -Eho "gulp\.task[^,]*" [Gg]ulpfile.* 2>/dev/null | sed s/\"/\'/g | cut -d "'" -f 2 | sort) + + completions=(${=compls}) + compadd -- $completions +} + +compdef gulpTasks gulp + diff --git a/templates/.zsh/config.zsh b/templates/.zsh/config.zsh new file mode 100644 index 0000000..e4ee650 --- /dev/null +++ b/templates/.zsh/config.zsh @@ -0,0 +1,47 @@ +HISTFILE=~/.zsh_history +HISTSIZE=10000 +SAVEHIST=10000 + +setopt APPEND_HISTORY +setopt AUTO_CD +setopt COMPLETE_IN_WORD +setopt CORRECT +setopt EXTENDED_GLOB +setopt EXTENDED_HISTORY +setopt HIST_IGNORE_ALL_DUPS +setopt HIST_REDUCE_BLANKS +setopt HIST_VERIFY +setopt INC_APPEND_HISTORY +setopt LOCAL_OPTIONS +setopt LOCAL_TRAPS +setopt NO_BG_NICE +setopt NO_HUP +setopt NO_LIST_BEEP +setopt PROMPT_SUBST + +# open a file for editing by choosing with fzf +fzf-open-file-or-dir() { + local cmd="command find -L . \ + \\( -path '*/\\.*' -o -fstype 'dev' -o -fstype 'proc' \\) -prune \ + -o -type f -print \ + -o -type d -print \ + -o -type l -print 2> /dev/null | sed 1d | cut -b3-" + local out=$(eval $cmd | fzf --exit-0) + if [ -f "$out" ]; then + $EDITOR "$out" < /dev/tty + elif [ -d "$out" ]; then + cd "$out" + zle reset-prompt + fi +} +zle -N fzf-open-file-or-dir + +bindkey '^[^[[D' backward-word +bindkey '^[^[[C' forward-word +bindkey '^[[5D' beginning-of-line +bindkey '^[[5C' end-of-line +bindkey '^[[3~' delete-char +bindkey '^[^N' newtab +bindkey '^?' backward-delete-char +bindkey '^R' history-incremental-search-backward +bindkey '^P' fzf-open-file-or-dir diff --git a/templates/.zsh/env.zsh b/templates/.zsh/env.zsh new file mode 100644 index 0000000..ba94eb4 --- /dev/null +++ b/templates/.zsh/env.zsh @@ -0,0 +1,17 @@ +export PROJECTS=~/code +export VIRTYX_DIR="$PROJECTS/src/github.com/virtyx-technologies" +export PASSWORD_STORE_GENERATED_LENGTH=64 +export GOPATH="$PROJECTS" +export LSCOLORS="exfxcxdxbxegedabagacad" +export CLICOLOR=true +export EDITOR=nvim +export LICENSE_FULL_NAME="Ben Burwell" +export WWW_HOME="https://duckduckgo.com/" +export FZF_DEFAULT_COMMAND='rg --files --no-ignore --hidden --follow -g "!{.git,node_modules}/*" 2> /dev/null' +export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" +export NVM_DIR="$HOME/.nvm" +export CDPATH=$HOME/c:$HOME +export SSLKEYLOGFILE="$HOME/.mitmproxy/sslkeylogfile.txt" +export BAT_PAGER="less -rf" +export CONF_SOURCE="$HOME/dotfiles" +export CONF_DEST="$HOME" diff --git a/templates/.zsh/functions/dirty.zsh b/templates/.zsh/functions/dirty.zsh new file mode 100644 index 0000000..19a550d --- /dev/null +++ b/templates/.zsh/functions/dirty.zsh @@ -0,0 +1,24 @@ +function dirty() { + base=~/code/src/github.com/virtyx-technologies + yellow='\033[0;33m' + green='\033[0;32m' + nc='\033[0m' + for repo in $(ls "$base"); do + p="$base/$repo" + is_dirty=$(git --git-dir="$p/.git" --work-tree="$p" diff --shortstat 2> /dev/null | tail -n1) + branch=$(git --git-dir="$p/.git" --work-tree="$p" rev-parse --abbrev-ref HEAD 2> /dev/null) + if [[ $branch != "master" && $branch != "HEAD" ]]; then + pr=$(curl --silent "https://benburwell:$GITHUB_TOKEN@api.github.com/repos/virtyx-technologies/$repo/pulls?state=open&head=virtyx-technologies:$branch" | jq --raw-output --monochrome-output '.[0]._links.html.href') + pr_link=$([[ $pr != "null" ]] && echo "($pr)") + if [[ $is_dirty != "" ]]; then + echo "$repo: ${yellow}$branch${nc} $pr_link" + else + echo "$repo: ${green}$branch${nc} $pr_link" + fi + else + if [[ $is_dirty ]]; then + echo "$repo: ${yellow}$branch${nc} $pr_link" + fi + fi + done +} diff --git a/templates/.zsh/functions/ebdeploy.zsh b/templates/.zsh/functions/ebdeploy.zsh new file mode 100644 index 0000000..76b8a04 --- /dev/null +++ b/templates/.zsh/functions/ebdeploy.zsh @@ -0,0 +1,3 @@ +function ebdeploy() { + eb deploy --timeout 30 --label "$(git rev-parse --short HEAD)-$(date +%Y-%m-%dT%H:%M:%SZ)" +} diff --git a/templates/.zsh/functions/ec2.zsh b/templates/.zsh/functions/ec2.zsh new file mode 100644 index 0000000..dfaf8e1 --- /dev/null +++ b/templates/.zsh/functions/ec2.zsh @@ -0,0 +1,6 @@ +function ec2() { + if [[ "$#" == "0" ]]; then + aws ec2 describe-instances | jq --raw-output 'include "aws"; getInstanceMetadata' | column -t -s $'\t' | sort + fi +} + diff --git a/templates/.zsh/functions/ghclone.zsh b/templates/.zsh/functions/ghclone.zsh new file mode 100644 index 0000000..7b976ef --- /dev/null +++ b/templates/.zsh/functions/ghclone.zsh @@ -0,0 +1,19 @@ +function ghclone() { + local username + local repo + local target_dir + + if [[ $# -lt 1 ]]; then + echo "Usage: ghclone " + return 1 + fi + + username=$(echo "$1" | cut -d'/' -f1) + repo=$(echo "$1" | cut -d'/' -f2) + target_dir="$PROJECTS/src/github.com/$username" + mkdir -p "$target_dir" + url="git@github.com:$username/$repo.git" + echo "Cloning $url into $target_dir..." + git clone "$url" "$target_dir/$repo" + cd "$target_dir/$repo" || return +} diff --git a/templates/.zsh/functions/git-branches.zsh b/templates/.zsh/functions/git-branches.zsh new file mode 100644 index 0000000..4636cab --- /dev/null +++ b/templates/.zsh/functions/git-branches.zsh @@ -0,0 +1,23 @@ +green=`tput setaf 2` +reset=`tput sgr0` + +git-branches() { + set -f + git branch | while read line; do + current=" " + name=${line##\* } ## removes leading * for current + + if [ ! "$name" = "$line" ]; then + current="${green}* " + fi + + description=`git config "branch.$name.description"` + + if [ "$description" != "" ]; then + description=" : $description" + fi + + echo "${reset}${current}${name}${description}${reset}" + done + set +f +} diff --git a/templates/.zsh/functions/prs.zsh b/templates/.zsh/functions/prs.zsh new file mode 100644 index 0000000..9a80c8d --- /dev/null +++ b/templates/.zsh/functions/prs.zsh @@ -0,0 +1,3 @@ +prs () { + hub browse -- pulls +} diff --git a/templates/.zsh/functions/rfc.zsh b/templates/.zsh/functions/rfc.zsh new file mode 100644 index 0000000..e69de29 diff --git a/templates/.zsh/functions/rp.zsh b/templates/.zsh/functions/rp.zsh new file mode 100644 index 0000000..1db3b16 --- /dev/null +++ b/templates/.zsh/functions/rp.zsh @@ -0,0 +1,7 @@ +# GitHub Request Pull +# +# Assuming the current git repo's `origin` is on GitHub, open the pull request +# editor for the current branch. +function rp() { + hub pull-request +} diff --git a/templates/.zsh/functions/sheb.zsh b/templates/.zsh/functions/sheb.zsh new file mode 100644 index 0000000..64efe66 --- /dev/null +++ b/templates/.zsh/functions/sheb.zsh @@ -0,0 +1,22 @@ +function sheb() { + # if an address wasn't specified, use the ec2 command to select an instance + if [[ $# == "0" ]]; then + 1=$(ec2 | fzf --no-multi --prompt="ec2 instance> " | sed 's/ .*//') + if [[ -z "$1" ]]; then + return 1 + fi + fi + + # first add key to agent if necessary + if [[ ! $(ssh-add -L) ]]; then + ssh-add -K ~/.ssh/id_rsa + fi + + if [[ $(echo "$1" | grep "@") ]]; then + # If a username was provided, use it + ssh -J virtyx -t "$1" "sudo su -" + else + # Otherwise, assume username is "ec2-user" + ssh -J virtyx -t "ec2-user@$1" "sudo su -" + fi +} diff --git a/templates/.zsh/functions/track.zsh b/templates/.zsh/functions/track.zsh new file mode 100644 index 0000000..e60f944 --- /dev/null +++ b/templates/.zsh/functions/track.zsh @@ -0,0 +1,81 @@ +local function dateimpl() { + if [[ $(uname) == "Darwin" ]]; then + echo "gdate" + else + echo "date" + fi +} + +local function datediff() { + local d0=$($(dateimpl) -d"$1" +%s) + local d1=$($(dateimpl) -d"$2" +%s) + echo "$(($d1 - $d0))" +} + +function track() { + if [[ $# -lt 1 ]]; then + echo "Usage: track " && return 1 + fi + local cmd=$1 + local trackdir + + if [[ $TRACK_ROOT ]]; then + trackdir=$TRACK_ROOT + else + trackdir=~/.track + fi + local logfile="$trackdir/log" + local startfile="$taskdir/started" + local archivedir="$trackdir/archive" + + if [[ $cmd == "archive" ]]; then + mkdir -p $archivedir + mv "$logfile" "$archivedir/$($(dateimpl) --iso-8601=seconds)" + return 0 + fi + + if [[ $# -lt 2 ]]; then + echo "Usage: track $cmd " && return 1 + fi + local task=$2 + local taskdir="$trackdir/task/$task" + + mkdir -p "$taskdir" + + if [[ $cmd == "start" ]]; then + if [[ -f $startfile ]]; then + echo "Task $task was already started at $(cat $startfile)" + return 1 + fi + $(dateimpl) --iso-8601=seconds > "$startfile" + return 0 + fi + + if [[ $cmd == "stop" ]]; then + if [[ ! -f $startfile ]]; then + echo "Task $task has not been started" + return 1 + fi + local started=$(cat "$startfile") + local ended=$($(dateimpl) --iso-8601=seconds) + echo "$task\t$started\t$ended" >> "$logfile" + rm "$startfile" + return 0 + fi + + if [[ $cmd == "hours" ]]; then + local lines=("${(@f)$(grep "^$task" < "$logfile" | cut -f2,3)}") + local sum=0 + for line in $lines; do + local t0=$(echo "$line" | cut -f1) + local t1=$(echo "$line" | cut -f2) + diff=$(datediff "$t0" "$t1") + sum=$((sum + diff)) + done + echo "$(($sum / 3600.0))" + return 0 + fi + + echo "Unrecognized command $cmd" + return 1 +} diff --git a/templates/.zsh/path.zsh b/templates/.zsh/path.zsh new file mode 100644 index 0000000..85bac09 --- /dev/null +++ b/templates/.zsh/path.zsh @@ -0,0 +1,13 @@ +export PATH="$PATH:$PROJECTS/bin" +export PATH="$PATH:$HOME/.bin" +export PATH="$PATH:/usr/local/bin" +export PATH="$PATH:/usr/bin" +export PATH="$PATH:/usr/local/sbin" +export PATH="$PATH:/usr/sbin" +export PATH="$PATH:/bin" +export PATH="$PATH:/sbin" +export PATH="$PATH:/usr/local/go/bin" +export PATH="$PATH:$HOME/.rvm/bin" +export PATH="$PATH:$HOME/Library/Python/2.7/bin" +export PATH="$PATH:$HOME/.vim/bundle/fzf/bin" + diff --git a/templates/.zsh/prompt.zsh b/templates/.zsh/prompt.zsh new file mode 100644 index 0000000..f98a73e --- /dev/null +++ b/templates/.zsh/prompt.zsh @@ -0,0 +1,23 @@ +autoload -Uz vcs_info +setopt prompt_subst +zstyle ':vcs_info:*' enable git +zstyle ':vcs_info:*' check-for-changes true +zstyle ':vcs_info:*' stagedstr '+' +zstyle ':vcs_info:git:*' unstagedstr '*' +zstyle ':vcs_info:git*' formats " %b%u%c" +zstyle ':vcs_info:git*' actionformats " %b (%a)" + +git_prompt() { + local dirty + if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then + dirty=$(git status --porcelain 2>/dev/null | wc -l) + vcs_info + if [[ "$dirty" -ne "0" ]]; then + echo -n "%F{yellow}${vcs_info_msg_0_}%f" + else + echo -n "%F{green}${vcs_info_msg_0_}%f" + fi + fi +} + +export PROMPT='%F{blue}%~%f$(git_prompt) ' diff --git a/templates/.zsh/window.zsh b/templates/.zsh/window.zsh new file mode 100644 index 0000000..805cb92 --- /dev/null +++ b/templates/.zsh/window.zsh @@ -0,0 +1,19 @@ +# From http://dotfiles.org/~_why/.zshrc +# Sets the window title nicely no matter where you are +function title() { + # escape '%' chars in $1, make nonprintables visible + a=${(V)1//\%/\%\%} + + # Truncate command, and join lines. + a=$(print -Pn "%40>...>$a" | tr -d "\n") + + case $TERM in + screen) + print -Pn "\ek$a:$3\e\\" # screen title (in ^A") + ;; + xterm*|rxvt) + print -Pn "\e]2;$2\a" # plain xterm title ($3 for pwd) + ;; + esac +} + diff --git a/templates/.zshenv b/templates/.zshenv new file mode 100644 index 0000000..5f1679d --- /dev/null +++ b/templates/.zshenv @@ -0,0 +1 @@ +export XDG_RUNTIME_DIR=~/.run diff --git a/templates/.zshrc b/templates/.zshrc new file mode 100644 index 0000000..14cd800 --- /dev/null +++ b/templates/.zshrc @@ -0,0 +1,41 @@ +# vim: set ft=zsh: + +# shortcut to this dotfiles path is $ZSH +export ZSH=$HOME/.zsh + +# Load any machine-specific config and environment variables +if [[ -a ~/.localrc ]]; then + source ~/.localrc +fi + +source $ZSH/env.zsh +source $ZSH/path.zsh +source $ZSH/window.zsh +source $ZSH/aliases.zsh +source $ZSH/config.zsh +source $ZSH/prompt.zsh + +for f in $(find $ZSH/functions -type f); do + source $f +done + +fpath=($HOME/.bin $ZSH/functions $fpath) + +export GPG_TTY="$(tty)" +export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) +gpgconf --launch gpg-agent +gpg-connect-agent updatestartuptty /bye > /dev/null 2>&1 + +# initialize autocomplete here, otherwise functions won't be loaded +autoload -U compinit +compinit +source $ZSH/completion.zsh + +# external scripts +{{ range .Vars.ZSH.AutoScripts }} +if [[ -f "{{ . }}" ]] ; then source "{{ . }}" ; fi +{{ end }} + +if [[ -x /usr/bin/setxkbmap ]]; then + setxkbmap -option caps:escape +fi diff --git a/vars.toml b/vars.toml index 8d44f88..223d37d 100644 --- a/vars.toml +++ b/vars.toml @@ -21,3 +21,14 @@ Cyan = "0x73b8bf" BrightCyan = "0x95dfe6" White = "0xe6e0cf" BrightWhite = "0xfff9e9" + +[ZSH] +AutoScripts = [ + "/usr/local/opt/fzf/shell/completion.zsh", + "/usr/local/opt/fzf/shell/key-bindings.zsh", + "$HOME/.iterm2_shell_integration.zsh", + "$HOME/.travis/travis.sh", + "$HOME/.rvm/scripts/rvm", + "$HOME/Applications/google-cloud-sdk/path.zsh.inc", + "$HOME/Applications/google-cloud-sdk/completion.zsh.inc" +] -- cgit v1.2.3