Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!husc6!sri-unix!quintus!ok
From: ok@quintus.UUCP (Richard A. O'Keefe)
Newsgroups: comp.unix.wizards,comp.unix.questions
Subject: Re: The whole prompt string thing (was: PS1 and the bourne shell...)
Message-ID: <440@cresswell.quintus.UUCP>
Date: Sun, 6-Dec-87 21:56:55 EST
Article-I.D.: cresswel.440
Posted: Sun Dec  6 21:56:55 1987
Date-Received: Sat, 12-Dec-87 03:55:51 EST
References: <279@caus-dp.UUCP> <1311@puff.wisc.edu> <137@anumb.UUCP> <1973@bloom-beacon.MIT.EDU>
Organization: Quintus Computer Systems, Mountain View, CA
Lines: 85
Summary: use the "." command
Xref: mnetor comp.unix.wizards:5885 comp.unix.questions:5232

The task is to come up with some form of Bourne shell command such that
	{initial stuff} {arg} {final stuff}
has the same effect as
	cd {arg}
except that in addition it sets PS1 to something like "`pwd` > ".
In this message I provide two solutions which should work in any
reasonable Bourne shell (no aliases or shell functions).

Since the directory is to be changed, the command ought to be executed
by the current shell.  The obvious thing to try is the "dot" command:
	. file
reads commands from file and executes them in the current shell.
The whole point of the "dot" command is to set environment variables.
Unfortunately, you can't pass positional parameters this way, so you
have to use environment variables.  Let's reserve the variable "d"
for this.  Letting the file be called "sd", the total command will be
	d={arg} . sd
It would be nice if
	. sd
acted like cd without an argument.  The rest is almost obvious.

# beginning of script to make sd
cat <<'EOF' >sd
cd ${d:-$HOME}
PS1="`pwd` > "
unset d
EOF	
chmod a=rx sd
exit
# end of script to make sd

Why the "unset" command?  Well, there is a fine point about keyword
parameters which is not in the manual.  The VSID says (Vol 2, p 105):
	The environment for any _simple-command_ may be augmented by
	prefixing it with one or more assignments to parameters.  Thus:
		TERM=123 cmd
		(export TERM; TERM=123; cmd)
	(where cmd uses the value of the environmental variable TERM) are
	equivalent as far as the execution of cmd is concerned.
The trouble with "dot" is that it is a "special command"; the SVID is
not clear about in which respects "special commands" are
_simple-commands_; for example in SVR1 special commands couldn't have
I/O redirection.  (In SVR2 and SVR3 they can.)  It turns out that
there is a difference between "special commands" and others with
respect to keyword parameters.  Keyword parameters are allowed on ANY
_simple-command_, but
	var=val PROGRAM		binds var to val for PROGRAM
				and does not change its global value.
				(let ((var val)) PROGRAM)

	var=val SPECIAL		permanently sets var to val and
				then executes SPECIAL
				(progn (setq var val) SPECIAL)
This is true in the 4.2, V.2, and V.3 systems I have tried.
The relevance to sd is that
	d=directory . sd
permanently changes d, so a later sd can't tell whether there was a
d keyword argument or not.  So I've made sd remove the binding for
d.  (unset arrived in SVR2, so on earlier Bourne shells, just forget
it and put up with always specifying d.)

This is not pretty, and it seems to me that keywords parameters should
be local to special commands as well as to ordinary programs, just as
you can now redirect I/O for special commands too.

Summary:
	d=directory . sd
should do the job in any reasonable Bourne shell.
It looks odd, but can typically be typed without touching the shift key.

There is another possibility.
	cat <<'EOF' >sd2
	cd ${1:-$HOME}
	here=`pwd`
	echo "PS1='$here > ' ; cd $here" 
	EOF
You execute this with eval:
	eval `sd2 directory`
You have to use the shift key for this one, but it is a general technique
for doing anything you like and then updating the parent shell.

I normally use a SUN, and have an alias set up which puts the current
hostname and current directory into the title-bar of a window.  Some
terminals have a mode-line which can be set, and either of these methods
could be used to set the mode-line rather than the prompt string.