Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Two



On Thu, 12 Mar 2009 02:20:35 -0400 (EDT)
"Benjamin R. Haskell" <zsh@xxxxxxxxxx> wrote:
> "^R" history-incremental-search-backward  is probably the command I use 
> most frequently in Zsh (behind "^J" accept-line).  But, recently there are 
> two quirky traps that I've found myself falling into.
> 
> The first is that I've been switching between systems more frequently, so 
> things that I've recently typed (or frequently type) aren't necessarily in 
> my history on a given box.  It'd be nice to be able to go from:
> 
> $ (etc etc etc ... some partial match ... etc etc etc)
> failing bck-i-search: some commandli_
> 
> to:
> 
> $ some commandli

The following improves incremental search so (i) it reports a useful status
(ii) it stores a value on an aborted search.  With this, the widget
function

hipsb() {
  zle history-incremental-pattern-search-backward
  if [[ $? = 3 ]]; then
    BUFFER=$LASTABORTEDSEARCH
  fi
}

replaces the editing buffer with the aborted search if you abort (type
^G).  I've hijacked abort because if you exit normally typically the shell
is about to run some other command such as accept-line, though there are
enough statuses to handle that case:  a failure is 1 (or 2 if it was a bad
pattern in a pattern match), so you can detect that.  However, I don't
think you can stop it running any command that caused isearch to exit.
With recent code you can use the new accept-search binding.

I also spotted that $LASTSEARCH was broken by my change to improve
multibyte handling of isearch, so that's fixed, too.

> The second is simpler and similar.  Sometimes I just want to look back in 
> history for some clue as to the syntax of a command.  (Read: every time I 
> use mencoder.  Oy.)  What's the best way to:
> 
> 1. Have some command partially entered
> 2. Do some reverse search
> 3. Return to the partial command, with the search "result" still visible
> 
> Out of long-ingrained habit, I tend to:
> 
> 1. ^A Go to start of line
> 2. ^K Kill the line
> 3. ^R (some-search) Do some search
> 4. ^F Move forward a character (to prevent losing the "result" on-screen)
> 5. ^C Cancel the search
> 6. ^Y Yank the killed line
> 
> I suspect there's a way to combine #1 and #2, and it'd be nice if #4 and 
> #5 were unnecessary due to a better way to do #6.

I think the answer is push-line, usually bound to ^Q or \eq, but I'm not
quite sure what's happening in steps 4 and 5, i.e. I don't know how you're
exiting from the search or what you want to do with the search result.

--- /home/pws/src/zsh/Doc/Zsh/zle.yo	2009-02-05 09:49:39.000000000 +0000
+++ /home/pws/src/zsh-debug/zsh/Doc/Zsh/zle.yo	2009-03-12 17:23:00.000000000 +0000
@@ -721,10 +721,16 @@
 non-zero strings gives the current length, both as seen by the user at the
 command line.
 )
-
+vindex(LASTABORTEDSEARCH)
+item(tt(LASTABORTEDSEARCH) (scalar))(
+The last search string used by an interactive search that was
+aborted by the user (status 3 returned by the search widget).
+)
 vindex(LASTSEARCH)
 item(tt(LASTSEARCH) (scalar))(
-The last search string used by an interactive search ; read-only.
+The last search string used by an interactive search; read-only.
+This is set even if the search failed (status 0, 1 or 2 returned
+by the search widget), but not if it was aborted by the user.
 )
 vindex(LASTWIDGET)
 item(tt(LASTWIDGET) (scalar))(
@@ -1116,7 +1122,10 @@
 Search backward incrementally for a specified string.  The search is
 case-insensitive if the search string does not have uppercase letters and no
 numeric argument was given.  The string may begin with `tt(^)' to anchor the
-search to the beginning of the line.
+search to the beginning of the line.  When called from a user-defined
+function returns the following statuses: 0, if the search succeeded;
+1, if the search failed; 2, if the search term was a bad pattern;
+3, if the search was aborted by the tt(send-break) command.
 
 A restricted set of editing functions
 is available in the mini-buffer.  Keys are looked up in the special
--- /home/pws/src/zsh/Src/Zle/zle_hist.c	2009-03-12 16:22:48.000000000 +0000
+++ /home/pws/src/zsh-debug/zsh/Src/Zle/zle_hist.c	2009-03-12 17:20:55.000000000 +0000
@@ -44,10 +44,15 @@
 /* Previous search string use in an incremental search */
 
 /**/
-ZLE_STRING_T previous_search = NULL;
+char *previous_search = NULL;
 
 /**/
-int previous_search_len = 0;
+int previous_search_len;
+
+/* Previous aborted search string use in an incremental search */
+
+/**/
+char *previous_aborted_search = NULL;
 
 /* Local keymap in isearch mode */
 
@@ -891,32 +896,28 @@
 int
 historyincrementalsearchbackward(char **args)
 {
-    doisearch(args, -1, 0);
-    return 0;
+    return doisearch(args, -1, 0);
 }
 
 /**/
 int
 historyincrementalsearchforward(char **args)
 {
-    doisearch(args, 1, 0);
-    return 0;
+    return doisearch(args, 1, 0);
 }
 
 /**/
 int
 historyincrementalpatternsearchbackward(char **args)
 {
-    doisearch(args, -1, 1);
-    return 0;
+    return doisearch(args, -1, 1);
 }
 
 /**/
 int
 historyincrementalpatternsearchforward(char **args)
 {
-    doisearch(args, 1, 1);
-    return 0;
+    return doisearch(args, 1, 1);
 }
 
 static struct isrch_spot {
@@ -1023,6 +1024,24 @@
     return -1;
 }
 
+/*
+ * Save an isearch buffer from sbuf to sbuf+sbptr
+ * into the string *search with length *searchlen.
+ * searchlen may be NULL; the string is a NULL-terminated metafied string.
+ */
+static void
+save_isearch_buffer(char *sbuf, int sbptr,
+		    char **search, int *searchlen)
+{
+    if (*search)
+	free(*search);
+    *search = zalloc(sbptr+1);
+    memcpy(*search, sbuf, sbptr);
+    if (searchlen)
+	*searchlen = sbptr;
+    (*search)[sbptr] = '\0';
+}
+
 #define ISEARCH_PROMPT		"XXXXXXX XXX-i-search: "
 #define FAILING_TEXT		"failing"
 #define INVALID_TEXT		"invalid"
@@ -1034,12 +1053,15 @@
 int isearch_active, isearch_startpos, isearch_endpos;
 
 /**/
-static void
+static int
 doisearch(char **args, int dir, int pattern)
 {
     /* The full search buffer, including space for all prompts */
     char *ibuf = zhalloc(80);
-    /* The part of the search buffer with the search string */
+    /*
+     * The part of the search buffer with the search string.
+     * This is a normal metafied string.
+     */
     char *sbuf = ibuf + FIRST_SEARCH_CHAR;
     /* The previous line shown to the user */
     char *last_line = NULL;
@@ -1141,9 +1163,13 @@
      * command line.
      */
     ZleIntFunc exitfn = (ZleIntFunc)0;
+    /*
+     * Flag that the search was aborted.
+     */
+    int aborted = 0;
 
     if (!(he = quietgethist(hl)))
-	return;
+	return 1;
 
     selectlocalmap(isearch_keymap);
 
@@ -1446,6 +1472,9 @@
 	zrefresh();
 	if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
 	    int i;
+	    aborted = 1;
+	    save_isearch_buffer(sbuf, sbptr,
+				&previous_aborted_search, NULL);
 	    get_isrch_spot(0, &hl, &pos, &pat_hl, &pat_pos, &end_pos,
 			   &i, &sbptr, &dir, &nomatch);
 	    he = quietgethist(hl);
@@ -1597,8 +1626,12 @@
 #endif
 	    } else {
 		ungetkeycmd();
-		if (cmd == Th(z_sendbreak))
+		if (cmd == Th(z_sendbreak)) {
+		    aborted = 1;
+		    save_isearch_buffer(sbuf, sbptr,
+					&previous_aborted_search, NULL);
 		    sbptr = 0;
+		}
 		break;
 	    }
 	ins:
@@ -1629,9 +1662,8 @@
 	feep = 0;
     }
     if (sbptr) {
-	zfree(previous_search, previous_search_len);
-	previous_search = zalloc(sbptr);
-	memcpy(previous_search, sbuf, previous_search_len = sbptr);
+	save_isearch_buffer(sbuf, sbptr,
+			    &previous_search, &previous_search_len);
     }
     statusline = NULL;
     unmetafy_line();
@@ -1650,6 +1682,8 @@
 	kungetct = savekeys;
 
     selectlocalmap(NULL);
+
+    return aborted ? 3 : nomatch;
 }
 
 static Histent
--- /home/pws/src/zsh/Src/Zle/zle_params.c	2009-03-12 16:22:48.000000000 +0000
+++ /home/pws/src/zsh-debug/zsh/Src/Zle/zle_params.c	2009-03-12 16:38:16.000000000 +0000
@@ -54,6 +54,8 @@
 { get_keymap, nullstrsetfn, zleunsetfn };
 static const struct gsu_scalar keys_gsu =
 { get_keys, nullstrsetfn, zleunsetfn };
+static const struct gsu_scalar lastabortedsearch_gsu =
+{ get_lasearch, nullstrsetfn, zleunsetfn };
 static const struct gsu_scalar lastsearch_gsu =
 { get_lsearch, nullstrsetfn, zleunsetfn };
 static const struct gsu_scalar lastwidget_gsu =
@@ -115,6 +117,8 @@
     { "KEYMAP", PM_SCALAR | PM_READONLY, GSU(keymap_gsu), NULL },
     { "KEYS", PM_SCALAR | PM_READONLY, GSU(keys_gsu), NULL },
     { "killring", PM_ARRAY, GSU(killring_gsu), NULL },
+    { "LASTABORTEDSEARCH", PM_SCALAR | PM_READONLY, GSU(lastabortedsearch_gsu),
+      NULL },
     { "LASTSEARCH", PM_SCALAR | PM_READONLY, GSU(lastsearch_gsu), NULL },
     { "LASTWIDGET", PM_SCALAR | PM_READONLY, GSU(lastwidget_gsu), NULL },
     { "LBUFFER", PM_SCALAR,  GSU(lbuffer_gsu), NULL },
@@ -641,12 +645,19 @@
 
 /**/
 static char *
+get_lasearch(UNUSED(Param pm))
+{
+    if (previous_aborted_search)
+	return previous_aborted_search;
+    return "";
+}
+
+/**/
+static char *
 get_lsearch(UNUSED(Param pm))
 {
-    if (previous_search_len) {
-	return zlelineasstring(previous_search, previous_search_len, 0,
-			       NULL, NULL, 1);
-    }
+    if (previous_search)
+	return previous_search;
     return "";
 }
 
-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



Messages sorted by: Reverse Date, Date, Thread, Author