This has been a project I have been wanting to work on for some time. I just configure something until it’s “good enough” and then forget about it. I’ve started several git repositories for my dotfiles, but I never really keep them up to date more than a couple weeks. Eventually I’d like to automate (to some extent) the deployment of my configuration on a new system. At this point I just scp them from my working machine, copy them to the correct places, and be done with it.

Maybe this existing method is good enough for my workflow? But the main point for me is to learn.

Why the .zshrc?

Well, it’s my main config file (aside from my vimrc, which will necessitate multiple posts), and since making the switch to mainly CLI on WSL instead of Arch/Void with a minimal GUI as my daily driver, it has replaced certain configurations such as .profile, .xprofile, and .xinitrc. Most things that I want to happen upon login live here instead of in one of those or another GUI application config file like my window manager or hotkey daemon. Having this file cleaned up makes me comfy in the terminal simply by installing two packages and creating one file.

But to be more specific:

First, I have several different versions that have slowly drifted from each other across my machines, and would like to consolidate into a single master version.

Second, I created a sort of frankenstein monster with Luke Smith’s zsh config and the Kali Linux zsh config, and would like to trim the fat. A bit embarrassed to admit that I just wanted the fancy Kali prompt, and just blindly copy pasted and edited until it was the way I wanted it -then left it alone and let it fester.

Third, I want to get rid of any config that makes sense to be stored elsewhere, such as kali’s ls -l alias to ll - the moment I’m on a bash system or su and don’t have that alias, it’s annoying. I’d like to stop depending on it, or at the very least store it somewhere other than my shell config, so that seeing it/changing it is more intuitive.

Current configuration

Here’s the copy that I started working from. Commented lines are supposed to be there, relics from my throw-it-at-the-wall-and-see-if-it-sticks approach to config up to this point.

# /.zshrc file for zsh interactive shells.
# see /usr/share/doc/zsh/examples/zshrc for examples

# attach tmux session automatically or start new tmux session
# if [ -z "$TMUX" ]
# then
#     tmux attach -t TMUX || tmux new -s TMUX
# fi

# print ssh motd and last login (as starting tmux overwrites this on ssh login)
# if [ -n "$TMUX" ]; then

#   # message of the day
#   if [ -f /etc/ssh/mybanner ]; then
#     cat /etc/ssh/mybanner
#   fi

  # last login
  # last $USER |awk 'NR==2 {
  #   if (NF==10) { i=1; if ($3!~/^:/) from = " from " $3 }
  #   printf("Last login: %s %s %s %s%s on %s\n",
  #     $(3+i), $(4+i), $(5+i), $(6+i), from, $2);
  #   exit
  # }'
# fi

# set personal env variables
export EDITOR="nvim"
export MANPAGER="nvim +Man!"
export PATH="$PATH:$HOME/.local/bin"
export KEYTIMEOUT=1

# load aliases + shortcuts
[ -f "$HOME/.config/shortcutrc" ] && source "$HOME/.config/shortcutrc"
[ -f "$HOME/.config/aliasrc" ] && source "$HOME/.config/aliasrc"

# BEGIN KALI CONFIG
setopt autocd              # change directory just by typing its name
#setopt correct            # auto correct mistakes
setopt interactivecomments # allow comments in interactive mode
setopt magicequalsubst     # enable filename expansion for arguments of the form ‘anything=expression’
setopt nonomatch           # hide error message if there is no match for the pattern
setopt notify              # report the status of background jobs immediately
setopt numericglobsort     # sort filenames numerically when it makes sense
setopt promptsubst         # enable command substitution in prompt

WORDCHARS=${WORDCHARS//\/} # Don't consider certain characters part of the word

# hide EOL sign ('%')
PROMPT_EOL_MARK=""

# configure key keybindings
bindkey -v                                        # emacs key bindings
bindkey ' ' magic-space                           # do history expansion on space
bindkey '^U' backward-kill-line                   # ctrl + U
bindkey '^[[3;5~' kill-word                       # ctrl + Supr
bindkey '^[[3~' delete-char                       # delete
bindkey '^[[1;5C' forward-word                    # ctrl + ->
bindkey '^[[1;5D' backward-word                   # ctrl + <-
bindkey '^[[5~' beginning-of-buffer-or-history    # page up
bindkey '^[[6~' end-of-buffer-or-history          # page down
bindkey '^[[H' beginning-of-line                  # home
bindkey '^[[F' end-of-line                        # end
bindkey '^[[Z' undo                               # shift + tab undo last action
bindkey '^R' history-incremental-search-backward  # ctrl + r reverse i search

# enable completion features
autoload -Uz compinit
autoload edit-command-line
zle -N edit-command-line
bindkey '^x' edit-command-line
zmodload zsh/complist
compinit -d ~/.cache/zcompdump
zstyle ':completion:*:*:*:*:*' menu select
zstyle ':completion:*' auto-description 'specify: %d'
zstyle ':completion:*' completer _expand _complete
zstyle ':completion:*' format 'Completing %d'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' list-colors ''
zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
zstyle ':completion:*' rehash true
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle ':completion:*' use-compctl false
zstyle ':completion:*' verbose true
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'

# vimbindings
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'l' vi-forward-char
bindkey -M menuselect 'j' vi-down-line-or-history
bindkey -v '^?' backward-delete-char

# History configurations
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=200000
setopt INC_APPEND_HISTORY
export HISTTIMEFORMAT="[%F %T] "
export HIST_STAMPS="yyyy-mm-dd"
setopt hist_expire_dups_first # delete duplicates first when HISTFILE size exceeds HISTSIZE
setopt hist_ignore_dups       # ignore duplicated commands history list
setopt hist_ignore_space      # ignore commands that start with space
setopt hist_verify            # show command with history expansion to user before running it
setopt share_history         # share command history data

# force zsh to show the complete history
alias history="history 0"

# configure `time` format
TIMEFMT=$'\nreal\t%E\nuser\t%U\nsys\t%S\ncpu\t%P'

# make less more friendly for non-text input files, see lesspipe(1)
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi

configure_prompt() {
    prompt_symbol=@
    # Skull emoji for root terminal
    #[ "$EUID" -eq 0 ] && prompt_symbol=💀
    case "$PROMPT_ALTERNATIVE" in
        twoline)
          PROMPT=$'%F{%(#.blue.green)}┌──${debian_chroot:+($debian_chroot)─}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))─}(%B%F{%(#.red.blue)}%n'$prompt_symbol$'%m%b%F{%(#.blue.green)})-[%B%F{reset}%(6~.%-1~/…/%4~.%5~)%b%F{%(#.blue.green)}]\n└─%B%(#.%F{red}#.%F{blue}$)%b%F{reset} '
            # Right-side prompt with exit codes and background processes
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT=$'%F{green}[%F{reset}%D{%Y-%m-%d} %D{%L:%M:%S}%F{green}]'
            ;;
        oneline)
            PROMPT=$'${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%B%F{%(#.red.blue)}%n@%m%b%F{reset}:%B%F{%(#.blue.green)}%~%b%F{reset}%(#.#.$) '
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT="%B%{$fg[green]%}[%{$fg[blue]%}%D{%Y-%m-%d} %D{%L:%M:%S}%{$fg[green]%}]"
            ;;
        backtrack)
            PROMPT=$'${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%B%F{red}%n@%m%b%F{reset}:%B%F{blue}%~%b%F{reset}%(#.#.$) '
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT="%B%{$fg[green]%}[%{$fg[blue]%}%D{%Y-%m-%d} %D{%L:%M:%S}%{$fg[green]%}]"
            ;;
    esac
    unset prompt_symbol
}

# The following block is surrounded by two delimiters.
# These delimiters must not be modified. Thanks.
# START KALI CONFIG VARIABLES
PROMPT_ALTERNATIVE=twoline
NEWLINE_BEFORE_PROMPT=yes
# STOP KALI CONFIG VARIABLES

if [ "$color_prompt" = yes ]; then
    # override default virtualenv indicator in prompt
    VIRTUAL_ENV_DISABLE_PROMPT=1

    configure_prompt

    # enable syntax-highlighting
    # if [ -f /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ]; then
    #     . /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
    #     ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern)
    #     ZSH_HIGHLIGHT_STYLES[default]=none
    #     ZSH_HIGHLIGHT_STYLES[unknown-token]=underline
    #     ZSH_HIGHLIGHT_STYLES[reserved-word]=fg=cyan,bold
    #     ZSH_HIGHLIGHT_STYLES[suffix-alias]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[global-alias]=fg=green,bold
    #     ZSH_HIGHLIGHT_STYLES[precommand]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[commandseparator]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[autodirectory]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[path]=bold
    #     ZSH_HIGHLIGHT_STYLES[path_pathseparator]=
    #     ZSH_HIGHLIGHT_STYLES[path_prefix_pathseparator]=
    #     ZSH_HIGHLIGHT_STYLES[globbing]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[history-expansion]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[command-substitution]=none
    #     ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[process-substitution]=none
    #     ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[single-hyphen-option]=fg=green
    #     ZSH_HIGHLIGHT_STYLES[double-hyphen-option]=fg=green
    #     ZSH_HIGHLIGHT_STYLES[back-quoted-argument]=none
    #     ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[single-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[double-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[rc-quote]=fg=magenta
    #     ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[assign]=none
    #     ZSH_HIGHLIGHT_STYLES[redirection]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[comment]=fg=black,bold
    #     ZSH_HIGHLIGHT_STYLES[named-fd]=none
    #     ZSH_HIGHLIGHT_STYLES[numeric-fd]=none
    #     ZSH_HIGHLIGHT_STYLES[arg0]=fg=cyan
    #     ZSH_HIGHLIGHT_STYLES[bracket-error]=fg=red,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-1]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-2]=fg=green,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-3]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-4]=fg=yellow,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-5]=fg=cyan,bold
    #     ZSH_HIGHLIGHT_STYLES[cursor-matchingbracket]=standout
    # fi
else
    PROMPT='${debian_chroot:+($debian_chroot)}%n@%m:%~%(#.#.$) '
fi
unset color_prompt force_color_prompt

toggle_oneline_prompt(){
    if [ "$PROMPT_ALTERNATIVE" = oneline ]; then
        PROMPT_ALTERNATIVE=twoline
    else
        PROMPT_ALTERNATIVE=oneline
    fi
    configure_prompt
    zle reset-prompt
}
zle -N toggle_oneline_prompt
bindkey ^P toggle_oneline_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*|Eterm|aterm|kterm|gnome*|alacritty)
    TERM_TITLE=$'\e]0;${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%n@%m: %~\a'
    ;;
*)
    ;;
esac

precmd() {
    # Print the previously configured title
    print -Pnr -- "$TERM_TITLE"

    # Print a new line before the prompt, but only if it is not the first line
    if [ "$NEWLINE_BEFORE_PROMPT" = yes ]; then
        if [ -z "$_NEW_LINE_BEFORE_PROMPT" ]; then
            _NEW_LINE_BEFORE_PROMPT=1
        else
            print ""
        fi
    fi
}

# enable color support of ls, less and man, and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    export LS_COLORS="$LS_COLORS:ow=30;44:" # fix ls color for folders with 777 permissions

    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
    alias diff='diff --color=auto'
    alias ip='ip --color=auto'

    export LESS_TERMCAP_mb=$'\E[1;31m'     # begin blink
    export LESS_TERMCAP_md=$'\E[1;36m'     # begin bold
    export LESS_TERMCAP_me=$'\E[0m'        # reset bold/blink
    export LESS_TERMCAP_so=$'\E[01;33m'    # begin reverse video
    export LESS_TERMCAP_se=$'\E[0m'        # reset reverse video
    export LESS_TERMCAP_us=$'\E[1;32m'     # begin underline
    export LESS_TERMCAP_ue=$'\E[0m'        # reset underline

    # Take advantage of $LS_COLORS for completion as well
    zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
    zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
fi

# some more ls aliases
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'

# enable auto-suggestions based on the history
if [ -f /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh ]; then
    . /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh
    # change suggestion color
    ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=#999'
fi

# enable command-not-found if installed
if [ -f /etc/zsh_command_not_found ]; then
    . /etc/zsh_command_not_found
fi

# END KALI CONFIG

# Change cursor shape for different vi modes.
function zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]] ||
     [[ $1 = 'block' ]]; then
    echo -ne '\e[1 q'

  elif [[ ${KEYMAP} == main ]] ||
       [[ ${KEYMAP} == viins ]] ||
       [[ ${KEYMAP} = '' ]] ||
       [[ $1 = 'beam' ]]; then
    echo -ne '\e[5 q'
  fi
}
zle -N zle-keymap-select

zle-line-init() {
    zle -K viins # initiate `vi insert` as keymap (can be removed if `bindkey -V` has been set elsewhere)
    echo -ne "\e[5 q"
}
zle -N zle-line-init

# Use beam shape cursor on startup.
echo -ne '\e[5 q'
# Use beam shape cursor for each new prompt.
preexec() { echo -ne '\e[5 q' ;}

# Load zsh-syntax-highlighting; should be last.
source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh 2>/dev/null

…I’ll be honest when I started this post, I didn’t realize just how long this was.

My plan for the rest of this project is to go line-by-line over the config and figure out what each line is doing.

Line-by-line

# attach tmux session automatically or start new tmux session
# if [ -z "$TMUX" ]
# then
#     tmux attach -t TMUX || tmux new -s TMUX
# fi

# print ssh motd and last login (as starting tmux overwrites this on ssh login)
# if [ -n "$TMUX" ]; then

#   # message of the day
#   if [ -f /etc/ssh/mybanner ]; then
#     cat /etc/ssh/mybanner
#   fi
  # last login
  # last $USER |awk 'NR==2 {
  #   if (NF==10) { i=1; if ($3!~/^:/) from = " from " $3 }
  #   printf("Last login: %s %s %s %s%s on %s\n",
  #     $(3+i), $(4+i), $(5+i), $(6+i), from, $2);
  #   exit
  # }'
# fi

Relic from when I wanted to start tmux automatically. Commented out already anyway. It’s getting snipped.

I didn’t write a lot of this (I am not this much of an awk wizard), but I forget where I adapted the code from.

# set personal env variables
export EDITOR="nvim"
export MANPAGER="nvim +Man!"
export PATH="$PATH:$HOME/.local/bin"
export KEYTIMEOUT=1

This section is staying. I am going to add comments next to the ones whose function is not immediately apparent (e.g. export KEYTIMEOUT=1).

It’s from when I moved from primarily minimal GUI to all CLI - these variables would get set in the .profile and I moved them to get loaded during the shell startup instead.

# load aliases + shortcuts
[ -f "$HOME/.config/shortcutrc" ] && source "$HOME/.config/shortcutrc"
[ -f "$HOME/.config/aliasrc" ] && source "$HOME/.config/aliasrc"

These are staying, relics and also on my todo list for scripts / files to clean up. These are very much per-machine, at least the files that specify what directories/files to load are, but the scripts are universal.

# BEGIN KALI CONFIG
setopt autocd              # change directory just by typing its name
#setopt correct            # auto correct mistakes
setopt interactivecomments # allow comments in interactive mode
setopt magicequalsubst     # enable filename expansion for arguments of the form ‘anything=expression’
setopt nonomatch           # hide error message if there is no match for the pattern
setopt notify              # report the status of background jobs immediately
setopt numericglobsort     # sort filenames numerically when it makes sense
setopt promptsubst         # enable command substitution in prompt

Now we get into the Kali config…thankfully there are helpful comments here.

  • Leaving autocd
  • Leaving out correct, I generally dislike autocorrect, I tend to form bad habits and get lazy when I have autocorrect enabled for anything, it’s also super annoying
  • Leaving in interactivecomments, seems innocuous
  • Unsure what to do with magicequalsubst, nonomatch, numericglobsort, and promptsubst - leaving them out until further notice
  • Leaving in notify, again seems innocuous
WORDCHARS=${WORDCHARS//\/} # Don't consider certain characters part of the word

I have no idea what this does, and going by my previous approach, I am removing it until I come across what it does.

# hide EOL sign ('%')
PROMPT_EOL_MARK=""

The same applies here.

# configure key keybindings
bindkey -v                                        # emacs key bindings
bindkey ' ' magic-space                           # do history expansion on space
bindkey '^U' backward-kill-line                   # ctrl + U
bindkey '^[[3;5~' kill-word                       # ctrl + Supr
bindkey '^[[3~' delete-char                       # delete
bindkey '^[[1;5C' forward-word                    # ctrl + ->
bindkey '^[[1;5D' backward-word                   # ctrl + <-
bindkey '^[[5~' beginning-of-buffer-or-history    # page up
bindkey '^[[6~' end-of-buffer-or-history          # page down
bindkey '^[[H' beginning-of-line                  # home
bindkey '^[[F' end-of-line                        # end
bindkey '^[[Z' undo                               # shift + tab undo last action
bindkey '^R' history-incremental-search-backward  # ctrl + r reverse i search

Most of these I do not use, but for the most part they seem to add additional editing capabilities when not in vi normal mode, and I will leave them. Nothing that I don’t understand except for the ctrl + Supr, which I will delete.

# enable completion features
autoload -Uz compinit
autoload edit-command-line
zle -N edit-command-line
bindkey '^x' edit-command-line
zmodload zsh/complist
compinit -d ~/.cache/zcompdump
zstyle ':completion:*:*:*:*:*' menu select
zstyle ':completion:*' auto-description 'specify: %d'
zstyle ':completion:*' completer _expand _complete
zstyle ':completion:*' format 'Completing %d'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' list-colors ''
zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
zstyle ':completion:*' rehash true
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle ':completion:*' use-compctl false
zstyle ':completion:*' verbose true
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'

Hefty research will need to be done on these. I am going to hasten that process by nuking this section.

EDIT: I nuked it, and all the nice tab-completion features went away. I added it back and plan to look into this section more methodically and do some testing along the way…eventually.

# vimbindings
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'l' vi-forward-char
bindkey -M menuselect 'j' vi-down-line-or-history
bindkey -v '^?' backward-delete-char

Well these are obviously staying.

The bindkey -v '^?' backward-delete-char seems to be binding the backspace key? I am deleting that one, and we’ll see if it comes back up.

EDIT: it did come back up almost immediately, and I replaced this line. Sometimes it worked and sometimes it didn’t, I couldn’t tell what affected it, and so I put it back in.

# History configurations
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=200000
setopt INC_APPEND_HISTORY
export HISTTIMEFORMAT="[%F %T] "
export HIST_STAMPS="yyyy-mm-dd"
setopt hist_expire_dups_first # delete duplicates first when HISTFILE size exceeds HISTSIZE
setopt hist_ignore_dups       # ignore duplicated commands history list
setopt hist_ignore_space      # ignore commands that start with space
setopt hist_verify            # show command with history expansion to user before running it
setopt share_history         # share command history data

# force zsh to show the complete history
alias history="history 0"

This is pretty standard history settings for me, I’ve messed with this a bit previously. The HISTSIZE and SAVEHIST are intentionally set to stupidly large sizes.

I removed the alias here and added to my aliasrc hist="history -i 0" which shows the full history with timestamps.

Also made all setopt values all caps to match formatting.

# configure `time` format
TIMEFMT=$'\nreal\t%E\nuser\t%U\nsys\t%S\ncpu\t%P'

This formats the time command. I have reviewed it and it seems reasonable to leave it be.

# make less more friendly for non-text input files, see lesspipe(1)
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

This is already commented out, so I am removing it for now.

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi

configure_prompt() {
    prompt_symbol=@
    # Skull emoji for root terminal
    #[ "$EUID" -eq 0 ] && prompt_symbol=💀
    case "$PROMPT_ALTERNATIVE" in
        twoline)
          PROMPT=$'%F{%(#.blue.green)}┌──${debian_chroot:+($debian_chroot)─}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))─}(%B%F{%(#.red.blue)}%n'$prompt_symbol$'%m%b%F{%(#.blue.green)})-[%B%F{reset}%(6~.%-1~/…/%4~.%5~)%b%F{%(#.blue.green)}]\n└─%B%(#.%F{red}#.%F{blue}$)%b%F{reset} '
            # Right-side prompt with exit codes and background processes
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT=$'%F{green}[%F{reset}%D{%Y-%m-%d} %D{%L:%M:%S}%F{green}]'
            ;;
        oneline)
            PROMPT=$'${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%B%F{%(#.red.blue)}%n@%m%b%F{reset}:%B%F{%(#.blue.green)}%~%b%F{reset}%(#.#.$) '
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT="%B%{$fg[green]%}[%{$fg[blue]%}%D{%Y-%m-%d} %D{%L:%M:%S}%{$fg[green]%}]"
            ;;
        backtrack)
            PROMPT=$'${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%B%F{red}%n@%m%b%F{reset}:%B%F{blue}%~%b%F{reset}%(#.#.$) '
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT="%B%{$fg[green]%}[%{$fg[blue]%}%D{%Y-%m-%d} %D{%L:%M:%S}%{$fg[green]%}]"
            ;;
    esac
    unset prompt_symbol
}

# The following block is surrounded by two delimiters.
# These delimiters must not be modified. Thanks.
# START KALI CONFIG VARIABLES
PROMPT_ALTERNATIVE=twoline
NEWLINE_BEFORE_PROMPT=yes
# STOP KALI CONFIG VARIABLES

f [ "$color_prompt" = yes ]; then
    # override default virtualenv indicator in prompt
    VIRTUAL_ENV_DISABLE_PROMPT=1

    configure_prompt

    # enable syntax-highlighting
    # if [ -f /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ]; then
    #     . /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
    #     ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern)
    #     ZSH_HIGHLIGHT_STYLES[default]=none
    #     ZSH_HIGHLIGHT_STYLES[unknown-token]=underline
    #     ZSH_HIGHLIGHT_STYLES[reserved-word]=fg=cyan,bold
    #     ZSH_HIGHLIGHT_STYLES[suffix-alias]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[global-alias]=fg=green,bold
    #     ZSH_HIGHLIGHT_STYLES[precommand]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[commandseparator]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[autodirectory]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[path]=bold
    #     ZSH_HIGHLIGHT_STYLES[path_pathseparator]=
    #     ZSH_HIGHLIGHT_STYLES[path_prefix_pathseparator]=
    #     ZSH_HIGHLIGHT_STYLES[globbing]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[history-expansion]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[command-substitution]=none
    #     ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[process-substitution]=none
    #     ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[single-hyphen-option]=fg=green
    #     ZSH_HIGHLIGHT_STYLES[double-hyphen-option]=fg=green
    #     ZSH_HIGHLIGHT_STYLES[back-quoted-argument]=none
    #     ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[single-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[double-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[rc-quote]=fg=magenta
    #     ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[assign]=none
    #     ZSH_HIGHLIGHT_STYLES[redirection]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[comment]=fg=black,bold
    #     ZSH_HIGHLIGHT_STYLES[named-fd]=none
    #     ZSH_HIGHLIGHT_STYLES[numeric-fd]=none
    #     ZSH_HIGHLIGHT_STYLES[arg0]=fg=cyan
    #     ZSH_HIGHLIGHT_STYLES[bracket-error]=fg=red,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-1]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-2]=fg=green,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-3]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-4]=fg=yellow,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-5]=fg=cyan,bold
    #     ZSH_HIGHLIGHT_STYLES[cursor-matchingbracket]=standout
    # fi
else
    PROMPT='${debian_chroot:+($debian_chroot)}%n@%m:%~%(#.#.$) '
fi
unset color_prompt force_color_prompt

toggle_oneline_prompt(){
    if [ "$PROMPT_ALTERNATIVE" = oneline ]; then
        PROMPT_ALTERNATIVE=twoline
    else
        PROMPT_ALTERNATIVE=oneline
    fi
    configure_prompt
    zle reset-prompt
}
zle -N toggle_oneline_prompt
bindkey ^P toggle_oneline_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*|Eterm|aterm|kterm|gnome*|alacritty)
    TERM_TITLE=$'\e]0;${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%n@%m: %~\a'
    ;;
*)
    ;;
esac

precmd() {
    # Print the previously configured title
    print -Pnr -- "$TERM_TITLE"

    # Print a new line before the prompt, but only if it is not the first line
    if [ "$NEWLINE_BEFORE_PROMPT" = yes ]; then
        if [ -z "$_NEW_LINE_BEFORE_PROMPT" ]; then
            _NEW_LINE_BEFORE_PROMPT=1
        else
            print ""
        fi
    fi
}

Oh good GOD. All this for a fancy prompt. I think not.

Rewritten:

PROMPT=$'%F{blue}[ %F{gray}%n%F{blue}@%F{gray}%m%F{blue} ]-[ %F{gray}%D{%Y-%m-%d} %*%F{blue} ]-[ %F{gray}%~%F{blue} ]\n%# '

Looks like so:

There’s a good 50% of the config nuked from orbit.

Config reference here.

# enable color support of ls, less and man, and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    export LS_COLORS="$LS_COLORS:ow=30;44:" # fix ls color for folders with 777 permissions

    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
    alias diff='diff --color=auto'
    alias ip='ip --color=auto'

    export LESS_TERMCAP_mb=$'\E[1;31m'     # begin blink
    export LESS_TERMCAP_md=$'\E[1;36m'     # begin bold
    export LESS_TERMCAP_me=$'\E[0m'        # reset bold/blink
    export LESS_TERMCAP_so=$'\E[01;33m'    # begin reverse video
    export LESS_TERMCAP_se=$'\E[0m'        # reset reverse video
    export LESS_TERMCAP_us=$'\E[1;32m'     # begin underline
    export LESS_TERMCAP_ue=$'\E[0m'        # reset underline

    # Take advantage of $LS_COLORS for completion as well
    zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
    zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
fi

Deleting this: bunch of aliases that I will take (already have taken) for granted and lose track of.

# some more ls aliases
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'

Deleting these, if I want them I can put them in my alias file. (EDIT: I did add ll and la.)

# enable auto-suggestions based on the history
if [ -f /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh ]; then
    . /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh
    # change suggestion color
    ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=#999'
fi

Removing this, only applicable if zsh-autosuggestions is installed.

# enable command-not-found if installed
if [ -f /etc/zsh_command_not_found ]; then
    . /etc/zsh_command_not_found
fi

Removing this, file/script is not there and I’m fine with the default “command not found” error. (I think that’s what it does.)

# Change cursor shape for different vi modes.
function zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]] ||
     [[ $1 = 'block' ]]; then
    echo -ne '\e[1 q'

  elif [[ ${KEYMAP} == main ]] ||
       [[ ${KEYMAP} == viins ]] ||
       [[ ${KEYMAP} = '' ]] ||
       [[ $1 = 'beam' ]]; then
    echo -ne '\e[5 q'
  fi
}
zle -N zle-keymap-select

zle-line-init() {
    zle -K viins # initiate `vi insert` as keymap (can be removed if `bindkey -V` has been set elsewhere)
    echo -ne "\e[5 q"
}
zle -N zle-line-init

# Use beam shape cursor on startup.
echo -ne '\e[5 q'
# Use beam shape cursor for each new prompt.
preexec() { echo -ne '\e[5 q' ;}

This is staying, makes the vi-mode sensible.

# Load zsh-syntax-highlighting; should be last.
source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh 2>/dev/null

This is also staying, it loads syntax highlighting.

Final zshrc (for now)

Down to just over 100 lines from about 350 lines. Not bad.

# .zshrc file for zsh interactive shells.
# see /usr/share/doc/zsh/examples/zshrc for examples
# vimoire custom configuration, taken from Luke Smith's zshrc and the Kali Linux zshrc, heavily adapted to suit individual needs. YMMV.

# set personal env variables
export EDITOR="nvim"
export MANPAGER="nvim +Man!"
export PATH="$PATH:$HOME/.local/bin"
export KEYTIMEOUT=1

# load aliases + shortcuts
[ -f "$HOME/.config/shortcutrc" ] && source "$HOME/.config/shortcutrc"
[ -f "$HOME/.config/aliasrc" ] && source "$HOME/.config/aliasrc"

# BEGIN KALI CONFIG
setopt autocd              # change directory just by typing its name
setopt interactivecomments # allow comments in interactive mode
setopt magicequalsubst     # enable filename expansion for arguments of the form ‘anything=expression’
setopt notify              # report the status of background jobs immediately

# configure key keybindings
bindkey -v                                        # emacs key bindings
bindkey ' ' magic-space                           # do history expansion on space
bindkey '^U' backward-kill-line                   # ctrl + U
bindkey '^[[3;5~' kill-word                       # ctrl + Supr
bindkey '^[[3~' delete-char                       # delete
bindkey '^[[1;5C' forward-word                    # ctrl + ->
bindkey '^[[1;5D' backward-word                   # ctrl + <-
bindkey '^[[5~' beginning-of-buffer-or-history    # page up
bindkey '^[[6~' end-of-buffer-or-history          # page down
bindkey '^[[H' beginning-of-line                  # home
bindkey '^[[F' end-of-line                        # end
bindkey '^[[Z' undo                               # shift + tab undo last action
bindkey '^R' history-incremental-search-backward  # ctrl + r reverse i search

# # enable completion features
autoload -Uz compinit
autoload edit-command-line
zle -N edit-command-line
bindkey '^x' edit-command-line
zmodload zsh/complist
compinit -d ~/.cache/zcompdump
zstyle ':completion:*:*:*:*:*' menu select
zstyle ':completion:*' auto-description 'specify: %d'
zstyle ':completion:*' completer _expand _complete
zstyle ':completion:*' format 'Completing %d'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' list-colors ''
zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
zstyle ':completion:*' rehash true
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle ':completion:*' use-compctl false
zstyle ':completion:*' verbose true
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'

# vimbindings
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'l' vi-forward-char
bindkey -M menuselect 'j' vi-down-line-or-history
bindkey -v '^?' backward-delete-char

# History configurations
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=200000
setopt INC_APPEND_HISTORY
export HISTTIMEFORMAT="[%F %T] "
export HIST_STAMPS="yyyy-mm-dd"
setopt HIST_EXPIRE_DUPS_FIRST # delete duplicates first when HISTFILE size exceeds HISTSIZE
setopt HIST_IGNORE_DUPS       # ignore duplicated commands history list
setopt HIST_IGNORE_SPACE      # ignore commands that start with space
setopt HIST_VERIFY            # show command with history expansion to user before running it
setopt SHARE_HISTORY         # share command history data

# configure `time` format
TIMEFMT=$'\nreal\t%E\nuser\t%U\nsys\t%S\ncpu\t%P'

# custom prompt configuration
PROMPT=$'%F{blue}[ %F{gray}%n%F{blue}@%F{gray}%m%F{blue} ]-[ %F{gray}%D{%Y-%m-%d} %*%F{blue} ]-[ %F{gray}%~%F{blue} ]\n%# '

# Change cursor shape for different vi modes.
function zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]] ||
     [[ $1 = 'block' ]]; then
    echo -ne '\e[1 q'

  elif [[ ${KEYMAP} == main ]] ||
       [[ ${KEYMAP} == viins ]] ||
       [[ ${KEYMAP} = '' ]] ||
       [[ $1 = 'beam' ]]; then
    echo -ne '\e[5 q'
  fi
}
zle -N zle-keymap-select

zle-line-init() {
    zle -K viins # initiate `vi insert` as keymap (can be removed if `bindkey -V` has been set elsewhere)
    echo -ne "\e[5 q"
}
zle -N zle-line-init

# Use beam shape cursor on startup.
echo -ne '\e[5 q'
# Use beam shape cursor for each new prompt.
preexec() { echo -ne '\e[5 q' ;}

# Load zsh-syntax-highlighting; should be last.
source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh 2>/dev/null

Deleted items, for future reference

#setopt correct            # auto correct mistakes

bindkey '^[[3;5~' kill-word                       # ctrl + Supr

# force zsh to show the complete history
alias history="history 0"

# make less more friendly for non-text input files, see lesspipe(1)
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi

configure_prompt() {
    prompt_symbol=@
    # Skull emoji for root terminal
    #[ "$EUID" -eq 0 ] && prompt_symbol=💀
    case "$PROMPT_ALTERNATIVE" in
        twoline)
          PROMPT=$'%F{%(#.blue.green)}┌──${debian_chroot:+($debian_chroot)─}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))─}(%B%F{%(#.red.blue)}%n'$prompt_symbol$'%m%b%F{%(#.blue.green)})-[%B%F{reset}%(6~.%-1~/…/%4~.%5~)%b%F{%(#.blue.green)}]\n└─%B%(#.%F{red}#.%F{blue}$)%b%F{reset} '
            # Right-side prompt with exit codes and background processes
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT=$'%F{green}[%F{reset}%D{%Y-%m-%d} %D{%L:%M:%S}%F{green}]'
            ;;
        oneline)
            PROMPT=$'${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%B%F{%(#.red.blue)}%n@%m%b%F{reset}:%B%F{%(#.blue.green)}%~%b%F{reset}%(#.#.$) '
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT="%B%{$fg[green]%}[%{$fg[blue]%}%D{%Y-%m-%d} %D{%L:%M:%S}%{$fg[green]%}]"
            ;;
        backtrack)
            PROMPT=$'${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%B%F{red}%n@%m%b%F{reset}:%B%F{blue}%~%b%F{reset}%(#.#.$) '
            # Kali custom RPROMPT=$'%(?.. %? %F{red}%B⨯%b%F{reset})%(1j. %j %F{yellow}%B⚙%b%F{reset}.)'
            # Personal custom
            RPROMPT="%B%{$fg[green]%}[%{$fg[blue]%}%D{%Y-%m-%d} %D{%L:%M:%S}%{$fg[green]%}]"
            ;;
    esac
    unset prompt_symbol
}

# The following block is surrounded by two delimiters.
# These delimiters must not be modified. Thanks.
# START KALI CONFIG VARIABLES
PROMPT_ALTERNATIVE=twoline
NEWLINE_BEFORE_PROMPT=yes
# STOP KALI CONFIG VARIABLES

if [ "$color_prompt" = yes ]; then
    # override default virtualenv indicator in prompt
    VIRTUAL_ENV_DISABLE_PROMPT=1

    configure_prompt

    # enable syntax-highlighting
    # if [ -f /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ]; then
    #     . /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
    #     ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern)
    #     ZSH_HIGHLIGHT_STYLES[default]=none
    #     ZSH_HIGHLIGHT_STYLES[unknown-token]=underline
    #     ZSH_HIGHLIGHT_STYLES[reserved-word]=fg=cyan,bold
    #     ZSH_HIGHLIGHT_STYLES[suffix-alias]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[global-alias]=fg=green,bold
    #     ZSH_HIGHLIGHT_STYLES[precommand]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[commandseparator]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[autodirectory]=fg=green,underline
    #     ZSH_HIGHLIGHT_STYLES[path]=bold
    #     ZSH_HIGHLIGHT_STYLES[path_pathseparator]=
    #     ZSH_HIGHLIGHT_STYLES[path_prefix_pathseparator]=
    #     ZSH_HIGHLIGHT_STYLES[globbing]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[history-expansion]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[command-substitution]=none
    #     ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[process-substitution]=none
    #     ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[single-hyphen-option]=fg=green
    #     ZSH_HIGHLIGHT_STYLES[double-hyphen-option]=fg=green
    #     ZSH_HIGHLIGHT_STYLES[back-quoted-argument]=none
    #     ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[single-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[double-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]=fg=yellow
    #     ZSH_HIGHLIGHT_STYLES[rc-quote]=fg=magenta
    #     ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[assign]=none
    #     ZSH_HIGHLIGHT_STYLES[redirection]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[comment]=fg=black,bold
    #     ZSH_HIGHLIGHT_STYLES[named-fd]=none
    #     ZSH_HIGHLIGHT_STYLES[numeric-fd]=none
    #     ZSH_HIGHLIGHT_STYLES[arg0]=fg=cyan
    #     ZSH_HIGHLIGHT_STYLES[bracket-error]=fg=red,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-1]=fg=blue,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-2]=fg=green,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-3]=fg=magenta,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-4]=fg=yellow,bold
    #     ZSH_HIGHLIGHT_STYLES[bracket-level-5]=fg=cyan,bold
    #     ZSH_HIGHLIGHT_STYLES[cursor-matchingbracket]=standout
    # fi
else
    PROMPT='${debian_chroot:+($debian_chroot)}%n@%m:%~%(#.#.$) '
fi
unset color_prompt force_color_prompt

toggle_oneline_prompt(){
    if [ "$PROMPT_ALTERNATIVE" = oneline ]; then
        PROMPT_ALTERNATIVE=twoline
    else
        PROMPT_ALTERNATIVE=oneline
    fi
    configure_prompt
    zle reset-prompt
}
zle -N toggle_oneline_prompt
bindkey ^P toggle_oneline_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*|Eterm|aterm|kterm|gnome*|alacritty)
    TERM_TITLE=$'\e]0;${debian_chroot:+($debian_chroot)}${VIRTUAL_ENV:+($(basename $VIRTUAL_ENV))}%n@%m: %~\a'
    ;;
*)
    ;;
esac

precmd() {
    # Print the previously configured title
    print -Pnr -- "$TERM_TITLE"

    # Print a new line before the prompt, but only if it is not the first line
    if [ "$NEWLINE_BEFORE_PROMPT" = yes ]; then
        if [ -z "$_NEW_LINE_BEFORE_PROMPT" ]; then
            _NEW_LINE_BEFORE_PROMPT=1
        else
            print ""
        fi
    fi
}

# enable color support of ls, less and man, and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    export LS_COLORS="$LS_COLORS:ow=30;44:" # fix ls color for folders with 777 permissions

    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
    alias diff='diff --color=auto'
    alias ip='ip --color=auto'

    export LESS_TERMCAP_mb=$'\E[1;31m'     # begin blink
    export LESS_TERMCAP_md=$'\E[1;36m'     # begin bold
    export LESS_TERMCAP_me=$'\E[0m'        # reset bold/blink
    export LESS_TERMCAP_so=$'\E[01;33m'    # begin reverse video
    export LESS_TERMCAP_se=$'\E[0m'        # reset reverse video
    export LESS_TERMCAP_us=$'\E[1;32m'     # begin underline
    export LESS_TERMCAP_ue=$'\E[0m'        # reset underline

    # Take advantage of $LS_COLORS for completion as well
    zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
    zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
fi

# some more ls aliases
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'

# enable auto-suggestions based on the history
if [ -f /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh ]; then
    . /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh
    # change suggestion color
    ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=#999'
fi

# enable command-not-found if installed
if [ -f /etc/zsh_command_not_found ]; then
    . /etc/zsh_command_not_found
fi

EOF