#!/bin/csh # setcd cshell script: execute using source # # To be able to use this script, you will need to set the environment variable # $cdScript # to the path of this file # ------------------------------------------------------------------------------ if ($?prompt) then # a prompt exists: session interactive # # -------------------------------------------------------------------------- if ( $shell =~ */tcsh ) then set Tcsh = 1 endif if ( $?0 ) then if ( $0 =~ *tcsh ) then set Tcsh = 1 endif endif if (! $?cdFirstTime) then # set depth counter (the number of "subshells" - used with setcd) if (! $?cdDepth ) then # for CD prompts on startup setenv cdDepth 1 setenv cdCmd setcd else setenv cdDepth `@ td = $cdDepth + 1 ; echo $td` endif set cdFirstTime endif # -------------------------------------------------------------------------- # # Setcd, autoaddcd, addcd, remcd and resetcd # # call setcd as follows: # setcd [n][u][t][h][C] # n: add node host name to prompt (N: only for xterm title) # u: add user name to prompt (U: only for xterm title) # t: add terminal name to prompt (T: only for xterm title) # h: add history number to prompt # C: shorten the path if too long - # if is > 0: max len = columns / # else show last - path elements # c: apply C shortening for icon (else last part of path) # x: use n, u options and display directory in xterm titles # X: display directory in xterm icons # +: add n, u values to end of directory in xterm icons # -: add n, u values to start of directory in xterm icons # i: ignore actual call to set up initial prompt # S: add shell name to prompt # this sets up the following commands: # cd change directory using pushd and prompt # cd change directory to th entry in pushd list # cd $ change directory to $ # cd $ change directory to th entry in $ # (where $'s separators are space and colons) # ccd change directory using chdir and prompt # lcd show stack using dirs # - pop directory using popd and set prompt # _ pop directory using popd and set prompt # these commands also perform a "source" operation on the files indicated # by the environment variables $cdrcfile and $cdfile - the first should be # placed in a fixed position (~ for example), the second in the new # directory # # call addcd as follows: # addcd # this adds as a "nickname" of the current directory path alias setcd 'setenv cdCmd setcd ; set cdCmdP = ( \!* ); source $cdScript' alias addcd 'setenv cdCmd addcd ; set cdCmdP = ( \!* ); source $cdScript' alias remcd 'setenv cdCmd remcd ; source $cdScript' alias resetcd 'setenv cdCmd resetcd; source $cdScript' alias mincd 'setenv cdCmd mincd ; source $cdScript' alias autoaddcd 'setenv cdCmd autoaddcd; source $cdScript' # --- argument "converters" (used by cd) # this depends on the implementation of awk set uname = `uname` if ( `uname` == SunOS && `uname -r` =~ 5.* ) set uname = Solaris alias Tput tput switch ( $uname ) case Solaris: case SunOS: case OSF1: alias awk nawk breaksw case Linux: set tputcmd = `whereis tput|sed -e 's:[^/]*/:/:'` breaksw endsw if ( $?Tcsh ) then alias Tput 'echo "%{`tput \!*`%}"' endif alias echolines "awk 'BEGIN{for(i=1;ij||i<1?1:i;'\ 'print a[i]}'"'" alias elem "awk 'BEGIN{i=ARGV[--ARGC]+1;i=i<1||i>=ARGC?1:i;"\ "print ARGV[i]}'" # set cdrcfile and cdfile to the names of files that the new cd instructions # will "source" to set up a directory specific environment if ( ! $?cdrcfile ) then setenv cdrcfile ~/.cshcdrc endif if ( ! $?cdfile ) then setenv cdfile .cshcd endif # cdCmd is the re/setcd invocation string (see the aliases) if ( ! $?cdCmd ) then setenv cdCmd . else # cdDirNames is for directory nicknames - its words are of the form # : if ( ! $?cdDirNames ) then setenv cdDirNames ":" endif # setcd's parameters are in cdCmdP; the options must all be in the # first of these switch ( $cdCmd ) case setcd: if ($?doing_setcd) breaksw set doing_setcd = "YES" set pbeg = "" alias pcd 'echolines $cdDirNames | sort -y0|'\ "awk '"'{print NR"\t"$0}'"'" if ( $?cdCmdP ) then if ( $#cdCmdP ) then if ( $cdCmdP[1] =~ *n* ) then # node indicator set pbeg = '`hostname`'":$pbeg" set pbeg = "`Tput bold``Tput smso`$pbeg" #set pbeg = "`Tput bold``Tput smso``hostname`:$pbeg" endif if ( $cdCmdP[1] =~ *u* ) then # user indicator set pbeg = "`Tput bold`"'`whoami`'"@$pbeg" #set pbeg = "`Tput bold``whoami`@$pbeg" endif if ( $cdCmdP[1] =~ *t* && { tty -s } ) then # terminal indicator set pbeg = \ "`Tput bold`["'`tty | sed -e s./dev/..`'"]$pbeg" endif if ( $cdCmdP[1] =~ *h* ) then # history indicator set pbeg = "["'\\!'"]$pbeg" endif if ($cdCmdP[1] =~ *[xX]* && $term == xterm ) then # xterm's window title set _007 = "`echo ''|tr '\012' '\007'`" set _033 = "`echo ''|tr '\012' '\033'`" # lead-in for xterm title set cdxinit = "${_033}]2;" # node/user for xterm title/icon set cdxNU = "" if ($cdCmdP[1] =~ *[uU]*) then set cdxNU = "${cdxNU}"'`whoami`@' endif if ($cdCmdP[1] =~ *[nN]*) then set cdxNU = "${cdxNU}"'`hostname`:' endif # build the xterm title # first the terminal indicator if ( $cdCmdP[1] =~ *[tT]* && { tty -s } ) then set cdxinit = \ "${cdxinit}["'`tty | sed -e s./dev/..`'"]" endif # then node/user set cdxinit = "${cdxinit}${cdxNU}" # then directory and end marker set cdxinit = "${cdxinit}"'`getDir`'"${_007}" # do we do the icon as well? if ( $cdCmdP[1] =~ *X* ) then # icon as well - last part of cwd set cdxinit = "${cdxinit}${_033}]1;" if ($cdCmdP[1] =~ *-*) then set cdxinit = "${cdxinit}${cdxNU}" endif if ( $cdCmdP[1] =~ *c* ) then set cdxinit = "${cdxinit}"'`getDir`' else set cdxinit = "${cdxinit}"'$cwd:t/' endif if ($cdCmdP[1] =~ *+*) then set cdxinit = "${cdxinit} ${cdxNU}" endif set cdxinit = "${cdxinit}${_007}" endif setenv cdXinit "$cdxinit" unset cdxinit unset cdxNU else if ( $?cdXinit ) then # set xterm's window title to a default set cdxinit = "`echo ''|tr '\012' '\033'`]2;" set cdxinit = "${cdxinit}`whoami`@`hostname`" set cdxinit = "${cdxinit}`echo ''|tr '\012' '\007'`" echo -n "$cdxinit" unsetenv cdXinit unset cdxinit endif endif endif if ( $cdDepth > 1 ) then # depth indicator set pbeg = "<`basename $shell`:${cdDepth}>$pbeg" set pbeg = "`Tput bold`$pbeg" else if ( $?cdCmdP ) then if ( "$cdCmdP" =~ *S* ) then # just add the shell name set pbeg = "<`basename $0`>$pbeg" set pbeg = "`Tput bold`$pbeg" endif endif if ( "$pbeg" != "" ) set pbeg = "`Tput rev`$pbeg`Tput sgr0`" set pbeg = "$pbeg`Tput rev`" set pend = "`Tput sgr0`" # the getDir alias is used to fetch the prompt's cwd path part alias getDir echo $cwd # reset the getDir alias: # the awk looks for the last longest match M of a nickname's # path and the current path D, setting match length Ml # and path string S accordingly ($1 is the nickname, $2 # is its path) set denom = 0 if ( $?cdCmdP ) then if ( $#cdCmdP ) then if ( $cdCmdP[1] =~ *C* ) then # cut off at a quarter (or fract of last param) set denom = 4 if ( $cdCmdP[$#cdCmdP] =~ [-0-9]* ) then set denom=$cdCmdP[$#cdCmdP] if ($denom == 0) set denom = 1 endif endif endif endif alias getDir\ 'echolines $cdDirNames |'\ 'awk -F: -v D="$cwd"'\ "'"'BEGIN {Ml=0;M="";N=S=X="";'\ 'c='"'"'`tput cols`'"'"';'\ 'gsub("[^0-9]","",c);'\ 'd='"$denom"';l=length(D);'\ 'if(d==0)X=D;'\ 'else'\ 'if(d<0){n=split(D,p,"/");'\ 'if(n<-d)X=D;'\ 'else{s="";'\ 'for(i=n+d+1;i<=n;i++)s=s p[i]"/";'\ 'X=substr(s,1,length(s)-1);}}'\ 'else'\ 'if(l>c/d)X="..."substr(D,l-c/d+4);'\ 'else X=D};'\ '{l=length($2);'\ 'if(l>=Ml&&substr(D,1,l)==$2'\ '&&(substr(D,l+1,1)=="/"||D==$2))'\ '{M=$2;S=$1;N=substr(D,l+2);Ml=l}};'\ 'END {if(S=="")print X;'\ 'else{if(N!="")S=S":"N;print S}}'"'" unset denom set setPrompt = '"'"$pbeg"'`getDir`'"$pend "'"' if ( ! $?oldPrompt ) set oldPrompt = "$prompt" alias cddest 'lcd -\!*' alias testcd '(set td = ( \!* "" ); chdir $td[1] >& /dev/null)' set cdexit = 'set cdold = "$cwd"' set cdinit = 'if (-r "$cdrcfile") source "$cdrcfile"' set cdinit = "$cdinit; "'if (-r "$cdfile") source "$cdfile"' set cdinit = "$cdinit; unset cdold" set setPrompt = "set prompt = $setPrompt" if ( $?cdXinit ) then set setPrompt = "$setPrompt; echo -n "'"'"$cdXinit"'"' endif set cdinit = "$cdinit; $setPrompt" alias cd- 'chdir \!* >&\! /dev/null;'"$setPrompt" alias cdP "$setPrompt" alias ccd "$cdexit; "'chdir \!* >&\! /dev/null;'"$cdinit" alias gd "$cdexit; "'pushd \!* >&\! /dev/null;'"$cdinit" alias - "$cdexit; "'popd \!* >&\! /dev/null;'"$cdinit" alias _ "$cdexit; "'popd \!* >&\! /dev/null;'"$cdinit" # in tcsh, chdir may echo results: beware alias cd 'set cdval = ( `echo \!* ""` );'\ 'set cdcmp = ( );'\ 'if ($#cdval == 0) set cdval = ( ~ );'\ \ 'set cdcmp = ( `elem $cdval` );'\ \ 'if ($#cdcmp > 0 && '\ '! { testcd "$cdval[1]" } && '\ '"$cdval[1]" =~ *:*)'\ 'set cdcmp = ( `elem: $cdval` );'\ \ 'if ($#cdcmp == 0) set cdcmp = "$cdval";'\ \ 'set cd = "$cdcmp[1]";'\ 'if ( -d "$cdval" ) set cd = "$cdval";'\ \ 'if ( ! -d "$cd" && "`cddest $cdval`" != "" )'\ 'set cd = ( "`cddest \!*`" );'\ \ 'set cdcmp = "";'\ 'if ("$cd[1]" != "-")'\ 'set cdcmp = `chdir "$cd[1]" >&\! /dev/null; pwd`;'\ 'if ("$cd[1]" == "-" && -d ./-)'\ 'set cdcmp = `chdir ./-; pwd`;'\ 'if ("$cd[1]" == "-" && ! -d ./-)'\ 'set cdcmp = "";'\ \ 'set cdOK = ok;'\ 'if ("$cdcmp" == "" && "$cd[1]" == "-")'\ 'set cdOK = up;'\ 'if ("$cdcmp" == "" && "$cd[1]" != "-")'\ 'set cdOK = bad;' \ \ "$cdexit;"\ 'if ($cdOK == up)'\ 'popd >&\! /dev/null;'\ 'if ($cdOK == bad)'\ 'pushd "$cd[1]";'\ 'if ($cdOK == ok && "$cdcmp" != "`pwd`")'\ 'pushd "$cdcmp" >&\! /dev/null;'\ 'pushd . >&\! /dev/null; popd >&\! /dev/null;'\ "$cdinit;"\ \ 'unset cd cdcmp cdval cdOK' # wow! # lcd prints numbered list of dirs # lcd - prints unnumbered list # lcd -nn prints entry of number nn # lcd nn prints entry of number nn as a number alias lcd "dirs | awk -F' ' -v HOME="'"$HOME"'\ "'"'{d=s=q="";p="\!*";'\ 'if(substr(p,1,1)=="-"){q=1;p=substr(p,2)}'\ 'x=(p=="")?-1:(p+0""==p)?p+0:NF+1;'\ 'n=0;i=1;'\ 'do{'\ 'if(substr($i,1,2)=="~/"||$i=="~"){'\ 'if(d)if(x==n++||x<0)print s;'\ 'd=HOME substr($i,2)}'\ 'else if(substr($i,1,1)!="/")d=d" "$i;'\ 'else{'\ 'if(d)if(x==n++||x<0)print s;d=$i}'\ 's=q?d:n"\t"d;}while(++i<=NF);'\ 'if(d)if(x==n++||x<0)print s}'"'" set setcd if ( ! $?cdCmdP ) then cd "$cwd" else if ( $#cdCmdP == 0 ) then cd "$cwd" else if ( $cdCmdP[1] !~ *[iI]* ) then cd "$cwd" endif endif endif breaksw case autoaddcd: if ($?doing_autoaddcd) breaksw if (! $?setcd) then setcd endif set doing_autoaddcd = "YES" set envvars = `env | awk -F= '{printf $1" "}'` foreach var ( $envvars ) set var = `echo '$'$var` alias getval echo $var set val = `getval` if ($#val == 1) then if (-d $val) then set cdDList = "" foreach cdDWord ( $cdDirNames ) if ( $cdDWord !~ ${var}:* && \ $cdDWord !~ *:$val && \ $cdDWord != : ) then set cdDList = ( $cdDList $cdDWord ) endif end setenv cdDirNames "$cdDList ${var}:$val" endif endif end cd- . breaksw case addcd: if ($?doing_addcd) breaksw if (! $?setcd) then setcd endif set doing_addcd = "YES" if ($?cdCmdP) then if ($#cdCmdP > 0) then # last param is nickname set cdDirName = $cdCmdP[1] # checkout $cdDirName set cdDirName = $cdDirName[1] set cdDirName = ${cdDirName:t} # update the environment if ( "$cdDirNames" == ":" ) then setenv cdDirNames "${cdDirName}:$cwd" else set cdDList = "" foreach cdDWord ( $cdDirNames ) if ( $cdDWord !~ ${cdDirName}:* && \ $cdDWord !~ *:$cwd ) then set cdDList = ( $cdDList $cdDWord ) endif end setenv cdDirNames "$cdDList ${cdDirName}:$cwd" endif unset cdDirName endif endif breaksw case remcd: if ($?doing_remcd) breaksw if (! $?setcd) then setcd endif set doing_remcd = "YES" # update the environment if ( $?cdDirNames ) then set cdDList = ( ) foreach cdDWord ( $cdDirNames ) if ( $cdDWord !~ *:$cwd ) then set cdDList = ( $cdDList $cdDWord ) endif end setenv cdDirNames "$cdDList" endif if ( ! $?cdDirNames ) setenv cdDirNames ":" set cdDList = ( $cdDirNames ) if ( $#cdDList == 0 ) setenv cdDirNames ":" cd- . breaksw case resetcd: # use the standard csh cd unset setcd unalias lcd unalias pcd unalias addcd unalias remcd unalias autoaddcd unalias cd- unalias cdP unalias ccd unalias cd unalias gd unalias - unalias _ if ( $?cdCmd ) unsetenv cdCmd if ( $?cdCmdP ) unsetenv cdCmdP if ( $?cdDirNames ) unsetenv cdDirNames if ( $?oldPrompt ) then set prompt = "$oldPrompt" unset oldPrompt endif unset cdCmdP cdFirstTime if ( $?cdDepth ) then if ( $cdDepth == 1 ) then unsetenv cdDepth else set cdDepth_tmp = $cdDepth @ cdDepth_tmp -- setenv cdDepth $cdDepth_tmp unset cdDepth_tmp endif endif breaksw case mincd: # minimal cd: doesn't change prompt but does do # auto-push and cdfile stuff if ($?doing_setcd) breaksw if ( $?oldPrompt ) then set prompt = "$oldPrompt" unset oldPrompt endif set doing_setcd = "YES" unset setcd unalias pcd unalias addcd unalias remcd unalias autoaddcd alias cddest 'dirs|echoNthIn \!*' set cdexit = 'set cdold = "$cwd"' set cdinit = 'if (-r "$cdrcfile") source "$cdrcfile"' set cdinit = "$cdinit; "'if (-r "$cdfile") source "$cdfile"' set cdinit = "$cdinit; unset cdold" alias cd- 'chdir \!* >&\! /dev/null;' alias cdP ":" alias ccd "$cdexit; "'chdir \!* >&\! /dev/null;'"$cdinit" alias gd "$cdexit; "'pushd \!* >&\! /dev/null;'"$cdinit" alias - "$cdexit; "'popd \!* >&\! /dev/null;'"$cdinit" alias _ "$cdexit; "'popd \!* >&\! /dev/null;'"$cdinit" alias cd 'set cd = ( `cddest \!*` \!* );'\ 'set cdcmp = ( `echo \!* ""` );'\ 'if ($#cdcmp == 0) set cdcmp = ( ~ );'\ 'if (-d "$cdcmp[1]") set cd = ( $cdcmp );'\ 'set cdcmp = `chdir $cd[1]; pwd`;'" $cdexit;"\ 'if ("$cdcmp" != "`pwd`")'\ 'pushd $cd[1] >&\! /dev/null;'\ 'pushd . >&\! /dev/null; popd >&\! /dev/null;'\ "$cdinit; unset cd cdcmp" alias lcd "dirs | awk '"'{for(i=1;i<=NF;i++)'\ 'if (substr($i,1,1)=="~")'\ 'print i-1"\t'"'"'$HOME'"'"'"'\ 'substr($i,2);'\ 'else'\ 'print i-1"\t"$i;}'"'" set setcd cd $cwd breaksw default: breaksw endsw unset pbeg pend cdexit cdinit cdDList cdDWord envvars setPrompt val var unset doing_setcd doing_autoaddcd doing_addcd doing_remcd endif # -------------------------------------------------------------------------- endif # of "if ( $?prompt ) then ..."