From c4be365696c733e761c66a6519c7d090a5af3dba Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 20 Dec 2015 23:39:59 -0500 Subject: [PATCH] Global bash/zsh aliases + new programs + add common.sh and common aliases + add bin/{since,til} + add bin/project-root + extract btl alias into bin/transmission-list --- .common.sh | 30 +++++ aliases | 285 ++++++++++++++++++++++++++++++++++++++++++ bin/project-root | 11 ++ bin/since | 58 +++++++++ bin/til | 58 +++++++++ bin/transmission-list | 10 ++ 6 files changed, 452 insertions(+) create mode 100644 .common.sh create mode 100755 aliases create mode 100755 bin/project-root create mode 100755 bin/since create mode 100755 bin/til create mode 100755 bin/transmission-list diff --git a/.common.sh b/.common.sh new file mode 100644 index 00000000..067144b4 --- /dev/null +++ b/.common.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +DOTFILES="$HOME/.dotfiles" +CACHE_DIR="$HOME/.cache" + +is-callable() { command -v "$1" >/dev/null; } +is-interactive() { [[ $- == *i* ]]; } +is-root() { [[ "$UID" -eq 0 ]]; } +is-ssh() { [[ "$SSH_CONNECTION" != '' ]]; } + +load() { source "$DOTFILES/$1"; } +iload() { is-interactive && load "$1"; } + +cache() { + if [[ -z "$CACHE_DIR" ]]; then + >&2 echo "Cache not set!" + return 1 + fi + + [[ ! -d "$CACHE_DIR" ]] && mkdir -p "$CACHE_DIR" + + is-callable "$1" || return 1 + local cache="${CACHE_DIR}/$1" + if ! [[ -f "$cache" && -s "$cache" ]]; then + echo "Caching $1" + $@ > "$cache" 2> /dev/null + fi + source $cache +} + diff --git a/aliases b/aliases new file mode 100755 index 00000000..a1c0a00e --- /dev/null +++ b/aliases @@ -0,0 +1,285 @@ +## aliases +# +# Aliases that apply regardless of shell. Loaded from ./.${SHELL}/aliases +# +## Named Directories ######################################################### + +W=~/Dropbox/work +O=~/Dropbox/org +LOGS=/var/log +DL=~/Downloads + +if [[ "$OSTYPE" == linux* ]]; then + WWW=/var/www + DL=~/dl +fi + + +## Fast folder navigation #################################################### + +# Must be separate from the main body; which otherwise interferes with z() +alias zz='cd -P $(project-root)' + +# fzf/fasd +is-callable 'z' && unalias z +if is-callable 'fasd' && is-callable 'fzf'; then + # MRU for directories; if blank, bring up fzf, otherwise use fasd + z() { + if (($# == 0)); then + cd -P "$(fasd_cd -l 2>&1 | fzf-tmux +s --tac -1 -e | sed 's/^[0-9,.]* *//')" + else + _last_z_args="$@" + fasd_cd -d "$@" + fi + } + + # Fuzzy find for $EDITOR if no args + v() { + if (($# == 0)); then + local t + t=$(fasd -lf "$*" |\ + fzf --tac +s -m -1 -e --query="$*") && \ + $EDITOR "${t[@]}" + else + $EDITOR $* + fi + } + + # Jump to a parent directory + b() { + (($#>0)) && local args="-f$*" + local dir + dir=$({ + local _path="$PWD" + while [[ -n "$_path" && "$_path" != "/" ]]; do + _path="${_path%/*}" + echo $_path + done + } | fzf +s -e -0 -1 $args --query="$*") && cd "$dir" + } + + # Emacs version of v + e() { + if pgrep Emacs 2>&1 >/dev/null; then + EDITOR='emacsclient -n' v $@ + else + EDITOR='/Applications/Emacs.app/Contents/MacOS/Emacs' v $@ & + fi + } +else + alias v='vim' + alias e='emacs' +fi + +# Editors +is-callable 'emacs' && alias emacs='emacs -nw' +is-callable 'nvim' && alias vim=nvim +ediff() { e --eval "(ediff-files \"$1\" \"$2\")"; } + + +## Redefined tools ########################################################### +# Always enable colored `grep` output +# Note: `GREP_OPTIONS="--color=auto"` is deprecated, hence the alias usage. +alias grep='grep --color=auto' +alias fgrep='fgrep --color=auto' +alias egrep='egrep --color=auto' + +alias ssh='ssh -C' # Compression for all ssh connections +alias ag='noglob ag' +alias l="ls -l" +alias ll="ls -1" +alias la="ls -la" +alias ln="ln -v" # Verbose ln +alias wget='wget -c' # Resume dl if possible +alias rsyncd='rsync -va --delete' # Hard sync two directories +alias mkdir='mkdir -p' +alias gurl='curl --compressed' +take() { mkdir "$1" && cd "$1"; } + + +## pbcopy/pbpaste, ls & open ################################################# +# Detect which `ls` flavor is in use +if ls --color > /dev/null 2>&1; then # GNU `ls` + colorflag="--color" +else # OS X `ls` + colorflag="-G" +fi +alias ls="command ls -F ${colorflag}" +case $OSTYPE in + "darwin"*) # is OSX + alias ls="ls -G" + alias date="gdate" + ;; + "linux"*) + alias open='xdg-open' + alias ls="ls --color=auto" + + if (( $+commands[xclip] )); then + alias pbcopy='xclip -selection clipboard -in' + alias pbpaste='xclip -selection clipboard -out' + elif (( $+commands[xsel] )); then + alias pbcopy='xsel --clipboard --input' + alias pbpaste='xsel --clipboard --output' + fi + ;; + "cygwin"*) + alias open='cygstart' + alias pbcopy='tee > /dev/clipboard' + alias pbpaste='cat /dev/clipboard' + ;; +esac +o() { open ${*:-.}; } # By default, open cwd +alias y='pbcopy' # Yank to clipboard +alias yy='tr -d '\n' | pbcopy' # Strip newlines + copy to clipboard +alias p='pbpaste' # Echo clipboard contents + + +## New tools ################################################################# +alias q='exit' +alias clr='clear' +# Enable aliases to be sudo’ed +alias sudo='sudo ' +alias ..="cd .." +alias ...="cd ../.." +alias ....="cd ../../.." +alias -- -="cd -" +# Intuitive map function +# For example, to list all directories that contain a certain file: find . -name +# .gitattributes | map dirname +alias map="xargs -n1" + +hex() { echo -n $@ | xxd -psdu; } + +# Canonical hex dump; some systems have this symlinked +is-callable hd || alias hd="hexdump -C" +# OS X has no `md5sum`, so use `md5` as a fallback +is-callable md5sum || alias md5sum="md5" +# OS X has no `sha1sum`, so use `shasum` as a fallback +is-callable sha1sum || alias sha1sum="shasum" + +## Remote resources +# URL-encode strings +alias urlencode='python -c "import sys, urllib as ul; print ul.quote_plus(sys.argv[1]);"' +# find conflicted dropbox files +alias findc="find . -iname '*conflicted*' -type f -exec echo '\"{}\" ' \;" +# Send to sprunge.us +alias bin="curl -s -F 'sprunge=<-' http://sprunge.us | head -n 1 | tr -d '\r\n ' | y" +# IP addresses +alias ip="dig +short myip.opendns.com @resolver1.opendns.com" +alias localip="ipconfig getifaddr en0" +alias ips="ifconfig -a | grep -o 'inet6\? \(addr:\)\?\s\?\(\(\([0-9]\+\.\)\{3\}[0-9]\+\)\|[a-fA-F0-9:]\+\)' | awk '{ sub(/inet6? (addr:)? ?/, \"\"); print }'" +# View HTTP traffic +alias sniff="sudo ngrep -d 'en0' -t '^(GET|POST) ' 'tcp and port 80'" +alias httpdump="sudo tcpdump -i en0 -n -s 0 -w - | grep -a -o -E \"Host\: .*|GET \/.*\"" +# Make URL REQUEST shortcuts +for method in GET HEAD POST PUT DELETE TRACE OPTIONS; do + alias "$method"="lwp-request -m '$method'" +done + + +## Compilers, interpretors 'n builders ####################################### +alias va='vagrant' +alias py='python' +alias pye='pyenv' +alias rb='ruby' +alias rbe='rbenv' +alias bu='bundle' +alias bue='bundle exec' +alias bui='bundle install -path vendor' +alias ans='ansible' +alias ansp='ansible-playbook' +alias fabg='noglob fab -f ~/.dotfiles/ansible/fabfile.py' +alias rk='rake' +alias rkg='rake -g' +alias mk='make' +alias dk='docker' +alias exe='exercism' +alias c11='clang++ -std=c++11' + +case $OSTYPE in + "darwin"*) # is OSX + # Homebrew + alias br='brew' + alias bru='brew update && brew upgrade --all' + alias brc='brew cask' + alias codekit='open -a CodeKit' + ;; + "linux"*) + alias apt='sudo apt-get' + alias aptu='sudo apt-get update && sudo apt-get upgrade' + ;; + "cygwin"*) + ;; +esac + + +## GIT ####################################################################### +is-callable 'hub' && alias git='hub' +g() { [ $# -eq 0 ] && git status --short || git $*; } + +alias gbr='git browse' +alias gi='git init' +alias gs='git status' +alias gsu='git submodule' +alias gsq='git squash' +alias gco='git checkout' +alias gc='git commit' +alias gcm='noglob git commit -m' +alias gcma='noglob git commit --amend -m' +alias gd='git diff' +alias gp='git push' +alias gpb='git push origin' +alias gpt='git push --follow-tags' +alias gpl='git pull' +alias ga='git add' +alias gau='git add -u' +alias gb='git branch' +alias gbd='git branch -D' +alias gap='git add --patch' +alias gr='git reset HEAD' +alias gt='git tag' +alias gtd='git tag -d' +alias gta='git tag -a' +alias gl='git log --oneline' +alias gls='git ls-files' + +# transmission-remote +if is-callable 'transmission-remote'; then + alias bt='transmission-remote server' + alias bt-clear='bt -t all -r' + alias btl='transmission-list server' +fi + +# Tmux +if is-callable 'tmux'; then + alias ta='tmux attach' + alias tl='tmux ls' + + if [[ -n $TMUX ]]; then + alias t='tmux' + alias tf='tmux find-window' + # Detach all other clients to this session + alias mine='tmux detach -a' + # Create new session (from inside one) + tn() { + local name="${1:-`basename $PWD`}" + TMUX= tmux new-session -d -s "$name" + tmux switch-client -t "$name" + tmux display-message "Session #S created" + } + ts() { + local session=$(tmux list-sessions -F "#{session_name}" | \ + fzf --query="$1" --select-1 --exit-0) && + tmux switch-client -t "$session" + } + else + t() { + if (( $# > 0 )); then + tmux $@ || tmux attach -t main + else tmux new -s main; fi + } + + # Start grouped session so I can be in two different windows in one session + tdup() { tmux new-session -t "${1:-`tmux display-message -p '#S'`}"; } + fi +fi diff --git a/bin/project-root b/bin/project-root new file mode 100755 index 00000000..534c236c --- /dev/null +++ b/bin/project-root @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +local dir="${PWD%/*}" +while [[ ! -d "$dir/.git" && ! -d "$dir/.hg" && ! -d "$dir/.svn" && ! -f "$dir/.project" ]]; do + dir="${dir%/*}" + if [[ -z "$dir" ]]; then + echo -n "$PWD" + return + fi +done +echo -n "$dir" diff --git a/bin/since b/bin/since new file mode 100755 index 00000000..abd73c26 --- /dev/null +++ b/bin/since @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -e +(( $# > 0 )) || exit 1 + +# Displays the time since $1 in a human readable format (e.g. 4h 25m 55s). If given a +# file, the modified time is used. If $1 == "--", then this script acts as a converter, +# converting $2 into human a readable format, e.g. since -- 72 #=> 1m 12s + +# TODO: A help fallback +# TODO: Options parsing + +# `date` on OSX does not have the --date parameter +date=date +if [[ "$OSTYPE" == darwin* ]]; then + date=gdate +else + echo "Unsupported system" + exit 1 +fi + +# If given a file, give time since last modification +(( $# == 1 )) && [[ -f "$*" ]] && arg=reference || arg=date + +args="$*" +if [[ "$1" == "--" ]]; then + t="$2" +else + now=$(${date} +%s) + then=$(${date} --$arg="$*" +%s) + + # Show full target date + echo $(${date} --date="@$then") + + t=$(( $now - $then )) +fi + +# Bash doesn't support floating point arithmetic like zsh does, therefore: +bc < 0) print weeks, "w " + if (days > 0) print days, "d " + if (hours > 0) print hours, "h " + if (minutes > 0) print minutes, "m " + print seconds, "s" +EOF + diff --git a/bin/til b/bin/til new file mode 100755 index 00000000..abd73c26 --- /dev/null +++ b/bin/til @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -e +(( $# > 0 )) || exit 1 + +# Displays the time since $1 in a human readable format (e.g. 4h 25m 55s). If given a +# file, the modified time is used. If $1 == "--", then this script acts as a converter, +# converting $2 into human a readable format, e.g. since -- 72 #=> 1m 12s + +# TODO: A help fallback +# TODO: Options parsing + +# `date` on OSX does not have the --date parameter +date=date +if [[ "$OSTYPE" == darwin* ]]; then + date=gdate +else + echo "Unsupported system" + exit 1 +fi + +# If given a file, give time since last modification +(( $# == 1 )) && [[ -f "$*" ]] && arg=reference || arg=date + +args="$*" +if [[ "$1" == "--" ]]; then + t="$2" +else + now=$(${date} +%s) + then=$(${date} --$arg="$*" +%s) + + # Show full target date + echo $(${date} --date="@$then") + + t=$(( $now - $then )) +fi + +# Bash doesn't support floating point arithmetic like zsh does, therefore: +bc < 0) print weeks, "w " + if (days > 0) print days, "d " + if (hours > 0) print hours, "h " + if (minutes > 0) print minutes, "m " + print seconds, "s" +EOF + diff --git a/bin/transmission-list b/bin/transmission-list new file mode 100755 index 00000000..133a0a1d --- /dev/null +++ b/bin/transmission-list @@ -0,0 +1,10 @@ +#!/usr/bin/env zsh + +# Pretty print remote transmission torrents. Takes one argument: the server hostname/ip + +local results +results=`transmission-remote "$1" -l | \ + awk 'NR > 1 { s = ""; for (i = 10; i <= NF; i++) s = s $i " "; print $9 " | " s }' | \ + sed '$d' | \ + perl -pe 's/\s\[[a-zA-Z0-9]+\]\s/ /g'` && echo "$results" || echo "No torrents!" +