1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-01-01 05:16:05 +01:00

Initial revision

This commit is contained in:
Tanaka Akira 1999-06-27 05:33:25 +00:00
parent adefa2757a
commit b346c4796b
5 changed files with 1061 additions and 0 deletions

15
Completion/User/_chown Normal file
View file

@ -0,0 +1,15 @@
#compdef chown chgrp
if [[ CURRENT -eq 2 || CURRENT -eq 3 && $words[CURRENT-1] = -* ]]; then
if [[ $words[1] = chgrp ]] || compset -P '*[:.]'; then
_groups
else
if [[ $OSTYPE = (solaris*|hpux*) ]]; then
compgen -u -S ':' -q
else
compgen -u -S '.' -q
fi
fi
else
_files
fi

6
Completion/User/_groups Normal file
View file

@ -0,0 +1,6 @@
#compdef newgrp
: ${(A)groups:=${${(s: :)$(</etc/group)}%%:*}}
# : ${(A)groups:=${${(s: :)$(ypcat group.byname)}%%:*}} # If you use NIS
compadd $groups

119
Doc/Zsh/mod_complist.yo Normal file
View file

@ -0,0 +1,119 @@
texinode(The complist Module)(The deltochar Module)(The compctl Module)(Zsh Modules)
sect(The complist Module)
cindex(completion, listing)
The tt(complist) module offers two extensions to completion listings:
the ability to highlight matches in such a list and a different
style of menu-completion.
subsect(Parameters)
For both extensions one of the parameters tt(ZLS_COLORS) or tt(ZLS_COLOURS)
must be set, even if the value is empty (which uses all the default values
given below). These describe how matches are highlighted. The format of the
value of these parameters is the same as used by the GNU version of the
tt(ls) command: a colon-separated list of specifications of the form
`var(name)=var(value)'. The var(name) may be one of the following strings,
most of which specify file-types for which the var(value) will be used. The
strings and their default values are:
startitem()
item(tt(no 0))(
for normal text (not the string displayed for a match)
)
item(tt(fi 0))(
for regular files
)
item(tt(di 32))(
for directories
)
item(tt(ln 36))(
for symbolic links
)
item(tt(pi 31))(
for named pipes (FIFOs)
)
item(tt(so 33))(
for sockets
)
item(tt(bd 44;37))(
for block devices
)
item(tt(cd 44;37))(
for character devices
)
item(tt(ex 35))(
for executable files
)
item(tt(mi) var(none))(
for names not naming a file (default is the value defined for tt(fi))
)
item(tt(lc \e[))(
for the left code (see below)
)
item(tt(rc m))(
for the right code
)
item(tt(ec) var(none))(
for the end code
)
enditem()
Apart from these strings, the var(name) may also be an asterisk
(`tt(*)') followed by any string. The var(value) given for such a
string will be used for all files whose name ends with the string.
When printing a match, the code prints the value of tt(lc), the value
for the file-type or the last matching specification with a `tt(*)',
the value of tt(rc), the string to display for the match itself, and
then the value of tt(ec) if that is defined or the values of tt(lc),
tt(no), and tt(rc) if tt(ec) is not defined.
The default values are ISO 6429 (ANSI) compliant and can be used on
vt100 compatible terminals such as tt(xterm)s. On monochrome terminals
the default values will have no visual effect.
Whenever one of the parameters tt(ZLS_COLORS) or tt(ZLS_COLOURS) is set
and the tt(complist) module is loaded or linked into the shell,
completion lists will be colored.
subsect(Menu selection)
The tt(complist) module also offers a different style of selecting
matches from a list called menu-selection. It can be invoked directly by
the widget tt(menu-select) defined by the module. Alternatively,
the parameter tt(SELECTMIN) can be set to an integer giving the minimum
number of matches which must be present before menu selection is
automatically turned on. This second method requires that menu completion
be started, either directly from a widget such as tt(menu-complete), or due
to one of the options tt(MENU_COMPLETE) or tt(AUTO_MENU) being set. If
tt(SELECTMIN) is set, but is 0, 1 or empty, menu selection will always be
started during menu completion if the completion is ambiguous.
After menu-selection is started, the matches will be listed. The
matches to insert into the command line can be selected from this
list. In the list one match is highlighted using the value for tt(ma)
from the tt(ZLS_COLORS) or tt(ZLS_COLOURS) parameter. The default
value for this it `tt(7)' which forces the selected match to be
highlighted using standout mode on a vt100 compatible terminal.
Selecting matches is done by moving the mark around using the zle movement
functions. The zle functions tt(send-break) and tt(accept-line) can be used
to leave menu-selection, leaving the match currently inserted into the line
in place. The functions tt(accept-and-hold) and
tt(accept-and-menu-complete) can be used to accept the match currently
inserted and continue inserting matches after that. Matches inserted this
way can be removed by invoking the tt(undo) function. Keys bound to one of
the completion functions will cycle to the next (or, in case of
tt(reverse-menu-complete), the previous) match, and the tt(redisplay) and
tt(clear-screen) functions work as usual without leaving
menu-selection. Any other zle function leaves menu-selection and executes
that function.
During this selection the widget uses the keymap tt(menuselect). Any
key that is not defined in this keymap or that is bound to
tt(undefined-key) is looked up in the keymap currently selected. This
is used to ensure that the most important keys used during selection
have sensible default (namely the cursor keys, return, and TAB). However,
keys in the the tt(menuselect) keymap can be modified directly using the
tt(bindkey) builtin command (see
ifzman(zmanref(zshmodules))\
ifnzman(noderef(The zle Module))\
).

918
Src/Zle/complist.c Normal file
View file

@ -0,0 +1,918 @@
/*
* complist.c - completion listing enhancements
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1999 Sven Wischnowsky
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Sven Wischnowsky or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Sven Wischnowsky and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Sven Wischnowsky and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Sven Wischnowsky and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#include "complist.mdh"
#include "complist.pro"
/* We use the parameters ZLS_COLORS and ZLS_COLOURS in the same way as
* the color ls does. It's just that we don't support the `or' file
* type. */
static Widget w_menuselect;
static Keymap mskeymap;
/* Indixes into the terminal string arrays. */
#define COL_NO 0
#define COL_FI 1
#define COL_DI 2
#define COL_LN 3
#define COL_PI 4
#define COL_SO 5
#define COL_BD 6
#define COL_CD 7
#define COL_EX 8
#define COL_MI 9
#define COL_LC 10
#define COL_RC 11
#define COL_EC 12
#define COL_MA 13
#define NUM_COLS 14
/* Names of the terminal strings. */
static char *colnames[] = {
"no", "fi", "di", "ln", "pi", "so", "bd", "cd", "ex", "mi",
"lc", "rc", "ec", "ma", NULL
};
/* Default values. */
static char *defcols[] = {
"0", "0", "1;34", "1;36", "33", "1;35", "1;33", "1;33", "1;32", NULL,
"\033[", "m", NULL, "7"
};
/* This describes a terminal string for a filename extension. */
typedef struct extcol *Extcol;
struct extcol {
char *ext; /* the extension */
char *col; /* the terminal color string */
Extcol next; /* the next one in the list */
};
/* This holds all terminal strings. */
typedef struct listcols *Listcols;
struct listcols {
char *cols[NUM_COLS]; /* strings for file types */
Extcol exts; /* strings for extensions */
};
/* This parses the value of a definition (the part after the `=').
* The return value is a pointer to the character after it. */
static char *
getcolval(char *s)
{
char *p;
for (p = s; *s && *s != ':'; p++, s++) {
if (*s == '\\' && s[1]) {
switch (*++s) {
case 'a': *p = '\007'; break;
case 'n': *p = '\n'; break;
case 'b': *p = '\b'; break;
case 't': *p = '\t'; break;
case 'v': *p = '\v'; break;
case 'f': *p = '\f'; break;
case 'r': *p = '\r'; break;
case 'e': *p = '\033'; break;
case '_': *p = ' '; break;
case '?': *p = '\177'; break;
default:
if (*s >= '0' && *s <= '7') {
int i = STOUC(*s);
if (*++s >= '0' && *s <= '7') {
i = (i * 8) + STOUC(*s);
if (*++s >= '0' && *s <= '7')
i = (i * 8) + STOUC(*s);
}
*p = (char) i;
} else
*p = *s;
}
} else if (*s == '^') {
if ((s[1] >= '@' && s[1] <= '_') ||
(s[1] >= 'a' && s[1] <= 'z'))
*p = (char) (STOUC(*s) & ~0x60);
else if (s[1] == '?')
*p = '\177';
else {
*p++ = *s;
*p = s[1];
}
s++;
} else
*p = *s;
}
if (p != s)
*p = '\0';
return s;
}
/* This parses one definition. Return value is a pointer to the
* character after it. */
static char *
getcoldef(Listcols c, char *s)
{
if (*s == '*') {
Extcol ec;
char *n, *p;
/* This is for an extension. */
n = ++s;
while (*s && *s != '=')
s++;
if (!*s )
return s;
*s++ = '\0';
p = getcolval(s);
if (*n) {
ec = (Extcol) zhalloc(sizeof(*ec));
ec->ext = n;
ec->col = s;
ec->next = c->exts;
c->exts = ec;
}
if (*p)
*p++ = '\0';
return p;
} else {
char *n = s, *p, **nn;
int i;
/* This is for a file type. */
while (*s && *s != '=')
s++;
if (!*s)
return s;
*s++ = '\0';
for (i = 0, nn = colnames; *nn; i++, nn++)
if (!strcmp(n ,*nn))
break;
p = getcolval(s);
if (*nn)
c->cols[i] = s;
if (*p)
*p++ = '\0';
return p;
}
}
/* This initializes the given terminal color structure. */
static int
getcols(Listcols c)
{
char *s;
int i;
if (!(s = getsparam("ZLS_COLORS")) &&
!(s = getsparam("ZLS_COLOURS"))) {
if (!c)
return 1;
for (i = 0; i < NUM_COLS; i++)
c->cols[i] = "";
c->exts = NULL;
return 1;
}
if (!c)
return 0;
/* We have one of the parameters, use it. */
memset(c, 0, sizeof(*c));
s = dupstring(s);
while (*s)
s = getcoldef(c, s);
/* Use default values for those that aren't set explicitly. */
for (i = 0; i < NUM_COLS; i++)
if (!c->cols[i])
c->cols[i] = defcols[i];
/* Default for missing files. */
if (!c->cols[COL_MI])
c->cols[COL_MI] = c->cols[COL_FI];
if (!c->cols[COL_EC]) {
char *e = (char *) zhalloc(strlen(c->cols[COL_LC]) +
strlen(c->cols[COL_NO]) +
strlen(c->cols[COL_RC]) + 1);
/* If no `ec' was given, we is `<lc><no><rc>' as the default. */
strcpy(e, c->cols[COL_LC]);
strcat(e, c->cols[COL_NO]);
strcat(e, c->cols[COL_RC]);
c->cols[COL_EC] = e;
}
return 0;
}
/* Get the terminal color string for the file with the given name and
* file modes. */
static char *
getcolstr(Listcols c, char *n, mode_t m)
{
Extcol e;
for (e = c->exts; e; e = e->next)
if (strsfx(e->ext, n))
return e->col;
if (S_ISDIR(m))
return c->cols[COL_DI];
else if (S_ISLNK(m))
return c->cols[COL_LN];
else if (S_ISFIFO(m))
return c->cols[COL_PI];
else if (S_ISSOCK(m))
return c->cols[COL_SO];
else if (S_ISBLK(m))
return c->cols[COL_BD];
else if (S_ISCHR(m))
return c->cols[COL_CD];
else if (S_ISREG(m) && (m & S_IXUGO))
return c->cols[COL_EX];
return c->cols[COL_FI];
}
/* Information about the list shown. */
static int noselect, mselect, inselect, mcol, mline, mcols, mlines;
static Cmatch *mmatch, **mtab;
static Cmgroup mgroup, *mgtab;
/* List the matches. Most of this is just taken from ilistmatches(),
* of course. */
static int
complistmatches(Hookdef dummy, Chdata dat)
{
Cmgroup amatches = dat->matches, g;
Cmatch *p, m;
Cexpl *e;
int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0, opl = 0;
int of = isset(LISTTYPES);
int mc, ml = 0, cc, hasm = 0;
struct listcols col;
if (minfo.asked == 2) {
showinglist = 0;
return (noselect = 1);
}
getcols(&col);
/* Set the cursor below the prompt. */
if (inselect)
clearflag = 0;
trashzle();
showinglist = listshown = 0;
clearflag = (isset(USEZLE) && !termflags &&
complastprompt && *complastprompt);
for (g = amatches; g; g = g->next) {
char **pp = g->ylist;
int nl = 0, l;
if (pp) {
/* We have an ylist, lets see, if it contains newlines. */
while (!nl && *pp)
nl = !!strchr(*pp++, '\n');
pp = g->ylist;
if (nl) {
/* Yup, there are newlines, count lines. */
char *nlptr, *sptr;
g->flags |= CGF_LINES;
noselect = 1;
while ((sptr = *pp)) {
while (sptr && *sptr) {
nlines += (nlptr = strchr(sptr, '\n'))
? 1 + (nlptr-sptr)/columns
: strlen(sptr)/columns;
sptr = nlptr ? nlptr+1 : NULL;
}
nlines++;
pp++;
}
nlines--;
} else {
while (*pp) {
if ((l = strlen(*pp)) > longest)
longest = l;
nlist++;
pp++;
}
}
} else {
for (p = g->matches; (m = *p); p++) {
if (!(m->flags & CMF_NOLIST)) {
if ((l = niceztrlen(m->str)) > longest)
longest = l;
nlist++;
} else
noselect = 1;
}
}
if ((e = g->expls)) {
while (*e) {
if ((*e)->count)
nlines += 1 + printfmt((*e)->str, (*e)->count, 0);
e++;
}
}
}
longest += 2 + of;
if ((ncols = (columns + 1) / longest)) {
for (g = amatches; g; g = g->next)
nlines += (g->lcount + ncols - 1) / ncols;
} else {
ncols = 1;
opl = 1;
for (g = amatches; g; g = g->next) {
char **pp = g->ylist;
if (pp) {
if (!(g->flags & CGF_LINES)) {
while (*pp) {
nlines += 1 + (strlen(*pp) / columns);
pp++;
}
}
} else
for (p = g->matches; (m = *p); p++)
if (!(m->flags & CMF_NOLIST))
nlines += 1 + ((1 + niceztrlen(m->str)) / columns);
}
}
/* Maybe we have to ask if the user wants to see the list. */
if ((!minfo.cur || !minfo.asked) &&
((complistmax && nlist > complistmax) ||
(!complistmax && nlines >= lines))) {
int qup;
zsetterm();
qup = printfmt("zsh: do you wish to see all %n possibilities? ", nlist, 1);
fflush(shout);
if (getzlequery() != 'y') {
if (clearflag) {
putc('\r', shout);
tcmultout(TCUP, TCMULTUP, qup);
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
tcmultout(TCUP, TCMULTUP, nlnct);
} else
putc('\n', shout);
noselect = 1;
if (minfo.cur)
minfo.asked = 2;
return 1;
}
if (clearflag) {
putc('\r', shout);
tcmultout(TCUP, TCMULTUP, qup);
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
} else
putc('\n', shout);
settyinfo(&shttyinfo);
if (minfo.cur)
minfo.asked = 1;
}
if (mselect >= 0) {
int i;
i = ncols * nlines;
free(mtab);
mtab = (Cmatch **) zalloc(i * sizeof(Cmatch **));
memset(mtab, 0, i * sizeof(Cmatch **));
free(mgtab);
mgtab = (Cmgroup *) zalloc(i * sizeof(Cmgroup));
memset(mgtab, 0, i * sizeof(Cmgroup));
mcols = ncols;
mlines = nlines;
}
/* Now print the matches. */
g = amatches;
while (g) {
char **pp = g->ylist;
if ((e = g->expls)) {
while (*e) {
if ((*e)->count) {
if (pnl) {
putc('\n', shout);
pnl = 0;
ml++;
}
ml += printfmt((*e)->str, (*e)->count, 1);
pnl = 1;
}
e++;
}
}
if (pp && *pp) {
if (pnl) {
putc('\n', shout);
pnl = 0;
ml++;
}
if (g->flags & CGF_LINES) {
while (*pp) {
zputs(*pp, shout);
if (*++pp)
putc('\n', shout);
}
} else {
int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, a;
char **pq;
while (n && nl--) {
i = ncols;
mc = 0;
pq = pp;
while (n && i--) {
if (pq - g->ylist >= g->lcount)
break;
zputs(*pq, shout);
if (i) {
a = longest - strlen(*pq);
while (a--)
putc(' ', shout);
}
pq += nc;
n--;
}
if (n) {
putc('\n', shout);
ml++;
}
pp++;
}
}
} else if (g->lcount) {
int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, j, a = 0;
int zt;
Cmatch *q;
if (n && pnl) {
putc('\n', shout);
pnl = 0;
ml++;
}
for (p = skipnolist(g->matches); n && nl--;) {
i = ncols;
mc = 0;
q = p;
while (n && i--) {
fputs(col.cols[COL_LC], shout);
if (!(m = *q)) {
fputs(col.cols[COL_MI], shout);
fputs(col.cols[COL_RC], shout);
a = longest - 2;
while (a--)
putc(' ', shout);
fputs(col.cols[COL_EC], shout);
break;
}
hasm = 1;
if (mselect >= 0) {
mtab[mc + (ncols * ml)] = q;
mgtab[mc + (ncols * ml)] = g;
}
if (m->gnum == mselect) {
mcol = mc;
mline = ml;
mmatch = q;
mgroup = g;
cc = COL_MA;
} else
cc = -1;
if (m->flags & CMF_FILE) {
struct stat buf;
char *pb;
pb = (char *) zhalloc((m->prpre ? strlen(m->prpre) : 0) +
3 + strlen(m->str));
sprintf(pb, "%s%s", (m->prpre ? m->prpre : "./"),
m->str);
zt = ztat(pb, &buf, 1);
if (cc >= 0)
fputs(col.cols[cc], shout);
else if (zt)
fputs(col.cols[COL_NO], shout);
else
fputs(getcolstr(&col, pb, buf.st_mode), shout);
fputs(col.cols[COL_RC], shout);
nicezputs(m->str, shout);
if (zt)
putc(' ', shout);
else
putc(file_type(buf.st_mode), shout);
} else {
fputs(col.cols[cc >= 0 ? cc : COL_NO], shout);
fputs(col.cols[COL_RC], shout);
nicezputs(m->str, shout);
if (of)
putc(' ', shout);
}
a = longest - niceztrlen(m->str) - 2 - of;
while (a--)
putc(' ', shout);
fputs(col.cols[COL_EC], shout);
if (i) {
fputs(col.cols[COL_LC], shout);
fputs(col.cols[COL_NO], shout);
fputs(col.cols[COL_RC], shout);
fputs(" ", shout);
fputs(col.cols[COL_EC], shout);
}
if (--n)
for (j = nc; j && *q; j--)
q = skipnolist(q + 1);
mc++;
}
if (i > 0) {
fputs(col.cols[COL_LC], shout);
fputs(col.cols[COL_MI], shout);
fputs(col.cols[COL_RC], shout);
a = longest - 2;
while (a--)
putc(' ', shout);
fputs(col.cols[COL_EC], shout);
}
if (n) {
putc('\n', shout);
ml++;
if (n && nl)
p = skipnolist(p + 1);
}
}
}
if (g->lcount)
pnl = 1;
g = g->next;
}
if (clearflag) {
/* Move the cursor up to the prompt, if always_last_prompt *
* is set and all that... */
if ((nlines += nlnct - 1) < lines) {
tcmultout(TCUP, TCMULTUP, nlines);
showinglist = -1;
listshown = 1;
} else
clearflag = 0, putc('\n', shout);
} else
putc('\n', shout);
if (!hasm || nlines >= lines)
noselect = 1;
return noselect;
}
typedef struct menustack *Menustack;
struct menustack {
Menustack prev;
char *line;
int cs;
struct menuinfo info;
};
static int
domenuselect(Hookdef dummy, Chdata dat)
{
Cmatch **p;
Cmgroup *pg;
Thingy cmd;
Menustack u = NULL;
int i = 0;
char *s;
if (getcols(NULL) || (dummy && (!(s = getsparam("SELECTMIN")) ||
(dat && dat->num < atoi(s)))))
return 1;
selectlocalmap(mskeymap);
noselect = 0;
mselect = (*(minfo.cur))->gnum;
for (;;) {
showinglist = -2;
zrefresh();
inselect = 1;
if (noselect)
break;
if (!i) {
i = mcols * mlines;
while (i--)
if (mtab[i])
break;
if (!i)
break;
i = 1;
}
p = mtab + mcol + (mline * mcols);
pg = mgtab + mcol + (mline * mcols);
minfo.cur = *p;
minfo.group = *pg;
getk:
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak) ||
cmd == Th(z_acceptline))
break;
else if (cmd == Th(z_acceptandhold) ||
cmd == Th(z_acceptandmenucomplete)) {
Menustack s = (Menustack) zhalloc(sizeof(*s));
s->prev = u;
u = s;
s->line = dupstring((char *) line);
s->cs = cs;
memcpy(&(s->info), &minfo, sizeof(struct menuinfo));
acceptlast();
do_menucmp(0);
mselect = (*(minfo.cur))->gnum;
continue;
} else if (cmd == Th(z_undo)) {
int l;
if (!u)
goto getk;
cs = 0;
foredel(ll);
spaceinline(l = strlen(u->line));
strncpy((char *) line, u->line, l);
cs = u->cs;
memcpy(&minfo, &(u->info), sizeof(struct menuinfo));
p = &(minfo.cur);
u = u->prev;
} else if (cmd == Th(z_redisplay)) {
redisplay(zlenoargs);
continue;
} else if (cmd == Th(z_clearscreen)) {
clearscreen(zlenoargs);
continue;
} else if (cmd == Th(z_downhistory) ||
cmd == Th(z_downlineorhistory) ||
cmd == Th(z_downlineorsearch) ||
cmd == Th(z_vidownlineorhistory)) {
do {
if (mline == mlines - 1) {
p -= mline * mcols;
mline = 0;
} else {
mline++;
p += mcols;
}
} while (!*p);
} else if (cmd == Th(z_uphistory) ||
cmd == Th(z_uplineorhistory) ||
cmd == Th(z_uplineorsearch) ||
cmd == Th(z_viuplineorhistory)) {
do {
if (!mline) {
mline = mlines - 1;
p += mline * mcols;
} else {
mline--;
p -= mcols;
}
} while (!*p);
} else if (cmd == Th(z_forwardchar) || cmd == Th(z_viforwardchar)) {
do {
if (mcol == mcols - 1) {
p -= mcol;
mcol = 0;
} else {
mcol++;
p++;
}
} while (!*p);
} else if (cmd == Th(z_backwardchar) || cmd == Th(z_vibackwardchar)) {
do {
if (!mcol) {
mcol = mcols - 1;
p += mcol;
} else {
mcol--;
p--;
}
} while (!*p);
} else if (cmd == Th(z_beginningofbufferorhistory) ||
cmd == Th(z_beginningofline) ||
cmd == Th(z_beginningoflinehist) ||
cmd == Th(z_vibeginningofline)) {
p -= mcol;
mcol = 0;
while (!*p) {
mcol++;
p++;
}
} else if (cmd == Th(z_endofbufferorhistory) ||
cmd == Th(z_endofline) ||
cmd == Th(z_endoflinehist) ||
cmd == Th(z_viendofline)) {
p += mcols - mcol - 1;
mcol = mcols - 1;
while (!*p) {
mcol--;
p--;
}
} else if (cmd == Th(z_forwardword) ||
cmd == Th(z_emacsforwardword) ||
cmd == Th(z_viforwardword) ||
cmd == Th(z_viforwardwordend)) {
Cmgroup g = *pg;
int ol = mline;
do {
if (mline == mlines - 1) {
p -= mline * mcols;
pg -= mline * mcols;
mline = 0;
} else {
mline++;
p += mcols;
pg += mcols;
}
} while (ol != mline && (*pg == g || !*pg));
} else if (cmd == Th(z_backwardword) ||
cmd == Th(z_emacsbackwardword) ||
cmd == Th(z_vibackwardword)) {
Cmgroup g = *pg;
int ol = mline;
do {
if (!mline) {
mline = mlines - 1;
p += mline * mcols;
pg += mline * mcols;
} else {
mline--;
p -= mcols;
pg -= mcols;
}
} while (ol != mline && (*pg == g || !*pg));
} else if (cmd == Th(z_completeword) ||
cmd == Th(z_expandorcomplete) ||
cmd == Th(z_expandorcompleteprefix) ||
cmd == Th(z_menucomplete) ||
cmd == Th(z_menuexpandorcomplete) ||
!strcmp(cmd->nam, "menu-select") ||
!strcmp(cmd->nam, "complete-word") ||
!strcmp(cmd->nam, "expand-or-complete") ||
!strcmp(cmd->nam, "expand-or-complete-prefix") ||
!strcmp(cmd->nam, "menu-complete") ||
!strcmp(cmd->nam, "menu-expand-or-complete")) {
do_menucmp(0);
mselect = (*(minfo.cur))->gnum;
continue;
} else if (cmd == Th(z_reversemenucomplete) ||
!strcmp(cmd->nam, "reverse-menu-complete")) {
reversemenucomplete(zlenoargs);
mselect = (*(minfo.cur))->gnum;
continue;
} else {
ungetkeycmd();
break;
}
do_single(**p);
mselect = (**p)->gnum;
}
selectlocalmap(NULL);
mselect = -1;
inselect = 0;
if (!noselect) {
showinglist = -2;
zrefresh();
}
return noselect;
}
/* The widget function. */
static int
menuselect(char **args)
{
int d = 0;
if (!minfo.cur) {
menucomplete(args);
if ((minfo.cur && minfo.asked == 2) || getsparam("ZLS_SELECT"))
return 0;
d = 1;
}
if (minfo.cur && (minfo.asked == 2 || domenuselect(NULL, NULL)) && !d)
menucomplete(args);
return 0;
}
/**/
int
setup_complist(Module m)
{
return 0;
}
/**/
int
boot_complist(Module m)
{
mtab = NULL;
mgtab = NULL;
mselect = -1;
inselect = 0;
w_menuselect = addzlefunction("menu-select", menuselect,
ZLE_MENUCMP|ZLE_KEEPSUFFIX|ZLE_ISCOMP);
if (!w_menuselect) {
zwarnnam(m->nam, "name clash when adding ZLE function `menu-select'",
NULL, 0);
return -1;
}
addhookfunc("list_matches", (Hookfn) complistmatches);
addhookfunc("menu_start", (Hookfn) domenuselect);
mskeymap = newkeymap(NULL, "menuselect");
linkkeymap(mskeymap, "menuselect", 1);
bindkey(mskeymap, "\t", refthingy(t_completeword), NULL);
bindkey(mskeymap, "\n", refthingy(t_acceptline), NULL);
bindkey(mskeymap, "\r", refthingy(t_acceptline), NULL);
bindkey(mskeymap, "\33[A", refthingy(t_uplineorhistory), NULL);
bindkey(mskeymap, "\33[B", refthingy(t_downlineorhistory), NULL);
bindkey(mskeymap, "\33[C", refthingy(t_forwardchar), NULL);
bindkey(mskeymap, "\33[D", refthingy(t_backwardchar), NULL);
bindkey(mskeymap, "\33OA", refthingy(t_uplineorhistory), NULL);
bindkey(mskeymap, "\33OB", refthingy(t_downlineorhistory), NULL);
bindkey(mskeymap, "\33OC", refthingy(t_forwardchar), NULL);
bindkey(mskeymap, "\33OD", refthingy(t_backwardchar), NULL);
return 0;
}
#ifdef MODULE
/**/
int
cleanup_complist(Module m)
{
free(mtab);
free(mgtab);
deletezlefunction(w_menuselect);
deletehookfunc("list_matches", (Hookfn) complistmatches);
deletehookfunc("menu_start", (Hookfn) domenuselect);
unlinkkeymap("menuselect", 1);
return 0;
}
/**/
int
finish_complist(Module m)
{
return 0;
}
#endif

3
Src/Zle/complist.mdd Normal file
View file

@ -0,0 +1,3 @@
moddeps="comp1 zle"
objects="complist.o"