From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14199 invoked from network); 20 Aug 1998 17:40:47 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns1.primenet.com.au with SMTP; 20 Aug 1998 17:40:47 -0000 Received: (from list@localhost) by math.gatech.edu (8.9.1/8.9.1) id NAA11962; Thu, 20 Aug 1998 13:27:02 -0400 (EDT) Resent-Date: Thu, 20 Aug 1998 13:27:02 -0400 (EDT) From: "Bart Schaefer" Message-Id: <980820102914.ZM3798@candle.brasslantern.com> Date: Thu, 20 Aug 1998 10:29:14 -0700 In-Reply-To: <980819120806.ZM11746@candle.brasslantern.com> Comments: In reply to "Bart Schaefer" "Bug? multicomp no longer works for paths starting with tilde (~)" (Aug 19, 12:08pm) References: <980819120806.ZM11746@candle.brasslantern.com> X-Mailer: Z-Mail (4.0b.820 20aug96) To: zsh-workers@math.gatech.edu Subject: Re: Bug? multicomp no longer works for paths starting with tilde (~) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Resent-Message-ID: <"VfL2o.0.pw2.cn5tr"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/4342 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu On Aug 19, 12:08pm, Bart Schaefer wrote: } Subject: Bug? multicomp no longer works for paths starting with tilde (~) } } This seems to apply to both 3.0.5 and 3.1.4. Am I just misunderstanding } what's supposed to be happening? I reverted back to the baseline 3.1.4 I've just diffed the 3.0.5 multicomp against a much older one, and found that the original function used eval "reply=($reply)" where the current version uses reply=(${~reply}) The former expands tildes, the latter does not. However, other changes make that eval unsuitable for the newer multicomp. So here's the latest that I have. The patch below should be applied to the original 3.1.4 multicomp, that is, -before- (and instead of) my two previous patches. I'm still not entirely happy about the handling of metacharacters. If the compctl doesn't include -Q, leading tildes get quoted; if it does include -Q, then other metacharacters do not get quoted. I think using a leading tilde is somewhat more common than having file names with an embedded metacharacter, so I've put -Q in the usage examples. I suppose a block of $reply:gs/// expressions could be added to quote all the metacharacters (except tilde), but I'm hoping someone has a better suggestion. The test of -z "$head" in the fourth hunk is to prevent having a trailing "*" appended to completions that end with a "/". E.g. before, zsh% ls /u/l/ would generate $reply from /usr/local/*, which doesn't seem right. The addition of -S '' to the usage examples is to prevent a space from being inserted following such a trailing slash. There may be a better approach to this as well (such as deleting a trailing slash earlier on). Index: Functions/multicomp =================================================================== --- multicomp 1998/06/01 17:08:43 1.1 +++ multicomp 1998/08/20 05:59:02 @@ -3,7 +3,7 @@ # e.g. s/z/s -> src/zsh-2.4/src # # Usage: e.g. -# compctl -D -f + -U -K multicomp +# compctl -D -f + -U -Q -S '' -K multicomp # # Note that exactly matched directories are not expanded, e.g. # s/zsh-2.4/s will not expand to src/zsh-2.4old/src. @@ -22,7 +22,7 @@ pref="${1}$2" # Hack to allow programmable completion to select multicomp after a : # (e.g. -# compctl -D -f -x 's[:]' -U -K multicomp +# compctl -D -f -x 's[:]' -U -Q -S '' -K multicomp # ) pref="${pref#:}" @@ -32,7 +32,7 @@ if [[ "$pref" = \~* ]]; then # If the string started with ~, save the head and what it will become. origtop="${pref%%/*}" - newtop=${~origtop} + eval "newtop=$origtop" # Save the expansion as the bit matched already sofar=($newtop) pref="${pref#$origtop}" @@ -48,12 +48,23 @@ else [[ -z "$pref" ]] && globdir= # if path segment contains wildcards, don't add another. - if [[ "$head" = *[\*\?]* ]]; then - wild= + if [[ "$head" = *[\[\(\*\?\$\~]* || -z "$head" ]]; then + wild=$head else - wild='*' + # Simulate case-insensitive globbing for ASCII characters + wild="[${(j(][))${(s())head:l}}]*" # :gs/a/[a]/ etc. + # The following could all be one expansion, but for readability: + wild=$wild:gs/a/aA/:gs/b/bB/:gs/c/cC/:gs/d/dD/:gs/e/eE/:gs/f/fF/ + wild=$wild:gs/g/gG/:gs/h/hH/:gs/i/iI/:gs/j/jJ/:gs/k/kK/:gs/l/lL/ + wild=$wild:gs/m/mM/:gs/n/nN/:gs/o/oO/:gs/p/pP/:gs/q/qQ/:gs/r/rR/ + wild=$wild:gs/s/sS/:gs/t/tT/:gs/u/uU/:gs/v/vV/:gs/w/wW/:gs/x/xX/ + wild=$wild:gs/y/yY/:gs/z/zZ/:gs/-/_/:gs/_/-_/:gs/[]// + + # Expand on both sides of '.' (except when leading) as for '/' + wild="${${wild:gs/[.]/*.*/}#\*}" fi - reply=(${sofar}"${head}${wild}${globdir}") + + reply=(${sofar}"${wild}${globdir}") reply=(${~reply}) fi -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.brasslantern.com