Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Colored completion listings



On Mon, 12 May 2008 16:13:46 +0400
sergio <zsh@xxxxxxxxxxxxx> wrote:
> Hello.
> 
> I have some troubles with colored completion listing.
> 
> 1) zsh highlights broken symlinks as unbroken. but mi color is defined
> and ls highlights it whith correct color.

My understanding of ls, and experiment, suggest you mean "or".  In other
words, in a broken link like:

lrwxrwxrwx 1 pws users 12 2008-05-12 16:15 going-nowhere -> non-existent

"going-nowhere" uses "or", while "non-existent" uses "mi".  As completion
doesn't show the target of the symbolic link, only the original name, "mi"
is therefore irrelevant in zsh.  However, I've fixed "or".  (By luck, this
is easy with the fix I've just made for ln=target.)

If you think I've got this wrong you'll have to point me at chapter and
verse.

> 2) zsh highlights directories like test.jpg as jpeg file
> color for directories is defined before *.jpg

Yes, the logic is the wrong way round.  File type tests from stat should
come before extension tests.  (This can be kind of annoying in files from
Windows that leave execute permissions all over the place but being
compatible with ls is preferable.)

Index: Src/Zle/complist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/complist.c,v
retrieving revision 1.114
diff -u -r1.114 complist.c
--- Src/Zle/complist.c	6 May 2008 16:01:19 -0000	1.114
+++ Src/Zle/complist.c	12 May 2008 16:00:30 -0000
@@ -533,9 +533,10 @@
     lr_caplen = strlen(mcolors.files[COL_LC]->col) +
 	strlen(mcolors.files[COL_RC]->col);
 
-    /* Default for orphans and missing files. Currently not used */
+    /* Default for orphan is same as link. */
     if (!mcolors.files[COL_OR] || !mcolors.files[COL_OR]->col)
-	mcolors.files[COL_OR] = mcolors.files[COL_FI];
+	mcolors.files[COL_OR] = mcolors.files[COL_LN];
+    /* Default for missing files:  currently not used */
     if (!mcolors.files[COL_MI] || !mcolors.files[COL_MI]->col)
 	mcolors.files[COL_MI] = mcolors.files[COL_FI];
 
@@ -871,36 +872,15 @@
  * file modes. */
 
 static int
-putfilecol(char *group, char *n, mode_t m)
+putfilecol(char *group, char *n, mode_t m, int special)
 {
-    int colour;
+    int colour = -1;
     Extcol ec;
     Patcol pc;
 
-    for (ec = mcolors.exts; ec; ec = ec->next)
-	if (strsfx(ec->ext, n) &&
-	    (!ec->prog || !group || pattry(ec->prog, group))) {
-	    zlrputs(ec->col);
-
-	    return 0;
-	}
-
-    nrefs = MAX_POS - 1;
-
-    for (pc = mcolors.pats; pc; pc = pc->next)
-	if ((!pc->prog || !group || pattry(pc->prog, group)) &&
-	    pattryrefs(pc->pat, n, -1, -1, 0, &nrefs, begpos, endpos)) {
-	    if (pc->cols[1]) {
-		patcols = pc->cols;
-
-		return 1;
-	    }
-	    zlrputs(pc->cols[0]);
-
-	    return 0;
-	}
-
-    if (S_ISDIR(m)) {
+    if (special != -1) {
+	colour = special;
+    } else if (S_ISDIR(m)) {
 	if (m & S_IWOTH)
 	    if (m & S_ISVTX)
 		colour = COL_TW;
@@ -926,10 +906,36 @@
 	colour = COL_SG;
     else if (S_ISREG(m) && (m & S_IXUGO))
 	colour = COL_EX;
-    else
-	colour = COL_FI;
 
-    zcputs(group, colour);
+    if (colour != -1) {
+	zcputs(group, colour);
+	return 0;
+    }
+
+    for (ec = mcolors.exts; ec; ec = ec->next)
+	if (strsfx(ec->ext, n) &&
+	    (!ec->prog || !group || pattry(ec->prog, group))) {
+	    zlrputs(ec->col);
+
+	    return 0;
+	}
+
+    nrefs = MAX_POS - 1;
+
+    for (pc = mcolors.pats; pc; pc = pc->next)
+	if ((!pc->prog || !group || pattry(pc->prog, group)) &&
+	    pattryrefs(pc->pat, n, -1, -1, 0, &nrefs, begpos, endpos)) {
+	    if (pc->cols[1]) {
+		patcols = pc->cols;
+
+		return 1;
+	    }
+	    zlrputs(pc->cols[0]);
+
+	    return 0;
+	}
+
+    zcputs(group, COL_FI);
 
     return 0;
 }
@@ -1752,10 +1758,17 @@
 	else if (mselect >= 0 && (m->flags & (CMF_MULT | CMF_FMULT)))
 	    zcputs(g->name, COL_DU);
 	else if (m->mode) {
+	    /*
+	     * Symlink is orphaned if we read the mode with lstat
+	     * but couldn't read one with stat.  That's the
+	     * only way they can be different so the following
+	     * test should be enough.
+	     */
+	    int orphan_colour = (m->mode && !m->fmode) ? COL_OR : -1;
 	    if (mcolors.flags & LC_FOLLOW_SYMLINKS) {
-		subcols = putfilecol(g->name, m->str, m->fmode);
+		subcols = putfilecol(g->name, m->str, m->fmode, orphan_colour);
 	    } else {
-		subcols = putfilecol(g->name, m->str, m->mode);
+		subcols = putfilecol(g->name, m->str, m->mode, orphan_colour);
 	    }
 	}
 	else



Messages sorted by: Reverse Date, Date, Thread, Author