Compare commits

...

9 commits

27 changed files with 27487 additions and 1447 deletions

View file

@ -1,3 +1,17 @@
# enable color support of ls and also add handy aliases
if hash dircolors 2>/dev/null; then
if [ -r ~/.dircolors ]; then
eval "$(dircolors -b ~/.dircolors)"
else
eval "$(dircolors -b)"
fi
alias ls='ls --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
# some more ls aliases
alias ll='ls -l'
alias la='ls -A'
@ -15,6 +29,7 @@ alias psa='ps aux'
alias psag='ps aux | grep'
alias ka=killall
alias s=sudo
alias g=git
alias k=kubectl
alias a=ansible
@ -22,17 +37,13 @@ alias c=code
alias e=$EDITOR
alias h=helm
alias d=docker
alias r=rancher
alias n="code ~/workspace/notes"
alias vi=vim
alias nano=vim
# Some shortcuts for me
function moby() {
[ -f ~/.bash_env ] && source ~/.bash_env
MACHINE=${1:-"default"}
docker-machine start $MACHINE
eval $(docker-machine env $MACHINE)
}
function jumphost() {
DEST=$1
@ -87,24 +98,43 @@ function rdp() {
fi
}
function aws() {
local PASS=$(pass providers/aws)
local AWS=$(which aws)
# Start original aws executable with short-lived keys
AWS_ACCESS_KEY_ID=$(sed -En 's/^Access-Key: (.*)/\1/p' <<< "$PASS") \
AWS_SECRET_ACCESS_KEY=$(sed -En 's/^Secret-Key: (.*)/\1/p' <<< "$PASS") \
$AWS $@
}
function restic() {
local RESTIC=$(which restic)
# Start original restic executable with short-lived keys
AWS_ACCESS_KEY_ID=restic \
AWS_SECRET_ACCESS_KEY=$(pass s3/minio-restic | head -n1) \
RESTIC_PASSWORD="$(pass restic/macbook | head -n1)" \
$RESTIC $@
(
export RESTIC_PASSWORD="$(pass restic/macbook)"
s3 minio-restic
$RESTIC $@
)
}
function backup() {
restic backup --exclude-if-present .resticignore ~
}
# Load S3 credentials from password-store
function s3() {
if [ "${AWS_ACCESS_KEY_PASS}" == $1 ]; then
return
fi
OUT=$(pass s3/$1)
AWS_SECRET_ACCESS_KEY=$(sed -n 1p <<< ${OUT})
AWS_ACCESS_KEY_ID=$(sed -En 's/^User: (.*)/\1/p' <<< ${OUT})
AWS_ACCESS_KEY_PASS=$1
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
}
function backup-phone() {
pushd ~/annex/
git annex sync --no-push --content android
popd
}
function oath() {
@ -113,7 +143,7 @@ function oath() {
alias acs-pass='PASSWORD_STORE_DIR=~/workspace/rwth/acs/lab/passwords pass'
alias chaos-family-invite='ssh -t ssb.vm.0l.de sudo /root/sbot invite.create 1 | jq -r . | pbcopy'
alias chaos-family-invite='kubectl --context=nulll --namespace=ssb exec svc/pub -- sbot invite.create 1 | jq -r . | pbcopy'
alias new-mac=$'openssl rand -hex 6 | sed \'s/\(..\)/\1:/g; s/.$//\' | xargs sudo ifconfig en0 ether'
@ -122,3 +152,5 @@ if type xdg-open > /dev/null 2>&1; then
fi
alias chrome="chromium-browser --enable-features=UseOzonePlatform --ozone-platform=wayland"
. ~/.homesick/repos/dotfiles/z.sh

View file

@ -2,65 +2,21 @@ if [ -f /usr/share/bash-completion/bash_completion ]; then
source /usr/share/bash-completion/bash_completion
fi
if type ykman > /dev/null 2>&1; then
_ykman_completion() {
local IFS=$'
'
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_YKMAN_COMPLETE=complete $1 ) )
return 0
}
_ykman_completionetup() {
local COMPLETION_OPTIONS=""
local BASH_VERSION_ARR=(${BASH_VERSION//./ })
# Only BASH version 4.4 and later have the nosort option.
if [ ${BASH_VERSION_ARR[0]} -gt 4 ] || ([ ${BASH_VERSION_ARR[0]} -eq 4 ] && [ ${BASH_VERSION_ARR[1]} -ge 4 ]); then
COMPLETION_OPTIONS="-o nosort"
fi
complete $COMPLETION_OPTIONS -F _ykman_completion ykman
}
_ykman_completionetup;
fi
if type kubectl > /dev/null 2>&1; then
source <(kubectl completion bash)
fi
if type doctl > /dev/null 2>&1; then
source <(doctl completion bash)
fi
if type helm > /dev/null 2>&1; then
source <(helm completion bash)
fi
if type mc > /dev/null 2>&1; then
complete -C mc mc
fi
# Homebrew completions
if command -v brew > /dev/null; then
HOMEBREW_PREFIX=$(brew --prefix)
if type brew &>/dev/null; then
for COMPLETION in "$HOMEBREW_PREFIX"/etc/bash_completion.d/*; do
[[ -f $COMPLETION ]] && source "$COMPLETION"
done
if [[ -f ${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh ]]; then
source "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh"
fi
fi
fi
# Docker completions
for COMPLETION in /Applications/Docker.app/Contents/Resources/etc/*.bash-completion; do
[ -f ${COMPLETION} ] && source ${COMPLETION}
for FILE in ~/.bash_completion.d/*; do
source ${FILE}
done
# Add completion to aliases
# See: https://github.com/cykerway/complete-alias
source ~/.homesick/repos/complete-alias/complete_alias
complete -F _complete_alias "${!BASH_ALIASES[@]}"
# Update complations if outdated
MAX_AGE=$(( 3*24*60*60 )) # Seconds
GENERATED=~/.bash_completion.d/generated
if (( $(date +%s) - $(date +%s -r "${GENERATED}") > ${MAX_AGE} )) || [ -n "${UPDATE_COMPLETIONS}" ]; then
echo "Start updating of completions..."
. ~/.homesick/repos/dotfiles/update-completions.sh ${GENERATED}
echo "Completions updated"
fi

View file

@ -0,0 +1 @@
/Users/stv0g_local/.homesick/repos/complete-alias/bash_completion.sh

View file

@ -0,0 +1,3 @@
if type doctl > /dev/null 2>&1; then
source <(doctl completion bash)
fi

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,3 @@
if type helm > /dev/null 2>&1; then
source <(helm completion bash)
fi

View file

@ -0,0 +1,3 @@
if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion
fi

View file

@ -0,0 +1 @@
/Users/stv0g_local/.homesick/repos/homeshick/completions/homeshick-completion.bash

View file

@ -0,0 +1,3 @@
if type doctl > /dev/null 2>&1; then
source <(doctl completion bash)
fi

View file

@ -0,0 +1,3 @@
if type mc > /dev/null 2>&1; then
complete -C mc mc
fi

View file

@ -0,0 +1,10 @@
function _oath_completion() {
if [ -n "$2" ]; then
WORD=$2
mapfile -t COMPREPLY < <(grep -i $2 ~/.oath_tokens)
else
mapfile -t COMPREPLY < ~/.oath_tokens
fi
}
complete -F _oath_completion oath

12
home/.bash_completion.d/ykman Executable file
View file

@ -0,0 +1,12 @@
if type ykman > /dev/null 2>&1; then
_ykman_completion() {
local IFS=$'
'
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_YKMAN_COMPLETE=complete $1 ) )
return 0
}
complete -F _ykman_completion ykman
fi

View file

@ -12,7 +12,7 @@ if [ -d /var/lib/snapd/snap/bin/code ]; then
export PATH="/var/lib/snapd/snap/bin/code:${PATH}"
fi
if [ -d ${KREW_ROOT:-$HOME/.krew}/bin ]; then
if [ -d ${KREW_ROOT:-${HOME}/.krew}/bin ]; then
PATH="${KREW_ROOT:-${HOME}/.krew}/bin:${PATH}"
fi
@ -34,23 +34,29 @@ fi
source ${HOME}/.cargo/env
if type brew > /dev/null 2>&1; then
eval $(brew shellenv)
export PATH="$(brew --prefix coreutils)/libexec/gnubin:${PATH}"
fi
# OS X stuff if availabe
if type brew > /dev/null 2>&1; then
#eval $(brew shellenv)
#export PATH="$(brew --prefix coreutils)/libexec/gnubin:${PATH}"
export HOMEBREW_PREFIX="/usr/local";
export HOMEBREW_CELLAR="/usr/local/Cellar";
export HOMEBREW_REPOSITORY="/usr/local/Homebrew";
export PATH="/usr/local/bin:/usr/local/sbin${PATH+:$PATH}";
export MANPATH="/usr/local/share/man${MANPATH+:$MANPATH}:";
export INFOPATH="/usr/local/share/info${INFOPATH+:$INFOPATH}";
export PATH="/usr/local/opt/coreutils/libexec/gnubin:${PATH}"
fi
# MacGPG2
if [ -d /usr/local/MacGPG2/bin/ ]; then
export PATH=/usr/local/MacGPG2/bin/:$PATH
fi
# Linux man-pages
if [ -d /opt/man-pages ]; then
export MANPATH=/opt/man-pages:${MANPATH}
fi
export MANPATH=~/.homesick/repos/dotfiles/man:/opt/man-pages:${MANPATH}
if type code > /dev/null 2>&1; then
export EDITOR="code -w"
@ -60,9 +66,6 @@ fi
export RESTIC_REPOSITORY="s3:http://moon.0l.de:9002/cam"
export AWS_ACCESS_KEY_ID=stv0g
export AWS_SECRET_ACCESS_KEY=m1n10Password
export GCC_COLORS="error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01"
export DEBEMAIL="post@steffenvogel.de"
@ -74,7 +77,7 @@ export LANG=en_US.UTF-8
export GRC_BLOCKS_PATH=/usr/local/share/gnuradio/grc/blocks/
export CALICO_DATASTORE_TYPE=kubernetes
export CALICO_KUBECONFIG=~/.kube/config
export CALICO_KUBECONFIG=~/.kube/config.d/nulll
function join_by { local IFS="$1"; shift; echo "$*"; }

View file

@ -66,6 +66,19 @@
# git always compare HEAD to @{upstream}
# svn always compare HEAD to your SVN upstream
#
# You can change the separator between the branch name and the above
# state symbols by setting GIT_PS1_STATESEPARATOR. The default separator
# is SP.
#
# When there is an in-progress operation such as a merge, rebase,
# revert, cherry-pick, or bisect, the prompt will include information
# related to the operation, often in the form "|<OPERATION-NAME>".
#
# When the repository has a sparse-checkout, a notification of the form
# "|SPARSE" will be included in the prompt. This can be shortened to a
# single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted
# by setting GIT_PS1_OMITSPARSESTATE.
#
# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
# find one, or @{upstream} otherwise. Once you have set
# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
@ -78,12 +91,19 @@
# contains relative to newer annotated tag (v1.6.3.2~35)
# branch relative to newer tag or branch (master~4)
# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
# tag relative to any older tag (v1.6.3.1-13-gdd42c2f)
# default exactly matching tag
#
# If you would like a colored hint about the current dirty state, set
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
# the colored output of "git status -sb" and are available only when
# using __git_ps1 for PROMPT_COMMAND or precmd.
# using __git_ps1 for PROMPT_COMMAND or precmd in Bash,
# but always available in Zsh.
#
# If you would like __git_ps1 to do nothing in the case when the current
# directory is set up to be ignored by git, then set
# GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the
# repository level by setting bash.hideIfPwdIgnored to "false".
# check whether printf supports -v
__git_printf_supports_v=
@ -118,6 +138,7 @@ __git_ps1_show_upstream ()
done <<< "$output"
# parse configuration values
local option
for option in ${GIT_PS1_SHOWUPSTREAM}; do
case "$option" in
git|svn) upstream="$option" ;;
@ -268,11 +289,43 @@ __git_ps1_colorize_gitstring ()
r="$c_clear$r"
}
# Helper function to read the first line of a file into a variable.
# __git_eread requires 2 arguments, the file path and the name of the
# variable, in that order.
__git_eread ()
{
local f="$1"
shift
test -r "$f" && read "$@" <"$f"
test -r "$1" && IFS=$'\r\n' read "$2" <"$1"
}
# see if a cherry-pick or revert is in progress, if the user has committed a
# conflict resolution with 'git commit' in the middle of a sequence of picks or
# reverts then CHERRY_PICK_HEAD/REVERT_HEAD will not exist so we have to read
# the todo file.
__git_sequencer_status ()
{
local todo
if test -f "$g/CHERRY_PICK_HEAD"
then
r="|CHERRY-PICKING"
return 0;
elif test -f "$g/REVERT_HEAD"
then
r="|REVERTING"
return 0;
elif __git_eread "$g/sequencer/todo" todo
then
case "$todo" in
p[\ \ ]|pick[\ \ ]*)
r="|CHERRY-PICKING"
return 0
;;
revert[\ \ ]*)
r="|REVERTING"
return 0
;;
esac
fi
return 1
}
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
@ -288,6 +341,8 @@ __git_eread ()
# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
__git_ps1 ()
{
# preserve exit status
local exit=$?
local pcmode=no
local detached=no
local ps1pc_start='\u@\h:\w '
@ -299,10 +354,14 @@ __git_ps1 ()
ps1pc_start="$1"
ps1pc_end="$2"
printf_format="${3:-$printf_format}"
# set PS1 to a plain prompt so that we can
# simply return early if the prompt should not
# be decorated
PS1="$ps1pc_start$ps1pc_end"
;;
0|1) printf_format="${1:-$printf_format}"
;;
*) return
*) return $exit
;;
esac
@ -340,8 +399,8 @@ __git_ps1 ()
# incorrect.)
#
local ps1_expanded=yes
[ -z "$ZSH_VERSION" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
[ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no
[ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
[ -z "${BASH_VERSION-}" ] || shopt -q promptvars || ps1_expanded=no
local repo_info rev_parse_exit_code
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
@ -350,14 +409,10 @@ __git_ps1 ()
rev_parse_exit_code="$?"
if [ -z "$repo_info" ]; then
if [ $pcmode = yes ]; then
#In PC mode PS1 always needs to be set
PS1="$ps1pc_start$ps1pc_end"
fi
return
return $exit
fi
local short_sha
local short_sha=""
if [ "$rev_parse_exit_code" = "0" ]; then
short_sha="${repo_info##*$'\n'}"
repo_info="${repo_info%$'\n'*}"
@ -369,6 +424,21 @@ __git_ps1 ()
local inside_gitdir="${repo_info##*$'\n'}"
local g="${repo_info%$'\n'*}"
if [ "true" = "$inside_worktree" ] &&
[ -n "${GIT_PS1_HIDE_IF_PWD_IGNORED-}" ] &&
[ "$(git config --bool bash.hideIfPwdIgnored)" != "false" ] &&
git check-ignore -q .
then
return $exit
fi
local sparse=""
if [ -z "${GIT_PS1_COMPRESSSPARSESTATE}" ] &&
[ -z "${GIT_PS1_OMITSPARSESTATE}" ] &&
[ "$(git config --bool core.sparseCheckout)" = "true" ]; then
sparse="|SPARSE"
fi
local r=""
local b=""
local step=""
@ -377,11 +447,7 @@ __git_ps1 ()
__git_eread "$g/rebase-merge/head-name" b
__git_eread "$g/rebase-merge/msgnum" step
__git_eread "$g/rebase-merge/end" total
if [ -f "$g/rebase-merge/interactive" ]; then
r="|REBASE-i"
else
r="|REBASE-m"
fi
r="|REBASE"
else
if [ -d "$g/rebase-apply" ]; then
__git_eread "$g/rebase-apply/next" step
@ -396,10 +462,8 @@ __git_ps1 ()
fi
elif [ -f "$g/MERGE_HEAD" ]; then
r="|MERGING"
elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
r="|CHERRY-PICKING"
elif [ -f "$g/REVERT_HEAD" ]; then
r="|REVERTING"
elif __git_sequencer_status; then
:
elif [ -f "$g/BISECT_LOG" ]; then
r="|BISECTING"
fi
@ -412,10 +476,7 @@ __git_ps1 ()
else
local head=""
if ! __git_eread "$g/HEAD" head; then
if [ $pcmode = yes ]; then
PS1="$ps1pc_start$ps1pc_end"
fi
return
return $exit
fi
# is it a symbolic ref?
b="${head#ref: }"
@ -427,6 +488,8 @@ __git_ps1 ()
git describe --contains HEAD ;;
(branch)
git describe --contains --all HEAD ;;
(tag)
git describe --tags HEAD ;;
(describe)
git describe HEAD ;;
(* | default)
@ -447,6 +510,7 @@ __git_ps1 ()
local i=""
local s=""
local u=""
local h=""
local c=""
local p=""
@ -460,10 +524,9 @@ __git_ps1 ()
if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
[ "$(git config --bool bash.showDirtyState)" != "false" ]
then
git diff --no-ext-diff --quiet --exit-code || w="*"
if [ -n "$short_sha" ]; then
git diff-index --cached --quiet HEAD -- || i="+"
else
git diff --no-ext-diff --quiet || w="*"
git diff --no-ext-diff --cached --quiet || i="+"
if [ -z "$short_sha" ] && [ -z "$i" ]; then
i="#"
fi
fi
@ -475,11 +538,16 @@ __git_ps1 ()
if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
[ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
git ls-files --others --exclude-standard --error-unmatch -- '*' >/dev/null 2>/dev/null
git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null
then
u="%${ZSH_VERSION+%}"
fi
if [ -n "${GIT_PS1_COMPRESSSPARSESTATE}" ] &&
[ "$(git config --bool core.sparseCheckout)" = "true" ]; then
h="?"
fi
if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
__git_ps1_show_upstream
fi
@ -487,9 +555,11 @@ __git_ps1 ()
local z="${GIT_PS1_STATESEPARATOR-" "}"
# NO color option unless in PROMPT_COMMAND mode
if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
__git_ps1_colorize_gitstring
# NO color option unless in PROMPT_COMMAND mode or it's Zsh
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
__git_ps1_colorize_gitstring
fi
fi
b=${b##refs/heads/}
@ -498,8 +568,8 @@ __git_ps1 ()
b="\${__git_ps1_branch_name}"
fi
local f="$w$i$s$u"
local gitstring="$c$b${f:+$z$f}$r$p"
local f="$h$w$i$s$u"
local gitstring="$c$b${f:+$z$f}${sparse}$r$p"
if [ $pcmode = yes ]; then
if [ "${__git_printf_supports_v-}" != yes ]; then
@ -511,4 +581,6 @@ __git_ps1 ()
else
printf -- "$printf_format" "$gitstring"
fi
return $exit
}

View file

@ -1,3 +1,7 @@
if [ -f "$HOME/.bashrc" ]; then
source "$HOME/.bashrc"
if [ -f "${HOME}/.bashrc" ]; then
source "${HOME}/.bashrc"
fi
if [ -f "${HOME}/.iterm2_shell_integration.bash" ]; then
source "${HOME}/.iterm2_shell_integration.bash"
fi

View file

@ -20,23 +20,17 @@ function show_prompt {
local EXIT="$?"
# Time
local pre='\[\e[01;35m\]\A '
local pre='\[\e[01;35m\]\t '
local post
# Check last return value
if [ $EXIT != 0 ]; then
pre+='\[\e[31m\]'
pre+='\[\e[31m\]'
else
pre+='\[\e[32m\]'
pre+='\[\e[32m\]'
fi
case "$TERM" in
xterm*|rxvt*)
echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"
;;
*)
;;
esac
pre+=' \[\e[;37m\]\j \l '
# Test if root
if [ $EUID -ne 0 ]; then
@ -47,7 +41,11 @@ function show_prompt {
post='\[\e[01;33m\]\w'
fi
post+='\n \[\e[01;30m\]\# \[\e[31m\]\$ \[\e[00m\]'
post+='\[\e[;37m\]\n \[\e[01;30m\]\# \[\e[31m\]\$ \[\e[00m\]'
__git_ps1 "$pre " "$post" '\[\e[01;30m\](%s\[\e[01;30m\]) '
if [[ $(git config --default true --get prompt.show) == "false" ]]; then
PS1="$pre $post"
else
__git_ps1 "$pre " "$post" '\[\e[01;30m\](%s\[\e[01;30m\]) '
fi
}

View file

@ -12,6 +12,9 @@ shopt -s globstar
# append to the history file, don't overwrite it
shopt -s histappend
# Auto "cd" when entering just a path
shopt -s autocd
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignorespace:ignoredups:erasedups
@ -20,26 +23,13 @@ HISTCONTROL=ignorespace:ignoredups:erasedups
HISTSIZE=99999999
HISTFILESIZE=99999999
HOSTFILE=~/.hosts
# make less more friendly for non-text input files, see lesspipe(1)
if [ -x /usr/bin/lesspipe ]; then eval "$(lesspipe)"; fi
# Homeshick
source ~/.homesick/repos/homeshick/homeshick.sh
source ~/.homesick/repos/homeshick/completions/homeshick-completion.bash
# enable color support of ls and also add handy aliases
if hash dircolors 2>/dev/null; then
if [ -r ~/.dircolors ]; then
eval "$(dircolors -b ~/.dircolors)"
else
eval "$(dircolors -b)"
fi
alias ls='ls --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
source ~/.bash_env
source ~/.bash_prompt

View file

@ -42,6 +42,7 @@
[difftool "sourcetree"]
cmd = code-insiders --diff --wait \"$LOCAL\" \"$REMOTE\"
path =
[mergetool "sourcetree"]
cmd = code-insiders -n --wait \"$MERGED\"
trustExitCode = true
@ -55,6 +56,7 @@
ll = log --graph --pretty=oneline --abbrev-commit
lll = "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
a = add
an = annex
d = diff
p = push
po = push origin
@ -73,8 +75,10 @@
smtpServer = mail.0l.de
smtpUser = stv0g
smtpServerPort = 587
[pull]
rebase = false
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
required = true
process = git-lfs filter-process
required = true

View file

@ -1,10 +1,46 @@
# Color files by types
set colored-stats On
set colored-stats on
# Append char to indicate type
set visible-stats On
set visible-stats on
# Mark symlinked directories
set mark-symlinked-directories On
set mark-symlinked-directories on
# Color the common prefix
set colored-completion-prefix On
set colored-completion-prefix on
# Color the common prefix in menu-complete
set menu-complete-display-prefix On
set menu-complete-display-prefix on
set editing-mode vi
set keymap vi-command
# Show all completions as soon as I press tab, even if there's more than one
set show-all-if-ambiguous on
# Ignore case
set completion-ignore-case on
set completion-query-items 500
set show-mode-in-prompt on
# Color files by types
# Note that this may cause completion text blink in some terminals (e.g. xterm).
set colored-stats on
# Append char to indicate type
set visible-stats on
# Mark symlinked directories
set mark-symlinked-directories on
# Color the common prefix
set colored-completion-prefix on
# Color the common prefix in menu-complete
set menu-complete-display-prefix on
set vi-ins-mode-string \1\e[5 q\2
set vi-cmd-mode-string \1\e[2 q\2

View file

@ -1,11 +1,49 @@
CanonicalizeHostname yes
CanonicalDomains 0l.de rwth-aachen.de eonerc.rwth-aachen.de acs-lab.eonerc.rwth-aachen.de
CanonicalizeMaxDots 1
CanonicalDomains home.0l.de eonerc.rwth-aachen.de acs-lab.eonerc.rwth-aachen.de os-cloud.eonerc.rwth-aachen.de
# PKCS11Provider /usr/lib/ssh-keychain.dylib
VerifyHostKeyDNS yes
User stv0g
#
# Private
#
Host *.0l.de
ForwardAgent yes
# ControlPath ~/.ssh/controlmasters/%r@%h:%p
# ControlMaster auto
# ControlPersist 10m
# RemoteForward /run/user/0/gnupg/S.gpg-agent /Users/stv0g_local/.gnupg/S.gpg-agent.extra
RemoteForward /run/user/0/gnupg/S.gpg-agent /Users/stv0g_local/.gnupg/S.gpg-agent
Host rpi.home.0l.de
User root
Host kub*.0l.de
User root
Host rck.home.0l.de
User rock64
Host vog.int.0l.de
User pi
# Uni
Host *.rwth-aachen.de
ForwardAgent yes
Host deploy1-jh.itc.rwth-aachen.de
User root
Host *.k8s.jupyter.rwth-aachen.de
User jupyter
# ACS
# Autocompletion
Host zerberus.acs-lab.eonerc.rwth-aachen.de
Host zebra.acs-lab.eonerc.rwth-aachen.de
@ -63,11 +101,6 @@ Host acs-fedora-svg-2
User svg
HostName 134.130.169.13
Host inl-villas
User root
HostName 141.221.118.93
ProxyJump acs-villas
Host *.fein-aachen.org
ForwardAgent yes

View file

@ -1,20 +0,0 @@
#!/usr/bin/env expect -f
set query [lindex $argv 0]
spawn ykman oath code $query
expect "Enter your password:"
stty -echo
expect_user -re "(.*)\n"
stty echo
set pin $expect_out(1,string)
send "$pin\r\r"
expect "Touch your YubiKey..."
expect -re {(\d{6})}
set code $expect_out(1,string)
system printf $code | pbcopy

File diff suppressed because it is too large Load diff

View file

@ -34,6 +34,27 @@ ITERM_SHELL_INTEGRATION_INSTALLED=Yes
# (including various custom escape sequences).
ITERM_PREV_PS1="$PS1"
# A note on execution. When you invoke a command at an interactive prompt the following steps are taken:
#
# 1. The DEBUG trap runs.
# It calls __bp_preexec_invoke_exec
# It runs any registered preexec_functions, including __iterm2_preexec
# 2. The command you executed runs.
# 3. PROMPT_COMMAND runs.
# It runs __bp_precmd_invoke_cmd, which is inserted as the first command in PROMPT_COMMAND.
# It calls any registered precmd_functions
# Then, pre-existing PROMPT_COMMANDs run
# 4. The prompt is shown.
#
# __iterm2_prompt_command used to be run from precmd_functions but then a pre-existing
# PROMPT_COMMAND could clobber the PS1 it modifies. Instead, add __iterm2_prompt_command as the last
# of the "preexisting" PROMPT_COMMANDs so it will be the very last thing done before the prompt is
# shown (unless someone amends PROMPT_COMMAND, but that is on them).
if [[ -n "$PROMPT_COMMAND" ]]; then
PROMPT_COMMAND+=$'\n'
fi;
PROMPT_COMMAND+='__iterm2_prompt_command'
# The following chunk of code, bash-preexec.sh, is licensed like this:
# The MIT License
#
@ -60,24 +81,9 @@ ITERM_PREV_PS1="$PS1"
# Wrap bash-preexec.sh in a function so that, if it exits early due to having
# been sourced elsewhere, it doesn't exit our entire script.
_install_bash_preexec () {
# -- BEGIN BASH-PREEXEC.SH --
#!/bin/bash
#
# bash-preexec.sh -- Bash support for ZSH-like 'preexec' and 'precmd' functions.
# https://github.com/rcaloras/bash-preexec
#
#
# 'preexec' functions are executed before each interactive command is
# executed, with the interactive command as its argument. The 'precmd'
# function is executed before each prompt is displayed.
#
# Author: Ryan Caloras (ryan@bashhub.com)
# Forked from Original Author: Glyph Lefkowitz
#
# V0.3.7
#
# -- END ITERM2 CUSTOMIZATIONS --
# -- BEGIN BASH-PREEXEC.SH --
# bash-preexec.sh -- Bash support for ZSH-like 'preexec' and 'precmd' functions.
# https://github.com/rcaloras/bash-preexec
#
@ -89,7 +95,7 @@ _install_bash_preexec () {
# Author: Ryan Caloras (ryan@bashhub.com)
# Forked from Original Author: Glyph Lefkowitz
#
# V0.3.7
# V0.4.0
#
# General Usage:
@ -130,13 +136,16 @@ __bp_last_argument_prev_command="$_"
__bp_inside_precmd=0
__bp_inside_preexec=0
# Initial PROMPT_COMMAND string that is removed from PROMPT_COMMAND post __bp_install
__bp_install_string=$'__bp_trap_string="$(trap -p DEBUG)"\ntrap - DEBUG\n__bp_install'
# Fails if any of the given variables are readonly
# Reference https://stackoverflow.com/a/4441178
__bp_require_not_readonly() {
local var
for var; do
if ! ( unset "$var" 2> /dev/null ); then
echo "iTerm2 Shell Integration:bash-preexec requires write access to ${var}" >&2
echo "bash-preexec requires write access to ${var}" >&2
return 1
fi
done
@ -169,6 +178,19 @@ __bp_trim_whitespace() {
echo -n "$var"
}
# Returns a copy of the passed in string trimmed of whitespace
# and removes any leading or trailing semi colons.
# Used for manipulating substrings in PROMPT_COMMAND
__bp_sanitize_string() {
local sanitized_string
sanitized_string=$(__bp_trim_whitespace "${1:-}")
sanitized_string=${sanitized_string%;}
sanitized_string=${sanitized_string#;}
sanitized_string=$(__bp_trim_whitespace "$sanitized_string")
echo -n "$sanitized_string"
}
# This function is installed as part of the PROMPT_COMMAND;
# It sets a variable to indicate that the prompt was just displayed,
# to allow the DEBUG trap to know that the next command is likely interactive.
@ -216,7 +238,7 @@ __bp_set_ret_value() {
__bp_in_prompt_command() {
local prompt_command_array
IFS=';' read -ra prompt_command_array <<< "$PROMPT_COMMAND"
IFS=$'\n;' read -rd '' -a prompt_command_array <<< "$PROMPT_COMMAND"
local trimmed_arg
trimmed_arg=$(__bp_trim_whitespace "${1:-}")
@ -239,6 +261,7 @@ __bp_in_prompt_command() {
# environment to attempt to detect if the current command is being invoked
# interactively, and invoke 'preexec' if so.
__bp_preexec_invoke_exec() {
# Save the contents of $_ so that it can be restored later on.
# https://stackoverflow.com/questions/40944532/bash-preserve-in-a-debug-trap#40944702
__bp_last_argument_prev_command="${1:-}"
@ -346,7 +369,6 @@ __bp_install() {
# Adjust our HISTCONTROL Variable if needed.
__bp_adjust_histcontrol
# Issue #25. Setting debug trap for subshells causes sessions to exit for
# backgrounded subshell commands (e.g. (pwd)& ). Believe this is a bug in Bash.
#
@ -358,24 +380,33 @@ __bp_install() {
shopt -s extdebug > /dev/null 2>&1
fi;
local __bp_existing_prompt_command
# Remove setting our trap install string and sanitize the existing prompt command string
__bp_existing_prompt_command="${PROMPT_COMMAND//$__bp_install_string[;$'\n']}" # Edge case of appending to PROMPT_COMMAND
__bp_existing_prompt_command="${__bp_existing_prompt_command//$__bp_install_string}"
__bp_existing_prompt_command=$(__bp_sanitize_string "$__bp_existing_prompt_command")
# Install our hooks in PROMPT_COMMAND to allow our trap to know when we've
# actually entered something.
PROMPT_COMMAND="__bp_precmd_invoke_cmd; __bp_interactive_mode"
PROMPT_COMMAND=$'__bp_precmd_invoke_cmd\n'
if [[ -n "$__bp_existing_prompt_command" ]]; then
PROMPT_COMMAND+=${__bp_existing_prompt_command}$'\n'
fi;
PROMPT_COMMAND+='__bp_interactive_mode'
# Add two functions to our arrays for convenience
# of definition.
precmd_functions+=(precmd)
preexec_functions+=(preexec)
# Since this function is invoked via PROMPT_COMMAND, re-execute PC now that it's properly set
eval "$PROMPT_COMMAND"
# Invoke our two functions manually that were added to $PROMPT_COMMAND
__bp_precmd_invoke_cmd
__bp_interactive_mode
}
# Sets our trap and __bp_install as part of our PROMPT_COMMAND to install
# Sets an installation string as part of our PROMPT_COMMAND to install
# after our session has started. This allows bash-preexec to be included
# at any point in our bash profile. Ideally we could set our trap inside
# __bp_install, but if a trap already exists it'll only set locally to
# the function.
# at any point in our bash profile.
__bp_install_after_session_init() {
# Make sure this is bash that's running this and return otherwise.
@ -387,28 +418,20 @@ __bp_install_after_session_init() {
# if it can't, just stop the installation
__bp_require_not_readonly PROMPT_COMMAND HISTCONTROL HISTTIMEFORMAT || return
# If there's an existing PROMPT_COMMAND capture it and convert it into a function
# So it is preserved and invoked during precmd.
if [[ -n "$PROMPT_COMMAND" ]]; then
eval '__bp_original_prompt_command() {
'"$PROMPT_COMMAND"'
}'
precmd_functions+=(__bp_original_prompt_command)
fi
# Installation is finalized in PROMPT_COMMAND, which allows us to override the DEBUG
# trap. __bp_install sets PROMPT_COMMAND to its final value, so these are only
# invoked once.
# It's necessary to clear any existing DEBUG trap in order to set it from the install function.
# Using \n as it's the most universal delimiter of bash commands
PROMPT_COMMAND=$'\n__bp_trap_string="$(trap -p DEBUG)"\ntrap DEBUG\n__bp_install\n'
local sanitized_prompt_command
sanitized_prompt_command=$(__bp_sanitize_string "$PROMPT_COMMAND")
if [[ -n "$sanitized_prompt_command" ]]; then
PROMPT_COMMAND=${sanitized_prompt_command}$'\n'
fi;
PROMPT_COMMAND+=${__bp_install_string}
}
# Run our install so long as we're not delaying it.
if [[ -z "$__bp_delay_install" ]]; then
if [[ -z "${__bp_delay_install:-}" ]]; then
__bp_install_after_session_init
fi;
# -- END BASH-PREEXEC.SH --
}
_install_bash_preexec
unset -f _install_bash_preexec
@ -431,8 +454,12 @@ function iterm2_end_osc {
}
function iterm2_print_state_data() {
local _iterm2_hostname="${iterm2_hostname}"
if [ -z "${iterm2_hostname:-}" ]; then
_iterm2_hostname=$(hostname -f 2>/dev/null)
fi
iterm2_begin_osc
printf "1337;RemoteHost=%s@%s" "$USER" "$iterm2_hostname"
printf "1337;RemoteHost=%s@%s" "$USER" "$_iterm2_hostname"
iterm2_end_osc
iterm2_begin_osc
@ -479,17 +506,20 @@ function iterm2_prompt_suffix() {
function iterm2_print_version_number() {
iterm2_begin_osc
printf "1337;ShellIntegrationVersion=14;shell=bash"
printf "1337;ShellIntegrationVersion=16;shell=bash"
iterm2_end_osc
}
# If hostname -f is slow on your system, set iterm2_hostname before sourcing this script.
# On macOS we run `hostname -f` every time because it is fast.
if [ -z "${iterm2_hostname:-}" ]; then
iterm2_hostname=$(hostname -f 2>/dev/null)
# some flavors of BSD (i.e. NetBSD and OpenBSD) don't have the -f option
if [ $? -ne 0 ]; then
iterm2_hostname=$(hostname)
if [ "$(uname)" != "Darwin" ]; then
iterm2_hostname=$(hostname -f 2>/dev/null)
# some flavors of BSD (i.e. NetBSD and OpenBSD) don't have the -f option
if [ $? -ne 0 ]; then
iterm2_hostname=$(hostname)
fi
fi
fi
@ -513,7 +543,9 @@ __iterm2_preexec() {
__bp_set_ret_value "$__iterm2_last_ret_value" "$__bp_last_argument_prev_command"
}
function __iterm2_precmd () {
# Prints the current directory and hostname control sequences. Modifies PS1 to
# add the FinalTerm A and B codes to locate the prompt.
function __iterm2_prompt_command () {
__iterm2_last_ret_value="$?"
# Work around a bug in CentOS 7.2 where preexec doesn't run if you press
@ -524,8 +556,6 @@ function __iterm2_precmd () {
fi
iterm2_ran_preexec=""
# This is an iTerm2 addition to try to work around a problem in the
# original preexec.bash.
# When the PS1 has command substitutions, this gets invoked for each
@ -596,9 +626,8 @@ function __iterm2_precmd () {
__bp_set_ret_value "$__iterm2_last_ret_value" "$__bp_last_argument_prev_command"
}
# Install my functions
# Install my function
preexec_functions+=(__iterm2_preexec)
precmd_functions+=(__iterm2_precmd)
iterm2_print_state_data
iterm2_print_version_number

173
man/man1/z.1 Normal file
View file

@ -0,0 +1,173 @@
.TH "Z" "1" "January 2013" "z" "User Commands"
.SH
NAME
z \- jump around
.SH
SYNOPSIS
z [\-chlrtx] [regex1 regex2 ... regexn]
.SH
AVAILABILITY
bash, zsh
.SH
DESCRIPTION
Tracks your most used directories, based on 'frecency'.
.P
After a short learning phase, \fBz\fR will take you to the most 'frecent'
directory that matches ALL of the regexes given on the command line, in order.
For example, \fBz foo bar\fR would match \fB/foo/bar\fR but not \fB/bar/foo\fR.
.SH
OPTIONS
.TP
\fB\-c\fR
restrict matches to subdirectories of the current directory
.TP
\fB\-e\fR
echo the best match, don't cd
.TP
\fB\-h\fR
show a brief help message
.TP
\fB\-l\fR
list only
.TP
\fB\-r\fR
match by rank only
.TP
\fB\-t\fR
match by recent access only
.TP
\fB\-x\fR
remove the current directory from the datafile
.SH EXAMPLES
.TP 14
\fBz foo\fR
cd to most frecent dir matching foo
.TP 14
\fBz foo bar\fR
cd to most frecent dir matching foo, then bar
.TP 14
\fBz -r foo\fR
cd to highest ranked dir matching foo
.TP 14
\fBz -t foo\fR
cd to most recently accessed dir matching foo
.TP 14
\fBz -l foo\fR
list all dirs matching foo (by frecency)
.SH
NOTES
.SS
Installation:
.P
Put something like this in your \fB$HOME/.bashrc\fR or \fB$HOME/.zshrc\fR:
.RS
.P
\fB. /path/to/z.sh\fR
.RE
.P
\fBcd\fR around for a while to build up the db.
.P
PROFIT!!
.P
Optionally:
.RS
Set \fB$_Z_CMD\fR to change the command name (default \fBz\fR).
.RE
.RS
Set \fB$_Z_DATA\fR to change the datafile (default \fB$HOME/.z\fR).
.RE
.RS
Set \fB$_Z_MAX_SCORE\fR lower to age entries out faster (default \fB9000\fR).
.RE
.RS
Set \fB$_Z_NO_RESOLVE_SYMLINKS\fR to prevent symlink resolution.
.RE
.RS
Set \fB$_Z_NO_PROMPT_COMMAND\fR to handle \fBPROMPT_COMMAND/precmd\fR yourself.
.RE
.RS
Set \fB$_Z_EXCLUDE_DIRS\fR to an array of directory trees to exclude.
.RE
.RS
Set \fB$_Z_OWNER\fR to allow usage when in 'sudo -s' mode.
.RE
.RS
(These settings should go in .bashrc/.zshrc before the line added above.)
.RE
.RS
Install the provided man page \fBz.1\fR somewhere in your \f$MANPATH, like
\fB/usr/local/man/man1\fR.
.RE
.SS
Aging:
The rank of directories maintained by \fBz\fR undergoes aging based on a simple
formula. The rank of each entry is incremented every time it is accessed. When
the sum of ranks is over 9000, all ranks are multiplied by 0.99. Entries with a
rank lower than 1 are forgotten.
.SS
Frecency:
Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted rank
that depends on how often and how recently something occurred. As far as I
know, Mozilla came up with the term.
.P
To \fBz\fR, a directory that has low ranking but has been accessed recently
will quickly have higher rank than a directory accessed frequently a long time
ago.
.P
Frecency is determined at runtime.
.SS
Common:
When multiple directories match all queries, and they all have a common prefix,
\fBz\fR will cd to the shortest matching directory, without regard to priority.
This has been in effect, if undocumented, for quite some time, but should
probably be configurable or reconsidered.
.SS
Tab Completion:
\fBz\fR supports tab completion. After any number of arguments, press TAB to
complete on directories that match each argument. Due to limitations of the
completion implementations, only the last argument will be completed in the
shell.
.P
Internally, \fBz\fR decides you've requested a completion if the last argument
passed is an absolute path to an existing directory. This may cause unexpected
behavior if the last argument to \fBz\fR begins with \fB/\fR.
.SH
ENVIRONMENT
A function \fB_z()\fR is defined.
.P
The contents of the variable \fB$_Z_CMD\fR is aliased to \fB_z 2>&1\fR. If not
set, \fB$_Z_CMD\fR defaults to \fBz\fR.
.P
The environment variable \fB$_Z_DATA\fR can be used to control the datafile
location. If it is not defined, the location defaults to \fB$HOME/.z\fR.
.P
The environment variable \fB$_Z_NO_RESOLVE_SYMLINKS\fR can be set to prevent
resolving of symlinks. If it is not set, symbolic links will be resolved when
added to the datafile.
.P
In bash, \fBz\fR appends a command to the \fBPROMPT_COMMAND\fR environment
variable to maintain its database. In zsh, \fBz\fR appends a function
\fB_z_precmd\fR to the \fBprecmd_functions\fR array.
.P
The environment variable \fB$_Z_NO_PROMPT_COMMAND\fR can be set if you want to
handle \fBPROMPT_COMMAND\fR or \fBprecmd\fR yourself.
.P
The environment variable \fB$_Z_EXCLUDE_DIRS\fR can be set to an array of
directory trees to exclude from tracking. \fB$HOME\fR is always excluded.
Directories must be full paths without trailing slashes.
.P
The environment variable \fB$_Z_OWNER\fR can be set to your username, to
allow usage of \fBz\fR when your sudo environment keeps \fB$HOME\fR set.
.SH
FILES
Data is stored in \fB$HOME/.z\fR. This can be overridden by setting the
\fB$_Z_DATA\fR environment variable. When initialized, \fBz\fR will raise an
error if this path is a directory, and not function correctly.
.P
A man page (\fBz.1\fR) is provided.
.SH
SEE ALSO
regex(7), pushd, popd, autojump, cdargs
.P
Please file bugs at https://github.com/rupa/z/

16
update-completions.sh Normal file
View file

@ -0,0 +1,16 @@
#!/bin/bash
GENERATED=${1:-~/.bash_completion.d/generated}
# Update hostlist
python3 ~/workspace/snippets/python/recursive-axfr/recursive-axfr.py > ~/.hosts
# python3 ~/workspace/snippets/python/recursive-axfr/recursive-axfr.py k8s.0l.de @kube-dns.kube-system.svc.k8s.0l.de. > ~/.hosts
rm ${GENERATED}
type kubectl > /dev/null 2>&1 && kubectl completion bash >> ${GENERATED}
type doctl > /dev/null 2>&1 && doctl completion bash >> ${GENERATED}
type helm > /dev/null 2>&1 && helm completion bash >> ${GENERATED}
type ykman > /dev/null 2>&1 && _YKMAN_COMPLETE=source ykman >> ${GENERATED}
ykman oath accounts list > ~/.oath_tokens

263
z.sh Executable file
View file

@ -0,0 +1,263 @@
# Copyright (c) 2009 rupa deadwyler. Licensed under the WTFPL license, Version 2
# maintains a jump-list of the directories you actually use
#
# INSTALL:
# * put something like this in your .bashrc/.zshrc:
# . /path/to/z.sh
# * cd around for a while to build up the db
# * PROFIT!!
# * optionally:
# set $_Z_CMD in .bashrc/.zshrc to change the command (default z).
# set $_Z_DATA in .bashrc/.zshrc to change the datafile (default ~/.z).
# set $_Z_MAX_SCORE lower to age entries out faster (default 9000).
# set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution.
# set $_Z_NO_PROMPT_COMMAND if you're handling PROMPT_COMMAND yourself.
# set $_Z_EXCLUDE_DIRS to an array of directories to exclude.
# set $_Z_OWNER to your username if you want use z while sudo with $HOME kept
#
# USE:
# * z foo # cd to most frecent dir matching foo
# * z foo bar # cd to most frecent dir matching foo and bar
# * z -r foo # cd to highest ranked dir matching foo
# * z -t foo # cd to most recently accessed dir matching foo
# * z -l foo # list matches instead of cd
# * z -e foo # echo the best match, don't cd
# * z -c foo # restrict matches to subdirs of $PWD
# * z -x # remove the current directory from the datafile
# * z -h # show a brief help message
[ -d "${_Z_DATA:-$HOME/.z}" ] && {
echo "ERROR: z.sh's datafile (${_Z_DATA:-$HOME/.z}) is a directory."
}
_z() {
local datafile="${_Z_DATA:-$HOME/.z}"
# if symlink, dereference
[ -h "$datafile" ] && datafile=$(readlink "$datafile")
# bail if we don't own ~/.z and $_Z_OWNER not set
[ -z "$_Z_OWNER" -a -f "$datafile" -a ! -O "$datafile" ] && return
_z_dirs () {
local line
while read line; do
# only count directories
[ -d "${line%%\|*}" ] && echo "$line"
done < "$datafile"
return 0
}
# add entries
if [ "$1" = "--add" ]; then
shift
# $HOME isn't worth matching
[ "$*" = "$HOME" ] && return
# don't track excluded directory trees
local exclude
for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do
case "$*" in "$exclude*") return;; esac
done
# maintain the data file
local tempfile="$datafile.$RANDOM"
local score=${_Z_MAX_SCORE:-9000}
_z_dirs | awk -v path="$*" -v now="$(date +%s)" -v score=$score -F"|" '
BEGIN {
rank[path] = 1
time[path] = now
}
$2 >= 1 {
# drop ranks below 1
if( $1 == path ) {
rank[$1] = $2 + 1
time[$1] = now
} else {
rank[$1] = $2
time[$1] = $3
}
count += $2
}
END {
if( count > score ) {
# aging
for( x in rank ) print x "|" 0.99*rank[x] "|" time[x]
} else for( x in rank ) print x "|" rank[x] "|" time[x]
}
' 2>/dev/null >| "$tempfile"
# do our best to avoid clobbering the datafile in a race condition.
if [ $? -ne 0 -a -f "$datafile" ]; then
env rm -f "$tempfile"
else
[ "$_Z_OWNER" ] && chown $_Z_OWNER:"$(id -ng $_Z_OWNER)" "$tempfile"
env mv -f "$tempfile" "$datafile" || env rm -f "$tempfile"
fi
# tab completion
elif [ "$1" = "--complete" -a -s "$datafile" ]; then
_z_dirs | awk -v q="$2" -F"|" '
BEGIN {
q = substr(q, 3)
if( q == tolower(q) ) imatch = 1
gsub(/ /, ".*", q)
}
{
if( imatch ) {
if( tolower($1) ~ q ) print $1
} else if( $1 ~ q ) print $1
}
' 2>/dev/null
else
# list/go
local echo fnd last list opt typ
while [ "$1" ]; do case "$1" in
--) while [ "$1" ]; do shift; fnd="$fnd${fnd:+ }$1";done;;
-*) opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in
c) fnd="^$PWD $fnd";;
e) echo=1;;
h) echo "${_Z_CMD:-z} [-cehlrtx] args" >&2; return;;
l) list=1;;
r) typ="rank";;
t) typ="recent";;
x) sed -i -e "\:^${PWD}|.*:d" "$datafile";;
esac; opt=${opt:1}; done;;
*) fnd="$fnd${fnd:+ }$1";;
esac; last=$1; [ "$#" -gt 0 ] && shift; done
[ "$fnd" -a "$fnd" != "^$PWD " ] || list=1
# if we hit enter on a completion just go there
case "$last" in
# completions will always start with /
/*) [ -z "$list" -a -d "$last" ] && builtin cd "$last" && return;;
esac
# no file yet
[ -f "$datafile" ] || return
local cd
cd="$( < <( _z_dirs ) awk -v t="$(date +%s)" -v list="$list" -v typ="$typ" -v q="$fnd" -F"|" '
function frecent(rank, time) {
# relate frequency and time
dx = t - time
return int(10000 * rank * (3.75/((0.0001 * dx + 1) + 0.25)))
}
function output(matches, best_match, common) {
# list or return the desired directory
if( list ) {
if( common ) {
printf "%-10s %s\n", "common:", common > "/dev/stderr"
}
cmd = "sort -n >&2"
for( x in matches ) {
if( matches[x] ) {
printf "%-10s %s\n", matches[x], x | cmd
}
}
} else {
if( common && !typ ) best_match = common
print best_match
}
}
function common(matches) {
# find the common root of a list of matches, if it exists
for( x in matches ) {
if( matches[x] && (!short || length(x) < length(short)) ) {
short = x
}
}
if( short == "/" ) return
for( x in matches ) if( matches[x] && index(x, short) != 1 ) {
return
}
return short
}
BEGIN {
gsub(" ", ".*", q)
hi_rank = ihi_rank = -9999999999
}
{
if( typ == "rank" ) {
rank = $2
} else if( typ == "recent" ) {
rank = $3 - t
} else rank = frecent($2, $3)
if( $1 ~ q ) {
matches[$1] = rank
} else if( tolower($1) ~ tolower(q) ) imatches[$1] = rank
if( matches[$1] && matches[$1] > hi_rank ) {
best_match = $1
hi_rank = matches[$1]
} else if( imatches[$1] && imatches[$1] > ihi_rank ) {
ibest_match = $1
ihi_rank = imatches[$1]
}
}
END {
# prefer case sensitive
if( best_match ) {
output(matches, best_match, common(matches))
exit
} else if( ibest_match ) {
output(imatches, ibest_match, common(imatches))
exit
}
exit(1)
}
')"
if [ "$?" -eq 0 ]; then
if [ "$cd" ]; then
if [ "$echo" ]; then echo "$cd"; else builtin cd "$cd"; fi
fi
else
return $?
fi
fi
}
alias ${_Z_CMD:-z}='_z 2>&1'
[ "$_Z_NO_RESOLVE_SYMLINKS" ] || _Z_RESOLVE_SYMLINKS="-P"
if type compctl >/dev/null 2>&1; then
# zsh
[ "$_Z_NO_PROMPT_COMMAND" ] || {
# populate directory list, avoid clobbering any other precmds.
if [ "$_Z_NO_RESOLVE_SYMLINKS" ]; then
_z_precmd() {
(_z --add "${PWD:a}" &)
: $RANDOM
}
else
_z_precmd() {
(_z --add "${PWD:A}" &)
: $RANDOM
}
fi
[[ -n "${precmd_functions[(r)_z_precmd]}" ]] || {
precmd_functions[$(($#precmd_functions+1))]=_z_precmd
}
}
_z_zsh_tab_completion() {
# tab completion
local compl
read -l compl
reply=(${(f)"$(_z --complete "$compl")"})
}
compctl -U -K _z_zsh_tab_completion _z
elif type complete >/dev/null 2>&1; then
# bash
# tab completion
complete -o filenames -C '_z --complete "$COMP_LINE"' ${_Z_CMD:-z}
[ "$_Z_NO_PROMPT_COMMAND" ] || {
# populate directory list. avoid clobbering other PROMPT_COMMANDs.
grep "_z --add" <<< "$PROMPT_COMMAND" >/dev/null || {
PROMPT_COMMAND="$PROMPT_COMMAND"$'\n''(_z --add "$(command pwd '$_Z_RESOLVE_SYMLINKS' 2>/dev/null)" 2>/dev/null &);'
}
}
fi