jbn35564@uxa.cso.uiuc.edu (J.B. Nicholson) (04/16/91)
I'm writing a function for KSH that shows you your current working directory using tilde notation: What you type: What you get from the function: --------------------------------------------------------------------------- cd ~/ cd ~joeuser ~joeuser cd /home/dir/of/joeuser ~joeuser cd .. /home/dir/of cd / / cd /home/dir/of/me/1/2/3 ~/1/2/3 So you get the idea. It runs pretty fast, but I was wondering if there's a program (written in some compiled language, or maybe even Perl or something) that'll give you the same thing, that would probably be better to run than my function because it would be faster. I'm currently trying to add some stuff that'll make it seem faster and trying to use only the quickest way of addressing things like if-then's and so forth (I posted a note about this before). I'll be glad to share my function once I've finished it. Thanks. Jeff -- +----------------------------------------------------------------------------+ | "If you hear an onion ring - answer it." J.B. Nicholson | +----------------------------------------------------------------------------+ | jeffo@uiuc.edu (Internet) These opinions are mine, that's all.| +----------------------------------------------------------------------------+
dws@margay.cs.wisc.edu (DaviD W. Sanderson) (04/16/91)
In article <1991Apr15.170910.28160@ux1.cso.uiuc.edu> jeffo@uiuc.edu writes: >I'm writing a function for KSH that shows you your current working directory >using tilde notation: [description deleted] This is what I use as part of my setup. It doesn't decide how to print things out; it just sets the variable PSD so you can use it elsewhere however you like. It is quite fast, since it only uses "case". #------- # setPSD - sets PSD, the part of my current directory path, to put # into my prompt. # # There is a small point about testing for directories under $HOME. # One should NOT simply check whether $PWD matches $HOME*, as this # will not tell you if $PWD is your home directory or a directory # under $HOME. (If HOME=/var/home/dws, and PWD=/var/home/dwsalterego, # this heuristic would tell you that you were in the dws account # when you were not.) Instead, one should check whether $PWD # matches $HOME or $HOME/*, which is what this routine does. # # The number of "/*" in _setPSD_strip determines the maximum # number of elements in the directory to be displayed after # it is trimmed. # # DaviD W. Sanderson (dws@cs.wisc.edu) #------- _setPSD_strip="/*/*/*" # tailor as desired. setPSD() { _wd="${1:-$PWD}" case $_wd { $HOME) #------- # An exact match of $HOME is the simplest case. #------- PSD="~" ;; $HOME/*) #------- # A directory under $HOME. #------- _wd="${_wd#$HOME}" PSD0="${_wd%$_setPSD_strip/*}" PSD="${_wd#$PSD0/*/}" PSD="~${PSD}" ;; *) #------- # Show up to the last N directories in PATH, where # N is the number of "/*" in _setPSD_strip. # PSD begins with / for directories up to # N levels deep, no / for directories further down. #------- PSD0="${_wd%$_setPSD_strip/*}" PSD="${_wd#$PSD0/*/}" case $PSD { /*) ;; *) PSD=" $PSD";; } ;; } unset _wd PSD0 } -- ___ / __\ U N S H I N E DaviD W. Sanderson | | | I N E dws@cs.wisc.edu _____| | |_____ ________ \ / \ |__/ /////__ Fusion Powered Locomotives Made to Order \____/ \__|_/ \\\\\______ (TARDIS model available at extra cost)
bjaspan@athena.mit.edu (Barr3y Jaspan) (04/18/91)
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