bindkey -e # emacs-style keybindings setopt autocd # last line without newline terminator # is swallowed if this is absent setopt prompt_sp autoload -U zmv setopt prompt_subst prompt_percent autoload colors && colors # wrap in %{%} to prevent zsh from counting the content towards # the text length, leading to over-compensation for zero-width characters zcol() { echo -n "%{$@%}" } timestamp() { echo $((`date "+%s + %N / 1e9"`)) } elapsed() { echo $(($(timestamp) - $command_start_time)) } humanize_duration() { # ORS= disables the trailing newline command awk -v ORS= ' function hmTime(time, stamp) { split("h:m:s:ms", units, ":") for (i = 2; i >= -1; i--) { if (t = int( i < 0 ? time % 1000 : time / (60 ^ i * 1000) % 60 )) { stamp = stamp t units[sqrt((i - 2) ^ 2) + 1] " " } } if (stamp ~ /^ *$/) { return "0ms" } return substr(stamp, 1, length(stamp) - 1) } { print hmTime($0) } ' } duration=0 command_start_time=$(timestamp) # called just before line is evaluated preexec() { command_start_time=$(timestamp) } # called just before prompt is updated which # is usually after the program ran, but also # on ^C or Enter on an empty line precmd() { duration=$(elapsed) command_start_time=$(timestamp) } git_prompt() { local git_branch=$(git branch 2>/dev/null | grep \* | sed 's/* //') # is in git repository if branch != "" if [[ -n "$git_branch" ]]; then # if no uncommitted changes if git diff-index --quiet HEAD --; then zcol "$fg[green]" else zcol "$fg[red]" fi echo -n "$git_branch " fi } left_prompt() { local last_status=$? case $USER in "$PRIMARY_USER" | "root") ;; *) echo -n $USER esac if test -n "$SSH_TTY" \ || [ -f /.dockerenv ]; then zcol "$fg[cyan]" echo -n "@$(hostname | tr -d '\n') " fi if test -n "$IN_NIX_SHELL"; then zcol "$fg[cyan]" echo -n "nix " fi if test -n "$IN_BWRAP"; then zcol "$fg[cyan]" echo -n "bwrap " fi if test -n "$DOCKER_HOST"; then zcol "$fg[cyan]" echo -n "$(basename "$DOCKER_HOST") " fi zcol "$fg[green]" { pwd; echo -n " " } | tr -d '\n' | sed -e "s:^$HOME:~:" git_prompt case $USER in root) zcol "$fg[red]"; echo -n "# " ;; *) zcol "$fg[blue]"; echo -n "> " ;; esac if [ "$last_status" -ne 0 ]; then zcol "$fg_bold[red]" echo -n "$last_status " fi zcol "$reset_color" } right_prompt() { command_start_time=$(timestamp) if (($duration > 0.99)); then zcol "$fg_bold[cyan]" humanize_duration <<<"$(( $duration * 1000 ))" fi zcol "$reset_color" } PROMPT='$(left_prompt)' RPROMPT='$(right_prompt)' bindkey "${terminfo[khome]}" beginning-of-line bindkey "${terminfo[kend]}" end-of-line bindkey '\eOA' history-substring-search-up # or ^[OA bindkey '\eOB' history-substring-search-down # or ^[OB export ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE=fg=cyan