Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Completion for brace expansion (zsh 3.1.2)
- X-seq: zsh-workers 3438
- From: Peter Stephenson <pws@xxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxxx (Zsh hackers list)
- Subject: Completion for brace expansion (zsh 3.1.2)
- Date: Tue, 12 Aug 1997 17:30:56 +0200
Here's some code to allow completion of expressions being expanded by
brace expansion, something I've wanted for ages. It was much simpler
and neater than I'd expected, which is a tribute to all the tidying up
that's been done on the completion code. It seems to work like a
charm and I've adapted the AUTO_PARAM_KEYS code to help it along.
For example, in the zsh source directory (with AUTO_PARAM_KEYS set):
% ls mk*
mkbltnmlst.sh mkstamp.sh
% echo mk{bl<TAB> ---> mk{bltnmlst.sh _
% echo mk{bltnmlst.sh,st<TAB> ---> mk{bltnmlst.sh,stamp.sh _
^comma is magic, space deleted
% echo mk{bltnmlst.sh,stamp.sh}
^ likewise with closing brace
COMPLETE_IN_WORD also works well (e.g. try mk{bl<TAB>}.sh and see what
happens). The most significant limitation is that only one layer of
braces is handled. The real problem comes when there is already a
complete brace expansion elsewhere in the string, then it becomes much
harder.
*** Doc/Zsh/options.yo.brace Thu Jun 26 18:33:51 1997
--- Doc/Zsh/options.yo Tue Aug 12 17:01:04 1997
***************
*** 99,105 ****
(normally a space) automatically
inserted, and the next character typed is one
of those that have to come directly after the name (like `tt(})', `tt(:)',
! etc.), the character is inserted em(before) the space rather than after.
)
pindex(AUTO_PARAM_SLASH)
item(tt(AUTO_PARAM_SLASH))(
--- 99,109 ----
(normally a space) automatically
inserted, and the next character typed is one
of those that have to come directly after the name (like `tt(})', `tt(:)',
! etc.), the character is inserted em(before) the space rather than
! after. Brace expansion is handled similarly, assuming
! tt(IGNORE_BRACES) is not set: if a completion was made in an
! unfinished brace expansion, then typing a comma or closing brace will
! cause it to be added before the space.
)
pindex(AUTO_PARAM_SLASH)
item(tt(AUTO_PARAM_SLASH))(
*** Src/Zle/zle_misc.c.brace Fri Jul 4 14:55:07 1997
--- Src/Zle/zle_misc.c Tue Aug 12 16:53:26 1997
***************
*** 67,77 ****
if (complexpect == 2 && /*{*/ c1 == '}') {
cs -= ks = addedsuffix;
complexpect = 0;
! } else if (c1 == ':' || c1 == '[' || (complexpect == 2 &&
(c1 == '#' || c1 == '%' || c1 == '-' ||
! c1 == '?' || c1 == '+' || c1 == '=')))
/* Otherwise, if the character being added needs to come *
! * immediately after the parameter name, remove the suffix. */
removesuffix();
}
ncs = neg ? cs : cs + m * len;
--- 67,80 ----
if (complexpect == 2 && /*{*/ c1 == '}') {
cs -= ks = addedsuffix;
complexpect = 0;
! } else if ((complexpect < 3 && (c1 == ':' || c1 == '[')) ||
! (complexpect == 2 &&
(c1 == '#' || c1 == '%' || c1 == '-' ||
! c1 == '?' || c1 == '+' || c1 == '=')) ||
! (complexpect == 3 && (c1 == '}' || c1 == ',')))
/* Otherwise, if the character being added needs to come *
! * immediately after the parameter name, remove the suffix. *
! * We also deal with brace expansion (no '$') here. */
removesuffix();
}
ncs = neg ? cs : cs + m * len;
*** Src/Zle/zle_tricky.c.brace Tue Aug 5 09:35:40 1997
--- Src/Zle/zle_tricky.c Tue Aug 12 16:50:26 1997
***************
*** 104,109 ****
--- 104,114 ----
static int menuce;
+ /* This is used as a flag from get_comp_string() that we are doing *
+ * completion inside a brace expansion. */
+
+ static int complinbrace;
+
/* The list of matches. fmatches contains the matches we first ignore *
* because of fignore. */
***************
*** 847,852 ****
--- 852,858 ----
int t0, tt0, i, j, k, cp, rd, sl, ocs;
char *s = NULL, *linptr, *tmp, *p, *tt = NULL;
+ complinbrace = 0;
/* This global flag is used to signal the lexer code if it should *
* expand aliases or not. */
noaliases = isset(COMPLETEALIASES);
***************
*** 1120,1125 ****
--- 1126,1199 ----
}
chuck(p--);
}
+
+ if (!isset(IGNOREBRACES)) {
+ /* Try and deal with foo{xxx etc.; only simple cases
+ * (only one inbrace, completion after inbrace and before outbrace
+ * if present).
+ */
+ int myoffs = isset(COMPLETEINWORD) ? offs : strlen(s);
+ tt = NULL;
+ /* First check the conditions mentioned above
+ * and locate opening brace
+ */
+ for (i = 0, p = s; *p; p++, i++) {
+ /* careful, ${... is not a brace expansion...
+ * in fact, if it's got a substitution in it's too
+ * hard for us anyway. sorry.
+ */
+ if (*p == String || *p == Qstring) {
+ tt = NULL;
+ break;
+ } else if (*p == Inbrace) {
+ if (tt) {
+ /* too many inbraces */
+ tt = NULL;
+ break;
+ }
+ tt = p;
+ } else if (*p == Outbrace && i < myoffs) {
+ /* outbrace is before cursor pos, so nothing to complete */
+ tt = NULL;
+ break;
+ }
+ }
+
+ if (tt && tt < s + myoffs) {
+ /* Braces are go: delete opening brace */
+ char *com = NULL;
+ chuck(tt);
+ offs--;
+ myoffs--;
+
+ /* Look for text up to comma before cursor and delete it */
+ for (i = tt - s, p = tt; *p && i < myoffs; p++, i++)
+ if (*p == Comma)
+ com = p;
+ if (com) {
+ i = com - tt + 1;
+ while (i--)
+ chuck(tt), offs--, myoffs--;
+ }
+
+ /* Look for text between subsequent comma
+ * and closing brace or end of string and delete it
+ */
+ for (p = s + myoffs; *p && *p != Outbrace; p++)
+ if (*p == Comma) {
+ while (*p && *p != Outbrace)
+ chuck(p);
+ break;
+ }
+ if (*p == Outbrace)
+ chuck(p);
+ else {
+ /* we are still waiting for an outbrace and maybe commas */
+ complinbrace = 1;
+ }
+ }
+ }
+
} LASTALLOC;
lexrestore();
***************
*** 2335,2340 ****
--- 2409,2416 ----
cc_dummy.mask = CC_PARAMS | CC_ENVVARS;
} else
complexpect = 0;
+ } else if (complinbrace) {
+ complexpect = 3;
}
ooffs = offs;
/* If we have to ignore the word, do that. */
--
Peter Stephenson <pws@xxxxxx> Tel: +49 33762 77366
WWW: http://www.ifh.de/~pws/ Fax: +49 33762 77413
Deutsches Elektronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen
DESY-IfH, Platanenallee 6, 15738 Zeuthen, Germany.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author