diff options
author | Oliver Kiddle <okiddle@yahoo.co.uk> | 2019-05-07 23:24:49 +0200 |
---|---|---|
committer | Oliver Kiddle <okiddle@yahoo.co.uk> | 2019-05-07 23:24:49 +0200 |
commit | cd6fd2b0a3641774e7854ff8298d1d82643c4b4a (patch) | |
tree | 1b09fbc0dfed078e48c945352c6635a4a6bcbb04 /Src/Zle/compcore.c | |
parent | 5200637bda09e34da934e18f3c30f4b124d8d597 (diff) | |
download | zsh-cd6fd2b0a3641774e7854ff8298d1d82643c4b4a.tar.gz zsh-cd6fd2b0a3641774e7854ff8298d1d82643c4b4a.tar.xz zsh-cd6fd2b0a3641774e7854ff8298d1d82643c4b4a.zip |
44274: allow finer control of completion match soring with compadd's -o option
Diffstat (limited to 'Src/Zle/compcore.c')
-rw-r--r-- | Src/Zle/compcore.c | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 0a454ad5f..9b8545360 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -2080,6 +2080,9 @@ addmatches(Cadata dat, char **argv) /* Select the group in which to store the matches. */ gflags = (((dat->aflags & CAF_NOSORT ) ? CGF_NOSORT : 0) | + ((dat->aflags & CAF_MATSORT) ? CGF_MATSORT : 0) | + ((dat->aflags & CAF_NUMSORT) ? CGF_NUMSORT : 0) | + ((dat->aflags & CAF_REVSORT) ? CGF_REVSORT : 0) | ((dat->aflags & CAF_UNIQALL) ? CGF_UNIQALL : 0) | ((dat->aflags & CAF_UNIQCON) ? CGF_UNIQCON : 0)); if (dat->group) { @@ -3034,8 +3037,9 @@ begcmgroup(char *n, int flags) HEAP_ERROR(p->heap_id); } #endif - if (p->name && - flags == (p->flags & (CGF_NOSORT|CGF_UNIQALL|CGF_UNIQCON)) && + if (p->name && flags == + (p->flags & (CGF_NOSORT|CGF_UNIQALL|CGF_UNIQCON| + CGF_MATSORT|CGF_NUMSORT|CGF_REVSORT)) && !strcmp(n, p->name)) { mgroup = p; @@ -3118,32 +3122,35 @@ addexpl(int always) /* The comparison function for matches (used for sorting). */ +static int matchorder; + /**/ static int matchcmp(Cmatch *a, Cmatch *b) { - if ((*a)->disp && !((*a)->flags & CMF_MORDER)) { - if ((*b)->disp) { - if ((*a)->flags & CMF_DISPLINE) { - if ((*b)->flags & CMF_DISPLINE) - return strcmp((*a)->disp, (*b)->disp); - else - return -1; - } else { - if ((*b)->flags & CMF_DISPLINE) - return 1; - else - return strcmp((*a)->disp, (*b)->disp); - } - } - return -1; + const char *as, *bs; + int cmp = !!(*b)->disp - !!(*a)->disp; + int sortdir = (matchorder & CGF_REVSORT) ? -1 : 1; + + /* if match sorting selected or we have no display strings */ + if ((matchorder & CGF_MATSORT) || (!cmp && !(*a)->disp)) { + as = (*a)->str; + bs = (*b)->str; + } else { + if (cmp) /* matches with display strings come first */ + return cmp; + + cmp = ((*b)->flags & CMF_DISPLINE) - ((*a)->flags & CMF_DISPLINE); + if (cmp) /* sort one-per-line display strings first */ + return cmp; + + as = (*a)->disp; + bs = (*b)->disp; } - if ((*b)->disp && !((*b)->flags & CMF_MORDER)) - return 1; - return zstrcmp((*a)->str, (*b)->str, (SORTIT_IGNORING_BACKSLASHES| - (isset(NUMERICGLOBSORT) ? - SORTIT_NUMERICALLY : 0))); + return sortdir * zstrcmp(as, bs, SORTIT_IGNORING_BACKSLASHES| + ((isset(NUMERICGLOBSORT) || + matchorder & CGF_NUMSORT) ? SORTIT_NUMERICALLY : 0)); } /* This tests whether two matches are equal (would produce the same @@ -3205,6 +3212,7 @@ makearray(LinkList l, int type, int flags, int *np, int *nlp, int *llp) } else { if (!(flags & CGF_NOSORT)) { /* Now sort the array (it contains matches). */ + matchorder = flags; qsort((void *) rp, n, sizeof(Cmatch), (int (*) _((const void *, const void *)))matchcmp); |