zsh-users
 help / color / mirror / code / Atom feed
* Two
@ 2009-03-12  6:20 Benjamin R. Haskell
  2009-03-12 17:35 ` Two Peter Stephenson
  0 siblings, 1 reply; 2+ messages in thread
From: Benjamin R. Haskell @ 2009-03-12  6:20 UTC (permalink / raw)
  To: Zsh Users

"^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


(i.e. the failing search becomes the current command line.)  Is there 
something like that in place already?  If not, what would be the best 
place to start tinkering?


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.

Best,
Ben


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Two
  2009-03-12  6:20 Two Benjamin R. Haskell
@ 2009-03-12 17:35 ` Peter Stephenson
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Stephenson @ 2009-03-12 17:35 UTC (permalink / raw)
  To: Zsh Users

On Thu, 12 Mar 2009 02:20:35 -0400 (EDT)
"Benjamin R. Haskell" <zsh@benizi.com> 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@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-03-12 17:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-12  6:20 Two Benjamin R. Haskell
2009-03-12 17:35 ` Two 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).