2 * compresult.c - the complete module, completion result handling
4 * This file is part of zsh, the Z shell.
6 * Copyright (c) 1999 Sven Wischnowsky
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
15 * In no event shall Sven Wischnowsky or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Sven Wischnowsky and the Zsh Development Group have been advised of
19 * the possibility of such damage.
21 * Sven Wischnowsky and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose. The software
24 * provided hereunder is on an "as is" basis, and Sven Wischnowsky and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
30 #include "complete.mdh"
31 #include "compresult.pro"
33 /* This counts how often the list of completions was invalidated.
34 * Can be used to detect if we have a new list. */
37 mod_export
int invcount
;
39 #define inststr(X) inststrlen((X),1,-1)
41 /* This cuts the cline list before the stuff that isn't worth
42 * inserting in the line. */
48 Cline q
, p
, e
= NULL
, maxp
= NULL
;
49 int sum
= 0, max
= 0, tmp
, ls
= 0, miss
= 0;
51 /* If no match was added with matching, we don't really know
52 * which parts of the unambiguous string are worth keeping,
53 * so for now we keep everything (in the hope that this
54 * produces a string containing at least everything that was
55 * originally on the line). */
61 e
= l
= cp_cline(l
, 0);
63 /* First, search the last struct for which we have something on
64 * the line. Anything before that is kept. */
66 for (q
= NULL
, p
= l
; p
; p
= p
->next
) {
67 if (p
->orig
|| p
->olen
|| !(p
->flags
& CLF_NEW
))
69 if (!p
->suffix
&& (p
->wlen
|| p
->llen
|| p
->prefix
))
72 if (!e
&& q
&& !q
->orig
&& !q
->olen
&& (q
->flags
& CLF_MISS
) &&
73 (!(q
->flags
& CLF_MATCHED
) || (!q
->prefix
&& !q
->suffix
)) &&
74 (q
->word
? q
->wlen
: q
->llen
) < 3) {
75 q
->word
= q
->line
= NULL
;
76 q
->wlen
= q
->llen
= 0;
78 /* Then keep all structs without missing characters. */
80 while (e
&& !(e
->flags
& CLF_MISS
))
84 /* Then we see if there is another struct with missing
85 * characters. If not, we keep the whole list. */
87 for (p
= e
->next
; p
&& !(p
->flags
& CLF_MISS
); p
= p
->next
);
90 for (p
= e
; p
; p
= p
->next
) {
91 if (!(p
->flags
& CLF_MISS
))
94 tmp
= cline_sublen(p
);
95 if (tmp
> 2 && tmp
> ((p
->max
+ p
->min
) >> 1))
96 sum
+= tmp
- (p
->max
- tmp
);
97 else if (tmp
< p
->min
)
98 sum
-= (((p
->max
+ p
->min
) >> 1) - tmp
) << (tmp
< 2);
113 for (p
= e
; p
; p
= p
->next
)
116 if (len
> ((minmlen
<< 1) / 3))
119 e
->line
= e
->word
= NULL
;
120 e
->llen
= e
->wlen
= e
->olen
= 0;
126 /* Sanity check. If there are no parts with missing characters but
127 * parts with joined substrings, remove those. */
129 for (p
= l
, e
= 0, tmp
= 0; p
; p
= p
->next
) {
130 if (p
->flags
& (CLF_MISS
|CLF_DIFF
))
132 for (q
= p
->prefix
; q
; q
= q
->next
)
133 if (q
->flags
& CLF_JOIN
) {
138 for (q
= p
->suffix
; q
; q
= q
->next
)
139 if (q
->flags
& CLF_JOIN
) {
145 if (e
&& (!miss
|| cline_sublen(e
) == e
->min
)) {
146 for (p
= (tmp
? e
->suffix
: e
->prefix
);
147 p
&& p
->next
&& !(p
->next
->flags
& CLF_JOIN
); p
= p
->next
);
157 /* This builds the unambiguous string. If ins is one, it is immediately
158 * inserted into the line. Otherwise csp is used to return the relative
159 * cursor position in the string returned and posl contains all
160 * positions with missing or ambiguous characters. If ins is two, csp
161 * and posl contain real command line positions (including braces). */
165 cline_str(Cline l
, int ins
, int *csp
, LinkList posl
)
168 int ocs
= zlemetacs
, ncs
, pcs
, scs
, opos
= -1, npos
;
169 int pm
, pmax
, pmm
, pma
, sm
, smax
, smm
, sma
, d
, dm
, mid
;
170 int i
, j
, li
= 0, cbr
, padd
= (ins
? wb
- ocs
: -ocs
);
177 pmm
= pma
= smm
= sma
= dm
= pcs
= scs
= 0;
178 pm
= pmax
= sm
= smax
= d
= mid
= cbr
= -1;
181 /* Get the information about the brace beginning and end we have
188 for (bp
= brbeg
; bp
; bp
= bp
->next
) {
189 bp
->curpos
= (hasunqu
? bp
->pos
: bp
->qpos
);
190 olen
-= strlen(bp
->str
);
193 if ((brs
= lastbrend
)) {
194 for (bp
= brend
; bp
; bp
= bp
->next
)
195 olen
-= strlen(bp
->str
);
197 for (bp
= brend
; bp
; bp
= bp
->next
)
198 bp
->curpos
= olen
- (hasunqu
? bp
->pos
: bp
->qpos
);
200 while (brp
&& !brp
->curpos
) {
201 inststrlen(brp
->str
, 1, -1);
204 while (brs
&& !brs
->curpos
) {
207 inststrlen(brs
->str
, 1, -1);
211 /* Walk through the top-level cline list. */
213 /* Insert the original string if no prefix. */
214 if (l
->olen
&& !(l
->flags
& CLF_SUF
) && !l
->prefix
) {
215 pcs
= zlemetacs
+ l
->olen
;
216 inststrlen(l
->orig
, 1, l
->olen
);
218 /* Otherwise insert the prefix. */
219 for (s
= l
->prefix
; s
; s
= s
->next
) {
220 pcs
= zlemetacs
+ s
->llen
;
221 if (s
->flags
& CLF_LINE
)
222 inststrlen(s
->line
, 1, s
->llen
);
224 inststrlen(s
->word
, 1, s
->wlen
);
227 if ((s
->flags
& CLF_DIFF
) && (!dm
|| (s
->flags
& CLF_MATCHED
))) {
228 d
= zlemetacs
; dm
= s
->flags
& CLF_MATCHED
;
229 if (posl
&& (npos
= zlemetacs
+ padd
) != opos
) {
231 addlinknode(posl
, (void *) ((long) npos
));
240 while (brp
&& li
>= brp
->curpos
) {
242 bl
= strlen(brp
->str
);
243 zlemetacs
= pcs
- (li
- brp
->curpos
);
244 inststrlen(brp
->str
, 1, bl
);
245 zlemetacs
= ocs
+ bl
;
251 /* Remember the position if this is the first prefix with
252 * missing characters. */
253 if ((l
->flags
& CLF_MISS
) && !(l
->flags
& CLF_SUF
)) {
254 if (posl
&& (npos
= zlemetacs
+ padd
) != opos
) {
256 addlinknode(posl
, (void *) ((long) npos
));
258 if (((pmax
<= (l
->max
- l
->min
) || (pma
&& l
->max
!= l
->min
)) &&
259 (!pmm
|| (l
->flags
& CLF_MATCHED
))) ||
260 ((l
->flags
& CLF_MATCHED
) && !pmm
)) {
261 pm
= zlemetacs
; pmax
= l
->max
- l
->min
; pmm
= l
->flags
& CLF_MATCHED
;
262 pma
= ((l
->prefix
|| l
->suffix
) && l
->min
== cline_sublen(l
));
268 while (brs
&& li
>= brs
->curpos
) {
270 bl
= strlen(brs
->str
);
271 zlemetacs
= scs
- (li
- brs
->curpos
);
274 inststrlen(brs
->str
, 1, bl
);
275 zlemetacs
= ocs
+ bl
;
281 /* Insert the anchor. */
282 if (l
->flags
& CLF_LINE
)
283 inststrlen(l
->line
, 1, l
->llen
);
285 inststrlen(l
->word
, 1, l
->wlen
);
292 while (brp
&& li
>= brp
->curpos
) {
294 bl
= strlen(brp
->str
);
295 zlemetacs
= pcs
+ l
->llen
- (li
- brp
->curpos
);
296 inststrlen(brp
->str
, 1, bl
);
297 zlemetacs
= ocs
+ bl
;
303 /* Remember the cursor position for suffixes and mids. */
304 if (l
->flags
& CLF_MISS
) {
305 if (l
->flags
& CLF_MID
)
307 else if (l
->flags
& CLF_SUF
) {
308 if (posl
&& (npos
= zlemetacs
+ padd
) != opos
) {
310 addlinknode(posl
, (void *) ((long) npos
));
312 if (((smax
<= (l
->min
- l
->max
) || (sma
&& l
->max
!= l
->min
)) &&
313 (!smm
|| (l
->flags
& CLF_MATCHED
))) ||
314 ((l
->flags
& CLF_MATCHED
) && !smm
)) {
315 sm
= zlemetacs
; smax
= l
->min
- l
->max
; smm
= l
->flags
& CLF_MATCHED
;
316 sma
= ((l
->prefix
|| l
->suffix
) && l
->min
== cline_sublen(l
));
323 while (brs
&& li
>= brs
->curpos
) {
325 bl
= strlen(brs
->str
);
326 zlemetacs
= scs
- (li
- brs
->curpos
);
329 inststrlen(brs
->str
, 1, bl
);
330 zlemetacs
= ocs
+ bl
;
335 /* And now insert the suffix or the original string. */
336 if (l
->olen
&& (l
->flags
& CLF_SUF
) && !l
->suffix
) {
338 inststrlen(l
->orig
, 1, l
->olen
);
344 while (brp
&& li
>= brp
->curpos
) {
346 bl
= strlen(brp
->str
);
347 zlemetacs
= pcs
+ l
->olen
- (li
- brp
->curpos
);
348 inststrlen(brp
->str
, 1, bl
);
349 zlemetacs
= ocs
+ bl
;
353 while (brs
&& li
>= brs
->curpos
) {
355 bl
= strlen(brs
->str
);
356 zlemetacs
= pcs
+ l
->olen
- (li
- brs
->curpos
);
359 inststrlen(brs
->str
, 1, bl
);
360 zlemetacs
= ocs
+ bl
;
368 for (j
= -1, i
= 0, s
= l
->suffix
; s
; s
= s
->next
) {
369 if (j
< 0 && (s
->flags
& CLF_DIFF
))
372 if (s
->flags
& CLF_LINE
) {
373 inststrlen(s
->line
, 0, s
->llen
);
374 i
+= s
->llen
; scs
= zlemetacs
+ s
->llen
;
376 inststrlen(s
->word
, 0, s
->wlen
);
377 i
+= s
->wlen
; scs
= zlemetacs
+ s
->wlen
;
384 while (brp
&& li
>= brp
->curpos
) {
386 bl
= strlen(brp
->str
);
387 zlemetacs
= pcs
+ (li
- brp
->curpos
);
388 inststrlen(brp
->str
, 1, bl
);
389 zlemetacs
= ocs
+ bl
;
394 while (brs
&& li
>= brs
->curpos
) {
396 bl
= strlen(brs
->str
);
397 zlemetacs
= scs
- (li
- brs
->curpos
);
400 inststrlen(brs
->str
, 1, bl
);
401 zlemetacs
= ocs
+ bl
;
408 if (j
>= 0 && (!dm
|| (js
->flags
& CLF_MATCHED
))) {
409 d
= zlemetacs
- j
; dm
= js
->flags
& CLF_MATCHED
;
410 if (posl
&& (npos
= zlemetacs
- j
+ padd
) != opos
) {
412 addlinknode(posl
, (void *) ((long) npos
));
418 if (posl
&& (npos
= zlemetacs
+ padd
) != opos
)
420 /* This could be used to put an extra colon before the end-of-word
421 * position if there is nothing missing. */
422 addlinknode(posl
, (void *) ((long) -npos
));
424 addlinknode(posl
, (void *) ((long) npos
));
429 for (; brp
; brp
= brp
->next
)
430 inststrlen(brp
->str
, 1, -1);
431 for (; brs
; brs
= brs
->prev
) {
434 inststrlen(brs
->str
, 1, -1);
437 mid
+= zlemetacs
- ocs
;
439 pm
+= zlemetacs
- ocs
;
441 sm
+= zlemetacs
- ocs
;
443 d
+= zlemetacs
- ocs
;
449 for (node
= firstnode(posl
); node
; incnode(node
)) {
450 p
= (long) getdata(node
);
452 setdata(node
, (void *) (p
+ zlemetacs
- ocs
));
456 /* This calculates the new cursor position. If we had a mid cline
457 * with missing characters, we take this, otherwise if we have a
458 * prefix with missing characters, we take that, the same for a
459 * suffix, and finally a place where the matches differ. */
460 ncs
= (mid
>= 0 ? mid
:
462 (pm
>= 0 ? pm
: (sm
>= 0 ? sm
: (d
>= 0 ? d
: zlemetacs
)))));
465 /* We always inserted the string in the line. If that was not
466 * requested, we copy it and remove from the line. */
467 char *r
= zalloc((i
= zlemetacs
- ocs
) + 1);
469 memcpy(r
, zlemetaline
+ ocs
, i
);
485 /* Small utility function turning a list of positions into a colon
486 * separated string. */
489 build_pos_string(LinkList list
)
496 for (node
= firstnode(list
), l
= 0; node
; incnode(node
)) {
497 p
= (long) getdata(node
);
499 /* This could be used to put an extra colon before the end-of-word
500 * position if there is nothing missing. */
502 sprintf(buf
, ":%ld", -p
);
505 sprintf(buf
, "%ld", p
);
506 setdata(node
, dupstring(buf
));
507 l
+= 1 + strlen(buf
);
509 s
= (char *) zalloc(l
* sizeof(char));
511 for (node
= firstnode(list
); node
;) {
512 strcat(s
, (char *) getdata(node
));
520 /* This is a utility function using the function above to allow access
521 * to the unambiguous string and cursor position via compstate. */
525 unambig_data(int *cp
, char **pp
, char **ip
)
527 static char *scache
= NULL
, *pcache
= NULL
, *icache
= NULL
;
531 if (mnum
!= unambig_mnum
) {
532 LinkList list
= newlinklist();
535 scache
= cline_str((ainfo
->count
? ainfo
->line
: fainfo
->line
),
541 pcache
= build_pos_string(list
);
545 list
= newlinklist();
546 zsfree(cline_str((ainfo
->count
? ainfo
->line
: fainfo
->line
),
551 icache
= build_pos_string(list
);
553 } else if (mnum
!= unambig_mnum
|| !ainfo
|| !scache
) {
572 /* Insert the given match. This returns the number of bytes inserted.
573 * scs is used to return the position where a automatically created suffix
574 * has to be inserted. */
578 instmatch(Cmatch m
, int *scs
)
580 int l
, r
= 0, ocs
, a
= zlemetacs
, brb
= 0, bradd
, *brpos
;
587 lastprebr
= lastpostbr
= NULL
;
589 /* Ignored prefix. */
591 char *p
= m
->ipre
+ (menuacc
? m
->qipl
: 0);
593 inststrlen(p
, 1, (l
= strlen(p
)));
598 inststrlen(m
->pre
, 1, (l
= strlen(m
->pre
)));
603 inststrlen(m
->ppre
, 1, (l
= strlen(m
->ppre
)));
606 /* The string itself. */
607 inststrlen(m
->str
, 1, (l
= strlen(m
->str
)));
610 /* Re-insert the brace beginnings, if any. */
615 for (bp
= brbeg
, brpos
= m
->brpl
,
616 bradd
= (m
->pre
? strlen(m
->pre
) : 0);
617 bp
; bp
= bp
->next
, brpos
++) {
618 zlemetacs
= a
+ *brpos
+ bradd
;
623 inststrlen(bp
->str
, 1, l
);
627 lastprebr
= (char *) zalloc(pcs
- a
+ 1);
628 memcpy(lastprebr
, zlemetaline
+ a
, pcs
- a
);
629 lastprebr
[pcs
- a
] = '\0';
634 inststrlen(m
->psuf
, 1, (l
= strlen(m
->psuf
)));
637 /* Re-insert the brace end. */
640 for (bp
= brend
, brpos
= m
->brsl
, bradd
= 0; bp
; bp
= bp
->next
, brpos
++) {
641 zlemetacs
= a
- *brpos
;
642 ocs
= brscs
= zlemetacs
;
645 inststrlen(bp
->str
, 1, l
);
649 zlemetacs
= a
+ bradd
;
660 inststrlen(m
->suf
, 1, (l
= strlen(m
->suf
)));
665 inststrlen(m
->isuf
, 1, (l
= strlen(m
->isuf
)));
669 lastpostbr
= (char *) zalloc(zlemetacs
- brb
+ 1);
670 memcpy(lastpostbr
, zlemetaline
+ brb
, zlemetacs
- brb
);
671 lastpostbr
[zlemetacs
- brb
] = '\0';
679 /* Check if the match has the given prefix/suffix before/after the
684 hasbrpsfx(Cmatch m
, char *pre
, char *suf
)
688 if (m
->flags
& CMF_ALL
)
691 /* May not be metafied if calculating whether to show a list. */
692 if (zlemetaline
== NULL
) {
699 char *op
= lastprebr
, *os
= lastpostbr
;
700 VARARR(char, oline
, zlemetall
);
701 int oll
= zlemetall
, ocs
= zlemetacs
, ole
= lastend
, opcs
= brpcs
, oscs
= brscs
, ret
;
703 memcpy(oline
, zlemetaline
, zlemetall
);
705 lastprebr
= lastpostbr
= NULL
;
710 foredel(zlemetall
, CUT_RAW
);
712 memcpy(zlemetaline
, oline
, oll
);
718 ret
= (((!pre
&& !lastprebr
) ||
719 (pre
&& lastprebr
&& !strcmp(pre
, lastprebr
))) &&
720 ((!suf
&& !lastpostbr
) ||
721 (suf
&& lastpostbr
&& !strcmp(suf
, lastpostbr
))));
734 /* Handle the case were we found more than one match. */
742 menucmp
= menuacc
= 0;
744 /* If we have to insert the first match, call do_single(). This is *
745 * how REC_EXACT takes effect. We effectively turn the ambiguous *
746 * completion into an unambiguous one. */
747 if (ainfo
&& ainfo
->exact
== 1 && !(fromcomp
& FC_LINE
)) {
749 do_single(ainfo
->exactm
);
753 /* Setting lastambig here means that the completion is ambiguous and *
754 * AUTO_MENU might want to start a menu completion next time round, *
755 * but this might be overridden below if we can complete an *
756 * unambiguous prefix. */
759 if (iforcemenu
!= -1 &&
760 (usemenu
|| (haspattern
&& comppatinsert
&&
761 !strcmp(comppatinsert
, "menu")))) {
762 /* We are in a position to start using menu completion due to one *
763 * of the menu completion options, or due to the menu-complete- *
764 * word command, or due to using GLOB_COMPLETE which does menu- *
765 * style completion regardless of the setting of the normal menu *
766 * completion options. */
769 int atend
= (zlemetacs
== we
), la
, eq
, tcs
;
770 VARARR(char, old
, we
- wb
);
777 /* First remove the old string from the line. */
780 memcpy(old
, zlemetaline
+ wb
, we
- wb
);
781 foredel(we
- wb
, CUT_RAW
);
783 /* Now get the unambiguous string and insert it into the line. */
784 cline_str(ainfo
->line
, 1, NULL
, NULL
);
786 /* Sometimes the different match specs used may result in a cline
787 * that gives an empty string. If that happened, we re-insert the
788 * old string. Unless there were matches added with -U, that is. */
790 if (lastend
< we
&& !lenchanged
&& !hasunmatched
) {
792 foredel(lastend
- wb
, CUT_RAW
);
793 inststrlen(old
, 0, we
- wb
);
800 for (eq
= eparq
; eq
; eq
--)
801 inststrlen("\"", 0, 1);
804 /* la is non-zero if listambiguous may be used. Copying and
805 * comparing the line looks like BFI but it is the easiest
806 * solution. Really. */
807 la
= (zlemetall
!= origll
|| strncmp(origline
, zlemetaline
, zlemetall
));
809 /* If REC_EXACT and AUTO_MENU are set and what we inserted is an *
810 * exact match, we want menu completion the next time round *
811 * so we set fromcomp, to ensure that the word on the line is not *
812 * taken as an exact match. Also we remember if we just moved the *
813 * cursor into the word. */
814 fromcomp
= ((isset(AUTOMENU
) ? FC_LINE
: 0) |
815 ((atend
&& zlemetacs
!= lastend
) ? FC_INWORD
: 0));
817 /* Probably move the cursor to the end. */
821 /* If the LIST_AMBIGUOUS option (meaning roughly `show a list only *
822 * if the completion is completely ambiguous') is set, and some *
823 * prefix was inserted, return now, bypassing the list-displaying *
824 * code. On the way, invalidate the list and note that we don't *
825 * want to enter an AUTO_MENU imediately. */
827 (!uselist
&& isset(BASHAUTOLIST
) && isset(LISTAMBIGUOUS
))) &&
828 la
&& iforcemenu
!= -1) {
840 /* At this point, we might want a completion listing. Show the listing *
841 * if it is needed. */
842 if (isset(LISTBEEP
) && !oldlist
)
845 if (uselist
&& (usemenu
!= 2 || (!listshown
&& !oldlist
)) &&
846 ((!showinglist
&& (!listshown
|| !oldlist
)) ||
847 (usemenu
== 3 && !oldlist
)) &&
848 (smatches
>= 2 || forcelist
))
854 /* This is a stat that ignores backslashes in the filename. The `ls' *
855 * parameter says if we have to do lstat() or stat(). I think this *
856 * should instead be done by use of a general function to expand a *
857 * filename (stripping backslashes), combined with the actual *
859 * Make sure input is unmetafied */
863 ztat(char *nam
, struct stat
*buf
, int ls
)
871 if ((ret
= ls
? lstat(nam
, buf
) : stat(nam
, buf
))) {
874 for (p
= q
= nam
; *q
; q
++)
875 if (*q
== '\\' && q
[1])
881 ret
= ls
? lstat(nam
, buf
) : stat(nam
, buf
);
887 /* Insert all matches in the command line. */
891 do_allmatches(UNUSED(int end
))
893 int first
= 1, nm
= nmatches
- 1, omc
= menucmp
, oma
= menuacc
, e
;
896 char *p
= (brbeg
? ztrdup(lastbrbeg
->str
) : NULL
);
898 memcpy(&mi
, &minfo
, sizeof(struct menuinfo
));
902 for (minfo
.group
= amatches
;
903 minfo
.group
&& !(minfo
.group
)->mcount
;
904 minfo
.group
= (minfo
.group
)->next
);
906 mc
= (minfo
.group
)->matches
;
909 if (!((*mc
)->flags
& CMF_ALL
)) {
921 if (!*++(minfo
.cur
)) {
923 if (!(minfo
.group
= (minfo
.group
)->next
))
925 } while (!(minfo
.group
)->mcount
);
928 minfo
.cur
= minfo
.group
->matches
;
936 memcpy(&minfo
, &mi
, sizeof(struct menuinfo
));
938 minfo
.len
= e
- minfo
.pos
;
941 zsfree(lastbrbeg
->str
);
946 /* Insert a single match in the command line. */
954 int partest
= (m
->ripre
|| ((m
->flags
& CMF_ISPAR
) && parpre
));
955 char *str
= m
->orig
, *ppre
= m
->ppre
, *psuf
= m
->psuf
, *prpre
= m
->prpre
;
957 if (!prpre
) prpre
= "";
958 if (!ppre
) ppre
= "";
959 if (!psuf
) psuf
= "";
964 /* We are currently not in a menu-completion, *
965 * so set the position variables. */
967 minfo
.we
= (movetoend
>= 2 || (movetoend
== 1 && !menucmp
) ||
968 (!movetoend
&& zlemetacs
== we
));
971 /* If we are already in a menu-completion or if we have done a *
972 * glob completion, we have to delete some of the stuff on the *
975 l
= minfo
.len
+ minfo
.insc
;
980 zlemetacs
= minfo
.pos
;
983 if (m
->flags
& CMF_ALL
) {
988 /* And then we insert the new string. */
989 minfo
.len
= instmatch(m
, &scs
);
990 minfo
.end
= zlemetacs
;
991 zlemetacs
= minfo
.pos
+ minfo
.len
;
996 * This strlen(0 got converted to a ztrlen(), but I don't
997 * think that's correct since it's dealing with raw bytes,
1000 minfo
.insc
= strlen(m
->suf
);
1001 minfo
.len
-= minfo
.insc
;
1003 minfo
.end
+= minfo
.insc
;
1004 if (m
->flags
& CMF_REMOVE
) {
1006 * Here we need the number of characters, not
1007 * bytes in the string.
1011 stringaszleline(m
->suf
, 0, &len
, NULL
, NULL
);
1012 makesuffixstr(m
->remf
, m
->rems
, len
);
1014 addsuffix(SUFTYP_POSSTR
, wsuf
, 1, 1);
1019 /* There is no user-specified suffix, *
1020 * so generate one automagically. */
1022 if (partest
&& (m
->flags
& CMF_PARBR
)) {
1026 /* Completing a parameter in braces. Add a removable `}' suffix. */
1028 for (pq
= parq
; pq
; pq
--)
1029 inststrlen("\"", 1, 1);
1031 inststrlen("}", 1, 1);
1034 minfo
.end
+= minfo
.insc
;
1035 if (m
->flags
& CMF_PARNEST
)
1038 if (((m
->flags
& CMF_FILE
) || (partest
&& isset(AUTOPARAMSLASH
))) &&
1039 zlemetacs
> 0 && zlemetaline
[zlemetacs
- 1] != '/') {
1040 /* If we have a filename or we completed a parameter name *
1041 * and AUTO_PARAM_SLASH is set, lets see if it is a directory. *
1042 * If it is, we append a slash. */
1047 if (m
->ipre
&& m
->ipre
[0] == '~' && !m
->ipre
[1])
1050 /* Build the path name. */
1051 if (partest
&& !*psuf
&& !(m
->flags
& CMF_PARNEST
)) {
1052 int ne
= noerrs
, tryit
= 1;
1054 p
= (char *) zhalloc(strlen((m
->flags
& CMF_ISPAR
) ?
1055 parpre
: m
->ripre
) +
1057 sprintf(p
, "%s%s%c",
1058 ((m
->flags
& CMF_ISPAR
) ? parpre
: m
->ripre
), str
,
1059 ((m
->flags
& CMF_PARBR
) ? '}' : '\0'));
1067 n
= dupstring(p
+ 2);
1068 e
= n
+ strlen(n
) - 1;
1075 if ((pm
= (Param
) paramtab
->getnode(paramtab
, n
)) &&
1076 PM_TYPE(pm
->node
.flags
) != PM_SCALAR
)
1087 p
= (char *) zhalloc(strlen(prpre
) + strlen(str
) +
1089 sprintf(p
, "%s%s%s", ((prpre
&& *prpre
) ?
1090 prpre
: "./"), str
, psuf
);
1092 /* And do the stat. */
1093 t
= (!(sr
= ztat(p
, &buf
, 0)) && S_ISDIR(buf
.st_mode
));
1096 /* It is a directory, so add the slash. */
1098 inststrlen("/", 1, 1);
1102 if (!menucmp
|| minfo
.we
) {
1103 if (m
->remf
|| m
->rems
)
1104 makesuffixstr(m
->remf
, m
->rems
, 1);
1105 else if (isset(AUTOREMOVESLASH
)) {
1107 addsuffix(SUFTYP_POSSTR
, ZWS("/"), 1, 1);
1113 zlemetacs
= minfo
.pos
+ minfo
.len
- m
->qisl
;
1115 /* If completing in a brace expansion... */
1119 /* If a suffix was added, and is removable, let *
1120 * `,' and `}' remove it. */
1121 if (isset(AUTOPARAMKEYS
))
1122 addsuffix(SUFTYP_POSSTR
, ZWS(",}"), 2, suffixnoinslen
);
1123 } else if (!menucmp
) {
1125 /* Otherwise, add a `,' suffix, and let `}' remove it. */
1128 inststrlen(",", 1, 1);
1131 if ((!menucmp
|| minfo
.we
) && isset(AUTOPARAMKEYS
))
1132 addsuffix(SUFTYP_POSSTR
, ZWS(",}"), 2, 1);
1134 } else if (!havesuff
&& (!(m
->flags
& CMF_FILE
) || !sr
)) {
1135 /* If we didn't add a suffix, add a space, unless we are *
1136 * doing menu completion or we are completing files and *
1137 * the string doesn't name an existing file. */
1138 if (m
->autoq
&& (!m
->isuf
|| !strpfx(m
->autoq
, m
->isuf
))) {
1139 int al
= strlen(m
->autoq
);
1140 inststrlen(m
->autoq
, 1, al
);
1143 if (!menucmp
&& !(m
->flags
& CMF_NOSPACE
) &&
1144 (usemenu
!= 3 || insspace
)) {
1145 inststrlen(" ", 1, 1);
1148 makesuffixstr(m
->remf
, m
->rems
, 1);
1151 if (minfo
.we
&& partest
&& isset(AUTOPARAMKEYS
) && minfo
.insc
- parq
> 0) {
1152 /* the suffix code needs numbers of characters, not octets */
1154 char *tmpstr
= dupstrpfx(zlemetaline
+ parq
, minfo
.insc
- parq
);
1155 ZLE_STRING_T subline
= stringaszleline(tmpstr
, 0, &outlen
, NULL
, NULL
);
1156 makeparamsuffix(((m
->flags
& CMF_PARBR
) ? 1 : 0), outlen
);
1160 if ((menucmp
&& !minfo
.we
) || !movetoend
) {
1161 zlemetacs
= minfo
.end
;
1162 if (zlemetacs
+ m
->qisl
== lastend
)
1163 zlemetacs
+= minfo
.insc
;
1166 Cmatch
*om
= minfo
.cur
;
1169 dat
.matches
= amatches
;
1175 runhookdef(INSERTMATCHHOOK
, (void *) &dat
);
1180 /* Do completion, given that we are in the middle of a menu completion. We *
1181 * don't need to generate a list of matches, because that's already been *
1182 * done by previous commands. We will either list the completions, or *
1183 * insert the next completion. */
1191 /* Just list the matches if the list was requested. */
1192 if (lst
== COMP_LIST_COMPLETE
) {
1197 /* Already metafied when called from domenuselect already */
1198 if (zlemetaline
== NULL
) {
1204 /* Otherwise go to the next match in the array... */
1206 if (!*++(minfo
.cur
)) {
1208 if (!(minfo
.group
= (minfo
.group
)->next
))
1209 minfo
.group
= amatches
;
1210 } while (!(minfo
.group
)->mcount
);
1211 minfo
.cur
= minfo
.group
->matches
;
1213 } while ((menuacc
&&
1214 !hasbrpsfx(*(minfo
.cur
), minfo
.prebr
, minfo
.postbr
)) ||
1215 ((*minfo
.cur
)->flags
& CMF_DUMMY
) ||
1216 (((*minfo
.cur
)->flags
& (CMF_NOLIST
| CMF_MULT
)) &&
1217 (!(*minfo
.cur
)->str
|| !*(*minfo
.cur
)->str
)));
1218 /* ... and insert it into the command line. */
1219 do_single(*minfo
.cur
);
1227 reverse_menu(UNUSED(Hookdef dummy
), UNUSED(void *dummy2
))
1231 if (minfo
.cur
== NULL
)
1235 if (minfo
.cur
== (minfo
.group
)->matches
) {
1237 if (!(minfo
.group
= (minfo
.group
)->prev
))
1238 minfo
.group
= lmatches
;
1239 } while (!(minfo
.group
)->mcount
);
1240 minfo
.cur
= (minfo
.group
)->matches
+ (minfo
.group
)->mcount
- 1;
1243 } while ((menuacc
&&
1244 !hasbrpsfx(*(minfo
.cur
), minfo
.prebr
, minfo
.postbr
)) ||
1245 ((*minfo
.cur
)->flags
& CMF_DUMMY
) ||
1246 (((*minfo
.cur
)->flags
& (CMF_NOLIST
| CMF_MULT
)) &&
1247 (!(*minfo
.cur
)->str
|| !*(*minfo
.cur
)->str
)));
1248 /* May already be metafied if called from within a selection */
1249 if (zlemetaline
== NULL
) {
1255 do_single(*(minfo
.cur
));
1262 /* Accepts the current completion and starts a new arg, *
1263 * with the next completions. This gives you a way to *
1264 * accept several selections from the list of matches. */
1270 /* give up trying to work out what state it should be in */
1272 if (zlemetaline
!= NULL
) {
1280 zsfree(minfo
.prebr
);
1281 minfo
.prebr
= ztrdup(lastprebr
);
1282 zsfree(minfo
.postbr
);
1283 minfo
.postbr
= ztrdup(lastpostbr
);
1285 if (listshown
&& (lastprebr
|| lastpostbr
)) {
1289 for (g
= amatches
, m
= NULL
; g
&& (!m
|| !*m
); g
= g
->next
)
1290 for (m
= g
->matches
; *m
; m
++)
1291 if (!hasbrpsfx(*m
, minfo
.prebr
, minfo
.postbr
)) {
1302 iremovesuffix(',', 1);
1304 l
= (brscs
>= 0 ? brscs
: zlemetacs
) - brpcs
;
1306 zsfree(lastbrbeg
->str
);
1307 lastbrbeg
->str
= (char *) zalloc(l
+ 2);
1308 memcpy(lastbrbeg
->str
, zlemetaline
+ brpcs
, l
);
1309 lastbrbeg
->str
[l
] = ',';
1310 lastbrbeg
->str
[l
+ 1] = '\0';
1314 zlemetacs
= minfo
.pos
+ minfo
.len
+ minfo
.insc
;
1315 iremovesuffix(' ', 1);
1317 zlemetacs
= minfo
.pos
+ minfo
.len
+ minfo
.insc
- (*(minfo
.cur
))->qisl
;
1319 foredel(l
- zlemetacs
, CUT_RAW
);
1320 else if (zlemetacs
> zlemetall
)
1321 zlemetacs
= zlemetall
;
1322 inststrlen(" ", 1, 1);
1323 minfo
.insc
= minfo
.len
= 0;
1324 minfo
.pos
= zlemetacs
;
1333 /* This maps the value in v into the range [0,m-1], decrementing v
1334 * if it is non-negative and making negative values count backwards. */
1338 comp_mod(int v
, int m
)
1351 /* This handles the beginning of menu-completion. */
1359 if (iforcemenu
== -1)
1368 if (oldins
&& minfo
.cur
)
1374 /* group-numbers in compstate[insert] */
1376 insgnum
= comp_mod(insgnum
, lastpermgnum
);
1377 for (minfo
.group
= amatches
;
1378 minfo
.group
&& (minfo
.group
)->num
!= insgnum
+ 1;
1379 minfo
.group
= (minfo
.group
)->next
);
1380 if (!minfo
.group
|| !(minfo
.group
)->mcount
) {
1385 insmnum
= comp_mod(insmnum
, (minfo
.group
)->mcount
);
1388 insmnum
= comp_mod(insmnum
, lastpermmnum
);
1389 for (minfo
.group
= amatches
;
1390 minfo
.group
&& (minfo
.group
)->mcount
<= insmnum
;
1391 minfo
.group
= (minfo
.group
)->next
)
1392 insmnum
-= (minfo
.group
)->mcount
;
1399 /* group-numbers in compstate[insert] */
1402 mc
= (minfo
.group
)->matches
+ insmnum
;
1403 if (iforcemenu
!= -1)
1408 /* Return the number of screen lines needed for the list. */
1419 amatches
= pmatches
;
1425 return listdat
.nlines
;
1435 onlyexpl
= (v
? ((strstr(v
, "expl") ? 1 : 0) |
1436 (strstr(v
, "messages") ? 2 : 0)) : 0);
1439 /* This skips over matches that are not to be listed. */
1443 skipnolist(Cmatch
*p
, int showall
)
1445 int mask
= (showall
? 0 : (CMF_NOLIST
| CMF_MULT
)) | CMF_HIDE
;
1447 while (*p
&& (((*p
)->flags
& mask
) ||
1449 ((*p
)->flags
& (CMF_DISPLINE
| CMF_HIDE
)))))
1457 calclist(int showall
)
1459 static int lastinvcount
= -1;
1464 int hidden
= 0, nlist
= 0, nlines
= 0;
1466 VARARR(int, mlens
, nmatches
+ 1);
1468 if (lastinvcount
== invcount
&&
1469 listdat
.valid
&& onlyexpl
== listdat
.onlyexpl
&&
1470 menuacc
== listdat
.menuacc
&& showall
== listdat
.showall
&&
1471 lines
== listdat
.lines
&& columns
== listdat
.columns
)
1473 lastinvcount
= invcount
;
1475 for (g
= amatches
; g
; g
= g
->next
) {
1476 char **pp
= g
->ylist
;
1477 int nl
= 0, l
, glong
= 1, gshort
= columns
, ndisp
= 0, totl
= 0;
1480 g
->flags
|= CGF_PACKED
| CGF_ROWS
;
1482 if (!onlyexpl
&& pp
) {
1484 if (!isset(LISTPACKED
))
1485 g
->flags
&= ~CGF_PACKED
;
1486 if (!isset(LISTROWSFIRST
))
1487 g
->flags
&= ~CGF_ROWS
;
1490 /* We have an ylist, lets see, if it contains newlines. */
1492 while (!nl
&& *pp
) {
1493 if (MB_METASTRWIDTH(*pp
) >= columns
)
1496 nl
= !!strchr(*pp
++, '\n');
1500 /* Yup, there are newlines, count lines. */
1503 g
->flags
|= CGF_LINES
;
1505 while ((sptr
= *pp
)) {
1507 if ((nlptr
= strchr(sptr
, '\n'))) {
1509 nlines
+= 1 + (MB_METASTRWIDTH(sptr
)-1) / columns
;
1513 nlines
+= (MB_METASTRWIDTH(sptr
)-1) / columns
;
1523 l
= MB_METASTRWIDTH(*pp
);
1534 } else if (!onlyexpl
) {
1535 for (p
= g
->matches
; (m
= *p
); p
++) {
1536 if (m
->flags
& CMF_FILE
)
1538 if (menuacc
&& !hasbrpsfx(m
, minfo
.prebr
, minfo
.postbr
)) {
1539 m
->flags
|= CMF_HIDE
;
1542 m
->flags
&= ~CMF_HIDE
;
1544 if (showall
|| !(m
->flags
& (CMF_NOLIST
| CMF_MULT
))) {
1545 if ((m
->flags
& (CMF_NOLIST
| CMF_MULT
)) &&
1546 (!m
->str
|| !*m
->str
)) {
1547 m
->flags
|= CMF_HIDE
;
1551 if (m
->flags
& CMF_DISPLINE
) {
1552 nlines
+= 1 + printfmt(m
->disp
, 0, 0, 0);
1553 g
->flags
|= CGF_HASDL
;
1555 l
= ZMB_nicewidth(m
->disp
);
1565 if (!(m
->flags
& CMF_PACKED
))
1566 g
->flags
&= ~CGF_PACKED
;
1567 if (!(m
->flags
& CMF_ROWS
))
1568 g
->flags
&= ~CGF_ROWS
;
1570 l
= ZMB_nicewidth(m
->str
) + !!m
->modec
;
1579 if (!(m
->flags
& CMF_PACKED
))
1580 g
->flags
&= ~CGF_PACKED
;
1581 if (!(m
->flags
& CMF_ROWS
))
1582 g
->flags
&= ~CGF_ROWS
;
1588 if ((e
= g
->expls
)) {
1590 if (((*e
)->count
|| (*e
)->always
) &&
1592 (onlyexpl
& ((*e
)->always
> 0 ? 2 : 1))))
1593 nlines
+= 1 + printfmt((*e
)->str
,
1594 ((*e
)->always
? -1 : (*e
)->count
),
1599 if (isset(LISTTYPES
) && hasf
)
1600 g
->flags
|= CGF_FILES
;
1601 g
->totl
= totl
+ (ndisp
* CM_SPACE
);
1603 g
->width
= glong
+ CM_SPACE
;
1604 g
->shortest
= gshort
+ CM_SPACE
;
1605 if ((g
->cols
= columns
/ g
->width
) > g
->dcount
)
1606 g
->cols
= g
->dcount
;
1608 i
= g
->cols
* g
->width
- CM_SPACE
;
1615 int *ws
, tlines
, tcols
, width
, glines
;
1617 for (g
= amatches
; g
; g
= g
->next
) {
1620 zfree(g
->widths
, 0);
1623 if ((pp
= g
->ylist
)) {
1624 if (!(g
->flags
& CGF_LINES
)) {
1626 glines
+= (arrlen(pp
) + g
->cols
- 1) / g
->cols
;
1628 g
->width
+= ((max
- (g
->width
* g
->cols
-
1636 glines
+= 1 + (MB_METASTRWIDTH(*pp
++) / columns
);
1641 glines
+= (g
->dcount
+ g
->cols
- 1) / g
->cols
;
1643 g
->width
+= ((max
- (g
->width
* g
->cols
- CM_SPACE
)) /
1645 } else if (!(g
->flags
& CGF_LINES
)) {
1649 for (p
= g
->matches
; (m
= *p
); p
++)
1650 if (!(m
->flags
& CMF_HIDE
)) {
1652 if (!(m
->flags
& CMF_DISPLINE
))
1653 glines
+= 1 + ((mlens
[m
->gnum
] - 1) / columns
);
1654 } else if (showall
||
1655 !(m
->flags
& (CMF_NOLIST
| CMF_MULT
)))
1656 glines
+= 1 + (((mlens
[m
->gnum
]) - 1) / columns
);
1663 for (g
= amatches
; g
; g
= g
->next
) {
1664 if (!(g
->flags
& CGF_PACKED
))
1667 ws
= g
->widths
= (int *) zalloc(columns
* sizeof(int));
1668 memset(ws
, 0, columns
* sizeof(int));
1673 if ((pp
= g
->ylist
)) {
1674 if (!(g
->flags
& CGF_LINES
)) {
1675 int yl
= arrlen(pp
), i
;
1676 VARARR(int, ylens
, yl
);
1678 for (i
= 0; *pp
; i
++, pp
++)
1679 ylens
[i
] = MB_METASTRWIDTH(*pp
) + CM_SPACE
;
1681 if (g
->flags
& CGF_ROWS
) {
1684 for (tcols
= columns
/ (g
->shortest
+ CM_SPACE
);
1688 memset(ws
, 0, tcols
* sizeof(int));
1690 for (width
= nth
= tcol
= 0, tlines
= 1;
1691 width
< columns
&& nth
< g
->dcount
;
1696 if (tcol
== tcols
) {
1702 if (len
> ws
[tcol
]) {
1703 width
+= len
- ws
[tcol
];
1707 if (width
< columns
)
1711 int nth
, tcol
, tline
, len
;
1713 for (tcols
= columns
/ (g
->shortest
+ CM_SPACE
);
1717 if ((tlines
= (g
->dcount
+ tcols
- 1) / tcols
) <= 0)
1720 memset(ws
, 0, tcols
* sizeof(int));
1722 for (width
= nth
= tcol
= tline
= 0;
1723 width
< columns
&& nth
< g
->dcount
;
1728 if (tline
== tlines
) {
1732 if (tcol
== tcols
) {
1738 if (len
> ws
[tcol
]) {
1739 width
+= len
- ws
[tcol
];
1743 if (width
< columns
)
1748 } else if (g
->width
) {
1749 if (g
->flags
& CGF_ROWS
) {
1752 for (tcols
= columns
/ (g
->shortest
+ CM_SPACE
);
1756 memset(ws
, 0, tcols
* sizeof(int));
1758 for (width
= nth
= tcol
= 0, tlines
= 1,
1759 p
= skipnolist(g
->matches
, showall
);
1760 *p
&& width
< columns
&& nth
< g
->dcount
;
1761 nth
++, p
= skipnolist(p
+ 1, showall
), tcol
++) {
1765 if (tcol
== tcols
) {
1769 len
= (mlens
[m
->gnum
] +
1770 (tcol
== tcols
- 1 ? 0 : CM_SPACE
));
1772 if (len
> ws
[tcol
]) {
1773 width
+= len
- ws
[tcol
];
1777 if (width
< columns
)
1781 int nth
, tcol
, tline
, len
;
1783 for (tcols
= columns
/ (g
->shortest
+ CM_SPACE
);
1787 if ((tlines
= (g
->dcount
+ tcols
- 1) / tcols
) <= 0)
1790 memset(ws
, 0, tcols
* sizeof(int));
1792 for (width
= nth
= tcol
= tline
= 0,
1793 p
= skipnolist(g
->matches
, showall
);
1794 *p
&& width
< columns
&& nth
< g
->dcount
;
1795 nth
++, p
= skipnolist(p
+ 1, showall
), tline
++) {
1799 if (tline
== tlines
) {
1803 if (tcol
== tcols
) {
1807 len
= (mlens
[m
->gnum
] +
1808 (tcol
== tcols
- 1 ? 0 : CM_SPACE
));
1810 if (len
> ws
[tcol
]) {
1811 width
+= len
- ws
[tcol
];
1815 if (width
< columns
) {
1823 if (tcols
<= g
->cols
)
1825 if (tlines
== g
->lins
) {
1826 zfree(ws
, columns
* sizeof(int));
1829 nlines
+= tlines
- g
->lins
;
1838 for (g
= amatches
; g
; g
= g
->next
) {
1840 int *p
, a
= (max
- g
->totl
+ CM_SPACE
) / g
->cols
;
1842 for (i
= g
->cols
, p
= g
->widths
; i
; i
--, p
++)
1844 } else if (g
->width
&& g
->cols
> 1)
1845 g
->width
+= (max
- (g
->width
* g
->cols
- CM_SPACE
)) / g
->cols
;
1849 for (g
= amatches
; g
; g
= g
->next
)
1851 zfree(g
->widths
, 0);
1855 listdat
.hidden
= hidden
;
1856 listdat
.nlist
= nlist
;
1857 listdat
.nlines
= nlines
;
1858 listdat
.menuacc
= menuacc
;
1859 listdat
.onlyexpl
= onlyexpl
;
1860 listdat
.columns
= columns
;
1861 listdat
.lines
= lines
;
1862 listdat
.showall
= showall
;
1871 /* Set the cursor below the prompt. */
1873 showinglist
= listshown
= 0;
1875 clearflag
= (isset(USEZLE
) && !termflags
&& dolastprompt
);
1878 /* Maybe we have to ask if the user wants to see the list. */
1879 if ((!minfo
.cur
|| !minfo
.asked
) &&
1880 ((complistmax
> 0 && listdat
.nlist
>= complistmax
) ||
1881 (complistmax
< 0 && listdat
.nlines
<= -complistmax
) ||
1882 (!complistmax
&& listdat
.nlines
>= lines
))) {
1886 l
= (listdat
.nlist
> 0 ?
1887 fprintf(shout
, "zsh: do you wish to see all %d possibilities (%d lines)? ",
1888 listdat
.nlist
, listdat
.nlines
) :
1889 fprintf(shout
, "zsh: do you wish to see all %d lines? ",
1891 qup
= ((l
+ columns
- 1) / columns
) - 1;
1893 if (!getzlequery()) {
1896 tcmultout(TCUP
, TCMULTUP
, qup
);
1897 if (tccan(TCCLEAREOD
))
1899 tcmultout(TCUP
, TCMULTUP
, nlnct
);
1907 tcmultout(TCUP
, TCMULTUP
, qup
);
1908 if (tccan(TCCLEAREOD
))
1912 settyinfo(&shttyinfo
);
1914 } else if (minfo
.asked
== 2)
1915 tcmultout(TCUP
, TCMULTUP
, nlnct
);
1917 return (minfo
.asked
? minfo
.asked
- 1 : 0);
1922 printlist(int over
, CLPrintFunc printm
, int showall
)
1927 int pnl
= 0, cl
= (over
? listdat
.nlines
: -1);
1928 int mc
= 0, ml
= 0, printed
= 0;
1932 if (tccan(TCCLEAREOD
))
1935 for (g
= amatches
; g
; g
= g
->next
) {
1936 char **pp
= g
->ylist
;
1938 if ((e
= g
->expls
)) {
1942 if (((*e
)->count
|| (*e
)->always
) &&
1943 (!listdat
.onlyexpl
||
1944 (listdat
.onlyexpl
& ((*e
)->always
> 0 ? 2 : 1)))) {
1949 if (cl
>= 0 && --cl
<= 1) {
1951 if (tccan(TCCLEAREOD
))
1955 l
= printfmt((*e
)->str
,
1956 ((*e
)->always
? -1 : (*e
)->count
), 1, 1);
1958 if (cl
>= 0 && (cl
-= l
) <= 1) {
1960 if (tccan(TCCLEAREOD
))
1968 if (!listdat
.onlyexpl
&& pp
&& *pp
) {
1973 if (cl
>= 0 && --cl
<= 1) {
1975 if (tccan(TCCLEAREOD
))
1979 if (g
->flags
& CGF_LINES
) {
1982 while ((p
= *pp
++)) {
1985 if (MB_METASTRWIDTH(p
) % columns
)
1988 fputs(" \010", shout
);
1992 int n
= g
->lcount
, nl
, nc
, i
, a
;
2002 if (pq
- g
->ylist
>= g
->lcount
)
2006 a
= (g
->widths
? g
->widths
[mc
] : g
->width
) -
2007 MB_METASTRWIDTH(*pq
);
2011 pq
+= ((g
->flags
& CGF_ROWS
) ? 1 : nc
);
2018 if (cl
>= 0 && --cl
<= 1) {
2020 if (tccan(TCCLEAREOD
))
2024 pp
+= ((g
->flags
& CGF_ROWS
) ? g
->cols
: 1);
2027 } else if (!listdat
.onlyexpl
&&
2028 (g
->lcount
|| (showall
&& g
->mcount
))) {
2029 int n
= g
->dcount
, nl
, nc
, i
, j
, wid
;
2034 if (g
->flags
& CGF_HASDL
) {
2035 for (p
= g
->matches
; (m
= *p
); p
++)
2036 if (m
->disp
&& (m
->flags
& CMF_DISPLINE
) &&
2037 (showall
|| !(m
->flags
& (CMF_HIDE
|CMF_NOLIST
)))) {
2042 if (cl
>= 0 && --cl
<= 1) {
2044 if (tccan(TCCLEAREOD
))
2049 printm(g
, p
, 0, ml
, 1, 0);
2057 if (cl
>= 0 && --cl
<= 1) {
2059 if (tccan(TCCLEAREOD
))
2063 for (p
= skipnolist(g
->matches
, showall
); n
&& nl
--;) {
2068 wid
= (g
->widths
? g
->widths
[mc
] : g
->width
);
2070 printm(g
, NULL
, mc
, ml
, (!i
), wid
);
2073 printm(g
, q
, mc
, ml
, (!i
), wid
);
2078 for (j
= ((g
->flags
& CGF_ROWS
) ? 1 : nc
);
2080 q
= skipnolist(q
+ 1, showall
);
2084 printm(g
, NULL
, mc
, ml
, (!i
),
2085 (g
->widths
? g
->widths
[mc
] : g
->width
));
2091 if (cl
>= 0 && --cl
<= 1) {
2093 if (tccan(TCCLEAREOD
))
2097 for (j
= ((g
->flags
& CGF_ROWS
) ? g
->cols
: 1);
2099 p
= skipnolist(p
+ 1, showall
);
2104 if (g
->lcount
|| (showall
&& g
->mcount
))
2109 /* Move the cursor up to the prompt, if always_last_prompt *
2110 * is set and all that... */
2111 if ((ml
= listdat
.nlines
+ nlnct
- 1) < lines
) {
2112 tcmultout(TCUP
, TCMULTUP
, ml
);
2115 lastlistlen
= listdat
.nlines
;
2117 clearflag
= 0, putc('\n', shout
);
2121 listshown
= (clearflag
? 1 : -1);
2128 bld_all_str(Cmatch all
)
2132 int len
= columns
- 5, t
, add
= 0;
2133 VARARR(char, buf
, columns
+ 1);
2137 for (g
= amatches
; g
&& !g
->mcount
; g
= g
->next
);
2142 if (!(m
->flags
& (CMF_ALL
| CMF_HIDE
)) && m
->str
) {
2143 t
= strlen(m
->str
) + add
;
2147 strcat(buf
, m
->str
);
2151 if (len
> add
+ 2) {
2154 strncat(buf
, m
->str
, len
);
2164 } while (!g
->mcount
);
2171 all
->disp
= ztrdup(buf
);
2176 iprintm(Cmgroup g
, Cmatch
*mp
, UNUSED(int mc
), UNUSED(int ml
), int lastc
, int width
)
2185 if ((m
->flags
& CMF_ALL
) && (!m
->disp
|| !m
->disp
[0]))
2188 if (m
->flags
& CMF_DISPLINE
) {
2189 printfmt(m
->disp
, 0, 1, 0);
2192 #ifdef MULTIBYTE_SUPPORT
2193 len
= mb_niceformat(m
->disp
, shout
, NULL
, 0);
2195 nicezputs(m
->disp
, shout
);
2196 len
= niceztrlen(m
->disp
);
2199 #ifdef MULTIBYTE_SUPPORT
2200 len
= mb_niceformat(m
->str
, shout
, NULL
, 0);
2202 nicezputs(m
->str
, shout
);
2203 len
= niceztrlen(m
->str
);
2206 if ((g
->flags
& CGF_FILES
) && m
->modec
) {
2207 putc(m
->modec
, shout
);
2221 ilistmatches(UNUSED(Hookdef dummy
), UNUSED(Chdata dat
))
2225 if (!listdat
.nlines
) {
2226 showinglist
= listshown
= 0;
2232 printlist(0, iprintm
, 0);
2237 /* List the matches. Note that the list entries are metafied. */
2241 list_matches(UNUSED(Hookdef dummy
), UNUSED(void *dummy2
))
2249 showmsg("BUG: listmatches called with bogus list");
2254 dat
.matches
= amatches
;
2257 ret
= runhookdef(COMPLISTMATCHESHOOK
, (void *) &dat
);
2262 /* Invalidate the completion list. */
2266 invalidate_list(void)
2270 if (showinglist
== -2) {
2273 freematches(lastmatches
, 1);
2277 lastambig
= menucmp
= menuacc
= validlist
= showinglist
= fromcomp
= 0;
2283 zsfree(minfo
.prebr
);
2284 zsfree(minfo
.postbr
);
2285 minfo
.postbr
= minfo
.prebr
= NULL
;