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

*** empty log message ***

This commit is contained in:
Sven Wischnowsky 2001-01-11 10:06:40 +00:00
parent 1853089714
commit 2a78c24842
7 changed files with 196 additions and 37 deletions

View file

@ -1,3 +1,11 @@
2001-01-11 Sven Wischnowsky <wischnow@zsh.org>
* 13339: Doc/Zsh/compwid.yo, Doc/Zsh/contrib.yo,
Functions/Zle/cycle-completion-positions, Src/Zle/comp.h,
Src/Zle/complete.c, Src/Zle/compresult.c: add
unambiguous_positions and insert_positions keys to $compstate; use
them in the new cycle-completion-positions shell function widget
2001-01-10 Geoff Wing <gcw@zsh.org>
* unposted: Etc/MACHINES: format leading spaces to tabs

View file

@ -240,6 +240,14 @@ matches generated be ignored and only the TAB be inserted.
Finally, it may also be set to tt(all), which makes all matches
generated be inserted into the line.
)
vindex(insert_positions, compstate)
item(tt(insert_positions))(
When the completion system inserts an unambiguous string into the
line, there may be multiple places where characters are missing or
where the character inserted differs from at least one match. The
value of this key contains a colon separated list of all these
positions, as indexes into the command line.
)
vindex(last_prompt, compstate)
item(tt(last_prompt))(
If this is set to an non-empty string for every match added, the
@ -397,6 +405,13 @@ common prefix in the tt(unambiguous) key were inserted, relative to
the value of that key. The cursor would be placed before the character
whose index is given by this key.
)
vindex(unambiguous_positions, compstate)
item(tt(unambiguous_positions))(
This contains all positions where characters in the unambiguous string
are missing or where the character inserted differs from at least one
of the matches. The positions are given as indexes into the string
given by the value of the tt(uanmbiguous) key.
)
vindex(vared, compstate)
item(tt(vared))(
If completion is called while editing a line using the tt(vared)

View file

@ -316,6 +316,20 @@ followed by an appropriate tt(bindkey) command to associate the function
with a key sequence. Suggested bindings are described below.
startitem()
tindex(cycle-completion-positions)
item(tt(cycle-completion-positions))(
After inserting an unambiguous string into the command line, the new
function based completion system may know about multiple places in
this string where characters are missing or differ from at least one
of the possible matches. It will then place the cursor on the
position it considers to be the most interesting one, i.e. the one
where one can disambiguate between as many matches as possible with as
little typing as possible.
This widget allows to easily move the cursor to the other interesting
spots. It can be invoked repeatedly to cycle between all positions
reported by the completion system.
)
tindex(edit-command-line)
item(tt(edit-command-line))(
Edit the command line using your visual editor, as in tt(ksh).

View file

@ -0,0 +1,16 @@
# This may be called after a completion that inserted the unambiguous
# (i.e. non-menu- and non-single-match-) string into the command line.
# If there are multiple positions in the string with missing or differing
# characters, repeatedly calling this widget cycles between all these
# positions.
emulate -L zsh
setopt extendedglob
local p="$_lastcomp[insert_positions]"
if [[ $p = ((#s)|*:)${CURSOR}:* ]]; then
CURSOR=${${p#(|*:)${CURSOR}:}%%:*}
elif [[ -n $p ]]; then
CURSOR=${p%%:*}
fi

View file

@ -345,27 +345,31 @@ typedef void (*CLPrintFunc)(Cmgroup, Cmatch *, int, int, int, int,
#define CP_UNAMBIG (1 << CPN_UNAMBIG)
#define CPN_UNAMBIGC 14
#define CP_UNAMBIGC (1 << CPN_UNAMBIGC)
#define CPN_LISTMAX 15
#define CPN_UNAMBIGP 15
#define CP_UNAMBIGP (1 << CPN_UNAMBIGP)
#define CPN_INSERTP 16
#define CP_INSERTP (1 << CPN_INSERTP)
#define CPN_LISTMAX 17
#define CP_LISTMAX (1 << CPN_LISTMAX)
#define CPN_LASTPROMPT 16
#define CPN_LASTPROMPT 18
#define CP_LASTPROMPT (1 << CPN_LASTPROMPT)
#define CPN_TOEND 17
#define CPN_TOEND 19
#define CP_TOEND (1 << CPN_TOEND)
#define CPN_OLDLIST 18
#define CPN_OLDLIST 20
#define CP_OLDLIST (1 << CPN_OLDLIST)
#define CPN_OLDINS 19
#define CPN_OLDINS 21
#define CP_OLDINS (1 << CPN_OLDINS)
#define CPN_VARED 20
#define CPN_VARED 22
#define CP_VARED (1 << CPN_VARED)
#define CPN_LISTLINES 21
#define CPN_LISTLINES 23
#define CP_LISTLINES (1 << CPN_LISTLINES)
#define CPN_QUOTES 22
#define CPN_QUOTES 24
#define CP_QUOTES (1 << CPN_QUOTES)
#define CPN_IGNORED 23
#define CPN_IGNORED 25
#define CP_IGNORED (1 << CPN_IGNORED)
#define CP_KEYPARAMS 24
#define CP_ALLKEYS ((unsigned int) 0xffffff)
#define CP_KEYPARAMS 26
#define CP_ALLKEYS ((unsigned int) 0x3ffffff)
/* Hooks. */

View file

@ -956,6 +956,10 @@ static struct compparam compkparams[] = {
{ "unambiguous", PM_SCALAR | PM_READONLY, NULL, NULL, VAL(get_unambig) },
{ "unambiguous_cursor", PM_INTEGER | PM_READONLY, NULL, NULL,
VAL(get_unambig_curs) },
{ "unambiguous_positions", PM_SCALAR | PM_READONLY, NULL, NULL,
VAL(get_unambig_pos) },
{ "insert_positions", PM_SCALAR | PM_READONLY, NULL, NULL,
VAL(get_insert_pos) },
{ "list_max", PM_INTEGER, VAL(complistmax), NULL, NULL },
{ "last_prompt", PM_SCALAR, VAL(complastprompt), NULL, NULL },
{ "to_end", PM_SCALAR, VAL(comptoend), NULL, NULL },
@ -1103,7 +1107,7 @@ get_complist(Param pm)
static char *
get_unambig(Param pm)
{
return unambig_data(NULL);
return unambig_data(NULL, NULL, NULL);
}
/**/
@ -1112,11 +1116,33 @@ get_unambig_curs(Param pm)
{
int c;
unambig_data(&c);
unambig_data(&c, NULL, NULL);
return c;
}
/**/
static char *
get_unambig_pos(Param pm)
{
char *p;
unambig_data(NULL, &p, NULL);
return p;
}
/**/
static char *
get_insert_pos(Param pm)
{
char *p;
unambig_data(NULL, NULL, &p);
return p;
}
/**/
static void
compunsetfn(Param pm, int exp)

View file

@ -154,18 +154,20 @@ cut_cline(Cline l)
return l;
}
/* This builds the unambiguous string. If ins is non-zero, it is
* immediatly inserted in the line. Otherwise csp is used to return
* the relative cursor position in the string returned. */
/* This builds the unambiguous string. If ins is one, it is immediately
* inserted into the line. Otherwise csp is used to return the relative
* cursor position in the string returned and posl contains all
* positions with missing or ambiguous characters. If ins is two, csp
* and posl contain real command line positions (including braces). */
/**/
static char *
cline_str(Cline l, int ins, int *csp)
cline_str(Cline l, int ins, int *csp, LinkList posl)
{
Cline s;
int ocs = cs, ncs, pcs, scs;
int pm, pmax, pmm, pma, sm, smax, smm, sma, d, dm, mid;
int i, j, li = 0, cbr;
int i, j, li = 0, cbr, padd = (ins ? wb - ocs : -ocs);
Brinfo brp, brs;
l = cut_cline(l);
@ -222,6 +224,8 @@ cline_str(Cline l, int ins, int *csp)
if ((s->flags & CLF_DIFF) && (!dm || (s->flags & CLF_MATCHED))) {
d = cs; dm = s->flags & CLF_MATCHED;
if (posl)
addlinknode(posl, (void *) ((long) (cs + padd)));
}
li += s->llen;
}
@ -242,12 +246,15 @@ cline_str(Cline l, int ins, int *csp)
}
/* Remember the position if this is the first prefix with
* missing characters. */
if ((l->flags & CLF_MISS) && !(l->flags & CLF_SUF) &&
(((pmax < (l->max - l->min) || (pma && l->max != l->min)) &&
(!pmm || (l->flags & CLF_MATCHED))) ||
((l->flags & CLF_MATCHED) && !pmm))) {
pm = cs; pmax = l->max - l->min; pmm = l->flags & CLF_MATCHED;
pma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
if ((l->flags & CLF_MISS) && !(l->flags & CLF_SUF)) {
if (posl && l->min != l->max)
addlinknode(posl, (void *) ((long) (cs + padd)));
if (((pmax < (l->max - l->min) || (pma && l->max != l->min)) &&
(!pmm || (l->flags & CLF_MATCHED))) ||
((l->flags & CLF_MATCHED) && !pmm)) {
pm = cs; pmax = l->max - l->min; pmm = l->flags & CLF_MATCHED;
pma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
}
}
if (ins) {
int ocs, bl;
@ -291,12 +298,15 @@ cline_str(Cline l, int ins, int *csp)
if (l->flags & CLF_MISS) {
if (l->flags & CLF_MID)
mid = cs;
else if ((l->flags & CLF_SUF) &&
(((smax < (l->min - l->max) || (sma && l->max != l->min)) &&
(!smm || (l->flags & CLF_MATCHED))) ||
((l->flags & CLF_MATCHED) && !smm))) {
sm = cs; smax = l->min - l->max; smm = l->flags & CLF_MATCHED;
sma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
else if (l->flags & CLF_SUF) {
if (posl && l->min != l->max)
addlinknode(posl, (void *) ((long) (cs + padd)));
if (((smax < (l->min - l->max) || (sma && l->max != l->min)) &&
(!smm || (l->flags & CLF_MATCHED))) ||
((l->flags & CLF_MATCHED) && !smm)) {
sm = cs; smax = l->min - l->max; smm = l->flags & CLF_MATCHED;
sma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
}
}
}
if (ins) {
@ -389,10 +399,14 @@ cline_str(Cline l, int ins, int *csp)
cs += i;
if (j >= 0 && (!dm || (js->flags & CLF_MATCHED))) {
d = cs - j; dm = js->flags & CLF_MATCHED;
if (posl)
addlinknode(posl, (void *) ((long) (cs - j + padd)));
}
}
l = l->next;
}
if (posl)
addlinknode(posl, (void *) ((long) (cs + padd)));
if (ins) {
int ocs = cs;
@ -411,6 +425,17 @@ cline_str(Cline l, int ins, int *csp)
sm += cs - ocs;
if (d >= ocs)
d += cs - ocs;
if (posl) {
LinkNode node;
long p;
for (node = firstnode(posl); node; incnode(node)) {
p = (long) getdata(node);
if (p >= ocs)
setdata(node, (void *) (p + cs - ocs));
}
}
}
/* This calculates the new cursor position. If we had a mid cline
* with missing characters, we take this, otherwise if we have a
@ -420,7 +445,7 @@ cline_str(Cline l, int ins, int *csp)
(cbr >= 0 ? cbr :
(pm >= 0 ? pm : (sm >= 0 ? sm : (d >= 0 ? d : cs)))));
if (!ins) {
if (ins != 1) {
/* We always inserted the string in the line. If that was not
* requested, we copy it and remove from the line. */
char *r = zalloc((i = cs - ocs) + 1);
@ -430,7 +455,8 @@ cline_str(Cline l, int ins, int *csp)
cs = ocs;
foredel(i);
*csp = ncs - ocs;
if (csp)
*csp = ncs - ocs;
return r;
}
@ -440,31 +466,81 @@ cline_str(Cline l, int ins, int *csp)
return NULL;
}
/* Small utility function turning a list of positions into a colon
* separated string. */
static char *
build_pos_string(LinkList list)
{
LinkNode node;
int l;
char buf[40], *s;
for (node = firstnode(list), l = 0; node; incnode(node)) {
sprintf(buf, "%ld", (long) getdata(node));
setdata(node, dupstring(buf));
l += 1 + strlen(buf);
}
s = (char *) zalloc(l * sizeof(char));
*s = 0;
for (node = firstnode(list); node;) {
strcat(s, (char *) getdata(node));
incnode(node);
if (node)
strcat(s, ":");
}
return s;
}
/* This is a utility function using the function above to allow access
* to the unambiguous string and cursor position via compstate. */
/**/
char *
unambig_data(int *cp)
unambig_data(int *cp, char **pp, char **ip)
{
static char *scache = NULL;
static char *scache = NULL, *pcache = NULL, *icache = NULL;
static int ccache;
if (mnum && ainfo) {
if (mnum != unambig_mnum) {
LinkList list = newlinklist();
zsfree(scache);
scache = cline_str((ainfo->count ? ainfo->line : fainfo->line),
0, &ccache);
0, &ccache, list);
zsfree(pcache);
if (empty(list))
pcache = ztrdup("");
else
pcache = build_pos_string(list);
zsfree(icache);
list = newlinklist();
zsfree(cline_str((ainfo->count ? ainfo->line : fainfo->line),
2, NULL, list));
if (empty(list))
icache = ztrdup("");
else
icache = build_pos_string(list);
}
} else if (mnum != unambig_mnum || !ainfo || !scache) {
zsfree(scache);
scache = ztrdup("");
zsfree(pcache);
pcache = ztrdup("");
zsfree(icache);
icache = ztrdup("");
ccache = 0;
}
unambig_mnum = mnum;
if (cp)
*cp = ccache + 1;
if (pp)
*pp = pcache;
if (ip)
*ip = icache;
return scache;
}
@ -665,7 +741,7 @@ do_ambiguous(void)
foredel(we - wb);
/* Now get the unambiguous string and insert it into the line. */
cline_str(ainfo->line, 1, NULL);
cline_str(ainfo->line, 1, NULL, NULL);
/* Sometimes the different match specs used may result in a cline
* that gives an empty string. If that happened, we re-insert the