[comp.unix.wizards] Using the directory stack like !-2:3 in csh

dg@lakart.UUCP (David Goodenough) (05/17/88)

Here's a problem I often face, and can find no reference to in the manual.

If I have (say) three entries in my directory stack in csh:

% dirs
~/work/lk/src ~/mail ~/work/vw/h/ether

is there any way to refer to ~/mail or ~/work/vw/h/ether with a syntax
like history substitution: say I want to edit tcp.ip.h in ~/work/vw/h/ether:
currently I can supply the full path:

    ~/work/vw/h/ether/tcp.ip.h

or a relative path:

    ../../vw/h/ether/tcp.ip.h

but what I really want to do is to be able to say:

    @:3/tcp.ip.h

where @:3 gets the third entry on my directory stack.

Can I do this??
-- 
	dg@lakart.UUCP - David Goodenough		+---+
							| +-+-+
	....... !harvard!adelie!cfisun!lakart!dg	+-+-+ |
						  	  +---+

ok@quintus.UUCP (Richard A. O'Keefe) (05/18/88)

In article <115@lakart.UUCP>, dg@lakart.UUCP (David Goodenough) writes:
> but what I really want to do is to be able to say:
> 
>     @:3/tcp.ip.h
> 
> where @:3 gets the third entry on my directory stack.
> 
> Can I do this??

Not directly, but it isn't hard.
(1) In your .cshrc file, introduce a new variable to hold the directory stack:
	set dirs = `dirs`
(2) The commands which can change the directory stack are pushd, popd, cd.
    Introduce aliases for them which maintain the directory stack.
	alias pushd 'pushd \!* ; set dirs = `dirs`'
	alias popd  'popd  \!* ; set dirs = `dirs`'
	alias cd    'chdir \!* ; set dirs = `dirs`'
(3) Now you're away laughing.  All you have to do is write
	$dirs[3]/tcp.ip.h

sahayman@watmath.waterloo.edu (Steve Hayman) (05/18/88)

In article <115@lakart.UUCP> dg@lakart.UUCP (David Goodenough) 
asks about a way to refer to the entries on csh's directory stack.

I have this in my .cshrc, I'm sure there are other ways but this is pretty
simple.  This lets me use $1, $2 and so on to refer to the directory
stack entries.


if ( ! $?prompt ) goto skipprompt

	 ... various other things for interactive shells only ...

	alias	cd	'cd \!*; setdirs'
	alias	pushd	'pushd \!*; setdirs'
	alias	popd	'popd \!*; setdirs'
	alias	setdirs	'set argv=(`dirs`)'
	
skipprompt:

Hope this is of some use to somebody.


Steve Hayman         Math Faculty Computing Facility     University of Waterloo
watmath!sahayman        sahayman@math.waterloo.edu        sahayman@water.bitnet

karl@cheops.cis.ohio-state.edu (Karl Kleinpaste) (05/19/88)

Tcsh provides for direct access to the directory stack with a
modification to the syntax for filenames.  From the tcsh man page,

14. DIRECTORY STACK ELEMENT ACCESS
     Tcsh will now allow the user to access all elements in the
     directory stack directly.  The syntax "=<digit>" is recog-
     nized by tcsh as indicating a particular directory in the
     stack.  (This works for the file/command name recognition as
     well.) This syntax is analogous to the ~ syntax for access
     to users' home directories.  The stack is viewed as zero-
     based, i.e., =0 is the same as $cwd, which is the same as
     ".".  As a special case, the string "=-" is recognized as
     indicating the last directory in the stack.  Thus,

          > dirs
          /usr/net/bin /usr/spool/uucp /usr/accts/sys
          > echo =2
          /usr/accts/sys
          > ls -l =1/LOGFILE
          -rw-r--r-- 1 uucp   2594 Jan 19 09:09 /usr/spool/uucp/LOGFILE
          > echo =-/.cs*
          /usr/accts/sys/.cshrc
          > echo =4
          Not that many dir stack entries.
          >

     Tcsh will complain if you ask for a directory stack item
     which does not exist.

I put this to use by having, in my .cshrc, the lines
	pushd /usr/spool/uucp
	pushd /u/osu/src
	pushd +2
Thereafter, I can use =1 to get at things under our source area, and
=- to check on the state of UUCP things.

Tcsh was distributed over comp.sources.unix a while back.  Check a
nearby archive site.

--Karl

bob@cloud9.UUCP (Bob Toxen) (05/20/88)

In article <115@lakart.UUCP>, dg@lakart.UUCP (David Goodenough) writes:
> If I have (say) three entries in my directory stack in csh:
> % dirs
> ~/work/lk/src ~/mail ~/work/vw/h/ether
> 
> is there any way to refer to ~/mail or ~/work/vw/h/ether with a syntax
> like history substitution: say I want to edit tcp.ip.h in ~/work/vw/h/ether:
> ...
> Can I do this??
> 	dg@lakart.UUCP - David Goodenough
> 	!harvard!adelie!cfisun!lakart!dg
% pushd +2
% setx=$cwd
% pushd
% vi $x/tcp.ip.h
I haven't done this in hours!  Also, I highly recommend:
	alias	popd	'popd \!*;set prompt="\! $cwd:t % "'
	alias	pushd	'pushd \!*;set prompt="\! $cwd:t % "'
	alias	d	dirs
	alias	po	popd
	alias	pu	pushd
-- 

Bob Toxen	{ucbvax!ihnp4,harvard,cloud9!es}!anvil!cavu!bob
Stratus Computer, Marlboro, MA
Pilot to Copilot: What's a mountain goat doing way up here in a cloud bank?

steve@geac.UUCP (Steve Lane) (05/24/88)

In article <115@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes:
>
>but what I really want to do is to be able to say:
>
>    @:3/tcp.ip.h
>
>where @:3 gets the third entry on my directory stack.
>
>Can I do this??
>-- 
>	dg@lakart.UUCP - David Goodenough		+---+
>							| +-+-+
>	....... !harvard!adelie!cfisun!lakart!dg	+-+-+ |
>						  	  +---+

You can use the 'dirs' command, and alias the usual directory commands in the
following manner:

- include the following shell variable initialization in your .login
	set d=$HOME

- and add three lines to your .cshrc
	alias cd    'cd \!*;set d=`dirs`'
	alias pushd 'pushd \!*; set d=`dirs`'
	alias popd  'popd; set d=`dirs`'

In that way, your directory stack is always saved in $d[1], $d[2], ... with
$d[1] being your current working directory.
-- 
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Steve Lane,                        UUCP: ...[mnetor, yunexus, utgpu]!geac!steve
Geac Computers International Inc.
Markham, Ontario.  (416) 475-0525

rbj@icst-cmr.arpa (Root Boy Jim) (05/25/88)

   From: Bob Toxen <bob@cloud9.uucp>

   I haven't done this in hours!  Also, I highly recommend:
	   alias	popd	'popd \!*;set prompt="\! $cwd:t % "'
	   alias	pushd	'pushd \!*;set prompt="\! $cwd:t % "'
	   alias	d	dirs
	   alias	po	popd
	   alias	pu	pushd

Try: alias \< pushd; alias \> popd; alias \? dirs.

   Bob Toxen	{ucbvax!ihnp4,harvard,cloud9!es}!anvil!cavu!bob
   Stratus Computer, Marlboro, MA
   Pilot to Copilot: What's a mountain goat doing way up here in a cloud bank?

	(Root Boy) Jim Cottrell	<rbj@icst-cmr.arpa>
	National Bureau of Standards
	Flamer's Hotline: (301) 975-5688
	The opinions expressed are solely my own
	and do not reflect NBS policy or agreement
	My name is in /usr/dict/words. Is yours?

dg@lakart.UUCP (David Goodenough) (05/26/88)

Being as I started this mess, I think it only fair to tell the most elegant
solution I got:

alias	cd	'cd \!* ; sds'
alias	popd	'popd \!* ; sds'
alias	pushd	'pushd \!* ; sds'
alias	sds	'set argv=(`dirs`)'

This works because in an interactive csh argv is idle. So when I set argv
to be ( ` dirs ` ), $1 == $cwd, $2 == second dir, etc.

Absolutely brilliant. Apologies to whoever suggested this, I've forgotton
your name. I still think this is simple, elegant, and it has made my life
SO MUCH easier.
-- 
	dg@lakart.UUCP - David Goodenough		+---+
							| +-+-+
	....... !harvard!adelie!cfisun!lakart!dg	+-+-+ |
						  	  +---+

rbj@icst-cmr.arpa (Root Boy Jim) (05/28/88)

   You can use the 'dirs' command, and alias the usual directory commands 
   in the following manner:

   - include the following shell variable initialization in your .login
	   set d=$HOME

   - and add three lines to your .cshrc
	   alias cd    'cd \!*;set d=`dirs`'
	   alias pushd 'pushd \!*; set d=`dirs`'
	   alias popd  'popd; set d=`dirs`'

   In that way, your directory stack is always saved in $d[1], $d[2], ... with
   $d[1] being your current working directory.

Even better is to replace `d' with `argv', then you can just reference
$1, $2, etc! BTW, popd should have a \!* as well, to handle `popd +2', etc.
Strictly speaking, the set command should have parens around the dirs
command, altho it seems to work anyway, probably because of the order
in which command substitution, blank interpretation, and builtin commands
are handled. Note to Paul Placeway: given this technique, there is no
reason to support the `=<num>' construct in tcsh, altho I do appreciate
its being there. Now to fix up my aliases...

   -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
   Steve Lane,              UUCP: ...[mnetor, yunexus, utgpu]!geac!steve
   Geac Computers International Inc.
   Markham, Ontario.  (416) 475-0525

	(Root Boy) Jim Cottrell	<rbj@icst-cmr.arpa>
	National Bureau of Standards
	Flamer's Hotline: (301) 975-5688
	The opinions expressed are solely my own
	and do not reflect NBS policy or agreement
	My name is in /usr/dict/words. Is yours?

John_M@spectrix.UUCP (John Macdonald) (06/10/88)

There have been enough people tossing off sets of csh aliases for
pushd and popd and so on that I decided to toss my hat into the ring
too.

I set up the alias:

alias @@ 'alias \!:1 cd `pwd`'

Instead of trying to maintain a stack of historical directories, I just
use the command:

@@ fred

when I am in a directory that I associate with "fred".  Later, when I
am somewhere else and want to return, I just use the command:

fred

which takes me back to where I was when I defined fred.  This makes it
easy to bounce around a number of directories, without having to remember
what order I first entered them "Now is the directory I want the third
or the seventh...?".
-- 
John Macdonald   UUCP:    {mnetor,utzoo}             !spectrix!jmm