summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG4
-rw-r--r--src/complete.c30
2 files changed, 25 insertions, 9 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 356a67a..64a3dba 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,9 @@
$LAAS$
+ 5. Improved command-line completion engine when the smallest common
+ denominator of the available matches is smaller than the current
+ command-line.
+
4. Add -package command line option.
3. Look for packages in $(datadir)/* by default, and implement
diff --git a/src/complete.c b/src/complete.c
index 5ba1de2..f36a8c8 100644
--- a/src/complete.c
+++ b/src/complete.c
@@ -54,10 +54,10 @@ elTclCompletion(EditLine *el, int ch)
{
ElTclInterpInfo *iinfo;
const LineInfo *linfo;
- Tcl_Obj *cmd[2], *buffer, *arg, **matches;
+ Tcl_Obj *cmd[2], *buffer, *arg, **matches, *cmdLine;
Tcl_Channel outChannel;
- int i,j,k, start, end, count, length0, length1, max;
- char *string0, *string1;
+ int i,j,k, start, end, count, length0, length1, max, oldLen;
+ char *string0, *string1, *old;
int again, ncols, nitems;
char c;
@@ -69,9 +69,10 @@ elTclCompletion(EditLine *el, int ch)
* current command (any incomplete lines entered so far) plus the
* current editline buffer */
cmd[1] = Tcl_DuplicateObj(iinfo->command);
- buffer = Tcl_NewStringObj(linfo->buffer, linfo->cursor - linfo->buffer);
- Tcl_AppendObjToObj(cmd[1], buffer);
+ cmdLine = Tcl_NewStringObj(linfo->buffer, linfo->cursor - linfo->buffer);
+ Tcl_AppendObjToObj(cmd[1], cmdLine);
Tcl_IncrRefCount(cmd[1]);
+ Tcl_IncrRefCount(cmdLine);
/* call the procedure that generates completion matches */
cmd[0] = iinfo->matchesName;
@@ -101,6 +102,7 @@ elTclCompletion(EditLine *el, int ch)
if (count == 2) {
/* no match */
+ Tcl_DecrRefCount(cmdLine);
return CC_ERROR;
}
@@ -112,6 +114,7 @@ elTclCompletion(EditLine *el, int ch)
el_insertstr(el, Tcl_GetStringFromObj(arg, NULL));
Tcl_ListObjIndex(iinfo->interp, matches[2], 1, &arg);
el_insertstr(el, Tcl_GetStringFromObj(arg, NULL));
+ Tcl_DecrRefCount(cmdLine);
return CC_REFRESH;
}
@@ -123,12 +126,14 @@ elTclCompletion(EditLine *el, int ch)
if (el_getc(iinfo->el, &c) <= 0) {
fputc('\n', stdout);
+ Tcl_DecrRefCount(cmdLine);
return CC_REDISPLAY;
}
if (c != 'y' && c != 'Y') {
fputc(c, stdout);
fputc('\n', stdout);
+ Tcl_DecrRefCount(cmdLine);
return CC_REDISPLAY;
}
@@ -154,10 +159,17 @@ elTclCompletion(EditLine *el, int ch)
}
}
} while (again);
- c = string0[end+1];
- string0[end+1] = 0;
- el_insertstr(el, string0);
- string0[end+1] = c;
+
+ old = Tcl_GetStringFromObj(cmdLine, &oldLen);
+ if (end+start >= oldLen) {
+ c = string0[end+1];
+ string0[end+1] = 0;
+ el_insertstr(el, string0);
+ string0[end+1] = c;
+ } else {
+ el_insertstr(el, old + start);
+ }
+ Tcl_DecrRefCount(cmdLine);
/* find the biggest match (for multicol display) */
max = 0;