458 lines
16 KiB
Bash
458 lines
16 KiB
Bash
#!/bin/zsh
|
||
|
||
# http://zsh.sourceforge.net/Doc/Release/Options.html
|
||
|
||
|
||
# =============================================================================
|
||
# History
|
||
# =============================================================================
|
||
|
||
# If this is set, zsh sessions will append their history list to the history
|
||
# file, rather than replace it.
|
||
setopt APPEND_HISTORY
|
||
|
||
# Save each command’s beginning timestamp and the duration to the history file.
|
||
setopt EXTENDED_HISTORY
|
||
|
||
# When searching for history entries in the line editor, do not display
|
||
# duplicates of a line previously found.
|
||
setopt HIST_FIND_NO_DUPS
|
||
|
||
# Remove command lines from the history list when the first character on the
|
||
# line is a space, or when one of the expanded aliases contains a leading space.
|
||
setopt HIST_IGNORE_SPACE
|
||
|
||
# Number of lines of history kept within the shell.
|
||
HISTSIZE=10000
|
||
|
||
# Number of lines of history to save to $HISTFILE.
|
||
SAVEHIST=10000
|
||
|
||
# File where history is saved.
|
||
HISTFILE=~/.histfile
|
||
|
||
|
||
# =============================================================================
|
||
# Input/Output
|
||
# =============================================================================
|
||
|
||
# Allow comments even in interactive shells.
|
||
setopt INTERACTIVE_COMMENTS
|
||
|
||
# Don't beep on error.
|
||
setopt NO_BEEP
|
||
|
||
|
||
# =============================================================================
|
||
# Changing Directories
|
||
# =============================================================================
|
||
|
||
# If a command is issued that can’t be executed as a normal command, and the
|
||
# command is the name of a directory, perform the cd command to that directory.
|
||
setopt AUTO_CD
|
||
|
||
# Make cd push the old directory onto the directory stack (cd -<tab complete>).
|
||
setopt AUTO_PUSHD
|
||
|
||
# Don’t push multiple copies of the same directory onto the directory stack.
|
||
setopt PUSHD_IGNORE_DUPS
|
||
|
||
# Global aliases for fast directory navigation. Global aliases are substituted
|
||
# anywhere on a line.
|
||
alias ...='../..'
|
||
alias ....='../../..'
|
||
alias .....='../../../..'
|
||
|
||
|
||
# =============================================================================
|
||
# Environment
|
||
# =============================================================================
|
||
|
||
# Add ~/.local/bin to $PATH.
|
||
export PATH="${HOME}/.local/bin:${PATH}"
|
||
|
||
# Automatically remove duplicates from these arrays.
|
||
typeset -U path PATH cdpath CDPATH fpath FPATH manpath MANPATH
|
||
|
||
|
||
# =============================================================================
|
||
# Job Control
|
||
# =============================================================================
|
||
|
||
# Report the status of background jobs immediately, rather than waiting until
|
||
# just before printing a prompt.
|
||
setopt NOTIFY
|
||
|
||
# Print job notifications in the long format (show e.g. PIDs) by default.
|
||
setopt LONG_LIST_JOBS
|
||
|
||
# Don't send SIGHUP to background processes when the shell exits.
|
||
setopt NO_HUP
|
||
|
||
|
||
# =============================================================================
|
||
# Colours
|
||
# =============================================================================
|
||
|
||
# Inside tmux TERM must be "screen", "tmux", or "tmux-256color".
|
||
# See https://github.com/tmux/tmux/wiki/FAQ and https://github.com/tmux/tmux/issues/625.
|
||
if [[ -v TMUX ]]; then
|
||
export TERM="tmux-256color"
|
||
else
|
||
export TERM="xterm-256color"
|
||
fi
|
||
|
||
# Evaluate dircolors to populate $LS_COLORS
|
||
eval "$(dircolors)"
|
||
|
||
# Add colour to common applications using aliases.
|
||
# https://wiki.archlinux.org/index.php/Color_output_in_console
|
||
alias diff='diff --color=auto'
|
||
alias grep='grep --color=auto'
|
||
alias egrep='egrep --color=auto'
|
||
alias fgrep='fgrep --color=auto'
|
||
alias ip='ip --color=auto'
|
||
|
||
|
||
# Add source code highlighting to less.
|
||
# https://www.gnu.org/software/src-highlite/source-highlight.html#Using-source_002dhighlight-with-less
|
||
if [[ -x "$(command -v source-highlight-esc.sh)" ]]; then # debian
|
||
export LESSOPEN="| source-highlight-esc.sh %s --tab=4"
|
||
export LESS=' -R '
|
||
elif [[ -x "$(command -v /usr/share/source-highlight/source-highlight-esc.sh)" ]]; then # ubuntu
|
||
export LESSOPEN="| /usr/share/source-highlight/source-highlight-esc.sh %s --tab=4"
|
||
export LESS=' -R '
|
||
else
|
||
print -P '%F{8}Warning: source-highlight package missing.'
|
||
fi
|
||
|
||
|
||
# =============================================================================
|
||
# Aliases
|
||
# =============================================================================
|
||
|
||
# Better ls
|
||
alias ls='ls --color=auto --classify --group-directories-first -v'
|
||
alias ll='ls -lh'
|
||
alias lla='ll -a'
|
||
|
||
# Nice-to-have aliases for (in)frequently used or hard-to-remember commands.
|
||
alias upgrade='sudo apt update && sudo apt upgrade && sudo apt autoremove'
|
||
alias rcheck='rhash --check --recursive --percents .'
|
||
alias rsynca='rsync --archive --compress --partial --human-readable --progress'
|
||
alias serve='python3 -m http.server'
|
||
|
||
function speedtest() {
|
||
function f() {
|
||
echo "================================= $1 ================================="
|
||
curl --max-time 10 --output /dev/null $2
|
||
}
|
||
f "Datapacket" http://fra.download.datapacket.com/10000mb.bin
|
||
f "Cachefly" http://cachefly.cachefly.net/100mb.test
|
||
f "OVH" http://www.ovh.net/files/1Gio.dat
|
||
f "Digital Ocean" http://speedtest-ams3.digitalocean.com/100mb.test
|
||
f "Linode" http://speedtest.frankfurt.linode.com/100MB-frankfurt.bin
|
||
f "Online.net" http://ping.online.net/10000Mo.dat
|
||
f "Hetzner" https://speed.hetzner.de/1GB.bin
|
||
f "Vultr" https://fra-de-ping.vultr.com/vultr.com.1000MB.bin
|
||
f "LeaseWeb" https://mirror.de.leaseweb.net/speedtest/1000mb.bin
|
||
f "Ramnode" http://lg.nl.ramnode.com/static/1000MB.test
|
||
f "OVH GRA" http://gra.proof.ovh.net/files/1Gio.dat
|
||
}
|
||
|
||
|
||
# =============================================================================
|
||
# Keybinds
|
||
# =============================================================================
|
||
|
||
# Enable searching through history for commands matching everything up to the
|
||
# current cursor position. (https://coderwall.com/p/jpj_6q/zsh-better-history-searching-with-arrow-keys).
|
||
autoload -U up-line-or-beginning-search
|
||
autoload -U down-line-or-beginning-search
|
||
zle -N up-line-or-beginning-search
|
||
zle -N down-line-or-beginning-search
|
||
|
||
# Use Emacs-style keybinds.
|
||
bindkey -e
|
||
|
||
# Bind keys as one would expect them to be bound.
|
||
# Use 'cat -v' to character sequences.
|
||
bindkey "$terminfo[kbs]" backward-delete-char # BackSpace
|
||
bindkey "$terminfo[khome]" beginning-of-line # Home
|
||
bindkey "$terminfo[kend]" end-of-line # End
|
||
bindkey "$terminfo[kich1]" overwrite-mode # Insert
|
||
bindkey "$terminfo[kdch1]" delete-char # Delete
|
||
bindkey "$terminfo[kcuu1]" up-line-or-beginning-search # Up
|
||
bindkey "$terminfo[kcud1]" down-line-or-beginning-search # Down
|
||
bindkey "$terminfo[kcub1]" backward-char # Left
|
||
bindkey "$terminfo[kcuf1]" forward-char # Right
|
||
#bindkey "$terminfo[kpp]" x # PageUp
|
||
#bindkey "$terminfo[knp]" x # PageDown
|
||
bindkey "^[[1;5D" backward-word # Ctrl+Left
|
||
bindkey "^[[1;5C" forward-word # Ctrl+Right
|
||
bindkey "^H" backward-delete-word # Ctrl+Backspace
|
||
bindkey "^[[3;5~" delete-word # Ctrl+Delete
|
||
bindkey "^[[Z" reverse-menu-complete # Shift+Tab
|
||
|
||
# Additional keybinds.
|
||
bindkey "^[?" run-help # Alt+?
|
||
bindkey "^[+" run-help # Alt++ (simpler on Danish keyboards)
|
||
|
||
# Remove '/' from WORDCHARS, making Ctrl+{Right,Left,Backspace} work correctly
|
||
# on path segments instead of operating on the entire path at once.
|
||
WORDCHARS=${WORDCHARS:s@/@}
|
||
|
||
|
||
# =============================================================================
|
||
# Completion
|
||
# =============================================================================
|
||
|
||
autoload -Uz compinit
|
||
compinit
|
||
|
||
#
|
||
# Options
|
||
#
|
||
|
||
# If a completion is performed with the cursor within a word, and a full
|
||
# completion is inserted, the cursor is moved to the end of the word.
|
||
setopt ALWAYS_TO_END
|
||
|
||
# Automatically list choices on an ambiguous completion.
|
||
setopt AUTO_LIST
|
||
|
||
# Automatically use menu completion after the second consecutive request for
|
||
# completion, for example by pressing the tab key repeatedly.
|
||
setopt AUTO_MENU
|
||
|
||
# If unset, the cursor is set to the end of the word if completion is started.
|
||
# Otherwise it stays there and completion is done from both ends.
|
||
setopt COMPLETE_IN_WORD
|
||
|
||
# If a parameter is completed whose content is the name of a directory, then
|
||
# add a trailing slash instead of a space.
|
||
setopt AUTO_PARAM_SLASH
|
||
|
||
# On an ambiguous completion, list possibilities instead of inserting the first
|
||
# match immediately.
|
||
setopt NO_MENU_COMPLETE
|
||
|
||
#
|
||
# Styles
|
||
#
|
||
|
||
# Group matches and describe.
|
||
zstyle ':completion:*:*:*:*:*' menu select
|
||
zstyle ':completion:*:matches' group 'yes'
|
||
zstyle ':completion:*:options' description 'yes'
|
||
zstyle ':completion:*:options' auto-description 'specify: %d'
|
||
zstyle ':completion:*:corrections' format ' %F{green}-- %d (errors: %e) --%f'
|
||
zstyle ':completion:*:descriptions' format ' %F{yellow}-- %d --%f'
|
||
zstyle ':completion:*:messages' format ' %F{purple} -- %d --%f'
|
||
zstyle ':completion:*:warnings' format ' %F{red}-- no matches found --%f'
|
||
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
|
||
zstyle ':completion:*' format ' %F{yellow}-- %d --%f'
|
||
zstyle ':completion:*' group-name ''
|
||
zstyle ':completion:*' verbose yes
|
||
|
||
# Try smart-case completion, then case-insensitive, then partial-word, and then
|
||
# substring completion.
|
||
# See http://zsh.sourceforge.net/Doc/Release/Completion-Widgets.html#Completion-Matching-Control.
|
||
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' 'm:{a-zA-Z}={A-Z}{a-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
|
||
|
||
# Use the same colors as 'ls' in completion
|
||
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
|
||
|
||
# Keep directories and files separated
|
||
zstyle ':completion:*' list-dirs-first true
|
||
|
||
# The value of this style is used in completion listing to separate the string
|
||
# to complete from a description when completing options.
|
||
zstyle ':completion:*:options' list-separator \|
|
||
|
||
# This makes it so that the option descriptions are gray instead of the same
|
||
# colour as the options themselves to avoid confusion. This code itself,
|
||
# however, is very confusing and I have no idea how it works.
|
||
zstyle ':completion:*:options' list-colors \
|
||
"=(#b)(-##)([^ ]#) #(\\|)(*)=0=38;5;23=${color[bold]}=38;5;237=38;5;242" \
|
||
"=(#b)(-##)([^ ]#)(*)=0=38;5;23=${color[bold]}" \
|
||
"=(#b) #(\\|)(*)=0=38;5;237=38;5;242"
|
||
|
||
# Enable completion for '../'
|
||
zstyle ':completion:*' special-dirs true
|
||
|
||
# Behave as if there were a ‘*’ between sequences of slashes in filename paths.
|
||
# E.g., foo//bar will be treated as foo/*/bar.
|
||
zstyle ':completion:*' squeeze-slashes false
|
||
|
||
# Make completions for apt etc. usable by activating completion caching layer.
|
||
zstyle ':completion::complete:*' use-cache on
|
||
|
||
# Don't complete hosts from /etc/hosts
|
||
zstyle -e ':completion:*' hosts 'reply=()'
|
||
|
||
# Provide more processes in completion of programs like kill and killall
|
||
zstyle ':completion:*:*:*:*:processes' command 'ps -u $LOGNAME -o pid,user,command -w'
|
||
zstyle ':completion:*:processes-names' command "ps -eo cmd= | sed 's:\([^ ]*\).*:\1:;s:\(/[^ ]*/\)::;/^\[/d'"
|
||
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;36=0=01'
|
||
zstyle ':completion:*:*:kill:*' menu yes select
|
||
zstyle ':completion:*:*:kill:*' force-list always
|
||
zstyle ':completion:*:*:kill:*' insert-ids single
|
||
|
||
# Man
|
||
zstyle ':completion:*:manuals' separate-sections true
|
||
zstyle ':completion:*:manuals.(^1*)' insert-sections true
|
||
zstyle ':completion:*:man:*' menu yes select
|
||
|
||
# Pasting with tabs doesn't perform completion
|
||
zstyle ':completion:*' insert-tab pending
|
||
|
||
# SSH/SCP/RSYNC tag order
|
||
zstyle ':completion:*:(scp|rsync):*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
|
||
zstyle ':completion:*:(scp|rsync):*' group-order users files all-files hosts-domain hosts-host hosts-ipaddr
|
||
zstyle ':completion:*:ssh:*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
|
||
zstyle ':completion:*:ssh:*' group-order users hosts-domain hosts-host users hosts-ipaddr
|
||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost
|
||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^[-[:alnum:]]##(.[-[:alnum:]]##)##' '*@*'
|
||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*'
|
||
|
||
# Ignore internal shell functions
|
||
zstyle ':completion:*:functions' ignored-patterns '_*'
|
||
|
||
|
||
# =============================================================================
|
||
# Prompting
|
||
# =============================================================================
|
||
|
||
# Prompt expansion 101: (http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html)
|
||
# %F => color dict (https://wiki.archlinux.org/index.php/Zsh#Colors)
|
||
# %f => reset color
|
||
# %~ => current path
|
||
# %n => username
|
||
# %m => shortname host
|
||
# %(?..) => prompt conditional - %(condition.true.false)
|
||
# vcs_info:
|
||
# %b => current branch
|
||
# %a => current action (rebase/merge)
|
||
|
||
#
|
||
# Options
|
||
#
|
||
|
||
# Enable command substitution and arithmetic expansion in prompts using '$()'.
|
||
setopt PROMPT_SUBST
|
||
|
||
# Disallow virtual envirnments from updating the prompt.
|
||
export VIRTUAL_ENV_DISABLE_PROMPT=1
|
||
|
||
#
|
||
# Git
|
||
# http://zsh.sourceforge.net/Doc/Release/User-Contributions.html
|
||
#
|
||
|
||
# Load vcs_info git module
|
||
autoload -Uz vcs_info
|
||
zstyle ':vcs_info:*' enable git
|
||
|
||
# Only export the one 'vcs_info_msg_0_' message variable.
|
||
zstyle ':vcs_info:*' max-exports 1
|
||
|
||
# Set formats
|
||
zstyle ':vcs_info:git*' formats '@%F{yellow}%b%f'
|
||
|
||
# actionformats is used if there is a special action going on in the current
|
||
# repository; like an interactive rebase or a merge conflict.
|
||
zstyle ':vcs_info:git*' actionformats '@%F{yellow}%b%f|%F{magenta}%a%f'
|
||
|
||
#
|
||
# Prompt
|
||
#
|
||
|
||
# Define the precmd hook function, which is executed before each prompt.
|
||
precmd () {
|
||
vcs_info # makes sure we have up-to-date vcs info
|
||
}
|
||
|
||
PROMPT=''
|
||
|
||
# Show '(venv)' in gray if in virtual environment.
|
||
PROMPT+='$([[ -v VIRTUAL_ENV ]] && print "%F{8}(`basename $VIRTUAL_ENV`)%f ")'
|
||
|
||
# Show 'hostname:' if logged in through SSH. Only checked once since it cannot
|
||
# change mid-session, unlike a virtual environment, like configured above.
|
||
# https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
|
||
if [[ -v SSH_CONNECTION ]]; then
|
||
PROMPT+='%F{010}%m%f:'
|
||
fi
|
||
|
||
# Add the current working directory.
|
||
PROMPT+='%F{12}%~%f'
|
||
|
||
# Add version control info
|
||
PROMPT+='${vcs_info_msg_0_}'
|
||
|
||
# Make the prompt character green if last command successful, otherwise red.
|
||
PROMPT+='%(?.%F{green}.%F{red})'
|
||
|
||
# Add the actual prompt character: '#' if running with privileges, '❯' if not.
|
||
PROMPT+='%(!.#.❯)%f '
|
||
|
||
|
||
# =============================================================================
|
||
# Xterm Title
|
||
# =============================================================================
|
||
|
||
autoload -Uz add-zsh-hook
|
||
function xterm_title_precmd () {
|
||
print -Pn '\e]2;%n@%m %1~\a'
|
||
}
|
||
function xterm_title_preexec () {
|
||
print -Pn '\e]2;%n@%m %1~ %# '
|
||
print -n "${(q)1}\a"
|
||
}
|
||
if [[ "$TERM" == (screen*|xterm*|rxvt*) ]]; then
|
||
add-zsh-hook -Uz precmd xterm_title_precmd
|
||
add-zsh-hook -Uz preexec xterm_title_preexec
|
||
fi
|
||
|
||
|
||
# =============================================================================
|
||
# Plugins -- Must be loaded last
|
||
# =============================================================================
|
||
|
||
#
|
||
# zsh syntax highlighting: Fish shell like syntax highlighting for Zsh
|
||
# https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md
|
||
#
|
||
|
||
if [[ -e /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ]]; then
|
||
source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
||
|
||
ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern cursor)
|
||
|
||
## Main
|
||
|
||
## Pattern
|
||
ZSH_HIGHLIGHT_PATTERNS+=('sudo rm' 'fg=white,bold,bg=red')
|
||
ZSH_HIGHLIGHT_PATTERNS+=('sudo dd' 'fg=white,bold,bg=red')
|
||
|
||
## Cursor
|
||
ZSH_HIGHLIGHT_STYLES[cursor]='underline'
|
||
|
||
else
|
||
print -P '%F{8}Warning: zsh-syntax-highlighting package missing.'
|
||
fi
|
||
|
||
#
|
||
# zsh auto-suggestions
|
||
#
|
||
|
||
if [[ -e /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh ]]; then
|
||
source /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh
|
||
|
||
ZSH_AUTOSUGGEST_STRATEGY=(match_prev_cmd completion)
|
||
#ZSH_AUTOSUGGEST_COMPLETION_IGNORE="(|sudo )apt install *"
|
||
else
|
||
print -P '%F{8}Warning: zsh-autosuggestions package missing.'
|
||
fi
|