X-Git-Url: http://gitweb.pimeys.fr/?a=blobdiff_plain;f=.zsh%2Frc%2Fextra%2F15_misc_functions;fp=.zsh%2Frc%2Fextra%2F15_misc_functions;h=fd74e70fd8fb95ab1ece64be79d27b613ce91ad7;hb=3d71eab53c5b63556363ece880859b0af7f162da;hp=0000000000000000000000000000000000000000;hpb=1f8b08895681d46802368eec0764ca70d08898ca;p=config-20-100.git diff --git a/.zsh/rc/extra/15_misc_functions b/.zsh/rc/extra/15_misc_functions new file mode 100644 index 0000000..fd74e70 --- /dev/null +++ b/.zsh/rc/extra/15_misc_functions @@ -0,0 +1,551 @@ +#!/bin/zsh + +# rename pictures based on information found in exif headers +#f5# Rename pictures based on information found in exif headers +exirename() { + emulate -L zsh + if [[ $# -lt 1 ]] ; then + echo 'Usage: jpgrename $FILES' >& 2 + return 1 + else + echo -n 'Checking for jhead with version newer than 1.9: ' + jhead_version=`jhead -h | grep 'used by most Digital Cameras. v.*' | awk '{print $6}' | tr -d v` + if [[ $jhead_version > '1.9' ]]; then + echo 'success - now running jhead.' + jhead -n%Y-%m-%d_%Hh%M_%f $* + else + echo 'failed - exiting.' + fi + fi +} + +# get_ic() - queries imap servers for capabilities; real simple. no imaps +ic_get() { + emulate -L zsh + local port + if [[ ! -z $1 ]] ; then + port=${2:-143} + print "querying imap server on $1:${port}...\n"; + print "a1 capability\na2 logout\n" | nc $1 ${port} + else + print "usage:\n $0 [port]" + fi +} + +# creates a Maildir/ with its {new,cur,tmp} subdirs +mkmaildir() { + emulate -L zsh + local root subdir + root=${MAILDIR_ROOT:-${HOME}/Mail} + if [[ -z ${1} ]] ; then print "Usage:\n $0 " ; return 1 ; fi + subdir=${1} + mkdir -p ${root}/${subdir}/{cur,new,tmp} +} + +#f5# Change the xterm title from within GNU-screen +xtrename() { + emulate -L zsh + if [[ $1 != "-f" ]] ; then + if [[ -z ${DISPLAY} ]] ; then + printf 'xtrename only makes sense in X11.\n' + return 1 + fi + else + shift + fi + if [[ -z $1 ]] ; then + printf 'usage: xtrename [-f] "title for xterm"\n' + printf ' renames the title of xterm from _within_ screen.\n' + printf ' also works without screen.\n' + printf ' will not work if DISPLAY is unset, use -f to override.\n' + return 0 + fi + print -n "\eP\e]0;${1}\C-G\e\\" + return 0 +} + +#f2# Find history events by search pattern and list them by date. +whatwhen() { +# {{{ + emulate -L zsh + local usage help ident format_l format_s first_char remain first last + usage='USAGE: whatwhen [options] ' + help='Use' \`'whatwhen -h'\'' for further explanations.' + ident=${(l,${#${:-Usage: }},, ,)} + format_l="${ident}%s\t\t\t%s\n" + format_s="${format_l//(\\t)##/\\t}" + # Make the first char of the word to search for case + # insensitive; e.g. [aA] + first_char=[${(L)1[1]}${(U)1[1]}] + remain=${1[2,-1]} + # Default search range is `-100'. + first=${2:-\-100} + # Optional, just used for ` ' given. + last=$3 + case $1 in + ("") + printf '%s\n\n' 'ERROR: No search string specified. Aborting.' + printf '%s\n%s\n\n' ${usage} ${help} && return 1 + ;; + (-h) + printf '%s\n\n' ${usage} + print 'OPTIONS:' + printf $format_l '-h' 'show help text' + print '\f' + print 'SEARCH RANGE:' + printf $format_l "'0'" 'the whole history,' + printf $format_l '-' 'offset to the current history number; (default: -100)' + printf $format_s '<[-]first> []' 'just searching within a give range' + printf '\n%s\n' 'EXAMPLES:' + printf ${format_l/(\\t)/} 'whatwhen grml' '# Range is set to -100 by default.' + printf $format_l 'whatwhen zsh -250' + printf $format_l 'whatwhen foo 1 99' + ;; + (\?) + printf '%s\n%s\n\n' ${usage} ${help} && return 1 + ;; + (*) + # -l list results on stout rather than invoking $EDITOR. + # -i Print dates as in YYYY-MM-DD. + # -m Search for a - quoted - pattern within the history. + fc -li -m "*${first_char}${remain}*" $first $last + ;; + esac +# }}} +} + +# change fluxbox keys from 'Alt-#' to 'Alt-F#' and vice versa +fluxkey-change() { + emulate -L zsh + [[ -n "$FLUXKEYS" ]] || local FLUXKEYS="$HOME/.fluxbox/keys" + if ! [[ -r "$FLUXKEYS" ]] ; then + echo "Sorry, \$FLUXKEYS file $FLUXKEYS could not be read - nothing to be done." + return 1 + else + if grep -q 'Mod1 F[0-9] :Workspace [0-9]' $FLUXKEYS ; then + echo -n 'Switching to Alt-# mode in ~/.fluxbox/keys: ' + sed -i -e 's|^\(Mod[0-9]\+[: space :]\+\)F\([0-9]\+[: space :]\+:Workspace.*\)|\1\2|' $FLUXKEYS && echo done || echo failed + elif grep -q 'Mod1 [0-9] :Workspace [0-9]' $FLUXKEYS ; then + echo -n 'Switching to Alt-F# mode in ~/.fluxbox/keys: ' + sed -i -e 's|^\(Mod[0-9]\+[: space :]\+\)\([0-9]\+[: space :]\+:Workspace.*\)|\1F\2|' $FLUXKEYS && echo done || echo failed + else + echo 'Sorry, do not know what to do.' + return 1 + fi + fi +} + +# retrieve weather information on the console +# Usage example: 'weather LOWG' +weather() { + emulate -L zsh + [ $1 = "-v" ] && local VERBOSE=1 && shift + [[ -n "$1" ]] || { + print 'Usage: weather [-v] ' >&2 + print 'List of stations: http://en.wikipedia.org/wiki/List_of_airports_by_ICAO_code'>&2 + print 'With -v, displays everything' >&2 + return 1 + } + + local PLACE="${1:u}" + local FILE="$HOME/.weather/$PLACE" + local LOG="$HOME/.weather/log" + + [[ -d $HOME/.weather ]] || { + print -n "Creating $HOME/.weather: " + mkdir $HOME/.weather + print 'done' + } + + print "Retrieving information for ${PLACE}:" + print + wget -T 10 --no-verbose --output-file=$LOG --output-document=$FILE --timestamping http://weather.noaa.gov/pub/data/observations/metar/decoded/$PLACE.TXT + + if [[ $? -eq 0 ]] ; then + if [[ -n "$VERBOSE" ]] ; then + cat $FILE + else + DATE=$(grep 'UTC' $FILE | sed 's#.* /##') + TEMPERATURE=$(awk '/Temperature/ { print $4" degree Celcius / " $2" degree Fahrenheit" }' $FILE| tr -d '(') + echo "date: $DATE" + echo "temp: $TEMPERATURE" + fi + else + print "There was an error retrieving the weather information for $PLACE" >&2 + cat $LOG + return 1 + fi +} + +# d():Copyright 2005 Nikolai Weibull +# note: option AUTO_PUSHD has to be set +#f5# Jump between directories +d() { + emulate -L zsh + autoload -U colors + local color=$fg_bold[blue] + integer i=0 + dirs -p | while read dir; do + local num="${$(printf "%-4d " $i)/ /.}" + printf " %s $color%s$reset_color\n" $num $dir + (( i++ )) + done + integer dir=-1 + read -r 'dir?Jump to directory: ' || return + (( dir == -1 )) && return + if (( dir < 0 || dir >= i )); then + echo d: no such directory stack entry: $dir + return 1 + fi + cd ~$dir +} + +#f5# Copied diff +cdiff() { + emulate -L zsh + diff -crd "$*" | egrep -v "^Only in |^Binary files " +} +#f5# Disassemble source files using gcc and as +disassemble(){ + emulate -L zsh + gcc -pipe -S -o - -O -g $* | as -aldh -o /dev/null +} +#f5# Firefox remote control - open given URL +fir() { + if [ -e /etc/debian_version ]; then + firefox -a iceweasel -remote "openURL($1)" || firefox ${1}& + else + firefox -a firefox -remote "openURL($1)" || firefox ${1}& + fi +} +#f5# Unified diff to timestamped outputfile +mdiff() { + diff -udrP "$1" "$2" > diff.`date "+%Y-%m-%d"`."$1" +} +#f5# Show contents of gzipped tar file +shtar() { + emulate -L zsh + gunzip -c $1 | tar -tf - -- | $PAGER +} +#f5# Show contents of zip file +shzip() { + emulate -L zsh + unzip -l $1 | $PAGER +} +#f5# Unified diff +udiff() { + emulate -L zsh + diff -urd $* | egrep -v "^Only in |^Binary files " +} +#f5# (Mis)use \kbd{vim} as \kbd{less} +viless() { + emulate -L zsh + vim --cmd 'let no_plugin_maps = 1' -c "so \$VIMRUNTIME/macros/less.vim" "${@:--}" +} + +# Function Usage: uopen $URL/$file +#f5# Download a file and display it locally +uopen() { + emulate -L zsh + if ! [[ -n "$1" ]] ; then + print "Usage: uopen \$URL/\$file">&2 + return 1 + else + FILE=$1 + MIME=$(curl --head $FILE | grep Content-Type | cut -d ' ' -f 2 | cut -d\; -f 1) + MIME=${MIME%$'\r'} + curl $FILE | see ${MIME}:- + fi +} + +#f5# Make screenshot +sshot() { + [[ ! -d ~/shots ]] && mkdir ~/shots + #cd ~/shots ; sleep 5 ; import -window root -depth 8 -quality 80 `date "+%Y-%m-%d--%H:%M:%S"`.png + cd ~/shots ; sleep 5; import -window root shot_`date --iso-8601=m`.jpg +} + +# list images only +limg() { + local -a images + images=( *.{jpg,gif,png}(.N) ) + + if [[ $#images -eq 0 ]] ; then + print "No image files found" + else + ls "$images[@]" + fi +} + +#f5# Create PDF file from source code +makereadable() { + emulate -L zsh + output=$1 + shift + a2ps --medium A4dj -E -o $output $* + ps2pdf $output +} + +# zsh with perl-regex - use it e.g. via: +# regcheck '\s\d\.\d{3}\.\d{3} Euro' ' 1.000.000 Euro' +#f5# Checks whether a regex matches or not.\\&\quad Example: \kbd{regcheck '.\{3\} EUR' '500 EUR'} +regcheck() { + emulate -L zsh + zmodload -i zsh/pcre + pcre_compile $1 && \ + pcre_match $2 && echo "regex matches" || echo "regex does not match" +} + +#f5# List files which have been changed within the last {\it n} days, {\it n} defaults to 1 +changed() { + emulate -L zsh + print -l *(c-${1:1}) +} + +#f5# List files which have been modified within the last {\it n} days, {\it n} defaults to 1 +new() { + emulate -L zsh + print -l *(m-${1:1}) +} + +# just press 'asdf' keys to toggle between dvorak and us keyboard layout +aoeu() { + echo -n 'Switching to us keyboard layout: ' + [[ -z "$DISPLAY" ]] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null + echo 'Done' +} +asdf() { + echo -n 'Switching to dvorak keyboard layout: ' + [[ -z "$DISPLAY" ]] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null + echo 'Done' +} +# just press 'asdf' key to toggle from neon layout to us keyboard layout +uiae() { + echo -n 'Switching to us keyboard layout: ' + setxkbmap us && echo 'Done' || echo 'Failed' +} + +# set up an ipv6 tunnel +ipv6-tunnel() { + emulate -L zsh + case $1 in + start) + if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then + print 'ipv6 tunnel already set up, nothing to be done.' + print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1 + else + [[ -n "$PUBLIC_IP" ]] || \ + local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \ + awk '/inet addr:/ {print $2}' | tr -d 'addr:') + + [[ -n "$PUBLIC_IP" ]] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 } + local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ })) + print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: " + ifconfig sit0 tunnel ::192.88.99.1 up + ifconfig sit1 add "$IPV6ADDR" && print done || print failed + fi + ;; + status) + if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then + print 'ipv6 tunnel available' ; return 0 + else + print 'ipv6 tunnel not available' ; return 1 + fi + ;; + stop) + if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then + print -n 'Stopping ipv6 tunnel (sit0 + sit1): ' + ifconfig sit1 down ; ifconfig sit0 down && print done || print failed + else + print 'No ipv6 tunnel found, nothing to be done.' ; return 1 + fi + ;; + *) + print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1 + ;; + esac +} + +# run dhclient for wireless device +iwclient() { + salias dhclient "$(wavemon -d | awk '/device/{print $2}')" +} + +# spawn a minimally set up mksh - useful if you want to umount /usr/. +minimal-shell() { + emulate -L zsh + local shell="/bin/mksh" + + if [[ ! -x ${shell} ]]; then + printf '`%s'\'' not available, giving up.\n' ${shell} >&2 + return 1 + fi + + exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ${shell} +} + +#f1# grep for patterns in grml's zsh setup +zg() { +#{{{ + LANG=C perl -e ' + +sub usage { + print "usage: zg -[anr] \n"; + print " Search for patterns in grml'\''s zshrc.\n"; + print " zg takes no or exactly one option plus a non empty pattern.\n\n"; + print " options:\n"; + print " -- no options (use if your pattern starts in with a dash.\n"; + print " -a search for the pattern in all code regions\n"; + print " -n search for the pattern in non-root code only\n"; + print " -r search in code for everyone (also root) only\n\n"; + print " The default is -a for non-root users and -r for root.\n\n"; + print " If you installed the zshrc to a non-default locations (ie *NOT*\n"; + print " in /etc/zsh/zshrc) do: export GRML_ZSHRC=\$HOME/.zshrc\n"; + print " ...in case you copied the file to that location.\n\n"; + exit 1; +} + +if ($ENV{GRML_ZSHRC} ne "") { + $RC = $ENV{GRML_ZSHRC}; +} else { + $RC = "/etc/zsh/zshrc"; +} + +usage if ($#ARGV < 0 || $#ARGV > 1); +if ($> == 0) { $mode = "allonly"; } +else { $mode = "all"; } + +$opt = $ARGV[0]; +if ($opt eq "--") { shift; } +elsif ($opt eq "-a") { $mode = "all"; shift; } +elsif ($opt eq "-n") { $mode = "nonroot"; shift; } +elsif ($opt eq "-r" ) { $mode = "allonly"; shift; } +elsif ($opt =~ m/^-/ || $#ARGV > 0) { usage(); } + +$pattern = $ARGV[0]; +usage() if ($pattern eq ""); + +open FH, "<$RC" or die "zg: Could not open $RC: $!\n"; +while ($line = ) { + chomp $line; + if ($line =~ m/^#:grep:marker:for:mika:/) { $markerfound = 1; next; } + next if ($mode eq "nonroot" && markerfound == 0); + break if ($mode eq "allonly" && markerfound == 1); + print $line, "\n" if ($line =~ /$pattern/); +} +close FH; +exit 0; + + ' -- "$@" +#}}} + return $? +} + +# {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson +# You use it as follows: +# $ NTREF=/reference/file +# $ ls -l *(e:nt:) +# This lists all the files in the current directory newer than the reference file. +# You can also specify the reference file inline; note quotes: +# $ ls -l *(e:'nt ~/.zshenv':) +nt() { + if [[ -n $1 ]] ; then + local NTREF=${~1} + fi + [[ $REPLY -nt $NTREF ]] +} +# }}} + +# shell functions {{{ + +#f1# Provide csh compatibility +setenv() { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" } # csh compatibility + +#f1# Reload an autoloadable function +freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done } +compdef _functions freload + +#f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s') +sll() { + [[ -z "$1" ]] && printf 'Usage: %s \n' "$0" && return 1 + for file in "$@" ; do + while [[ -h "$file" ]] ; do + ls -l $file + file=$(readlink "$file") + done + done +} + +# fast manual access +if check_com qma ; then + #f1# View the zsh manual + manzsh() { qma zshall "$1" } + compdef _man qma +else + manzsh() { /usr/bin/man zshall | vim -c "se ft=man| se hlsearch" +/"$1" - ; } +fi + +# zsh profiling +profile() { + ZSH_PROFILE_RC=1 $SHELL "$@" +} + +#f1# Edit an alias via zle +edalias() { + [[ -z "$1" ]] && { echo "Usage: edalias " ; return 1 } || vared aliases'[$1]' ; +} +compdef _aliases edalias + +#f1# Edit a function via zle +edfunc() { + [[ -z "$1" ]] && { echo "Usage: edfun " ; return 1 } || zed -f "$1" ; +} +compdef _functions edfunc + +#f1# Provides useful information on globbing +H-Glob() { + echo -e " + / directories + . plain files + @ symbolic links + = sockets + p named pipes (FIFOs) + * executable plain files (0100) + % device files (character or block special) + %b block special files + %c character special files + r owner-readable files (0400) + w owner-writable files (0200) + x owner-executable files (0100) + A group-readable files (0040) + I group-writable files (0020) + E group-executable files (0010) + R world-readable files (0004) + W world-writable files (0002) + X world-executable files (0001) + s setuid files (04000) + S setgid files (02000) + t files with the sticky bit (01000) + + print *(m-1) # Files modified up to a day ago + print *(a1) # Files accessed a day ago + print *(@) # Just symlinks + print *(Lk+50) # Files bigger than 50 kilobytes + print *(Lk-50) # Files smaller than 50 kilobytes + print **/*.c # All *.c files recursively starting in \$PWD + print **/*.c~file.c # Same as above, but excluding 'file.c' + print (foo|bar).* # Files starting with 'foo' or 'bar' + print *~*.* # All Files that do not contain a dot + chmod 644 *(.^x) # make all plain non-executable files publically readable + print -l *(.c|.h) # Lists *.c and *.h + print **/*(g:users:) # Recursively match all files that are owned by group 'users' + echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<" +} +alias help-zshglob=H-Glob #dépendant du truc au dessus + +function swapfiles(){ + TMPF="/tmp/tmp.$$" + mv -f $1 $TMPF + mv -f $2 $1 + mv -f $TMPF $2 +}