From 63363f48bb83f8b6946053caf2717cb16e9e07e8 Mon Sep 17 00:00:00 2001 From: Emiliano Vavassori Date: Wed, 29 Dec 2021 19:14:18 +0100 Subject: [PATCH] Import iniziale, da testare. --- .zshrc | 26 ++ zsh/aliases/base.aliases.zsh | 10 + zsh/functions/_pip | 102 +++++++ zsh/plugins/command-not-found.plugin.zsh | 72 +++++ zsh/plugins/common-aliases.plugin.zsh | 93 +++++++ zsh/plugins/copydir.plugin.zsh | 8 + zsh/plugins/copyfile.plugin.zsh | 10 + zsh/plugins/fzf.plugin.zsh | 203 ++++++++++++++ zsh/plugins/git.plugin.zsh | 340 +++++++++++++++++++++++ zsh/plugins/jump.plugin.zsh | 23 ++ zsh/plugins/pip.plugin.zsh | 114 ++++++++ zsh/plugins/python.plugin.zsh | 89 ++++++ zsh/plugins/rsync.plugin.zsh | 7 + zsh/plugins/sudo.plugin.zsh | 98 +++++++ zsh/plugins/systemadmin.plugin.zsh | 158 +++++++++++ zsh/plugins/systemd.plugin.zsh | 119 ++++++++ zsh/plugins/tmux.plugin.zsh | 111 ++++++++ zsh/plugins/z.plugin.zsh | 9 + zsh/plugins/z.sh | 270 ++++++++++++++++++ zsh/themes/gentoo.zsh-theme | 30 ++ 20 files changed, 1892 insertions(+) create mode 100644 .zshrc create mode 100644 zsh/aliases/base.aliases.zsh create mode 100644 zsh/functions/_pip create mode 100644 zsh/plugins/command-not-found.plugin.zsh create mode 100644 zsh/plugins/common-aliases.plugin.zsh create mode 100644 zsh/plugins/copydir.plugin.zsh create mode 100644 zsh/plugins/copyfile.plugin.zsh create mode 100644 zsh/plugins/fzf.plugin.zsh create mode 100644 zsh/plugins/git.plugin.zsh create mode 100644 zsh/plugins/jump.plugin.zsh create mode 100644 zsh/plugins/pip.plugin.zsh create mode 100644 zsh/plugins/python.plugin.zsh create mode 100644 zsh/plugins/rsync.plugin.zsh create mode 100644 zsh/plugins/sudo.plugin.zsh create mode 100644 zsh/plugins/systemadmin.plugin.zsh create mode 100644 zsh/plugins/systemd.plugin.zsh create mode 100644 zsh/plugins/tmux.plugin.zsh create mode 100644 zsh/plugins/z.plugin.zsh create mode 100644 zsh/plugins/z.sh create mode 100644 zsh/themes/gentoo.zsh-theme diff --git a/.zshrc b/.zshrc new file mode 100644 index 0000000..14b92ae --- /dev/null +++ b/.zshrc @@ -0,0 +1,26 @@ +# vim:sts=2:sw=2:ft=zsh + +# Autocompletion +export FPATH=~/.dotfiles/zsh/functions:$FPATH + +# Theme +source ~/.dotfiles/zsh/themes/gentoo.zsh.theme + +# zsh packages from system +source /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh +source /usr/share/zsh-syntax-highlighting/zsh-syntax-hightlighting.zsh + +# Plugins +source ~/.dotfiles/zsh/plugins/*.plugin.zsh + +# EDITOR +export EDITOR="/usr/bin/vim" + +# FZF default options +export FZF_DEFAULT_OPTS="--multi --no-mouse --ansi --color=dark" + +# Loading rvm if exists +[ -f /etc/profile.d/rvm.sh ] && source /etc/profile.d/rvm.sh + +# Loading additional aliases +source ~/.dotfiles/zsh/aliases/*.aliases.zsh diff --git a/zsh/aliases/base.aliases.zsh b/zsh/aliases/base.aliases.zsh new file mode 100644 index 0000000..5f1f958 --- /dev/null +++ b/zsh/aliases/base.aliases.zsh @@ -0,0 +1,10 @@ +# vim:sts=2:sw=2:ft=zsh +# Aliases +alias grep="grep --colour=auto" +alias egrep="egrep --colour=auto" +alias fgrep="fgrep --colour=auto" +alias ip="ip --color=auto" +alias ap="ansible-playbook" +alias digs="dig +short" +# L'impostazione predefinita dell'alias di ping non mi piace +unalias ping diff --git a/zsh/functions/_pip b/zsh/functions/_pip new file mode 100644 index 0000000..03b54da --- /dev/null +++ b/zsh/functions/_pip @@ -0,0 +1,102 @@ +#compdef pip pip2 pip-2.7 pip3 pip-3.2 pip-3.3 pip-3.4 +#autoload + +# pip zsh completion, based on last stable release (pip8) +# homebrew completion and backwards compatibility + +_pip_all() { + # we cache the list of packages (originally from the macports plugin) + if (( ! $+piplist )); then + zsh-pip-cache-packages + piplist=($(cat $ZSH_PIP_CACHE_FILE)) + fi +} + +_pip_installed() { + installed_pkgs=($($service freeze | cut -d '=' -f 1)) +} + +local -a _1st_arguments +_1st_arguments=( + 'install:install packages' + 'download:download packages' + 'uninstall:uninstall packages' + 'freeze:output all currently installed packages (exact versions) to stdout' + 'list:list installed packages' + 'show:show information about installed packages' + 'search:search PyPI' + 'wheel:build individual wheel archives for your requirements and dependencies' + 'hash:compute a hash of a local package archive' + 'help:show available commands' + 'bundle:create pybundles (archives containing multiple packages)(deprecated)' + 'unzip:unzip individual packages(deprecated)' + 'zip:zip individual packages(deprecated)' +) + +local expl +local -a all_pkgs installed_pkgs + +_arguments \ + '(-h --help)'{-h,--help}'[show help]' \ + '(--isolated)--isolated[run pip in isolated mode, ignores environment variables and user configuration]' \ + '(-v --verbose)'{-v,--verbose}'[give more output]' \ + '(-V --version)'{-V,--version}'[show version number of program and exit]' \ + '(-q --quiet)'{-q,--quiet}'[give less output]' \ + '(--log)--log[log file location]' \ + '(--proxy)--proxy[proxy in form user:passwd@proxy.server:port]' \ + '(--retries)--retries[max number of retries per connection (default 5 times)]' \ + '(--timeout)--timeout[socket timeout (default 15s)]' \ + '(--exists-action)--exists-action[default action when a path already exists: (s)witch, (i)gnore, (w)ipe, (b)ackup]' \ + '(--trusted-host)--trusted-host[mark this host as trusted]' \ + '(--cert)--cert[path to alternate CA bundle]' \ + '(--client-cert)--client-cert[path to SSL client certificate]' \ + '(--cache-dir)--cache-dir[store the cache data in specified directory]' \ + '(--no-cache-dir)--no-cache-dir[disable de cache]' \ + '(--disable-pip-version-check)--disable-pip-version-check[do not check periodically for new pip version downloads]' \ + '(-E --environment)'{-E,--environment}'[virtualenv environment to run pip in (deprecated)]' \ + '(-s --enable-site-packages)'{-s,--enable-site-packages}'[include site-packages in virtualenv (deprecated)]' \ + '*:: :->subcmds' && return 0 + +if (( CURRENT == 1 )); then + _describe -t commands "pip subcommand" _1st_arguments + return +fi + +case "$words[1]" in + search) + _arguments \ + '(--index)--index[base URL of Python Package Index]' ;; + freeze) + _arguments \ + '(-l --local)'{-l,--local}'[report only virtualenv packages]' ;; + install) + _arguments \ + '(-U --upgrade)'{-U,--upgrade}'[upgrade all packages to the newest available version]' \ + '(--user)--user[install packages to user home]' \ + '(-f --find-links)'{-f,--find-links}'[URL for finding packages]' \ + '(-r --requirement)'{-r,--requirement}'[Requirements file for packages to install]:File:_files' \ + '(--no-deps --no-dependencies)'{--no-deps,--no-dependencies}'[iIgnore package dependencies]' \ + '(--no-install)--no-install[only download packages]' \ + '(--no-download)--no-download[only install downloaded packages]' \ + '(--install-option)--install-option[extra arguments to be supplied to the setup.py]' \ + '(--single-version-externally-managed)--single-version-externally-managed[do not download/install dependencies. requires --record or --root]'\ + '(--root)--root[treat this path as a fake chroot, installing into it. implies --single-version-externally-managed]'\ + '(--record)--record[file to record all installed files to.]'\ + '(-r --requirement)'{-r,--requirement}'[requirements file]: :_files'\ + '(-e --editable)'{-e,--editable}'[path of or url to source to link to instead of installing.]: :_files -/'\ + '1: :->packages' && return 0 + + if [[ "$state" == packages ]]; then + _pip_all + _wanted piplist expl 'packages' compadd -a piplist + _files -g "*.(tar.gz|whl)" + fi ;; + uninstall) + _pip_installed + _wanted installed_pkgs expl 'installed packages' compadd -a installed_pkgs ;; + show) + _pip_installed + _wanted installed_pkgs expl 'installed packages' compadd -a installed_pkgs ;; +esac +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/pip/_pip diff --git a/zsh/plugins/command-not-found.plugin.zsh b/zsh/plugins/command-not-found.plugin.zsh new file mode 100644 index 0000000..fe8271f --- /dev/null +++ b/zsh/plugins/command-not-found.plugin.zsh @@ -0,0 +1,72 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/command-not-found/command-not-found.plugin.zsh +# +## Platforms with a built-in command-not-found handler init file + +for file ( + # Arch Linux. Must have pkgfile installed: https://wiki.archlinux.org/index.php/Pkgfile#Command_not_found + /usr/share/doc/pkgfile/command-not-found.zsh + # macOS (M1 and classic Homebrew): https://github.com/Homebrew/homebrew-command-not-found + /opt/homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh + /usr/local/Homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh +); do + if [[ -r "$file" ]]; then + source "$file" + unset file + return 0 + fi +done +unset file + + +## Platforms with manual command_not_found_handler() setup + +# Debian and derivatives: https://launchpad.net/ubuntu/+source/command-not-found +if [[ -x /usr/lib/command-not-found || -x /usr/share/command-not-found/command-not-found ]]; then + command_not_found_handler() { + if [[ -x /usr/lib/command-not-found ]]; then + /usr/lib/command-not-found -- "$1" + return $? + elif [[ -x /usr/share/command-not-found/command-not-found ]]; then + /usr/share/command-not-found/command-not-found -- "$1" + return $? + else + printf "zsh: command not found: %s\n" "$1" >&2 + return 127 + fi + } +fi + +# Fedora: https://fedoraproject.org/wiki/Features/PackageKitCommandNotFound +if [[ -x /usr/libexec/pk-command-not-found ]]; then + command_not_found_handler() { + if [[ -S /var/run/dbus/system_bus_socket && -x /usr/libexec/packagekitd ]]; then + /usr/libexec/pk-command-not-found "$@" + return $? + fi + + printf "zsh: command not found: %s\n" "$1" >&2 + return 127 + } +fi + +# NixOS: https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/programs/command-not-found +if [[ -x /run/current-system/sw/bin/command-not-found ]]; then + command_not_found_handler() { + /run/current-system/sw/bin/command-not-found "$@" + } +fi + +# Termux: https://github.com/termux/command-not-found +if [[ -x /data/data/com.termux/files/usr/libexec/termux/command-not-found ]]; then + command_not_found_handler() { + /data/data/com.termux/files/usr/libexec/termux/command-not-found "$1" + } +fi + +# SUSE and derivates: https://www.unix.com/man-page/suse/1/command-not-found/ +if [[ -x /usr/bin/command-not-found ]]; then + command_not_found_handler() { + /usr/bin/command-not-found "$1" + } +fi diff --git a/zsh/plugins/common-aliases.plugin.zsh b/zsh/plugins/common-aliases.plugin.zsh new file mode 100644 index 0000000..b9f2b08 --- /dev/null +++ b/zsh/plugins/common-aliases.plugin.zsh @@ -0,0 +1,93 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/common-aliases/common-aliases.plugin.zsh +# +# Advanced Aliases. +# Use with caution +# + +# ls, the common ones I use a lot shortened for rapid fire usage +alias l='ls -lFh' #size,show type,human readable +alias la='ls -lAFh' #long list,show almost all,show type,human readable +alias lr='ls -tRFh' #sorted by date,recursive,show type,human readable +alias lt='ls -ltFh' #long list,sorted by date,show type,human readable +alias ll='ls -l' #long list +alias ldot='ls -ld .*' +alias lS='ls -1FSsh' +alias lart='ls -1Fcart' +alias lrt='ls -1Fcrt' +alias lsr='ls -lARFh' #Recursive list of files and directories +alias lsn='ls -1' #A column contains name of files and directories + +alias zshrc='${=EDITOR} ${ZDOTDIR:-$HOME}/.zshrc' # Quick access to the .zshrc file + +alias grep='grep --color' +alias sgrep='grep -R -n -H -C 5 --exclude-dir={.git,.svn,CVS} ' + +alias t='tail -f' + +# Command line head / tail shortcuts +alias -g H='| head' +alias -g T='| tail' +alias -g G='| grep' +alias -g L="| less" +alias -g M="| most" +alias -g LL="2>&1 | less" +alias -g CA="2>&1 | cat -A" +alias -g NE="2> /dev/null" +alias -g NUL="> /dev/null 2>&1" +alias -g P="2>&1| pygmentize -l pytb" + +alias dud='du -d 1 -h' +alias duf='du -sh *' +(( $+commands[fd] )) || alias fd='find . -type d -name' +alias ff='find . -type f -name' + +alias h='history' +alias hgrep="fc -El 0 | grep" +alias help='man' +alias p='ps -f' +alias sortnr='sort -n -r' +alias unexport='unset' + +alias rm='rm -i' +alias cp='cp -i' +alias mv='mv -i' + +# zsh is able to auto-do some kungfoo +# depends on the SUFFIX :) +autoload -Uz is-at-least +if is-at-least 4.2.0; then + # open browser on urls + if [[ -n "$BROWSER" ]]; then + _browser_fts=(htm html de org net com at cx nl se dk) + for ft in $_browser_fts; do alias -s $ft='$BROWSER'; done + fi + + _editor_fts=(cpp cxx cc c hh h inl asc txt TXT tex) + for ft in $_editor_fts; do alias -s $ft='$EDITOR'; done + + if [[ -n "$XIVIEWER" ]]; then + _image_fts=(jpg jpeg png gif mng tiff tif xpm) + for ft in $_image_fts; do alias -s $ft='$XIVIEWER'; done + fi + + _media_fts=(ape avi flv m4a mkv mov mp3 mpeg mpg ogg ogm rm wav webm) + for ft in $_media_fts; do alias -s $ft=mplayer; done + + #read documents + alias -s pdf=acroread + alias -s ps=gv + alias -s dvi=xdvi + alias -s chm=xchm + alias -s djvu=djview + + #list whats inside packed file + alias -s zip="unzip -l" + alias -s rar="unrar l" + alias -s tar="tar tf" + alias -s tar.gz="echo " + alias -s ace="unace l" +fi + +# Make zsh know about hosts already accessed by SSH +zstyle -e ':completion:*:(ssh|scp|sftp|rsh|rsync):hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%[# ]*}//,/ })' diff --git a/zsh/plugins/copydir.plugin.zsh b/zsh/plugins/copydir.plugin.zsh new file mode 100644 index 0000000..084efe3 --- /dev/null +++ b/zsh/plugins/copydir.plugin.zsh @@ -0,0 +1,8 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/copydir/copydir.plugin.zsh +# +# Copies the pathname of the current directory to the system or X Windows clipboard +function copydir { + emulate -L zsh + print -n $PWD | clipcopy +} diff --git a/zsh/plugins/copyfile.plugin.zsh b/zsh/plugins/copyfile.plugin.zsh new file mode 100644 index 0000000..5196715 --- /dev/null +++ b/zsh/plugins/copyfile.plugin.zsh @@ -0,0 +1,10 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/copyfile/copyfile.plugin.zsh +# +# Copies the contents of a given file to the system or X Windows clipboard +# +# copyfile +function copyfile { + emulate -L zsh + clipcopy $1 +} diff --git a/zsh/plugins/fzf.plugin.zsh b/zsh/plugins/fzf.plugin.zsh new file mode 100644 index 0000000..77d2092 --- /dev/null +++ b/zsh/plugins/fzf.plugin.zsh @@ -0,0 +1,203 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/fzf/fzf.plugin.zsh +function fzf_setup_using_base_dir() { + local fzf_base fzf_shell fzfdirs dir + + test -d "${FZF_BASE}" && fzf_base="${FZF_BASE}" + + if [[ -z "${fzf_base}" ]]; then + fzfdirs=( + "${HOME}/.fzf" + "${HOME}/.nix-profile/share/fzf" + "${XDG_DATA_HOME:-$HOME/.local/share}/fzf" + "/usr/local/opt/fzf" + "/usr/share/fzf" + "/usr/local/share/examples/fzf" + ) + for dir in ${fzfdirs}; do + if [[ -d "${dir}" ]]; then + fzf_base="${dir}" + break + fi + done + + if [[ -z "${fzf_base}" ]]; then + if (( ${+commands[fzf-share]} )) && dir="$(fzf-share)" && [[ -d "${dir}" ]]; then + fzf_base="${dir}" + elif (( ${+commands[brew]} )) && dir="$(brew --prefix fzf 2>/dev/null)"; then + if [[ -d "${dir}" ]]; then + fzf_base="${dir}" + fi + fi + fi + fi + + if [[ ! -d "${fzf_base}" ]]; then + return 1 + fi + + # Fix fzf shell directory for Arch Linux, NixOS or Void Linux packages + if [[ ! -d "${fzf_base}/shell" ]]; then + fzf_shell="${fzf_base}" + else + fzf_shell="${fzf_base}/shell" + fi + + # Setup fzf binary path + if (( ! ${+commands[fzf]} )) && [[ "$PATH" != *$fzf_base/bin* ]]; then + export PATH="$PATH:$fzf_base/bin" + fi + + # Auto-completion + if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then + source "${fzf_shell}/completion.zsh" 2> /dev/null + fi + + # Key bindings + if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then + source "${fzf_shell}/key-bindings.zsh" + fi +} + + +function fzf_setup_using_debian() { + if (( ! $+commands[dpkg] )) || ! dpkg -s fzf &>/dev/null; then + # Either not a debian based distro, or no fzf installed + return 1 + fi + + # NOTE: There is no need to configure PATH for debian package, all binaries + # are installed to /usr/bin by default + + local completions key_bindings + + case $PREFIX in + *com.termux*) + # Support Termux package + completions="${PREFIX}/share/fzf/completion.zsh" + key_bindings="${PREFIX}/share/fzf/key-bindings.zsh" + ;; + *) + # Determine completion file path: first bullseye/sid, then buster/stretch + completions="/usr/share/doc/fzf/examples/completion.zsh" + [[ -f "$completions" ]] || completions="/usr/share/zsh/vendor-completions/_fzf" + key_bindings="/usr/share/doc/fzf/examples/key-bindings.zsh" + ;; + esac + + # Auto-completion + if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then + source $completions 2> /dev/null + fi + + # Key bindings + if [[ ! "$DISABLE_FZF_KEY_BINDINGS" == "true" ]]; then + source $key_bindings + fi + + return 0 +} + +function fzf_setup_using_opensuse() { + # OpenSUSE installs fzf in /usr/bin/fzf + # If the command is not found, the package isn't installed + (( $+commands[fzf] )) || return 1 + + # The fzf-zsh-completion package installs the auto-completion in + local completions="/usr/share/zsh/site-functions/_fzf" + # The fzf-zsh-completion package installs the key-bindings file in + local key_bindings="/etc/zsh_completion.d/fzf-key-bindings" + + # If these are not found: (1) maybe we're not on OpenSUSE, or + # (2) maybe the fzf-zsh-completion package isn't installed. + if [[ ! -f "$completions" || ! -f "$key_bindings" ]]; then + return 1 + fi + + # Auto-completion + if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then + source "$completions" 2>/dev/null + fi + + # Key bindings + if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then + source "$key_bindings" 2>/dev/null + fi + + return 0 +} + +function fzf_setup_using_openbsd() { + # openBSD installs fzf in /usr/local/bin/fzf + if [[ "$OSTYPE" != openbsd* ]] || (( ! $+commands[fzf] )); then + return 1 + fi + + # The fzf package installs the auto-completion in + local completions="/usr/local/share/zsh/site-functions/_fzf_completion" + # The fzf package installs the key-bindings file in + local key_bindings="/usr/local/share/zsh/site-functions/_fzf_key_bindings" + + # Auto-completion + if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then + source "$completions" 2>/dev/null + fi + + # Key bindings + if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then + source "$key_bindings" 2>/dev/null + fi + + return 0 +} + +function fzf_setup_using_cygwin() { + # Cygwin installs fzf in /usr/local/bin/fzf + if [[ "$OSTYPE" != cygwin* ]] || (( ! $+commands[fzf] )); then + return 1 + fi + + # The fzf-zsh-completion package installs the auto-completion in + local completions="/etc/profile.d/fzf-completion.zsh" + # The fzf-zsh package installs the key-bindings file in + local key_bindings="/etc/profile.d/fzf.zsh" + + # Auto-completion + if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then + source "$completions" 2>/dev/null + fi + + # Key bindings + if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then + source "$key_bindings" 2>/dev/null + fi + + return 0 +} + +# Indicate to user that fzf installation not found if nothing worked +function fzf_setup_error() { + cat >&2 <<'EOF' +[oh-my-zsh] fzf plugin: Cannot find fzf installation directory. +Please add `export FZF_BASE=/path/to/fzf/install/dir` to your .zshrc +EOF +} + +fzf_setup_using_openbsd \ + || fzf_setup_using_debian \ + || fzf_setup_using_opensuse \ + || fzf_setup_using_cygwin \ + || fzf_setup_using_base_dir \ + || fzf_setup_error + +unset -f -m 'fzf_setup_*' + +if [[ -z "$FZF_DEFAULT_COMMAND" ]]; then + if (( $+commands[rg] )); then + export FZF_DEFAULT_COMMAND='rg --files --hidden --glob "!.git/*"' + elif (( $+commands[fd] )); then + export FZF_DEFAULT_COMMAND='fd --type f --hidden --exclude .git' + elif (( $+commands[ag] )); then + export FZF_DEFAULT_COMMAND='ag -l --hidden -g "" --ignore .git' + fi +fi diff --git a/zsh/plugins/git.plugin.zsh b/zsh/plugins/git.plugin.zsh new file mode 100644 index 0000000..f5a0636 --- /dev/null +++ b/zsh/plugins/git.plugin.zsh @@ -0,0 +1,340 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/git/git.plugin.zsh +# +# Git version checking +autoload -Uz is-at-least +git_version="${${(As: :)$(git version 2>/dev/null)}[3]}" + +# +# Functions +# + +# The name of the current branch +# Back-compatibility wrapper for when this function was defined here in +# the plugin, before being pulled in to core lib/git.zsh as git_current_branch() +# to fix the core -> git plugin dependency. +function current_branch() { + git_current_branch +} + +# Pretty log messages +function _git_log_prettily(){ + if ! [ -z $1 ]; then + git log --pretty=$1 + fi +} +compdef _git _git_log_prettily=git-log + +# Warn if the current branch is a WIP +function work_in_progress() { + if $(git log -n 1 2>/dev/null | grep -q -c "\-\-wip\-\-"); then + echo "WIP!!" + fi +} + +# Check if main exists and use instead of master +function git_main_branch() { + command git rev-parse --git-dir &>/dev/null || return + local ref + for ref in refs/{heads,remotes/{origin,upstream}}/{main,trunk}; do + if command git show-ref -q --verify $ref; then + echo ${ref:t} + return + fi + done + echo master +} + +# Check for develop and similarly named branches +function git_develop_branch() { + command git rev-parse --git-dir &>/dev/null || return + local branch + for branch in dev devel development; do + if command git show-ref -q --verify refs/heads/$branch; then + echo $branch + return + fi + done + echo develop +} + +# +# Aliases +# (sorted alphabetically) +# + +alias g='git' + +alias ga='git add' +alias gaa='git add --all' +alias gapa='git add --patch' +alias gau='git add --update' +alias gav='git add --verbose' +alias gap='git apply' +alias gapt='git apply --3way' + +alias gb='git branch' +alias gba='git branch -a' +alias gbd='git branch -d' +alias gbda='git branch --no-color --merged | command grep -vE "^([+*]|\s*($(git_main_branch)|$(git_develop_branch))\s*$)" | command xargs git branch -d 2>/dev/null' +alias gbD='git branch -D' +alias gbl='git blame -b -w' +alias gbnm='git branch --no-merged' +alias gbr='git branch --remote' +alias gbs='git bisect' +alias gbsb='git bisect bad' +alias gbsg='git bisect good' +alias gbsr='git bisect reset' +alias gbss='git bisect start' + +alias gc='git commit -v' +alias gc!='git commit -v --amend' +alias gcn!='git commit -v --no-edit --amend' +alias gca='git commit -v -a' +alias gca!='git commit -v -a --amend' +alias gcan!='git commit -v -a --no-edit --amend' +alias gcans!='git commit -v -a -s --no-edit --amend' +alias gcam='git commit -a -m' +alias gcsm='git commit -s -m' +alias gcas='git commit -a -s' +alias gcasm='git commit -a -s -m' +alias gcb='git checkout -b' +alias gcf='git config --list' + +function gccd() { + command git clone --recurse-submodules "$@" + [[ -d "$_" ]] && cd "$_" || cd "${${_:t}%.git}" +} +compdef _git gccd=git-clone + +alias gcl='git clone --recurse-submodules' +alias gclean='git clean -id' +alias gpristine='git reset --hard && git clean -dffx' +alias gcm='git checkout $(git_main_branch)' +alias gcd='git checkout $(git_develop_branch)' +alias gcmsg='git commit -m' +alias gco='git checkout' +alias gcor='git checkout --recurse-submodules' +alias gcount='git shortlog -sn' +alias gcp='git cherry-pick' +alias gcpa='git cherry-pick --abort' +alias gcpc='git cherry-pick --continue' +alias gcs='git commit -S' +alias gcss='git commit -S -s' +alias gcssm='git commit -S -s -m' + +alias gd='git diff' +alias gdca='git diff --cached' +alias gdcw='git diff --cached --word-diff' +alias gdct='git describe --tags $(git rev-list --tags --max-count=1)' +alias gds='git diff --staged' +alias gdt='git diff-tree --no-commit-id --name-only -r' +alias gdup='git diff @{upstream}' +alias gdw='git diff --word-diff' + +function gdnolock() { + git diff "$@" ":(exclude)package-lock.json" ":(exclude)*.lock" +} +compdef _git gdnolock=git-diff + +function gdv() { git diff -w "$@" | view - } +compdef _git gdv=git-diff + +alias gf='git fetch' +# --jobs= was added in git 2.8 +is-at-least 2.8 "$git_version" \ + && alias gfa='git fetch --all --prune --jobs=10' \ + || alias gfa='git fetch --all --prune' +alias gfo='git fetch origin' + +alias gfg='git ls-files | grep' + +alias gg='git gui citool' +alias gga='git gui citool --amend' + +function ggf() { + [[ "$#" != 1 ]] && local b="$(git_current_branch)" + git push --force origin "${b:=$1}" +} +compdef _git ggf=git-checkout +function ggfl() { + [[ "$#" != 1 ]] && local b="$(git_current_branch)" + git push --force-with-lease origin "${b:=$1}" +} +compdef _git ggfl=git-checkout + +function ggl() { + if [[ "$#" != 0 ]] && [[ "$#" != 1 ]]; then + git pull origin "${*}" + else + [[ "$#" == 0 ]] && local b="$(git_current_branch)" + git pull origin "${b:=$1}" + fi +} +compdef _git ggl=git-checkout + +function ggp() { + if [[ "$#" != 0 ]] && [[ "$#" != 1 ]]; then + git push origin "${*}" + else + [[ "$#" == 0 ]] && local b="$(git_current_branch)" + git push origin "${b:=$1}" + fi +} +compdef _git ggp=git-checkout + +function ggpnp() { + if [[ "$#" == 0 ]]; then + ggl && ggp + else + ggl "${*}" && ggp "${*}" + fi +} +compdef _git ggpnp=git-checkout + +function ggu() { + [[ "$#" != 1 ]] && local b="$(git_current_branch)" + git pull --rebase origin "${b:=$1}" +} +compdef _git ggu=git-checkout + +alias ggpur='ggu' +alias ggpull='git pull origin "$(git_current_branch)"' +alias ggpush='git push origin "$(git_current_branch)"' + +alias ggsup='git branch --set-upstream-to=origin/$(git_current_branch)' +alias gpsup='git push --set-upstream origin $(git_current_branch)' + +alias ghh='git help' + +alias gignore='git update-index --assume-unchanged' +alias gignored='git ls-files -v | grep "^[[:lower:]]"' +alias git-svn-dcommit-push='git svn dcommit && git push github $(git_main_branch):svntrunk' + +alias gk='\gitk --all --branches &!' +alias gke='\gitk --all $(git log -g --pretty=%h) &!' + +alias gl='git pull' +alias glg='git log --stat' +alias glgp='git log --stat -p' +alias glgg='git log --graph' +alias glgga='git log --graph --decorate --all' +alias glgm='git log --graph --max-count=10' +alias glo='git log --oneline --decorate' +alias glol="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset'" +alias glols="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --stat" +alias glod="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset'" +alias glods="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset' --date=short" +alias glola="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --all" +alias glog='git log --oneline --decorate --graph' +alias gloga='git log --oneline --decorate --graph --all' +alias glp="_git_log_prettily" + +alias gm='git merge' +alias gmom='git merge origin/$(git_main_branch)' +alias gmtl='git mergetool --no-prompt' +alias gmtlvim='git mergetool --no-prompt --tool=vimdiff' +alias gmum='git merge upstream/$(git_main_branch)' +alias gma='git merge --abort' + +alias gp='git push' +alias gpd='git push --dry-run' +alias gpf='git push --force-with-lease' +alias gpf!='git push --force' +alias gpoat='git push origin --all && git push origin --tags' +alias gpr='git pull --rebase' +alias gpu='git push upstream' +alias gpv='git push -v' + +alias gr='git remote' +alias gra='git remote add' +alias grb='git rebase' +alias grba='git rebase --abort' +alias grbc='git rebase --continue' +alias grbd='git rebase $(git_develop_branch)' +alias grbi='git rebase -i' +alias grbm='git rebase $(git_main_branch)' +alias grbom='git rebase origin/$(git_main_branch)' +alias grbo='git rebase --onto' +alias grbs='git rebase --skip' +alias grev='git revert' +alias grh='git reset' +alias grhh='git reset --hard' +alias groh='git reset origin/$(git_current_branch) --hard' +alias grm='git rm' +alias grmc='git rm --cached' +alias grmv='git remote rename' +alias grrm='git remote remove' +alias grs='git restore' +alias grset='git remote set-url' +alias grss='git restore --source' +alias grst='git restore --staged' +alias grt='cd "$(git rev-parse --show-toplevel || echo .)"' +alias gru='git reset --' +alias grup='git remote update' +alias grv='git remote -v' + +alias gsb='git status -sb' +alias gsd='git svn dcommit' +alias gsh='git show' +alias gsi='git submodule init' +alias gsps='git show --pretty=short --show-signature' +alias gsr='git svn rebase' +alias gss='git status -s' +alias gst='git status' + +# use the default stash push on git 2.13 and newer +is-at-least 2.13 "$git_version" \ + && alias gsta='git stash push' \ + || alias gsta='git stash save' + +alias gstaa='git stash apply' +alias gstc='git stash clear' +alias gstd='git stash drop' +alias gstl='git stash list' +alias gstp='git stash pop' +alias gsts='git stash show --text' +alias gstu='gsta --include-untracked' +alias gstall='git stash --all' +alias gsu='git submodule update' +alias gsw='git switch' +alias gswc='git switch -c' +alias gswm='git switch $(git_main_branch)' +alias gswd='git switch $(git_develop_branch)' + +alias gts='git tag -s' +alias gtv='git tag | sort -V' +alias gtl='gtl(){ git tag --sort=-v:refname -n -l "${1}*" }; noglob gtl' + +alias gunignore='git update-index --no-assume-unchanged' +alias gunwip='git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1' +alias gup='git pull --rebase' +alias gupv='git pull --rebase -v' +alias gupa='git pull --rebase --autostash' +alias gupav='git pull --rebase --autostash -v' +alias glum='git pull upstream $(git_main_branch)' + +alias gwch='git whatchanged -p --abbrev-commit --pretty=medium' +alias gwip='git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign -m "--wip-- [skip ci]"' + +alias gam='git am' +alias gamc='git am --continue' +alias gams='git am --skip' +alias gama='git am --abort' +alias gamscp='git am --show-current-patch' + +function grename() { + if [[ -z "$1" || -z "$2" ]]; then + echo "Usage: $0 old_branch new_branch" + return 1 + fi + + # Rename branch locally + git branch -m "$1" "$2" + # Rename branch in origin remote + if git push origin :"$1"; then + git push --set-upstream origin "$2" + fi +} + +unset git_version diff --git a/zsh/plugins/jump.plugin.zsh b/zsh/plugins/jump.plugin.zsh new file mode 100644 index 0000000..d4c5ff1 --- /dev/null +++ b/zsh/plugins/jump.plugin.zsh @@ -0,0 +1,23 @@ +# Jump through folders. +if [[ -d "$HOME/.bookmarks" ]]; then + export CDPATH=".:$HOME/.bookmarks:/" + + # Functions + function jump_add_bookmark() { + ln -sf $(pwd) $HOME/.bookmarks/$1 + } + + function jump_del_bookmark() { + rm $HOME/.bookmarks/$1 + } + + function jump_list() { + ls -l $HOME/.bookmarks | sed -ne '/^l/p' | sed -e 's/[^@]*//' + } + + alias jump="cd -P" + alias j="cd -P" + alias jl="jump_list" + alias ja="jump_add_bookmark" + alias jd="jump_del_bookmark" +fi diff --git a/zsh/plugins/pip.plugin.zsh b/zsh/plugins/pip.plugin.zsh new file mode 100644 index 0000000..029c53e --- /dev/null +++ b/zsh/plugins/pip.plugin.zsh @@ -0,0 +1,114 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/pip/pip.plugin.zsh +# +# Usage: +# Just add pip to your installed plugins. + +# If you would like to change the cheeseshops used for autocomplete set +# ZSH_PIP_INDEXES in your zshrc. If one of your indexes are bogus you won't get +# any kind of error message, pip will just not autocomplete from them. Double +# check! +# +# If you would like to clear your cache, go ahead and do a +# "zsh-pip-clear-cache". + +if [[ -d "${XDG_CACHE_HOME:-$HOME/.cache}/pip" ]]; then + ZSH_PIP_CACHE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/pip/zsh-cache" +else + ZSH_PIP_CACHE_FILE=~/.pip/zsh-cache +fi +ZSH_PIP_INDEXES=(https://pypi.org/simple/) + +zsh-pip-clear-cache() { + rm $ZSH_PIP_CACHE_FILE + unset piplist +} + +zsh-pip-clean-packages() { + sed -n '/\([^<]\{1,\}\).*/\1/p' +} + +zsh-pip-cache-packages() { + if [[ ! -d ${ZSH_PIP_CACHE_FILE:h} ]]; then + mkdir -p ${ZSH_PIP_CACHE_FILE:h} + fi + + if [[ ! -f $ZSH_PIP_CACHE_FILE ]]; then + echo -n "(...caching package index...)" + tmp_cache=/tmp/zsh_tmp_cache + touch $tmp_cache + for index in $ZSH_PIP_INDEXES ; do + # well... I've already got two problems + curl -L $index 2>/dev/null | \ + zsh-pip-clean-packages \ + >> $tmp_cache + done + sort $tmp_cache | uniq | tr '\n' ' ' > $ZSH_PIP_CACHE_FILE + rm $tmp_cache + fi +} + +# A test function that validates the regex against known forms of the simple +# index. If you modify the regex to make it work for you, you should add a test +# case in here and make sure that your changes don't break things for someone +# else. +zsh-pip-test-clean-packages() { + local expected + local actual + expected="0x10c-asm +1009558_nester" + + actual=$(echo -n "Simple Index +0x10c-asm
+1009558_nester
+" | zsh-pip-clean-packages) + + if [[ $actual != $expected ]] ; then + echo -e "python's simple index is broken:\n$actual\n !=\n$expected" + else + echo "python's simple index is fine" + fi + + actual=$(echo -n ' + + Simple Package Index + + + 0x10c-asm
+ 1009558_nester
+' | zsh-pip-clean-packages) + + if [[ $actual != $expected ]] ; then + echo -e "the djangopypi2 index is broken:\n$actual\n !=\n$expected" + else + echo "the djangopypi2 index is fine" + fi +} + +if (( $+commands[pip3] && !$+commands[pip] )); then + alias pip="noglob pip3" +else + alias pip="noglob pip" +fi + +# Create requirements file +alias pipreq="pip freeze > requirements.txt" + +# Install packages from requirements file +alias pipir="pip install -r requirements.txt" + +# Update all installed packages +function pipupall { + # non-GNU xargs does not support nor need `--no-run-if-empty` + local xargs="xargs --no-run-if-empty" + xargs --version 2>/dev/null | grep -q GNU || xargs="xargs" + pip list --outdated --format freeze | cut -d= -f1 | ${=xargs} pip install --upgrade +} + +# Uninstalled all installed packages +function pipunall { + # non-GNU xargs does not support nor need `--no-run-if-empty` + local xargs="xargs --no-run-if-empty" + xargs --version 2>/dev/null | grep -q GNU || xargs="xargs" + pip list --format freeze | cut -d= -f1 | ${=xargs} pip uninstall +} diff --git a/zsh/plugins/python.plugin.zsh b/zsh/plugins/python.plugin.zsh new file mode 100644 index 0000000..0729b1d --- /dev/null +++ b/zsh/plugins/python.plugin.zsh @@ -0,0 +1,89 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/python/python.plugin.zsh +# +# python command +alias py='python' + +# Find python file +alias pyfind='find . -name "*.py"' + +# Remove python compiled byte-code and mypy/pytest cache in either the current +# directory or in a list of specified directories (including sub directories). +function pyclean() { + ZSH_PYCLEAN_PLACES=${*:-'.'} + find ${ZSH_PYCLEAN_PLACES} -type f -name "*.py[co]" -delete + find ${ZSH_PYCLEAN_PLACES} -type d -name "__pycache__" -delete + find ${ZSH_PYCLEAN_PLACES} -depth -type d -name ".mypy_cache" -exec rm -r "{}" + + find ${ZSH_PYCLEAN_PLACES} -depth -type d -name ".pytest_cache" -exec rm -r "{}" + +} + +# Add the user installed site-packages paths to PYTHONPATH, only if the +# directory exists. Also preserve the current PYTHONPATH value. +# Feel free to autorun this when .zshrc loads. +function pyuserpaths() { + local targets=("python2" "python3") # bins + + # Get existing interpreters. + local interps=() + for target in $targets; do + [ `command -v $target` ] && interps+=($target) + done + + # Check for a non-standard install directory. + local user_base="${HOME}/.local" + [ $PYTHONUSERBASE ] && user_base=$PYTHONUSERBASE + + # Add version specific paths, if: + # it exists in the filesystem; + # it isn't in PYTHONPATH already. + for interp in $interps; do + # Get minor release version. + local ver=`$interp -V 2>&1` + ver=`echo ${ver:7} | cut -d '.' -f 1,2` # The patch version is variable length, truncate it. + + local site_pkgs="${user_base}/lib/python${ver}/site-packages" + [[ -d $site_pkgs && ! $PYTHONPATH =~ $site_pkgs ]] && export PYTHONPATH=${site_pkgs}:$PYTHONPATH + done +} + +# Grep among .py files +alias pygrep='grep -nr --include="*.py"' + +# Run proper IPython regarding current virtualenv (if any) +alias ipython="python -c 'import IPython; IPython.terminal.ipapp.launch_new_instance()'" + +# Share local directory as a HTTP server +alias pyserver="python -m http.server" + + +## venv utilities + +# Activate a the python virtual environment specified. +# If none specified, use 'venv'. +function vrun() { + local name="${1:-venv}" + local venvpath="${name:P}" + + if [[ ! -d "$venvpath" ]]; then + echo >&2 "Error: no such venv in current directory: $name" + return 1 + fi + + if [[ ! -f "${venvpath}/bin/activate" ]]; then + echo >&2 "Error: '${name}' is not a proper virtual environment" + return 1 + fi + + . "${venvpath}/bin/activate" || return $? + echo "Activated virtual environment ${name}" +} + +# Create a new virtual environment, with default name 'venv'. +function mkv() { + local name="${1:-venv}" + local venvpath="${name:P}" + + python3 -m venv "${name}" || return + echo >&2 "Created venv in '${venvpath}'" + vrun "${name}" +} diff --git a/zsh/plugins/rsync.plugin.zsh b/zsh/plugins/rsync.plugin.zsh new file mode 100644 index 0000000..1e02340 --- /dev/null +++ b/zsh/plugins/rsync.plugin.zsh @@ -0,0 +1,7 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/rsync/rsync.plugin.zsh +# +alias rsync-copy="rsync -avz --progress -h" +alias rsync-move="rsync -avz --progress -h --remove-source-files" +alias rsync-update="rsync -avzu --progress -h" +alias rsync-synchronize="rsync -avzu --delete --progress -h" diff --git a/zsh/plugins/sudo.plugin.zsh b/zsh/plugins/sudo.plugin.zsh new file mode 100644 index 0000000..98a4380 --- /dev/null +++ b/zsh/plugins/sudo.plugin.zsh @@ -0,0 +1,98 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/sudo/sudo.plugin.zsh +# +# ------------------------------------------------------------------------------ +# Description +# ----------- +# +# sudo or sudoedit will be inserted before the command +# +# ------------------------------------------------------------------------------ +# Authors +# ------- +# +# * Dongweiming +# * Subhaditya Nath +# * Marc Cornellà +# +# ------------------------------------------------------------------------------ + +__sudo-replace-buffer() { + local old=$1 new=$2 space=${2:+ } + if [[ ${#LBUFFER} -le ${#old} ]]; then + RBUFFER="${space}${BUFFER#$old }" + LBUFFER="${new}" + else + LBUFFER="${new}${space}${LBUFFER#$old }" + fi +} + +sudo-command-line() { + # If line is empty, get the last run command from history + [[ -z $BUFFER ]] && LBUFFER="$(fc -ln -1)" + + # Save beginning space + local WHITESPACE="" + if [[ ${LBUFFER:0:1} = " " ]]; then + WHITESPACE=" " + LBUFFER="${LBUFFER:1}" + fi + + # If $EDITOR is not set, just toggle the sudo prefix on and off + if [[ -z "$EDITOR" ]]; then + case "$BUFFER" in + sudoedit\ *) __sudo-replace-buffer "sudoedit" "" ;; + sudo\ *) __sudo-replace-buffer "sudo" "" ;; + *) LBUFFER="sudo $LBUFFER" ;; + esac + else + # Check if the typed command is really an alias to $EDITOR + + # Get the first part of the typed command + local cmd="${${(Az)BUFFER}[1]}" + # Get the first part of the alias of the same name as $cmd, or $cmd if no alias matches + local realcmd="${${(Az)aliases[$cmd]}[1]:-$cmd}" + # Get the first part of the $EDITOR command ($EDITOR may have arguments after it) + local editorcmd="${${(Az)EDITOR}[1]}" + + # Note: ${var:c} makes a $PATH search and expands $var to the full path + # The if condition is met when: + # - $realcmd is '$EDITOR' + # - $realcmd is "cmd" and $EDITOR is "cmd" + # - $realcmd is "cmd" and $EDITOR is "cmd --with --arguments" + # - $realcmd is "/path/to/cmd" and $EDITOR is "cmd" + # - $realcmd is "/path/to/cmd" and $EDITOR is "/path/to/cmd" + # or + # - $realcmd is "cmd" and $EDITOR is "cmd" + # - $realcmd is "cmd" and $EDITOR is "/path/to/cmd" + # or + # - $realcmd is "cmd" and $EDITOR is /alternative/path/to/cmd that appears in $PATH + if [[ "$realcmd" = (\$EDITOR|$editorcmd|${editorcmd:c}) \ + || "${realcmd:c}" = ($editorcmd|${editorcmd:c}) ]] \ + || builtin which -a "$realcmd" | command grep -Fx -q "$editorcmd"; then + editorcmd="$cmd" # replace $editorcmd with the typed command so it matches below + fi + + # Check for editor commands in the typed command and replace accordingly + case "$BUFFER" in + $editorcmd\ *) __sudo-replace-buffer "$editorcmd" "sudoedit" ;; + \$EDITOR\ *) __sudo-replace-buffer '$EDITOR' "sudoedit" ;; + sudoedit\ *) __sudo-replace-buffer "sudoedit" "$EDITOR" ;; + sudo\ *) __sudo-replace-buffer "sudo" "" ;; + *) LBUFFER="sudo $LBUFFER" ;; + esac + fi + + # Preserve beginning space + LBUFFER="${WHITESPACE}${LBUFFER}" + + # Redisplay edit buffer (compatibility with zsh-syntax-highlighting) + zle redisplay +} + +zle -N sudo-command-line + +# Defined shortcut keys: [Esc] [Esc] +bindkey -M emacs '\e\e' sudo-command-line +bindkey -M vicmd '\e\e' sudo-command-line +bindkey -M viins '\e\e' sudo-command-line diff --git a/zsh/plugins/systemadmin.plugin.zsh b/zsh/plugins/systemadmin.plugin.zsh new file mode 100644 index 0000000..df39c34 --- /dev/null +++ b/zsh/plugins/systemadmin.plugin.zsh @@ -0,0 +1,158 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/systemadmin/systemadmin.plugin.zsh +# +# ------------------------------------------------------------------------------ +# Description +# ----------- +# +# This is one for the system administrator, operation and maintenance. +# +# ------------------------------------------------------------------------------ +# Authors +# ------- +# +# * Dongweiming +# +# ------------------------------------------------------------------------------ + +function retlog() { + if [[ -z $1 ]];then + echo '/var/log/nginx/access.log' + else + echo $1 + fi +} + +alias ping='ping -c 5' +alias clr='clear; echo Currently logged in on $TTY, as $USERNAME in directory $PWD.' +alias path='print -l $path' +alias mkdir='mkdir -pv' +# get top process eating memory +alias psmem='ps -e -orss=,args= | sort -b -k1 -nr' +alias psmem10='ps -e -orss=,args= | sort -b -k1 -nr | head -n 10' +# get top process eating cpu if not work try execute : export LC_ALL='C' +alias pscpu='ps -e -o pcpu,cpu,nice,state,cputime,args|sort -k1,1n -nr' +alias pscpu10='ps -e -o pcpu,cpu,nice,state,cputime,args|sort -k1,1n -nr | head -n 10' +# top10 of the history +alias hist10='print -l ${(o)history%% *} | uniq -c | sort -nr | head -n 10' + +# directory LS +dls () { + print -l *(/) +} +psgrep() { + ps aux | grep "${1:-.}" | grep -v grep +} +# Kills any process that matches a regexp passed to it +killit() { + ps aux | grep -v "grep" | grep "$@" | awk '{print $2}' | xargs sudo kill +} + +# list contents of directories in a tree-like format +if ! (( $+commands[tree] )); then + tree () { + find $@ -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g' + } +fi + +# Sort connection state +sortcons() { + netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn +} + +# View all 80 Port Connections +con80() { + netstat -nat|grep -i ":80"|wc -l +} + +# On the connected IP sorted by the number of connections +sortconip() { + netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n +} + +# top20 of Find the number of requests on 80 port +req20() { + netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20 +} + +# top20 of Using tcpdump port 80 access to view +http20() { + sudo tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -n 20 +} + +# top20 of Find time_wait connection +timewait20() { + netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20 +} + +# top20 of Find SYN connection +syn20() { + netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr|head -n20 +} + +# Printing process according to the port number +port_pro() { + netstat -ntlp | grep "${1:-.}" | awk '{print $7}' | cut -d/ -f1 +} + +# top10 of gain access to the ip address +accessip10() { + awk '{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}' "$(retlog)" +} + +# top20 of Most Visited file or page +visitpage20() { + awk '{print $11}' "$(retlog)"|sort|uniq -c|sort -nr|head -n 20 +} + +# top100 of Page lists the most time-consuming (more than 60 seconds) as well as the corresponding page number of occurrences +consume100() { + awk '($NF > 60 && $7~/\.php/){print $7}' "$(retlog)" |sort -n|uniq -c|sort -nr|head -n 100 + # if django website or other website make by no suffix language + # awk '{print $7}' "$(retlog)" |sort -n|uniq -c|sort -nr|head -n 100 +} + +# Website traffic statistics (G) +webtraffic() { + awk "{sum+=$10} END {print sum/1024/1024/1024}" "$(retlog)" +} + +# Statistical connections 404 +c404() { + awk '($9 ~/404/)' "$(retlog)" | awk '{print $9,$7}' | sort +} + +# Statistical http status. +httpstatus() { + awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}' "$(retlog)" +} + +# Delete 0 byte file +d0() { + find "${1:-.}" -type f -size 0 -exec rm -rf {} \; +} + +# gather external ip address +geteip() { + curl -s -S -4 https://icanhazip.com + curl -s -S -6 https://icanhazip.com +} + +# determine local IP address(es) +getip() { + if (( ${+commands[ip]} )); then + ip addr | awk '/inet /{print $2}' | command grep -v 127.0.0.1 + else + ifconfig | awk '/inet /{print $2}' | command grep -v 127.0.0.1 + fi +} + +# Clear zombie processes +clrz() { + ps -eal | awk '{ if ($2 == "Z") {print $4}}' | kill -9 +} + +# Second concurrent +conssec() { + awk '{if($9~/200|30|404/)COUNT[$4]++}END{for( a in COUNT) print a,COUNT[a]}' "$(retlog)"|sort -k 2 -nr|head -n10 +} diff --git a/zsh/plugins/systemd.plugin.zsh b/zsh/plugins/systemd.plugin.zsh new file mode 100644 index 0000000..7fa8a1a --- /dev/null +++ b/zsh/plugins/systemd.plugin.zsh @@ -0,0 +1,119 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/systemd/systemd.plugin.zsh +# +# systemctl aliases +user_commands=( + cat + get-default + help + is-active + is-enabled + is-failed + is-system-running + list-dependencies + list-jobs + list-sockets + list-timers + list-unit-files + list-units + show + show-environment + status +) + +sudo_commands=( + add-requires + add-wants + cancel + daemon-reexec + daemon-reload + default + disable + edit + emergency + enable + halt + import-environment + isolate + kexec + kill + link + list-machines + load + mask + preset + preset-all + reenable + reload + reload-or-restart + reset-failed + rescue + revert + set-default + set-environment + set-property + start + stop + switch-root + try-reload-or-restart + try-restart + unmask + unset-environment +) + +power_commands=( + hibernate + hybrid-sleep + poweroff + reboot + restart + suspend +) + +for c in $user_commands; do + alias "sc-$c"="systemctl $c" + alias "scu-$c"="systemctl --user $c" +done + +for c in $sudo_commands; do + alias "sc-$c"="sudo systemctl $c" + alias "scu-$c"="systemctl --user $c" +done + +for c in $power_commands; do + alias "sc-$c"="systemctl $c" +done + +unset c user_commands sudo_commands power_commands + + +# --now commands +alias sc-enable-now="sc-enable --now" +alias sc-disable-now="sc-disable --now" +alias sc-mask-now="sc-mask --now" + +alias scu-enable-now="scu-enable --now" +alias scu-disable-now="scu-disable --now" +alias scu-mask-now="scu-mask --now" + + +function systemd_prompt_info { + local unit + for unit in "$@"; do + echo -n "$ZSH_THEME_SYSTEMD_PROMPT_PREFIX" + + if [[ -n "$ZSH_THEME_SYSTEMD_PROMPT_CAPS" ]]; then + echo -n "${(U)unit:gs/%/%%}:" + else + echo -n "${unit:gs/%/%%}:" + fi + + if systemctl is-active "$unit" &>/dev/null; then + echo -n "$ZSH_THEME_SYSTEMD_PROMPT_ACTIVE" + else + echo -n "$ZSH_THEME_SYSTEMD_PROMPT_NOTACTIVE" + fi + + echo -n "$ZSH_THEME_SYSTEMD_PROMPT_SUFFIX" + done +} diff --git a/zsh/plugins/tmux.plugin.zsh b/zsh/plugins/tmux.plugin.zsh new file mode 100644 index 0000000..654e8c3 --- /dev/null +++ b/zsh/plugins/tmux.plugin.zsh @@ -0,0 +1,111 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/tmux/tmux.plugin.zsh +# +if ! (( $+commands[tmux] )); then + print "zsh tmux plugin: tmux not found. Please install tmux before using this plugin." >&2 + return 1 +fi + +# ALIASES + +alias ta='tmux attach -t' +alias tad='tmux attach -d -t' +alias ts='tmux new-session -s' +alias tl='tmux list-sessions' +alias tksv='tmux kill-server' +alias tkss='tmux kill-session -t' + +# CONFIGURATION VARIABLES +# Automatically start tmux +: ${ZSH_TMUX_AUTOSTART:=false} +# Only autostart once. If set to false, tmux will attempt to +# autostart every time your zsh configs are reloaded. +: ${ZSH_TMUX_AUTOSTART_ONCE:=true} +# Automatically connect to a previous session if it exists +: ${ZSH_TMUX_AUTOCONNECT:=true} +# Automatically close the terminal when tmux exits +: ${ZSH_TMUX_AUTOQUIT:=$ZSH_TMUX_AUTOSTART} +# Set term to screen or screen-256color based on current terminal support +: ${ZSH_TMUX_FIXTERM:=true} +# Set '-CC' option for iTerm2 tmux integration +: ${ZSH_TMUX_ITERM2:=false} +# The TERM to use for non-256 color terminals. +# Tmux states this should be screen, but you may need to change it on +# systems without the proper terminfo +: ${ZSH_TMUX_FIXTERM_WITHOUT_256COLOR:=screen} +# The TERM to use for 256 color terminals. +# Tmux states this should be screen-256color, but you may need to change it on +# systems without the proper terminfo +: ${ZSH_TMUX_FIXTERM_WITH_256COLOR:=screen-256color} +# Set the configuration path +: ${ZSH_TMUX_CONFIG:=$HOME/.tmux.conf} +# Set -u option to support unicode +: ${ZSH_TMUX_UNICODE:=false} + +# Determine if the terminal supports 256 colors +if [[ $terminfo[colors] == 256 ]]; then + export ZSH_TMUX_TERM=$ZSH_TMUX_FIXTERM_WITH_256COLOR +else + export ZSH_TMUX_TERM=$ZSH_TMUX_FIXTERM_WITHOUT_256COLOR +fi + +# Handle $0 according to the standard: +# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html +0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" +0="${${(M)0:#/*}:-$PWD/$0}" + +# Set the correct local config file to use. +if [[ "$ZSH_TMUX_ITERM2" == "false" && -e "$ZSH_TMUX_CONFIG" ]]; then + export ZSH_TMUX_CONFIG + export _ZSH_TMUX_FIXED_CONFIG="${0:h:a}/tmux.extra.conf" +else + export _ZSH_TMUX_FIXED_CONFIG="${0:h:a}/tmux.only.conf" +fi + +# Wrapper function for tmux. +function _zsh_tmux_plugin_run() { + if [[ -n "$@" ]]; then + command tmux "$@" + return $? + fi + + local -a tmux_cmd + tmux_cmd=(command tmux) + [[ "$ZSH_TMUX_ITERM2" == "true" ]] && tmux_cmd+=(-CC) + [[ "$ZSH_TMUX_UNICODE" == "true" ]] && tmux_cmd+=(-u) + + # Try to connect to an existing session. + [[ "$ZSH_TMUX_AUTOCONNECT" == "true" ]] && $tmux_cmd attach + + # If failed, just run tmux, fixing the TERM variable if requested. + if [[ $? -ne 0 ]]; then + if [[ "$ZSH_TMUX_FIXTERM" == "true" ]]; then + tmux_cmd+=(-f "$_ZSH_TMUX_FIXED_CONFIG") + elif [[ -e "$ZSH_TMUX_CONFIG" ]]; then + tmux_cmd+=(-f "$ZSH_TMUX_CONFIG") + fi + if [[ -n "$ZSH_TMUX_DEFAULT_SESSION_NAME" ]]; then + $tmux_cmd new-session -s $ZSH_TMUX_DEFAULT_SESSION_NAME + else + $tmux_cmd new-session + fi + fi + + if [[ "$ZSH_TMUX_AUTOQUIT" == "true" ]]; then + exit + fi +} + +# Use the completions for tmux for our function +compdef _tmux _zsh_tmux_plugin_run +# Alias tmux to our wrapper function. +alias tmux=_zsh_tmux_plugin_run + +# Autostart if not already in tmux and enabled. +if [[ -z "$TMUX" && "$ZSH_TMUX_AUTOSTART" == "true" && -z "$INSIDE_EMACS" && -z "$EMACS" && -z "$VIM" ]]; then + # Actually don't autostart if we already did and multiple autostarts are disabled. + if [[ "$ZSH_TMUX_AUTOSTART_ONCE" == "false" || "$ZSH_TMUX_AUTOSTARTED" != "true" ]]; then + export ZSH_TMUX_AUTOSTARTED=true + _zsh_tmux_plugin_run + fi +fi diff --git a/zsh/plugins/z.plugin.zsh b/zsh/plugins/z.plugin.zsh new file mode 100644 index 0000000..0f9e673 --- /dev/null +++ b/zsh/plugins/z.plugin.zsh @@ -0,0 +1,9 @@ +# vim:sts=2:sw=2:ft=zsh +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/z/z.plugin.zsh +# +# Handle $0 according to the standard: +# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html +0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" +0="${${(M)0:#/*}:-$PWD/$0}" + +source "${0:h}/z.sh" diff --git a/zsh/plugins/z.sh b/zsh/plugins/z.sh new file mode 100644 index 0000000..51e824a --- /dev/null +++ b/zsh/plugins/z.sh @@ -0,0 +1,270 @@ +# vim:sts=2:sw=2 +# Taken from: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/plugins/z/z.sh +# +# 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 () { + [ -f "$datafile" ] || return + + 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 and / aren't worth matching + [ "$*" = "$HOME" -o "$*" = '/' ] && return + + # don't track excluded directory trees + if [ ${#_Z_EXCLUDE_DIRS[@]} -gt 0 ]; then + local exclude + for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do + case "$*" in "$exclude"*) return;; esac + done + fi + + # 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 diff --git a/zsh/themes/gentoo.zsh-theme b/zsh/themes/gentoo.zsh-theme new file mode 100644 index 0000000..8839aba --- /dev/null +++ b/zsh/themes/gentoo.zsh-theme @@ -0,0 +1,30 @@ +# vim:ft=zsh +# Taken from https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/themes/gentoo.zsh-theme +autoload -Uz colors && colors + +autoload -Uz vcs_info +zstyle ':vcs_info:*' check-for-changes true +zstyle ':vcs_info:*' unstagedstr '%F{red}*' # display this when there are unstaged changes +zstyle ':vcs_info:*' stagedstr '%F{yellow}+' # display this when there are staged changes +zstyle ':vcs_info:*' actionformats '%F{5}(%F{2}%b%F{3}|%F{1}%a%c%u%m%F{5})%f ' +zstyle ':vcs_info:*' formats '%F{5}(%F{2}%b%c%u%m%F{5})%f ' +zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b%F{1}:%F{3}%r' +zstyle ':vcs_info:*' enable git cvs svn +zstyle ':vcs_info:git*+set-message:*' hooks untracked-git + ++vi-untracked-git() { + if command git status --porcelain 2>/dev/null | command grep -q '??'; then + hook_com[misc]='%F{red}?' + else + hook_com[misc]='' + fi +} + +gentoo_precmd() { + vcs_info +} + +autoload -U add-zsh-hook +add-zsh-hook precmd gentoo_precmd + +PROMPT='%(!.%B%F{red}.%B%F{green}%n@)%m %F{blue}%(!.%1~.%~) ${vcs_info_msg_0_}%F{blue}%(!.#.$)%k%b%f '