* PATCH: expand existing $'...' in completion string
@ 2007-08-30 21:41 Peter Stephenson
0 siblings, 0 replies; only message in thread
From: Peter Stephenson @ 2007-08-30 21:41 UTC (permalink / raw)
To: Zsh hackers list
This is supposed to help completion of strings with unprintable/invalid
characters by expanding existing $'...' strings that are already on the
command line when completion starts. You won't be surprised to hear
this is fairly hairy; there are lots of ill-documented offsets to get
right. I've actually tried it out with normal characters. For example,
h$'\x69'$'\x73' is treated as "his" and so completes to hist.c etc.
(The expression is unquoted and then requoted later; attempting to
preserve the original quoting would be highly complicated and didn't
seem worthwhile.)
I've tried to cover problem cases such as where the $' expression
isn't finished, or when the cursor is in the middle of it, by simply
leaving the expression alone.
It seemed to handle the following case:
% touch A\ B
% echo A$'\x20'<TAB>
% echo A\ B
at which point I decided it was time to leave well alone.
I'm sure you'll let me know if it doesn't work.
Index: Src/Zle/zle_tricky.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_tricky.c,v
retrieving revision 1.87
diff -u -r1.87 zle_tricky.c
--- Src/Zle/zle_tricky.c 29 May 2007 17:01:09 -0000 1.87
+++ Src/Zle/zle_tricky.c 30 Aug 2007 21:30:55 -0000
@@ -1611,7 +1611,90 @@
/* While building the quoted form, we also clean up the command line. */
for (p = s, i = wb, j = 0; *p; p++, i++) {
int skipchars;
- if ((*p == String || *p == Qstring) && p[1] == Snull)
+ if (*p == String && p[1] == Snull) {
+ char *pe;
+ for (pe = p + 2; *pe && *pe != Snull && i + (pe - p) < zlemetacs;
+ pe++)
+ ;
+ if (!*pe) {
+ /* no terminating Snull, can't substitute */
+ skipchars = 2;
+ } else {
+ /*
+ * Try and substitute the $'...' expression.
+ */
+ int len, tlen;
+ char *t = getkeystring(p + 2, &len, GETKEYS_DOLLARS_QUOTE,
+ NULL);
+ len += 2;
+ tlen = strlen(t);
+ skipchars = len - tlen;
+ /*
+ * If this makes the line longer, we don't attempt
+ * to substitute it. This is because "we" don't
+ * really understand what the heck is going on anyway
+ * and have blindly copied the code here from
+ * the sections below.
+ */
+ if (skipchars >= 0) {
+ /* Update the completion string */
+ memcpy(p, t, tlen);
+ /* Update the version of the line we are operating on */
+ ocs = zlemetacs;
+ zlemetacs = i;
+ if (skipchars > 0) {
+ /* Move the tail of the completion string up. */
+ char *dptr = p + tlen;
+ char *sptr = p + len;
+ while ((*dptr++ = *sptr++))
+ ;
+ /*
+ * If the character is before the cursor, we need to
+ * update the offset into the completion string to the
+ * cursor position, too. (Use ocs since we've hacked
+ * zlemetacs at this point.)
+ */
+ if (i < ocs)
+ offs -= skipchars;
+ /* Move the tail of the line up */
+ foredel(skipchars);
+ /*
+ * Update the offset into the command line to the
+ * cursor position if that's after the current position.
+ */
+ if ((zlemetacs = ocs) > i)
+ zlemetacs -= skipchars;
+ /* Always update the word end. */
+ we -= skipchars;
+ }
+ /*
+ * Copy the unquoted string into place, which
+ * now has the correct size.
+ */
+ memcpy(zlemetaline + i, t, tlen);
+
+ /*
+ * Move both the completion string pointer
+ * and the command line offset to the end of
+ * the chunk we've copied in (minus 1 for
+ * the end of loop increment). The line
+ * and completion string chunks are now the
+ * same length.
+ */
+ p += tlen - 1;
+ i += tlen - 1;
+ continue;
+ } else {
+ /*
+ * We give up if the expansion is longer the original
+ * string. That's because "we" don't really have the
+ * first clue how the completion system actually works.
+ */
+ skipchars = 2;
+ }
+ }
+ }
+ else if (*p == Qstring && p[1] == Snull)
skipchars = 2;
else if (inull(*p))
skipchars = 1;
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-08-30 21:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-30 21:41 PATCH: expand existing $'...' in completion string Peter Stephenson
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).