Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!know!sdd.hp.com!think.com!mintaka!bloom-picayune.mit.edu!athena.mit.edu!bjaspan From: bjaspan@athena.mit.edu (Barr3y Jaspan) Newsgroups: comp.unix.shell Subject: Re: Is there a smart pwd display program? Keywords: smart pwd display tilde-notation fast Message-ID: <1991Apr17.210228.23187@athena.mit.edu> Date: 17 Apr 91 21:02:28 GMT References: <1991Apr15.170910.28160@ux1.cso.uiuc.edu> Sender: news@athena.mit.edu (News system) Organization: Massachusetts Institute of Technology Lines: 140 In article <1991Apr15.170910.28160@ux1.cso.uiuc.edu>, jbn35564@uxa.cso.uiuc.edu (J.B. Nicholson) writes: |> I'm writing a function for KSH that shows you your current working directory |> using tilde notation: |> |> [ examples deleted ] You might be interested in a hack I wrote called (surprise!) 'prompt'. Essentially, it takes a list of path/replacement pairs and replaces the matching part of any path with its replacement. It also truncates the final path to a specified number of components. Here is how I use it (with csh or tcsh): alias pcmd '~bjaspan/${bindir}/prompt 4 $cwd $home 0 ~ /afs/athena.mit.edu/user/b/bjaspan 0 ~ /afs/athena.mit.edu/user 3 ~ /afs/sipb.mit.edu/project/sipbsrc 1 "sipbsrc: "' alias cd_magic 'set noglob && set prompt = "<%m> `pcmd`% " && unset noglob alias cd 'cd \!* && cd_magic' alias pushd 'pushd \!* && cd_magic' alias popd 'popd \!* && cd_magic' (Obviously, we use AFS here.) The arguments to prompt mean: o only display a total of four components of the final path, after replacement o $cwd is in the alias literally, so it gets expanded at each invokation, thus passing the current working dir to the program The rest are actually triples, "path-offset-replacement". Any current path beginning with "path" is replaced by "replacement", and "offset" characters are deleted from the remaining componenets (if there aren't that many characters left, nothing happens). Here is a transcript demonstrating the program's behavior (with commentary): ~% cd # $home is replaced by ~ with 0 chars deleted ~% cd src # only the specified components are removed from the path ~/src% cd /afs/sipb.mit.edu/project/sipbsrc/ # offset==1 for sipbsrc, and since there aren't that many more characters, # nothing happens here /afs/sipb.mit.edu/project/sipbsrc% cd src # Now there are more characters, so 1 (the leading /) is deleted. sipbsrc: src% cd lib/elisp/gnus-dist/attic # Only four components are shown sipbsrc: .../lib/elisp/gnus-dist/attic% cd /afs/athena.mit.edu/user # /afs/athena.mit.edu/user deletes three characters, and there aren't that many /afs/athena.mit.edu/user% cd t # Still not enough characters /afs/athena.mit.edu/user/t% cd tytso # Now there are, so replace the text with ~ and delete the 3 chars ~tytso% (Note for the sharp eyed: yes, there is a <%m> in the prompt to display the hostname, and yes, it works. I deleted it so everything would fit on one line.) ---------------------------------------------------------------------- Anyway, the best thing about this program is its size -- about 3K on a vax running bsd (and similarly small on other machines). It uses one syscall (write) and one library function (strlen). It provides its own bcopy() in case yours doesn't do overlapping regions (although, clearly, any bcopy should, and could probably be done better in assembly). Note: your mileage may vary. If you find problems, feel free to tell me but I may or may not care to fix them. It works for me. :-) Oh, and I don't usually read this newsgroup... Barr3y Jaspan, bjaspan@mit.edu Watchmaker Computing ---- snip snip ---- #define MHT 10 #define USAGE "Usage: prompt max_dirs cwd [ hometop offset text ... ]\n" int left_bcopy(src, dest, len) char *src, *dest; int len; { while (len--) *dest++ = *src++; } main(argc, argv) int argc; char **argv; { char *cwd, *hometop[MHT], *hometop_text[MHT]; int cwd_len, hometop_len[MHT], hometop_offset[MHT]; int hometop_num, i, max_dirs, count; if (argc < 3) { write(1, USAGE, strlen(USAGE)); exit(1); } hometop_num = i = 0; max_dirs = atoi(*++argv); cwd = *++argv; cwd_len = strlen(cwd); while ((hometop_num < MHT) && (hometop[hometop_num] = *++argv)) { hometop_offset[hometop_num] = atoi(*++argv); hometop_text[hometop_num] = *++argv; hometop_len[hometop_num] = strlen(hometop[hometop_num]); ++hometop_num; } while (i < hometop_num) { if (strncmp(hometop[i], cwd, hometop_len[i])==0 && (cwd_len >= hometop_len[i]+hometop_offset[i])) { left_bcopy(cwd+hometop_len[i]+hometop_offset[i], cwd, cwd_len-hometop_len[i]); cwd[cwd_len-hometop_len[i]] = '\0'; cwd_len = strlen(cwd); write(1, hometop_text[i], strlen(hometop_text[i])); break; } ++i; } if (max_dirs) { for (i=cwd_len, count=0; i>0; i--) { if (*(cwd+i) == '/' && (++count == max_dirs)) { write(1, "...", 3); write(1, cwd+i, cwd_len-i); return 0; } } } write(1, cwd, cwd_len); return 0; } -- Barr3y Jaspan, bjaspan@mit.edu