From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10691 invoked from network); 6 May 2008 15:56:19 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.4 (2008-01-01) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.4 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 6 May 2008 15:56:19 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 83041 invoked from network); 6 May 2008 15:56:14 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 6 May 2008 15:56:14 -0000 Received: (qmail 28858 invoked by alias); 6 May 2008 15:56:11 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 24951 Received: (qmail 28845 invoked from network); 6 May 2008 15:56:11 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 6 May 2008 15:56:11 -0000 Received: from cluster-g.mailcontrol.com (cluster-g.mailcontrol.com [85.115.41.190]) by bifrost.dotsrc.org (Postfix) with ESMTP id 8A95480ED172 for ; Tue, 6 May 2008 17:56:04 +0200 (CEST) Received: from rly30g.srv.mailcontrol.com (localhost.localdomain [127.0.0.1]) by rly30g.srv.mailcontrol.com (MailControl) with ESMTP id m46Fu110018745 for ; Tue, 6 May 2008 16:56:02 +0100 Received: from submission.mailcontrol.com (submission.mailcontrol.com [86.111.216.190]) by rly30g.srv.mailcontrol.com (MailControl) id m46Fu0CJ018643 for zsh-workers@sunsite.dk; Tue, 6 May 2008 16:56:00 +0100 Received: from cameurexb01.EUROPE.ROOT.PRI ([62.189.241.200]) by [10.71.0.140] (envelope-sender Peter.Stephenson@csr.com) (MIMEDefang) with ESMTP id m46FtvuE018248; Tue, 06 May 2008 16:56:00 +0100 (BST) Received: from news01 ([10.103.143.38]) by cameurexb01.EUROPE.ROOT.PRI with Microsoft SMTPSVC(6.0.3790.3959); Tue, 6 May 2008 16:55:58 +0100 Date: Tue, 6 May 2008 16:55:58 +0100 From: Peter Stephenson To: zsh-workers@sunsite.dk Cc: martin f krafft , 479576@bugs.debian.org Subject: Re: Bug#479576: incorrect interpretation of LS_COLORS link=target by compsys Message-ID: <20080506165558.2d16b14b@news01> In-Reply-To: <20080506145855.GA31177@scru.org> References: <20080505145016.GA16248@lapse.madduck.net> <20080506145855.GA31177@scru.org> Organization: CSR X-Mailer: Claws Mail 3.3.1 (GTK+ 2.12.5; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 06 May 2008 15:55:58.0766 (UTC) FILETIME=[AD005CE0:01C8AF91] X-Scanned-By: MailControl A-08-50-01 (www.mailcontrol.com) on 10.71.1.140 X-Virus-Scanned: ClamAV 0.91.2/7040/Tue May 6 03:52:15 2008 on bifrost X-Virus-Status: Clean On Tue, 6 May 2008 15:58:55 +0100 Clint Adams wrote: > On Mon, May 05, 2008 at 03:50:16PM +0100, martin f krafft wrote: > > zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} > > > > This is a common way to get colouring of menus and lists by compsys. > > Unfortunately, it's not aware of all of the features of LS_COLORS. > > Specifically, if LS_COLORS sets ln=target, that's supposed to mean > > that the link should be dereferenced and coloured according to the > > target. zsh unfortunately somehow prepends 'argetm' to the items in > > the menu list: > > > > lapse:/tmp/cdt.EaF16274% touch a > > lapse:/tmp/cdt.EaF16274% ln -s a b > > lapse:/tmp/cdt.EaF16274% ls > > a argetmb@ > > Anyone up for special-casing "target" in complist? It's easier than most things in complist.c and I can't imagine anyone else is going to looking in the file if they can get away with it. Fairly lightly tested (I tried it once and it looked OK). I've added the traditional bad-tempered comment. Index: Doc/Zsh/mod_complist.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/mod_complist.yo,v retrieving revision 1.19 diff -u -r1.19 mod_complist.yo --- Doc/Zsh/mod_complist.yo 20 Apr 2008 06:41:23 -0000 1.19 +++ Doc/Zsh/mod_complist.yo 6 May 2008 15:49:15 -0000 @@ -37,7 +37,9 @@ for directories ) item(tt(ln 36))( -for symbolic links +for symbolic links. If this has the special value tt(target), +symbolic links are dereferenced and the target file used to +determine the display format. ) item(tt(pi 31))( for named pipes (FIFOs) Index: Src/Zle/comp.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/comp.h,v retrieving revision 1.16 diff -u -r1.16 comp.h --- Src/Zle/comp.h 7 Oct 2006 08:05:03 -0000 1.16 +++ Src/Zle/comp.h 6 May 2008 15:49:15 -0000 @@ -114,6 +114,8 @@ int gnum; /* global number */ mode_t mode; /* mode field of a stat */ char modec; /* LIST_TYPE-character for mode or nul */ + mode_t fmode; /* mode field of a stat, following symlink */ + char fmodec; /* LIST_TYPE-character for fmode or nul */ }; #define CMF_FILE (1<< 0) /* this is a file */ Index: Src/Zle/compcore.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/compcore.c,v retrieving revision 1.93 diff -u -r1.93 compcore.c --- Src/Zle/compcore.c 13 Apr 2008 16:58:42 -0000 1.93 +++ Src/Zle/compcore.c 6 May 2008 15:49:16 -0000 @@ -2784,8 +2784,8 @@ (complist ? ((strstr(complist, "packed") ? CMF_PACKED : 0) | (strstr(complist, "rows") ? CMF_ROWS : 0)) : 0)); - cm->mode = 0; - cm->modec = '\0'; + cm->mode = cm->fmode = 0; + cm->modec = cm->fmodec = '\0'; if ((flags & CMF_FILE) && orig[0] && orig[strlen(orig) - 1] != '/') { struct stat buf; char *pb; @@ -2799,6 +2799,11 @@ if ((cm->modec = file_type(buf.st_mode)) == ' ') cm->modec = '\0'; } + if (!ztat(pb, &buf, 0)) { + cm->fmode = buf.st_mode; + if ((cm->fmodec = file_type(buf.st_mode)) == ' ') + cm->fmodec = '\0'; + } } if ((*compqstack == QT_BACKSLASH && compqstack[1]) || (autoq && *compqstack && compqstack[1] == QT_BACKSLASH)) @@ -3208,6 +3213,8 @@ r->disp = ztrdup(m->disp); r->mode = m->mode; r->modec = m->modec; + r->fmode = m->fmode; + r->fmodec = m->fmodec; return r; } Index: Src/Zle/complist.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/complist.c,v retrieving revision 1.113 diff -u -r1.113 complist.c --- Src/Zle/complist.c 22 Apr 2008 15:08:13 -0000 1.113 +++ Src/Zle/complist.c 6 May 2008 15:49:16 -0000 @@ -108,12 +108,6 @@ * as mtab and mmtabp. */ static Cmgroup *mgtab, *mgtabp; -/* - * Contains information about the colours to be used for entries. - * Sometimes mcolors is passed as an argument even though it's - * available to all the functions. - */ -static struct listcols mcolors; #ifdef DEBUG /* * Allow us to keep track of pointer arithmetic for mgtab; could @@ -248,12 +242,26 @@ typedef struct listcols *Listcols; +/* values for listcol flags */ +enum { + /* ln=target: follow symlinks to determine highlighting */ + LC_FOLLOW_SYMLINKS = 0x0001 +}; + struct listcols { Filecol files[NUM_COLS]; /* strings for file types */ Patcol pats; /* strings for patterns */ Extcol exts; /* strings for extensions */ + int flags; /* special settings, see above */ }; +/* + * Contains information about the colours to be used for entries. + * Sometimes mcolors is passed as an argument even though it's + * available to all the functions. + */ +static struct listcols mcolors; + /* Combined length of LC and RC, maximum length of capability strings. */ static int lr_caplen, max_caplen; @@ -428,24 +436,33 @@ for (i = 0, nn = colnames; *nn; i++, nn++) if (!strcmp(n, *nn)) break; - p = getcolval(s, 0); - if (*nn) { - Filecol fc, fo; - - fc = (Filecol) zhalloc(sizeof(*fc)); - fc->prog = (i == COL_EC || i == COL_LC || i == COL_RC ? - NULL : gprog); - fc->col = s; - fc->next = NULL; - if ((fo = mcolors.files[i])) { - while (fo->next) - fo = fo->next; - fo->next = fc; - } else - mcolors.files[i] = fc; + /* + * special case: highlighting link targets + */ + if (i == COL_LN && strpfx("target", s) && + (s[6] == ':' || !s[6])) { + mcolors.flags |= LC_FOLLOW_SYMLINKS; + p = s + 6; + } else { + p = getcolval(s, 0); + if (*nn) { + Filecol fc, fo; + + fc = (Filecol) zhalloc(sizeof(*fc)); + fc->prog = (i == COL_EC || i == COL_LC || i == COL_RC ? + NULL : gprog); + fc->col = s; + fc->next = NULL; + if ((fo = mcolors.files[i])) { + while (fo->next) + fo = fo->next; + fo->next = fc; + } else + mcolors.files[i] = fc; + } + if (*p) + *p++ = '\0'; } - if (*p) - *p++ = '\0'; return p; } } @@ -474,6 +491,7 @@ int i, l; max_caplen = lr_caplen = 0; + mcolors.flags = 0; queue_signals(); if (!(s = getsparam("ZLS_COLORS")) && !(s = getsparam("ZLS_COLOURS"))) { @@ -1685,7 +1703,7 @@ } zcoff(); } else { - int mx; + int mx, modec; if (g->widths) { int i; @@ -1733,8 +1751,13 @@ zcputs(g->name, COL_HI); else if (mselect >= 0 && (m->flags & (CMF_MULT | CMF_FMULT))) zcputs(g->name, COL_DU); - else if (m->mode) - subcols = putfilecol(g->name, m->str, m->mode); + else if (m->mode) { + if (mcolors.flags & LC_FOLLOW_SYMLINKS) { + subcols = putfilecol(g->name, m->str, m->fmode); + } else { + subcols = putfilecol(g->name, m->str, m->mode); + } + } else subcols = putmatchcol(g->name, (m->disp ? m->disp : m->str)); @@ -1747,12 +1770,13 @@ len = ZMB_nicewidth(m->disp ? m->disp : m->str); mlprinted = len ? (len-1) / columns : 0; - if ((g->flags & CGF_FILES) && m->modec) { + modec = (mcolors.flags & LC_FOLLOW_SYMLINKS) ? m->fmodec : m->modec; + if ((g->flags & CGF_FILES) && modec) { if (m->gnum != mselect) { zcoff(); zcputs(g->name, COL_TC); } - putc(m->modec, shout); + putc(modec, shout); len++; } if ((len = width - len - 2) > 0) { @@ -2556,6 +2580,15 @@ s->origcs = origcs; s->origll = origll; s->status = dupstring(status); + /* + * with just the slightest hint of a note of infuriation: + * mode here is the menu mode, not the file mode, despite + * the fact we're in a file dealing with file highlighting; + * but that's OK, because s is a menu stack entry, despite + * the fact we're in a function declaring s as char *. + * anyway, in functions we really mean *mode* it's + * called m, to be clear. + */ s->mode = mode; menucmp = menuacc = hasoldlist = 0; minfo.cur = NULL; @@ -2674,6 +2707,7 @@ s->origcs = origcs; s->origll = origll; s->status = dupstring(status); + /* see above */ s->mode = mode; accept_last(); handleundo(); -- Peter Stephenson Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070