#!/bin/sh # (C) 2002-2003 Dan Allen and Stefan Kamphausen # Written by Dan Allen # - small additions by Stefan Kamphausen # - better completion code by Robi Malik robi.malik@nexgo.de # - trailing path support by Damon Harper Feb 2006 # Globals CDARGS_SORT=0 # set to 1 if you want mark to sort the list CDARGS_NODUPS=1 # set to 1 if you want mark to delete dups # --------------------------------------------- # # Run the cdargs program to get the target # # directory to be used in the various context # # This is the fundamental core of the # # bookmarking idea. An alias or substring is # # expected and upon receiving one it either # # resolves the alias if it exists or opens a # # curses window with the narrowed down options # # waiting for the user to select one. # # # # @param string alias # # # # @access private # # @return 0 on success, >0 on failure # # --------------------------------------------- # CDARGSPATH="$SHELLRC/etc/soft/cdargs/cdargs" CDARGSRESULT="$SHELLRC/etc/soft/cdargs/cdargsresult" function _cdargs_get_dir () { local bookmark extrapath # if there is one exact match (possibly with extra path info after it), # then just use that match without calling cdargs if [ -e "$CDARGSPATH" ]; then dir=`grep "^$1 " "$CDARGSPATH"` if [ -z "$dir" ]; then bookmark="${1/\/*/}" if [ "$bookmark" != "$1" ]; then dir=`grep "^$bookmark " "$CDARGSPATH"` extrapath=`echo "$1" | sed 's#^[^/]*/#/#'` fi fi [ -n "$dir" ] && dir=`echo "$dir" | sed 's/^[^ ]* //'` fi if [ -z "$dir" -o "$dir" != "${dir/ /}" ]; then # okay, we need cdargs to resolve this one. # note: intentionally retain any extra path to add back to selection. dir= if cdargs --noresolve "${1/\/*/}"; then dir=`cat "$CDARGSRESULT"` rm -f "$CDARGSRESULT" 2>/dev/null; fi fi if [ -z "$dir" ]; then echo "Aborted: no directory selected" >&2 return 1 fi [ -n "$extrapath" ] && dir="$dir$extrapath" if [ ! -d "$dir" ]; then echo "Failed: no such directory '$dir'" >&2 return 2 fi } # --------------------------------------------- # # Perform the command (cp or mv) using the # # cdargs bookmark alias as the target directory # # # # @param string command argument list # # # # @access private # # @return void # # --------------------------------------------- # function _cdargs_exec () { local arg dir i last call_with_browse # Get the last option which will be the bookmark alias eval last=\${$#}; # Resolve the bookmark alias. If it cannot resolve, the # curses window will come up at which point a directory # will need to be choosen. After selecting a directory, # the function will continue and $_cdargs_dir will be set. if [ -e $last ]; then last= fi if _cdargs_get_dir "$last"; then # For each argument save the last, move the file given in # the argument to the resolved cdargs directory i=1; for arg; do if [ $i -lt $# ]; then $command "$arg" "$dir"; fi let i=$i+1; done fi } # --------------------------------------------- # # Prepare to move file list into the cdargs # # target directory # # # # @param string command argument list # # # # @access public # # @return void # # --------------------------------------------- # function mvb () { local command command='mv -i'; _cdargs_exec $*; } # --------------------------------------------- # # Prepare to copy file list into the cdargs # # target directory # # # # @param string command argument list # # # # @access public # # @return void # # --------------------------------------------- # function cpb () { local command command='cp -i'; _cdargs_exec $*; } # --------------------------------------------- # # Change directory to the cdargs target # # directory # # # # @param string alias # # # # @access public # # @return void # # --------------------------------------------- # function cdb () { local dir _cdargs_get_dir "$1" && cd "$dir" && echo `pwd`; } alias cb='cdb' alias cv='cdb' # --------------------------------------------- # # Mark the current directory with alias # # provided and store as a cdargs bookmark # # directory # # # # @param string alias # # # # @access public # # @return void # # --------------------------------------------- # function mark () { local tmpfile # first clear any bookmarks with this same alias, if file exists if [[ "$CDARGS_NODUPS" && -e "$CDARGSPATH" ]]; then tmpfile=`echo ${TEMP:-${TMPDIR:-/tmp}} | sed -e "s/\\/$//"` tmpfile=$tmpfile/cdargs.$USER.$$.$RANDOM grep -v "^$1 " "$CDARGSPATH" > $tmpfile && 'mv' -f $tmpfile "$CDARGSPATH"; fi # add the alias to the list of bookmarks cdargs --add=":$1:`pwd`"; # sort the resulting list if [ "$CDARGS_SORT" ]; then sort -o "$CDARGSPATH" "$CDARGSPATH"; fi } # Oh, no! Not overwrite 'm' for stefan! This was # the very first alias I ever wrote in my un*x # carreer and will always be aliased to less... # alias m='mark' # --------------------------------------------- # # Mark the current directory with alias # # provided and store as a cdargs bookmark # # directory but do not overwrite previous # # bookmarks with same name # # # # @param string alias # # # # @access public # # @return void # # author: SKa # # --------------------------------------------- # function ca () { # add the alias to the list of bookmarks cdargs --add=":$1:`pwd`"; } # --------------------------------------------- # # Bash programming completion for cdargs # # Sets the $COMPREPLY list for complete # # # # @param string substring of alias # # # # @access private # # @return void # # --------------------------------------------- # function _cdargs_aliases () { local cur bookmark dir strip oldIFS COMPREPLY=() if [ -e "$CDARGSPATH" ]; then cur=${COMP_WORDS[COMP_CWORD]} if [ "$cur" != "${cur/\//}" ]; then # if at least one / bookmark="${cur/\/*/}" dir=`grep "^$bookmark " "$CDARGSPATH" | sed 's#^[^ ]* ##'` if [ -n "$dir" -a "$dir" = "${dir/ /}" -a -d "$dir" ]; then strip="${dir//?/.}" oldIFS="$IFS" IFS=' ' COMPREPLY=( $( compgen -d "$dir`echo "$cur" | sed 's#^[^/]*##'`" \ | sed -e "s/^$strip/$bookmark/" -e "s/\([^\/a-zA-Z0-9#%_+\\\\,.-]\)/\\\\\\1/g" ) ) IFS="$oldIFS" fi else COMPREPLY=( $( (echo $cur ; cat "$CDARGSPATH") | \ awk 'BEGIN {first=1} {if (first) {cur=$0; l=length(cur); first=0} else if (substr($1,1,l) == cur) {print $1}}' ) ) fi fi return 0 } # --------------------------------------------- # # Bash programming completion for cdargs # # Set up completion (put in a function just so # # `nospace' can be a local variable) # # # # @param none # # # # @access private # # @return void # # --------------------------------------------- # _cdargs_complete() { local nospace= [ "${BASH_VERSINFO[0]}" -ge 3 -o \( "${BASH_VERSINFO[0]}" = 2 -a \( "${BASH_VERSINFO[1]}" = 05a -o "${BASH_VERSINFO[1]}" = 05b \) \) ] && nospace='-o nospace' complete $nospace -S / -X '*/' -F _cdargs_aliases cv cb cdb } _cdargs_complete