[comp.unix.questions] prompt wars

zben@umd5.UUCP (03/15/87)

I started by picking up and enhancing some aliases originally posted by
Chris Torek in article <5150@mimsy.uucp>.  I wanted to have the name of
the current directory in the prompt, but some amount of its parentage.
This precluded use of the :t modifier.  Via a combination of aliases I
got what I wanted (see below) but it was taking over four SECONDS to do
a change directory.  This was considered annoying, so I replaced the mess
with a C program (at the end of this article).  The change directory time
is now one second or less.

WHAT I WANTED:

Current machine (no need for domains) and the last two directory names of
the full name of the current directory.  Here is an example:

umd5[3] ~ % cd /usr/spool/news/comp/unix/questions
umd5[4] ...unix/questions %

ALIAS, SHELL SCRIPT, AND AWK SOLUTION:

in ".cshrc":

   alias set_prompt 'set prompt="`hnm1`[\\!] `dirs|cdt2` % "'
   alias cd 'cd \!*; set_prompt'
   alias pushd 'pushd \!*; set_prompt'
   alias popd 'popd \!*; set_prompt'
   set_prompt

in "~/bin/hnm1":

   #! /bin/sh
   # output user-friendly head of host name

   hostname | awk -F. '{ print $1 }'

in "~/bin/cdt2":

   #! /bin/sh
   # output user-friendly tail of CD name

   awk '{print $1}' |
   awk -F/ '
   (NF>3)||(NF>2)&&(length($1)!=0) {printf "..."}
   (NF>1) {printf "%s/",$(NF-1)}
   {printf "%s\n",$NF}'

ALIAS AND C PROGRAM SOLUTION:

in ".cshrc":

   alias cd 'cd \!*; set prompt="`dirs|genpro`"'
   alias pushd 'pushd \!*; set prompt="`dirs|genpro`"'
   alias popd 'popd \!*; set prompt="`dirs|genpro`"'
   set prompt="`dirs|genpro`"

and the following C program in "~/bin/genpro":

/* Generate prompt string
 * Ben Cranston 3/14/87
 *
 * designed to be called as:
 *
 * alias cd 'cd \!*; set prompt="`dirs|genpro`"'
 *
 * builds and outputs string:  <hostname> [!] <workdir>
 *
 * where <hostname> is the name of the current host sans trailing domains
 *       <workdir>  is the current directory, with all but the last two
 *                  directory names replaced by ... for brevity.
 *
 * I had all this working with "awk" scripts, but it was taking over
 * four SECONDS to switch directories.  This was considered wasteful.
 *
 */

#define BUFFSIZE 512

#include <sys/param.h>     /* MAXHOSTNAMELEN */
#include <strings.h>       /* string funcs   */

main(argc,argv)
int argc;
char **argv;
{
    char hostname[MAXHOSTNAMELEN];
    char dirs[BUFFSIZE], buff[BUFFSIZE];
    char *cp;
    char *p1, *p2;

    gethostname(hostname,sizeof(hostname));
    if ( 0 != (cp=index(hostname,'.')) )
	*cp = 0;        /* truncate hostname at first period (if any) */

    gets(dirs);
    if ( 0 != (cp=index(dirs,' ')) )
	*cp = 0;        /* truncate dir string at first space (if any) */

/* search backwards for slash.  if found, temporarily make null and
 * search backwards for slash again.  if found again, replace string
 * to the left of the second slash with "..."
 *
 * the additional test of (p1!=dirs) is for a special case, a two-string
 * explicitly rooted.  that is, "cd /etc/ns" will display as /etc/ns
 * rather than ...etc/ns
 */

    buff[0] = 0;
    cp = dirs;

    if ( 0 != (p2 = rindex(dirs,'/')) ) {
	*p2 = 0;
	if ( (0 != (p1 = rindex(dirs,'/'))) && (p1 != dirs) ) {
	    strcpy(buff,"...");
	    cp = p1 + 1;
	}
	*p2 = '/';
    }

    strcat(buff,cp);

    printf("%s[!] %s %% ",hostname,buff);
}

Needless to say this technique provides a skeleton upon which a variety
of personal preferences can be hung.  Enjoy!
-- 
                    umd5.UUCP    <= {seismo!mimsy,ihnp4!rlgvax}!cvl!umd5!zben
Ben Cranston zben @ umd2.UMD.EDU    Kingdom of Merryland UniSys 1100/92
                    umd2.BITNET     "via HASP with RSCS"

chris@mimsy.UUCP (03/15/87)

In article <1480@umd5> zben@umd5 (Ben Cranston) writes:
>   alias set_prompt 'set prompt="`hnm1`[\\!] `dirs|cdt2` % "'

>in "~/bin/hnm1":

>   #! /bin/sh
>   # output user-friendly head of host name
>
>   hostname | awk -F. '{ print $1 }'

Instead of using a shell script and awk, it is much faster to do this:

    set hostname=`hostname | sed -e 's/\..*//'`
    alias set_prompt 'set prompt="${hostname}[\\!] `dirs|cdt2` % "'

Likewise, using `sed' to change `/usr/spool/news/comp/unix/questions'
to `...unix/questions' is also faster, and if done in an alias rather
than in a shell script, should be as fast as the C program Ben wrote.

The sed commands to do this are left as an exercise to the reader. :-)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu

dupuy@columbia.UUCP (Alex Dupuy) (03/17/87)

Here's a little sed alias which trims the directories in a "dirs" listing to
the last two names (if there are more):

    alias trim   "sed -e 's=~*/[^ ]*/\([^ /]*/[^ /]*\)=...\1=g'"

so you could say:

    set prompt = `hostname`[\!]`dirs | trim`

note that it leaves all the directory elements in - you may want to strip out
all but the first (current).  I leave that as an exercise for the reader...
I use it to set up a label for my sun shelltool windows.

@alex

zben@mimsy.UUCP (Ben Cranston) (03/18/87)

In article <5823@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:

> Instead of using a shell script and awk, it is much faster to do this:

>    set hostname=`hostname | sed -e 's/\..*//'`
>    alias set_prompt 'set prompt="${hostname}[\\!] `dirs|cdt2` % "'

> Likewise, using `sed' to change `/usr/spool/news/comp/unix/questions'
> to `...unix/questions' is also faster, and if done in an alias rather
> than in a shell script, should be as fast as the C program Ben wrote.
> The sed commands to do this are left as an exercise to the reader. :-)

Well, this alias seems to do the trick.  It seems a little slow, but this
is mimsy rather than umd5 so I don't have the basis for comparison...

alias set_prompt 'set prompt="`hostname|sed -e '\''s|\..*||'\''`[\\!] `dirs|sed -e '\''s| .*||'\'' -e '\''s|.*[^/]\(/[^/]*/[^/]*\)|...\1|'\''` % "'

It could probably be decomposed in the way Chris suggests...
-- 
                    umd5.UUCP    <= {seismo!mimsy,ihnp4!rlgvax}!cvl!umd5!zben
Ben Cranston zben @ umd2.UMD.EDU    Kingdom of Merryland UniSys 1100/92
                    umd2.BITNET     "via HASP with RSCS"

jgy@hropus.UUCP (03/19/87)

> In article <5823@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
> 
> > Instead of using a shell script and awk, it is much faster to do this:
> 
> >    set hostname=`hostname | sed -e 's/\..*//'`
> >    alias set_prompt 'set prompt="${hostname}[\\!] `dirs|cdt2` % "'
> 
> > Likewise, using `sed' to change `/usr/spool/news/comp/unix/questions'
> > to `...unix/questions' is also faster, and if done in an alias rather
> > than in a shell script, should be as fast as the C program Ben wrote.
> > The sed commands to do this are left as an exercise to the reader. :-)
> 
> Well, this alias seems to do the trick.  It seems a little slow, but this
> is mimsy rather than umd5 so I don't have the basis for comparison...
> 
> alias set_prompt 'set prompt="`hostname|sed -e '\''s|\..*||'\''`[\\!] `dirs|sed -e '\''s| .*||'\'' -e '\''s|.*[^/]\(/[^/]*/[^/]*\)|...\1|'\''` % "'
> 
> It could probably be decomposed in the way Chris suggests...

For korn shell users to get the prompt set to the machine name without
need for ANY new processes (after setting your machine name) so....

In your .profile add:
UNAME=`uname`
export UNAME
alias -xt set_prompt='cd ../..;_x=$PWD;cd -; PS1="$UNAME!!...${PWD#$_x} "'


That's it, no new processes, and hopefully only two system calls
executed by KSH (2 chdir's), each time you do a set_prompt.