Zsh Utilities Functions
This is part of the Zsh Utilities.
Zsh Utilities - Functions
This file provides several functions for very different use. See the description to understand the aim of each of them.
Package manager
This part defines some function in relation with package management. It defines generic function name given the linux system installed : "debian-like" system or archlinux.
Check linux system
function __is_debian () { if pkgtools__has_binary apt-fast; then __pkg_mgr="apt-fast" return 0 elif pkgtools__has_binary apt-get; then __pkg_mgr="apt-get" return 0 elif pkgtools__has_binary yaourt; then __pkg_mgr="yaourt" return 1 elif pkgtools__has_binary pacman; then __pkg_mgr="pacman" return 1 fi }
Implement generic function
alias pkg-notify='notify -t 2000 -i stock_dialog-info "${__pkg_mgr}"' if __is_debian; then function install () { __pkgtools__at_function_enter install sudo ${__pkg_mgr} install -y $* && pkg-notify "Installed $@" __pkgtools__at_function_exit return 0 } compdef "_deb_packages uninstalled" install function remove () { __pkgtools__at_function_enter remove sudo ${__pkg_mgr} remove -y $* && pkg-notify "Removed $@" __pkgtools__at_function_exit return 0 } compdef "_deb_packages installed" remove function upgrade () { __pkgtools__at_function_enter upgrade sudo ${__pkg_mgr} update && sudo ${__pkg_mgr} upgrade && pkg-notify "Upgrade done" __pkgtools__at_function_exit return 0 } function search () { __pkgtools__at_function_enter search apt-cache search $@ __pkgtools__at_function_exit return 0 } function purge () { __pkgtools__at_function_enter purge sudo ${__pkg_mgr} purge && pkg-notify "Purge done" __pkgtools__at_function_exit return 0 } function distupgrade () { __pkgtools__at_function_enter distupgrade sudo ${__pkg_mgr} update && sudo ${__pkg_mgr} dist-upgrade && pkg-notify "Distribution upgrade done" __pkgtools__at_function_exit return 0 } function autoremove () { __pkgtools__at_function_enter autoremove sudo ${__pkg_mgr} autoremove && pkg-notify "Autoremove done" __pkgtools__at_function_exit return 0 } else function upgrade () { __pkgtools__at_function_enter upgrade ${__pkg_mgr} -Suy && pkg-notify "Upgrade done" __pkgtools__at_function_exit return 0 } function upgrade-aur () { __pkgtools__at_function_enter upgrade-aur ${__pkg_mgr} -Suya --devel && pkg-notify "Upgrade done" __pkgtools__at_function_exit return 0 } function search () { __pkgtools__at_function_enter search ${__pkg_mgr} -Ss $@ __pkgtools__at_function_exit return 0 } function purge () { __pkgtools__at_function_enter purge ${__pkg_mgr} -Qdt && pkg-notify "Purge done" __pkgtools__at_function_exit return 0 } fi
Extract archive
function extract () { __pkgtools__at_function_enter extract local remove_archive local success local file_name local extract_dir if [[ "$1" == "" ]]; then echo "Usage: extract [-option] [file ...]" echo echo "Options:" echo " -r, --remove : Remove archive." echo fi remove_archive=1 if [[ "$1" == "-r" ]] || [[ "$1" == "--remove" ]]; then remove_archive=0 shift fi while [ -n "$1" ]; do if [[ ! -f "$1" ]]; then pkgtools__msg_warning "'$1' is not a valid file" shift continue fi success=0 file_name="$( basename "$1" )" extract_dir="$( echo "$file_name" | sed "s/\.${1##*.}//g" )" case "$1" in (*.tar.gz|*.tgz) tar xvzf "$1" ;; (*.tar.bz2|*.tbz|*.tbz2) tar xvjf "$1" ;; (*.tar.xz|*.txz) tar --xz --help &> /dev/null \ && tar --xz -xvf "$1" \ || xzcat "$1" | tar xvf - ;; (*.tar.zma|*.tlz) tar --lzma --help &> /dev/null \ && tar --lzma -xvf "$1" \ || lzcat "$1" | tar xvf - ;; (*.tar) tar xvf "$1" ;; (*.gz) gunzip "$1" ;; (*.bz2) bunzip2 "$1" ;; (*.xz) unxz "$1" ;; (*.lzma) unlzma "$1" ;; (*.Z) uncompress "$1" ;; (*.zip) unzip "$1" -d $extract_dir ;; (*.rar) unrar e -ad "$1" ;; (*.7z) 7za x "$1" ;; (*.deb) mkdir -p "$extract_dir/control" mkdir -p "$extract_dir/data" cd "$extract_dir"; ar vx "../${1}" > /dev/null cd control; tar xzvf ../control.tar.gz cd ../data; tar xzvf ../data.tar.gz cd ..; rm *.tar.gz debian-binary cd .. ;; (*) pkgtools__msg_error "'$1' cannot be extracted" 1>&2 success=1 ;; esac (( success = $success > 0 ? $success : $? )) (( $success == 0 )) && (( $remove_archive == 0 )) && rm "$1" shift done __pkgtools__at_function_exit return 0 }
Notification
Base function for notification
function notify () { if pkgtools__has_binary notify-send; then if [ "$HOSTNAME" = "garrido-laptop" ]; then notify-send $@ > /dev/null 2>&1 fi fi return 0 }
Success
function notify_success () { __pkgtools__at_function_enter notify_success if [ $? -ne 0 ]; then notify -t 2000 -i stock_dialog-info "Notice" "${PREEXEC_CMD:-Shell Command}" fi __pkgtools__at_function_exit return 0 }
Error
function notify_error () { if [ $? -ne 0 ]; then notify -t 2000 -i stock_dialog-error " " "${PREEXEC_CMD:-Shell Command} $@" return 1 fi return 0 }
Warning
function notify_warning () { notify -t 3000 -i stock_dialog-warning " " "${PREEXEC_CMD:-Shell Command} $@" return 0 }
Zsh precmd
and preexec
These two functions are only available for zsh
shell. There are run at every
shell command and trigger notification events in case of long time command or
failling ones. This is pretty useful when long command such as compilation
command are running : user can go to another desktop do whatever he wants but
get warned when the command has finished or has failed.
function precmd () { # must be first notify_error # BEGIN notify long running cmds stop=$(date +'%s') start=${PREEXEC_TIME:-$stop} let elapsed=$stop-$start max=${PREEXEC_MAX:-10} for i in ${PREEXEC_EXCLUDE_LIST:-}; do if [ "x$i" = "x$PREEXEC_CMD" ]; then max=999999; break; fi done if [ $elapsed -gt $max ]; then notify_warning "finished ($elapsed secs)" fi # END notify long running cmds # Update scheme color if (( $+functions[__load_scheme] )); then __load_scheme fi return 0 } function preexec () { if [[ "$TERM" == "screen" ]]; then local CMD=${1} echo -ne "\ek$CMD\e\\" fi # for notifying of long running commands export PREEXEC_CMD=`echo $1 | awk '{ print $1; }'` export PREEXEC_TIME=$(date +'%s') return 0 }
SSH connection
This should be improved by doing something as wakeonlan did with a small machine db.
function connect () { __pkgtools__at_function_enter connect local use_screen=0 local server_name= local ssh_option= local append_command= if [[ "$1" == "" ]]; then echo "Missing the name of machine to connect !" echo "" __pkgtools__at_function_exit return 1 fi while [ -n "$1" ]; do if [[ "$1" == "-s" ]]; then use_screen=1 elif [[ "$1" == "fzk" ]]; then ssh_option="-p 24" server_name="augerlogin.fzk.de" elif [[ "$1" == "cern" ]]; then server_name="xgarrido@lxplus.cern.ch" elif [[ "$1" == "lyon" ]]; then server_name="garrido@ccage.in2p3.fr" elif [[ $1 == ccige* ]]; then server_name="garrido@$1.in2p3.fr" elif [[ $1 == ccage* ]]; then server_name="garrido@$1.in2p3.fr" elif [[ "$1" == "ovh" ]]; then ssh_option="-p 1234" server_name="garrido@r17187.ovh.net" elif [[ "$1" == "laptop" ]]; then server_name="garrido@nb-nemo6.lal.in2p3.fr" elif [[ "$1" == "mac" ]]; then ssh_option="-p 24" server_name="garrido@xgarrido.dyndns.org" elif [[ "$1" == "syno" ]]; then server_name="garrido@xgarrido.synology.me" # elif [[ "$1" == "debian" ]]; then # server_name="debian@xgarrido.dyndns.org" elif [[ "$1" == "lx3" ]]; then server_name="garrido@lx3.lal.in2p3.fr" elif [[ "$1" == "daq-nemo" ]]; then server_name="bipolal@pc-nemo12.lal.in2p3.fr" elif [[ "$1" == "daq-lsm" ]]; then server_name="nemoacq@lsmlx5.in2p3.fr" elif [[ $1 == pc-nemo* ]]; then server_name="nemo@$1" elif [[ $1 == pc-91089 ]]; then server_name="garrido@$1" elif [[ $1 == nemo* ]]; then server_name="garrido@$1.lal.in2p3.fr" # else # if [ "${HOSTNAME}" = "garrido-laptop" ]; then # server_name="garrido@localhost" # if [ -f /tmp/npu.d/ports ]; then # ssh_port=$(cat /tmp/npu.d/ports | grep $1 | cut -d' ' -f2) # ssh_option="-p ${ssh_port}" # else # append_command+="$1 " # fi # else # if [[ "$1" == "pc" ]]; then # server_name="pc-91089.lal.in2p3.fr" # else # server_name="$1.lal.in2p3.fr" # fi # fi fi shift 1 done if [ ${use_screen} -eq 0 ]; then pkgtools__msg_notice "Connecting to ${server_name}..." ssh -Y ${ssh_option} ${server_name} "${append_command}" else pkgtools__msg_notice "Connecting to ${server_name} with screen support..." screen ssh -Y ${ssh_option} ${server_name} fi __pkgtools__at_function_exit return 0 } # Connect completion system compdef _connect connect function _connect () { local -a _machines _machines=( ccage:'CC Lyon job machines' ccige:'CC Lyon interactive machines' laptop:'Laptop machine' mac:'iMac machine' syno:'Synology server @ home' lx3:'lxplus machine @ LAL' nemo3:'nemo3 machine @ LAL' nemo4:'nemo4 machine @ LAL' pc-91089:'PC server machine @ LAL' pc-nemo4:'V. Treytak machine' pc-nemo5:'H. Gomez machine' pc-nemo6:'Student machine' pc-nemo8:'G. Eurin machine' ) _describe -t _machines 'SSH machines' _machines && ret=0 }
Grepping information
Find a running job
function psgrep () { __pkgtools__at_function_enter psgrep if [[ ! -z $1 ]] ; then pkgtools__msg_notice "Grepping for processes matching $1..." ps aux | grep $1 | grep -v grep else pkgtools__msg_error "Need name to grep for !" __pkgtools__at_function_exit return 1 fi __pkgtools__at_function_exit return 0 }
Find a running job & kill it
function pskill () { __pkgtools__at_function_enter pskill psgrep $1 | awk '{print "kill -9",$2}' | sh __pkgtools__at_function_exit return 0 }
Find a command within history
function hgrep () { __pkgtools__at_function_enter hgrep if [[ ! -z $1 ]] ; then pkgtools__msg_notice "Grepping for command matching $1..." history | grep $1 else pkgtools__msg_error "Need name to grep for !" __pkgtools__at_function_exit return 1 fi __pkgtools__at_function_exit return 0 }
Text edition
Remove all trailing whitespace in a given file
function remove_trailing_whitespace () { __pkgtools__at_function_enter remove_trailing_whitespace if [[ ! -z $1 ]] ; then pkgtools__msg_notice "Removing trailing whitespace in file $1..." find $1 -type f -exec sed -i 's/ *$//' '{}' ';' else pkgtools__msg_error "Missing filename !" __pkgtools__at_function_exit return 1 fi __pkgtools__at_function_exit return 0 }
Remove duplicate lines
function remove_duplicate_lines () { __pkgtools__at_function_enter remove_duplicate_lines if [[ ! -z $1 ]] ; then pkgtools__msg_notice "Removing duplicate lines in file $1..." awk '!seen[$0]++' $1 > /tmp/$(basename $1).tmp mv /tmp/$(basename $1).tmp $1 else pkgtools__msg_error "Missing filename !" __pkgtools__at_function_exit return 1 fi __pkgtools__at_function_exit return 0 }
Image edition
Convert an EPS figure into tikz
function eps2tikz () { __pkgtools__at_function_enter eps2tikz local use_helvetica=0 local keep_xfig=0 local remove_duplicate_lines=1 local eps_file= local parse_switch=1 if [[ "$1" == "" ]]; then echo "Usage: eps2tikz [-option] [eps files ...]" echo echo "Options:" echo " -k, --keep-xfig : Keep the intermediate xfig file." echo fi while [ -n "$1" ]; do token="$1" if [[ "${token[1]}" = "-" ]]; then opt=${token} if [[ ${parse_switch} -eq 0 ]]; then break fi if [ "${opt}" = "--keep-xfig" ]; then keep_xfig=1 elif [ "${opt}" = "--do-not-remove-duplicate-lines" ]; then remove_duplicate_lines=0 else pkgtools__msg_warning "Ignoring option '${opt}' !" fi else arg=${token} parse_switch=0 if [ "${arg##*.}" = "eps" ]; then eps_file="${eps_file} ${arg}" else pkgtools__msg_warning "'${eps_file}' is not an Encapsulated PostScript" fi fi shift done if [[ -z "${eps_file}" ]]; then pkgtools__msg_error "Missing EPS file !" __pkgtools__at_function_exit return 1 fi for i in $(echo ${eps_file}); do if [ ! -f "${i}" ]; then pkgtools__msg_warning "File ${i} does not exist! Skip it" continue fi local fig_file=${i/.eps/.fig} local tikz_file=${i/.eps/.tikz} pkgtools__msg_notice "Converting ${i} file to ${tikz_file}..." if [[ ! -x $(which pstoedit) ]]; then pkgtools__msg_error "Missing 'pstoedit' binary !" __pkgtools__at_function_exit return 1 fi pstoedit -f xfig "${i}" > ${fig_file} 2> /dev/null if [[ ! -x $(which fig2tikz) ]]; then pkgtools__msg_error "Missing fig2tikz' binary !" __pkgtools__at_function_exit return 1 fi fig2tikz ${fig_file} > ${tikz_file}.tmp if [[ ${remove_duplicate_lines} -eq 1 ]]; then pkgtools__msg_notice "Remove duplicate lines..." awk '{if (match($0,"definecolor") || !seen[$0]++) {print $0}}' ${tikz_file}.tmp > ${tikz_file} else cp ${tikz_file}.tmp ${tikz_file} fi rm -f ${tikz_file}.tmp if [[ ${keep_xfig} -eq 0 ]]; then rm -f ${fig_file} fi done __pkgtools__at_function_exit return 0 } # Connect completion system compdef _eps2tikz eps2tikz function _eps2tikz () { _arguments -C \ '(-v --verbose)'{-v,--verbose}'[verbose output]' \ '(-h --help)'{-h,--help}'[print help message]' \ --keep-xfig'[Keep Xfig files]' \ --do-not-remove-duplicate-lines'[do not edit tikz file by removing duplicated lines]' \ "*:filename: _alternative 'files:file:_files -g \"*.eps\"'" && ret=0 }
Grab point with dexter
Dexter is a little java program to interactively or semi-automatically extract data from scanned graphs. In its applet incarnation it is used by the Astrophysics Data System.
function dexter () { __pkgtools__at_function_enter dexter if [[ "$1" == "" ]]; then echo "Usage: dexter [image files ...]" echo __pkgtools__at_function_exit return 1 else java -jar /home/garrido/Workdir/Development/java/dexter/Debuxter.jar $1 fi __pkgtools__at_function_exit return 0 }
Mounting/unmounting USB drives
function usb_umount () { for d in /media/*; do sudo umount $d done sudo modprobe usb_storage }
Subversion functions
Better SVN status
function svnstatus () { __pkgtools__at_function_enter svnstatus templist=$(svn status $*) echo "$(echo $templist | grep '^?' | wc -l) unversioned files/directories" echo $templist | grep -v '^?' __pkgtools__at_function_exit return 0 }
Better SVN diff (needs code2color)
function svndiff () { __pkgtools__at_function_enter svndiff svn diff $* | code2color -l patch - __pkgtools__at_function_exit return 0 }
Better ls
with git
support
Original work done by supercrabtree
zmodload zsh/datetime zmodload -F zsh/stat b:zstat k () { # ---------------------------------------------------------------------------- # Setup # ---------------------------------------------------------------------------- # Stop stat failing when a directory contains either no files or no hidden files # Track if we _accidentally_ create a new global variable setopt local_options null_glob warn_create_global # Turn on 256 colour terminal, not sure this works at all. typeset OLD_TERM="$TERM" TERM='xterm-256color' # ---------------------------------------------------------------------------- # Vars # ---------------------------------------------------------------------------- typeset -a MAX_LEN A RESULTS STAT_RESULTS typeset TOTAL_BLOCKS # Get now typeset K_EPOCH="${EPOCHSECONDS:?}" typeset -i TOTAL_BLOCKS=0 MAX_LEN=(0 0 0 0 0 0) # Array to hold results from `stat` call RESULTS=() # only set once so must be out of the main loop typeset -i IS_GIT_REPO=0 typeset -i LARGE_FILE_COLOR=196 typeset -a SIZELIMITS_TO_COLOR # SIZELIMITS_TO_COLOR=( # 1024 46 # <= 1kb # 2048 82 # <= 2kb # 3072 118 # <= 3kb # 5120 154 # <= 5kb # 10240 190 # <= 10kb # 20480 226 # <= 20kb # 40960 220 # <= 40kb # 102400 214 # <= 100kb # 262144 208 # <= 0.25mb || 256kb # 524288 202 # <= 0.5mb || 512kb # ) SIZELIMITS_TO_COLOR=( 1024 226 # <= 1kb 2048 220 # <= 2kb 5120 214 # <= 5kb 524288 208 # <= 512kb 1024000 202 # <= 1Mb ) typeset -i ANCIENT_TIME_COLOR=252 # > more than 2 years old typeset -a FILEAGES_TO_COLOR FILEAGES_TO_COLOR=( 0 196 # < in the future, #spooky 60 236 # < less than a min old 3600 238 # < less than an hour old 86400 240 # < less than 1 day old 604800 242 # < less than 1 week old 2419200 244 # < less than 28 days (4 weeks) old 15724800 244 # < less than 26 weeks (6 months) old 31449600 250 # < less than 1 year old 62899200 252 # < less than 2 years old ) # ---------------------------------------------------------------------------- # Stat call to get directory listing # ---------------------------------------------------------------------------- # Break total blocks of the front of the stat call, then push the rest to results typeset -i i=1 j=1 k=1 typeset -a STATS_PARAMS_LIST typeset fn statvar typeset -A sv # for fn in . .. *(D) for fn in $(command \ls -rt $@) do if [[ $fn == "." || $fn == ".." ]]; then continue; fi statvar="stats_$i" typeset -A $statvar zstat -H $statvar -Lsn -F "%s^%d^%b^%H:%M^%Y" -- "$fn" # use lstat, render mode/uid/gid to strings STATS_PARAMS_LIST+=($statvar) i+=1 done # On each result calculate padding by getting max length on each array member for statvar in "${STATS_PARAMS_LIST[@]}" do sv=("${(@Pkv)statvar}") if [[ ${#sv[mode]} -gt $MAX_LEN[1] ]]; then MAX_LEN[1]=${#sv[mode]} ; fi if [[ ${#sv[nlink]} -gt $MAX_LEN[2] ]]; then MAX_LEN[2]=${#sv[nlink]} ; fi if [[ ${#sv[uid]} -gt $MAX_LEN[3] ]]; then MAX_LEN[3]=${#sv[uid]} ; fi if [[ ${#sv[gid]} -gt $MAX_LEN[4] ]]; then MAX_LEN[4]=${#sv[gid]} ; fi if [[ ${#sv[size]} -gt $MAX_LEN[5] ]]; then MAX_LEN[5]=${#sv[size]} ; fi TOTAL_BLOCKS+=$sv[blocks] done # Print total block before listing echo "total $TOTAL_BLOCKS" # ---------------------------------------------------------------------------- # Loop through each line of stat, pad where appropriate and do git dirty checking # ---------------------------------------------------------------------------- typeset REPOMARKER typeset PERMISSIONS HARDLINKCOUNT OWNER GROUP FILESIZE DATE NAME SYMLINK_TARGET typeset FILETYPE PER1 PER2 PER3 PERMISSIONS_OUTPUT STATUS typeset TIME_DIFF TIME_COLOR DATE_OUTPUT typeset -i IS_DIRECTORY IS_SYMLINK IS_EXECUTABLE typeset -i COLOR k=1 for statvar in "${STATS_PARAMS_LIST[@]}" do sv=("${(@Pkv)statvar}") # We check if the result is a git repo later, so set a blank marker indication the result is not a git repo REPOMARKER="" IS_DIRECTORY=0 IS_SYMLINK=0 IS_EXECUTABLE=0 PERMISSIONS="${sv[mode]}" HARDLINKCOUNT="${sv[nlink]}" OWNER="${sv[uid]}" GROUP="${sv[gid]}" FILESIZE="${sv[size]}" DATE=(${(s:^:)sv[mtime]}) # Split date on ^ NAME="${sv[name]}" SYMLINK_TARGET="${sv[link]}" # Check for file types if [[ -d "$NAME" ]]; then IS_DIRECTORY=1; fi if [[ -L "$NAME" ]]; then IS_SYMLINK=1; fi # is this a git repo if [[ $k == 1 && $(command git rev-parse --is-inside-work-tree 2>/dev/null) == true ]] then IS_GIT_REPO=1 fi; # Pad so all the lines align - firstline gets padded the other way PERMISSIONS="${(r:MAX_LEN[1]:)PERMISSIONS}" HARDLINKCOUNT="${(l:MAX_LEN[2]:)HARDLINKCOUNT}" OWNER="${(l:MAX_LEN[3]:)OWNER}" GROUP="${(l:MAX_LEN[4]:)GROUP}" FILESIZE="${(l:MAX_LEN[5]:)FILESIZE}" # -------------------------------------------------------------------------- # Colour the permissions - TODO # -------------------------------------------------------------------------- # Colour the first character based on filetype FILETYPE="${PERMISSIONS[1]}" # if (( IS_DIRECTORY )) # then # FILETYPE=${FILETYPE//d/$'\e[01;38;5;004m'd$'\e[0m'}; # elif (( IS_SYMLINK )) # then # FILETYPE=${FILETYPE//l/$'\e[0;35m'l$'\e[0m'}; # elif [[ $FILETYPE == "-" ]]; # then # FILETYPE=${FILETYPE//-/$'\e[0;37m'-$'\e[0m'}; # fi # Permissions Owner PER1="${PERMISSIONS[2,4]}" # Permissions Group PER2="${PERMISSIONS[5,7]}" # Permissions User PER3="${PERMISSIONS[8,10]}" PERMISSIONS_OUTPUT="$FILETYPE$PER1$PER2$PER3" # --x --x --x warning if [[ $PER1[3] == "x" || $PER2[3] == "x" || $PER3[3] == "x" ]]; then IS_EXECUTABLE=1; fi # --- --- rwx warning if [[ $PER3 == "rwx" && ! IS_SYMLINK ]]; then PERMISSIONS_OUTPUT=$'\e[30;41m'"$PERMISSIONS"$'\e[0m'; fi # -------------------------------------------------------------------------- # Colour the symlinks - TODO # -------------------------------------------------------------------------- # -------------------------------------------------------------------------- # Colour Owner and Group # -------------------------------------------------------------------------- # OWNER=$'\e[38;5;011m'"$OWNER"$'\e[0m' # GROUP=$'\e[38;5;009m'"$GROUP"$'\e[0m' # -------------------------------------------------------------------------- # Colour file weights # -------------------------------------------------------------------------- COLOR=LARGE_FILE_COLOR for i j in ${SIZELIMITS_TO_COLOR[@]} do (( FILESIZE <= i )) || continue COLOR=$j break done FILESIZE="$(command numfmt --to=si --format="%4f" $FILESIZE)" FILESIZE=$'\e[38;5;'"${COLOR}m$FILESIZE"$'\e[0m' # -------------------------------------------------------------------------- # Colour the date and time based on age, then format for output # -------------------------------------------------------------------------- # Setup colours based on time difference TIME_DIFF=$(( K_EPOCH - DATE[1] )) TIME_COLOR=$ANCIENT_TIME_COLOR for i j in ${FILEAGES_TO_COLOR[@]} do (( TIME_DIFF < i )) || continue TIME_COLOR=$j break done # Format date to show year if more than 6 months since last modified if (( TIME_DIFF < 15724800 )); then DATE_OUTPUT="${DATE[2]} ${(r:5:: :)${DATE[3][0,5]}} ${DATE[4]}" else DATE_OUTPUT="${DATE[2]} ${(r:6:: :)${DATE[3][0,5]}} ${DATE[5]}" # extra space; 4 digit year instead of 5 digit HH:MM fi; DATE_OUTPUT[1]="${DATE_OUTPUT[1]//0/ }" # If day of month begins with zero, replace zero with space # # Apply colour to formated date # DATE_OUTPUT=$'\e[38;5;'"${TIME_COLOR}m${DATE_OUTPUT}"$'\e[0m' # -------------------------------------------------------------------------- # Colour the repomarker # -------------------------------------------------------------------------- # # Check for git repo, first checking if the result is a directory # if (( IS_GIT_REPO == 0)) || (( k <= 2 )) # then # if (( IS_DIRECTORY )) && [[ -d "$NAME/.git" ]] # then # if command git --git-dir="$PWD/$NAME/.git" --work-tree="$PWD/$NAME" diff --quiet --ignore-submodules HEAD &>/dev/null # if dirty # then REPOMARKER=$'\e[38;5;46m|\e[0m' # Show a green vertical bar for dirty # else REPOMARKER=$'\e[0;31m|\e[0m' # Show a red vertical bar if clean # fi # fi # fi if (( IS_GIT_REPO )) && (( k > 0 )) && [[ "$NAME" != '.git' ]] then STATUS="$(command git status --porcelain --ignored --untracked-files=normal "$NAME")" STATUS="${STATUS[1,2]}" if [[ $STATUS == ' M' ]]; then REPOMARKER=$'\e[01;38;5;001m✘\e[0m'; # Modified elif [[ $STATUS == '??' ]]; then REPOMARKER=$'\e[01;38;5;009m⚑\e[0m'; # Untracked elif [[ $STATUS == '!!' ]]; then REPOMARKER=$'\e[01;38;5;004m⚐\e[0m'; # Ignored elif [[ $STATUS == 'A ' ]]; then REPOMARKER=$'\e[01;38;5;093m|\e[0m'; # Added else REPOMARKER=$'\e[01;38;5;002m✔\e[0m'; # Good fi fi # -------------------------------------------------------------------------- # Colour the filename # -------------------------------------------------------------------------- # Unfortunately, the choices for quoting which escape ANSI color sequences are q & qqqq; none of q- qq qqq work. # But we don't want to quote '.'; so instead we escape the escape manually and use q- NAME="${(q-)NAME//$'\e'/\\e}" # also propagate changes to SYMLINK_TARGET below if (( IS_SYMLINK )) then NAME=$'\e[07;38;5;4m'"$NAME"$'\e[0m' elif (( IS_DIRECTORY )) then NAME=$'\e[01;38;5;4m'"$NAME"$'\e[0m' fi # -------------------------------------------------------------------------- # Format symlink target # -------------------------------------------------------------------------- if [[ $SYMLINK_TARGET != "" ]]; then SYMLINK_TARGET="-> ${(q-)SYMLINK_TARGET//$'\e'/\\e}"; fi #SYMLINK_TARGET=$'\e[38;5;27m'"$SYMLINK_TARGET"$'\e[0m' # -------------------------------------------------------------------------- # Display final result # -------------------------------------------------------------------------- print -r -- "$PERMISSIONS_OUTPUT $HARDLINKCOUNT $OWNER $GROUP $FILESIZE $DATE_OUTPUT $REPOMARKER $NAME $SYMLINK_TARGET" # print -r -- "$FILESIZE $DATE_OUTPUT $REPOMARKER $NAME $SYMLINK_TARGET" k=$((k+1)) # Bump loop index done # cleanup / recovery TERM="$OLD_TERM" } # http://upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg
Better tree
with git
support
function t() { skip_ignore_files=0 if [[ $@ == *--skip-ignore-files* ]]; then skip_ignore_files=1 arguments=${@/--skip-ignore-files/} fi tree -ft $arguments | awk -v skip_ignore_files=$skip_ignore_files '{ status="" marker=" " color="\033[0m" # if (system("test -f " $NF) == 0) print "file="$NF if (system("test -d " $NF) == 0) { is_git_repo=system("git rev-parse --is-inside-work-tree > /dev/null 2>&1") color="\033[01;38;5;004m" marker="" } if (is_git_repo == 0) { cmd = "git status --porcelain --ignored --untracked-files=normal \"" $NF "\"" cmd | getline status status=substr(status,1,2) if (status == " M") { color="\033[38;5;001m" marker="✘ " } else if (status == "??") { color="\033[38;5;009m" marker="⚑ " } else if (status == "!!") { color="\033[38;5;004m" marker=color "⚐ " if (skip_ignore_files) next } else if (status == "A ") { color="\033[38;5;093m" marker="| " } else { color="\033[38;5;002m" marker="✔ " } } basefile=$NF sub(".*/",color marker,basefile) sub($NF,basefile,$0) print $0 "\033[0m" }' } alias tt='t -L 1' alias ta='t -a -L 1' alias ti='t --skip-ignore-files'
Misc.
Grabbing video from mms link
function grab_video () { __pkgtools__at_function_enter grab_video if [[ ! -z $1 ]] ; then pkgtools__msg_notice "Grabing video from $1 link and saving it to /tmp/dump_video.avi..." mplayer -dumpstream "$1" -dumpfile /tmp/dump_video.avi else pkgtools__msg_error "Missing mms link !" __pkgtools__at_function_exit return 1 fi __pkgtools__at_function_exit return 0 }