1 /*
2  * comp.h - header file for completion
3  *
4  * This file is part of zsh, the Z shell.
5  *
6  * Copyright (c) 1992-1997 Paul Falstad
7  * All rights reserved.
8  *
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.
14  *
15  * In no event shall Paul Falstad 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 Paul Falstad and the Zsh Development Group have been advised of
19  * the possibility of such damage.
20  *
21  * Paul Falstad 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 Paul Falstad and the
25  * Zsh Development Group have no obligation to provide maintenance,
26  * support, updates, enhancements, or modifications.
27  *
28  */
29 
30 typedef struct cmatcher  *Cmatcher;
31 typedef struct cmlist    *Cmlist;
32 typedef struct cpattern  *Cpattern;
33 typedef struct menuinfo  *Menuinfo;
34 typedef struct cexpl *Cexpl;
35 typedef struct cmgroup *Cmgroup;
36 typedef struct cmatch *Cmatch;
37 
38 /* This is for explanation strings. */
39 
40 struct cexpl {
41     int always;                 /* display even without matches */
42     char *str;			/* the string */
43     int count;			/* the number of matches */
44     int fcount;			/* number of matches with fignore ignored */
45 };
46 
47 /* This describes a group of matches. */
48 
49 struct cmgroup {
50     char *name;			/* the name of this group */
51     Cmgroup prev;		/* previous on the list */
52     Cmgroup next;		/* next one in list */
53     int flags;			/* see CGF_* below */
54     int mcount;			/* number of matches */
55     Cmatch *matches;		/* the matches */
56     int lcount;			/* number of things to list here */
57     int llcount;		/* number of line-displays */
58     char **ylist;		/* things to list */
59     int ecount;			/* number of explanation string */
60     Cexpl *expls;		/* explanation strings */
61     int ccount;			/* number of compctls used */
62     LinkList lexpls;		/* list of explanation string while building */
63     LinkList lmatches;		/* list of matches */
64     LinkList lfmatches;		/* list of matches without fignore */
65     LinkList lallccs;		/* list of used compctls */
66     int num;			/* number of this group */
67     int nbrbeg;			/* number of opened braces */
68     int nbrend;			/* number of closed braces */
69     int new;			/* new matches since last permalloc() */
70     /* The following is collected/used during listing. */
71     int dcount;			/* number of matches to list in columns */
72     int cols;			/* number of columns */
73     int lins;			/* number of lines */
74     int width;			/* column width */
75     int *widths;		/* column widths for listpacked */
76     int totl;			/* total length */
77     int shortest;		/* length of shortest match */
78     Cmgroup perm;		/* perm. alloced version of this group */
79 #ifdef ZSH_HEAP_DEBUG
80     Heapid heap_id;
81 #endif
82 };
83 
84 
85 #define CGF_NOSORT   1		/* don't sort this group */
86 #define CGF_LINES    2		/* these are to be printed on different lines */
87 #define CGF_HASDL    4		/* has display strings printed on separate lines */
88 #define CGF_UNIQALL  8		/* remove all duplicates */
89 #define CGF_UNIQCON 16		/* remove consecutive duplicates */
90 #define CGF_PACKED  32		/* LIST_PACKED for this group */
91 #define CGF_ROWS    64		/* LIST_ROWS_FIRST for this group */
92 #define CGF_FILES   128		/* contains file names */
93 #define CGF_MATSORT 256		/* sort by match rather than by display string */
94 #define CGF_NUMSORT 512		/* sort numerically */
95 #define CGF_REVSORT 1024	/* sort in reverse */
96 
97 /* This is the struct used to hold matches. */
98 
99 struct cmatch {
100     char *str;			/* the match itself */
101     char *orig;                 /* the match string unquoted */
102     char *ipre;			/* ignored prefix, has to be re-inserted */
103     char *ripre;		/* ignored prefix, unquoted */
104     char *isuf;			/* ignored suffix */
105     char *ppre;			/* the path prefix */
106     char *psuf;			/* the path suffix */
107     char *prpre;		/* path prefix for opendir */
108     char *pre;			/* prefix string from -P */
109     char *suf;			/* suffix string from -S */
110     char *disp;			/* string to display (compadd -d) */
111     char *autoq;		/* closing quote to add automatically */
112     int flags;			/* see CMF_* below */
113     int *brpl;			/* places where to put the brace prefixes */
114     int *brsl;			/* ...and the suffixes */
115     char *rems;			/* when to remove the suffix */
116     char *remf;			/* shell function to call for suffix-removal */
117     int qipl;			/* length of quote-prefix */
118     int qisl;			/* length of quote-suffix */
119     int rnum;			/* group relative number */
120     int gnum;			/* global number */
121     mode_t mode;                /* mode field of a stat */
122     char modec;                 /* LIST_TYPE-character for mode or nul */
123     mode_t fmode;               /* mode field of a stat, following symlink */
124     char fmodec;                /* LIST_TYPE-character for fmode or nul */
125 };
126 
127 #define CMF_FILE     (1<< 0)	/* this is a file */
128 #define CMF_REMOVE   (1<< 1)	/* remove the suffix */
129 #define CMF_ISPAR    (1<< 2)	/* is parameter expansion */
130 #define CMF_PARBR    (1<< 3)	/* parameter expansion with a brace */
131 #define CMF_PARNEST  (1<< 4)	/* nested parameter expansion */
132 #define CMF_NOLIST   (1<< 5)	/* should not be listed */
133 #define CMF_DISPLINE (1<< 6)	/* display strings one per line */
134 #define CMF_HIDE     (1<< 7)	/* temporarily hide this one */
135 #define CMF_NOSPACE  (1<< 8)	/* don't add a space */
136 #define CMF_PACKED   (1<< 9)	/* prefer LIST_PACKED */
137 #define CMF_ROWS     (1<<10)	/* prefer LIST_ROWS_FIRST */
138 #define CMF_MULT     (1<<11)	/* string appears more than once */
139 #define CMF_FMULT    (1<<12)	/* first of multiple equal strings */
140 #define CMF_ALL      (1<<13)	/* a match representing all other matches */
141 #define CMF_DUMMY    (1<<14)	/* unselectable dummy match */
142 #define CMF_MORDER   (1<<15)    /* order by matches, not display strings */
143 
144 /* Stuff for completion matcher control. */
145 
146 struct cmlist {
147     Cmlist next;		/* next one in the list of global matchers */
148     Cmatcher matcher;		/* the matcher definition */
149     char *str;			/* the string for it */
150 };
151 
152 struct cmatcher {
153     int refc;			/* reference counter */
154     Cmatcher next;		/* next matcher */
155     int flags;			/* see CMF_* below */
156     Cpattern line;		/* what matches on the line */
157     int llen;			/* length of line pattern */
158     Cpattern word;		/* what matches in the word */
159     int wlen;			/* length of word pattern, or:
160 				    -1: word pattern is one asterisk
161 				    -2: word pattern is two asterisks */
162     Cpattern left;		/* left anchor */
163     int lalen;			/* length of left anchor */
164     Cpattern right;		/* right anchor */
165     int ralen;			/* length of right anchor */
166 };
167 
168 /* Flags for cmatcher::flags */
169 /* Upon match, insert the string from the line rather than the string
170  * from the trial completion ("word"). */
171 #define CMF_LINE  1
172 /* Match with an anchor on the left. */
173 #define CMF_LEFT  2
174 /* Match with an anchor on the right. */
175 #define CMF_RIGHT 4
176 /* ... */
177 #define CMF_INTER 8
178 
179 /*
180  * Types of cpattern structure.
181  * Note freecpattern() assumes any <= CPAT_EQUIV have string.
182  */
183 enum {
184     CPAT_CCLASS,		/* [...]: ordinary character class */
185     CPAT_NCLASS,		/* [!...]: ordinary character class, negated */
186     CPAT_EQUIV,			/* {...}: equivalence class */
187     CPAT_ANY,			/* ?: any character */
188     CPAT_CHAR			/* Single character given explicitly */
189 };
190 
191 /*
192  * A pattern element in a matcher specification.
193  * Unlike normal patterns this only presents one character in
194  * either the test completion or the word on the command line.
195  */
196 struct cpattern {
197     Cpattern next;		/* next sub-pattern */
198     int tp;			/* type of object as above */
199     union {
200 	char *str;		/* if a character class, the objects
201 				 * in it in a similar form to normal
202 				 * pattern matching (a metafied string
203 				 * with tokens).
204 				 * Note the allocated length may be longer
205 				 * than the null-terminated string.
206 				 */
207 	convchar_t chr;		/* if a single character, it */
208     } u;
209 };
210 
211 /*
212  * For now this just handles single-byte characters.
213  * TODO: this will change.
214  */
215 #ifdef MULTIBYTE_SUPPORT
216 #define PATMATCHRANGE(r, c, ip, mtp)		\
217     mb_patmatchrange(r, c, ZMB_VALID, ip, mtp)
218 #define PATMATCHINDEX(r, i, cp, mtp)    mb_patmatchindex(r, i, cp, mtp)
219 #define CONVCAST(c)			((wchar_t)(c))
220 #define CHR_INVALID			(WEOF)
221 #else
222 #define PATMATCHRANGE(r, c, ip, mtp)	patmatchrange(r, c, ip, mtp)
223 #define PATMATCHINDEX(r, i, cp, mtp)	patmatchindex(r, i, cp, mtp)
224 #define CONVCAST(c)			(c)
225 #define CHR_INVALID			(-1)
226 #endif
227 
228 /* This is a special return value for parse_cmatcher(), *
229  * signalling an error. */
230 
231 #define pcm_err ((Cmatcher) 1)
232 
233 /* Information about what to put on the line as the unambiguous string.
234  * The code always keeps lists of these structs up to date while
235  * matches are added (in the aminfo structs below).
236  * The lists have two levels: in the first one we have one struct per
237  * word-part, where parts are separated by the anchors of `*' patterns.
238  * These structs have pointers (in the prefix and suffix fields) to
239  * lists of cline structs describing the strings before or after the
240  * the anchor. */
241 
242 typedef struct cline *Cline;
243 
244 struct cline {
245     Cline next;
246     int flags;
247     char *line;
248     int llen;
249     char *word;
250     int wlen;
251     char *orig;
252     int olen;
253     int slen;
254     Cline prefix, suffix;
255     int min, max;
256 };
257 
258 #define CLF_MISS      1
259 #define CLF_DIFF      2
260 #define CLF_SUF       4
261 #define CLF_MID       8
262 #define CLF_NEW      16
263 #define CLF_LINE     32
264 #define CLF_JOIN     64
265 #define CLF_MATCHED 128
266 #define CLF_SKIP    256
267 
268 /* Information for ambiguous completions. One for fignore ignored and   *
269  * one for normal completion. */
270 
271 typedef struct aminfo *Aminfo;
272 
273 struct aminfo {
274     Cmatch firstm;		/* the first match                        */
275     int exact;			/* if there was an exact match            */
276     Cmatch exactm;		/* the exact match (if any)               */
277     int count;			/* number of matches                      */
278     Cline line;			/* unambiguous line string                */
279 };
280 
281 /* Information about menucompletion stuff. */
282 
283 struct menuinfo {
284     Cmgroup group;		/* position in the group list */
285     Cmatch *cur;		/* match currently inserted */
286     int pos;			/* begin on line */
287     int len;			/* length of inserted string */
288     int end;			/* end on the line */
289     int we;			/* non-zero if the cursor was at the end */
290     int insc;			/* length of suffix inserted */
291     int asked;			/* we asked if the list should be shown */
292     char *prebr;		/* prefix before a brace, if any */
293     char *postbr;		/* suffix after a brace */
294 };
295 
296 /* Flags for compadd and addmatches(). */
297 
298 #define CAF_QUOTE    1    /* compadd -Q: positional arguments already quoted */
299 #define CAF_NOSORT   2    /* compadd -V: don't sort */
300 #define CAF_MATCH    4    /* compadd without -U: do matching */
301 #define CAF_UNIQCON  8    /* compadd -2: don't deduplicate */
302 #define CAF_UNIQALL 16    /* compadd -1: deduplicate */
303 #define CAF_ARRAYS  32    /* compadd -a or -k: array/assoc parameter names */
304 #define CAF_KEYS    64    /* compadd -k: assoc parameter names */
305 #define CAF_ALL    128    /* compadd -C: _all_matches */
306 #define CAF_MATSORT 256   /* compadd -o match: sort by match rather than by display string */
307 #define CAF_NUMSORT 512   /* compadd -o numeric: sort numerically */
308 #define CAF_REVSORT 1024  /* compadd -o numeric: sort in reverse */
309 
310 /* Data for compadd and addmatches() */
311 
312 typedef struct cadata *Cadata;
313 
314 struct cadata {
315     char *ipre;			/* ignored prefix (-i) */
316     char *isuf;			/* ignored suffix (-I) */
317     char *ppre;			/* `path' prefix (-p) */
318     char *psuf;			/* `path' suffix (-s) */
319     char *prpre;		/* expanded `path' prefix (-W) */
320     char *pre;			/* prefix to insert (-P) */
321     char *suf;			/* suffix to insert (-S) */
322     char *group;		/* name of the group (-[JV]) */
323     char *rems;			/* remove suffix on chars... (-r) */
324     char *remf;			/* function to remove suffix (-R) */
325     char *ign;			/* ignored suffixes (-F) */
326     int flags;			/* CMF_* flags (-[fqn]) */
327     int aflags;			/* CAF_* flags (-[QUa]) */
328     Cmatcher match;		/* match spec (parsed from -M) */
329     char *exp;			/* explanation (-X) */
330     char *apar;			/* array to store matches in (-A) */
331     char *opar;			/* array to store originals in (-O) */
332     char *dpar;			/* array to delete non-matches in (-D) */
333     char *disp;			/* array with display lists (-d) */
334     char *mesg;			/* message to show unconditionally (-x) */
335     int dummies;               /* add that many dummy matches */
336 };
337 
338 /* List data. */
339 
340 typedef struct cldata *Cldata;
341 
342 struct cldata {
343     int zterm_columns;		/* screen width */
344     int zterm_lines;		/* screen height */
345     int menuacc;		/* value of global menuacc */
346     int valid;			/* no need to calculate anew */
347     int nlist;			/* number of matches to list */
348     int nlines;			/* number of lines needed */
349     int hidden;			/* != 0 if there are hidden matches */
350     int onlyexpl;		/* != 0 if only explanations to print */
351     int showall;		/* != 0 if hidden matches should be shown */
352 };
353 
354 typedef void (*CLPrintFunc)(Cmgroup, Cmatch *, int, int, int, int);
355 
356 /* Flags for fromcomp. */
357 
358 #define FC_LINE   1
359 #define FC_INWORD 2
360 
361 /* Flags for special parameters. */
362 
363 #define CPN_WORDS      0
364 #define CP_WORDS       (1 <<  CPN_WORDS)
365 #define CPN_REDIRS     1
366 #define CP_REDIRS      (1 <<  CPN_REDIRS)
367 #define CPN_CURRENT    2
368 #define CP_CURRENT     (1 <<  CPN_CURRENT)
369 #define CPN_PREFIX     3
370 #define CP_PREFIX      (1 <<  CPN_PREFIX)
371 #define CPN_SUFFIX     4
372 #define CP_SUFFIX      (1 <<  CPN_SUFFIX)
373 #define CPN_IPREFIX    5
374 #define CP_IPREFIX     (1 <<  CPN_IPREFIX)
375 #define CPN_ISUFFIX    6
376 #define CP_ISUFFIX     (1 <<  CPN_ISUFFIX)
377 #define CPN_QIPREFIX   7
378 #define CP_QIPREFIX    (1 <<  CPN_QIPREFIX)
379 #define CPN_QISUFFIX   8
380 #define CP_QISUFFIX    (1 <<  CPN_QISUFFIX)
381 #define CPN_COMPSTATE  9
382 #define CP_COMPSTATE   (1 <<  CPN_COMPSTATE)
383 /* See comprpms */
384 #define CP_REALPARAMS  10
385 #define CP_ALLREALS    ((unsigned int) 0x3ff)
386 
387 
388 #define CPN_NMATCHES   0
389 #define CP_NMATCHES    (1 << CPN_NMATCHES)
390 #define CPN_CONTEXT    1
391 #define CP_CONTEXT     (1 << CPN_CONTEXT)
392 #define CPN_PARAMETER  2
393 #define CP_PARAMETER   (1 << CPN_PARAMETER)
394 #define CPN_REDIRECT   3
395 #define CP_REDIRECT    (1 << CPN_REDIRECT)
396 #define CPN_QUOTE      4
397 #define CP_QUOTE       (1 << CPN_QUOTE)
398 #define CPN_QUOTING    5
399 #define CP_QUOTING     (1 << CPN_QUOTING)
400 #define CPN_RESTORE    6
401 #define CP_RESTORE     (1 << CPN_RESTORE)
402 #define CPN_LIST       7
403 #define CP_LIST        (1 << CPN_LIST)
404 #define CPN_INSERT     8
405 #define CP_INSERT      (1 << CPN_INSERT)
406 #define CPN_EXACT      9
407 #define CP_EXACT       (1 << CPN_EXACT)
408 #define CPN_EXACTSTR   10
409 #define CP_EXACTSTR    (1 << CPN_EXACTSTR)
410 #define CPN_PATMATCH   11
411 #define CP_PATMATCH    (1 << CPN_PATMATCH)
412 #define CPN_PATINSERT  12
413 #define CP_PATINSERT   (1 << CPN_PATINSERT)
414 #define CPN_UNAMBIG    13
415 #define CP_UNAMBIG     (1 << CPN_UNAMBIG)
416 #define CPN_UNAMBIGC   14
417 #define CP_UNAMBIGC    (1 << CPN_UNAMBIGC)
418 #define CPN_UNAMBIGP   15
419 #define CP_UNAMBIGP    (1 << CPN_UNAMBIGP)
420 #define CPN_INSERTP    16
421 #define CP_INSERTP     (1 << CPN_INSERTP)
422 #define CPN_LISTMAX    17
423 #define CP_LISTMAX     (1 << CPN_LISTMAX)
424 #define CPN_LASTPROMPT 18
425 #define CP_LASTPROMPT  (1 << CPN_LASTPROMPT)
426 #define CPN_TOEND      19
427 #define CP_TOEND       (1 << CPN_TOEND)
428 #define CPN_OLDLIST    20
429 #define CP_OLDLIST     (1 << CPN_OLDLIST)
430 #define CPN_OLDINS     21
431 #define CP_OLDINS      (1 << CPN_OLDINS)
432 #define CPN_VARED      22
433 #define CP_VARED       (1 << CPN_VARED)
434 #define CPN_LISTLINES  23
435 #define CP_LISTLINES   (1 << CPN_LISTLINES)
436 #define CPN_QUOTES     24
437 #define CP_QUOTES      (1 << CPN_QUOTES)
438 #define CPN_IGNORED    25
439 #define CP_IGNORED     (1 << CPN_IGNORED)
440 /* See compkpms */
441 #define CP_KEYPARAMS   26
442 #define CP_ALLKEYS     ((unsigned int) 0x3ffffff)
443 
444 /* Hooks. */
445 
446 #define INSERTMATCHHOOK     (comphooks + 0)
447 #define MENUSTARTHOOK       (comphooks + 1)
448 #define COMPCTLMAKEHOOK     (comphooks + 2)
449 #define COMPCTLCLEANUPHOOK  (comphooks + 3)
450 #define COMPLISTMATCHESHOOK (comphooks + 4)
451 
452 /* compctl hook data struct */
453 
454 struct ccmakedat {
455     char *str;
456     int incmd;
457     int lst;
458 };
459 
460 /* Data given to offered hooks. */
461 
462 typedef struct chdata *Chdata;
463 
464 struct chdata {
465     Cmgroup matches;		/* the matches generated */
466     int num;			/* the number of matches */
467     int nmesg;			/* the number of messages */
468     Cmatch cur;			/* current match or NULL */
469 };
470 
471 /* The number of columns to leave empty between rows of matches. */
472 
473 #define CM_SPACE  2
474 
475