Subject: Re: [PATCH] Expose isearch and suffix regions to widgets.
From: Daniel Shahaf <[email-masked]>
To: m0viefreak <[email-masked]>
Cc: [email-masked]
Date: Sat, 23 Apr 2016 21:36:07 +0000
List-Id: Zsh Workers List <zsh-workers.zsh.org>

m0viefreak wrote on Sat, Apr 16, 2016 at 18:17:40 +0200:
> 
> 
> On 11.04.2016 16:25, Bart Schaefer wrote:
> > On Apr 11,  6:16am, Daniel Shahaf wrote:
> > } Subject: Re: [PATCH] Expose isearch and suffix regions to widgets.
> > }
> > } m0viefreak wrote on Sun, Apr 10, 2016 at 15:10:39 +0200:
> > } > ISEARCH_ACTIVE does not describe the fact that the minibuffer is active,
> > } > but the fact that a pattern that was typed in there does actually
> > } > matches the BUFFER.
> > } 
> > } Rename the shell parameter, then?
> > 
> > ISEARCH_MATCH ?  (I wonder if, like $MATCH, it could contain the actual
> > matched string, instead of merely being a boolean.)
> 
> 
> I think ISEARCH_MATCH would be the ideal name, if the matched string was
> exposed, but I haven't found a simple way to do that.
> 

Something like the attached, perhaps?  Do you think something like this
should be added?  (Myself, I'm not sure, since the value would be
derivable from the three ISEARCHMATCH_* parameters' values.)

> On the other hand, I would also like to keep the _ACTIVE part at the
> end, to keep all four of those special parameters named similarly:
> 
> {YANK,SUFFIX,REGION,ISEARCH}_ACTIVE
> 
> What do you think of ISEARCHMATCH_{ACTIVE,START,END}?
> 
> That would still reflect that it's merely a boolean flag, while still
> keeping the semantic that it describes the match.

I've (rebased and) applied this.  We can tweak it further if needed.

Cheers,

Daniel
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 80d3f39..7c3e46b 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -835,6 +835,10 @@ which always gives the number of the history line being added to the main
 shell's history.  tt(HISTNO) refers to the line being retrieved within
 zle.
 )
+vindex(ISEARCH_MATCH)
+item(tt(ISEARCH_MATCH) (scalar))(
+TODO: TBW
+)
 vindex(ISEARCHMATCH_ACTIVE)
 vindex(ISEARCHMATCH_START)
 vindex(ISEARCHMATCH_END)
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index c6387bf..4f66be1 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -78,6 +78,8 @@ static const struct gsu_scalar widgetstyle_gsu =
 { get_widgetstyle, nullstrsetfn, zleunsetfn };
 static const struct gsu_scalar zle_state_gsu =
 { get_zle_state, nullstrsetfn, zleunsetfn };
+static const struct gsu_scalar isearchmatch_gsu =
+{ get_isearchmatch, NULL, zleunsetfn };
 
 static const struct gsu_integer bufferlines_gsu =
 { get_bufferlines, NULL, zleunsetfn };
@@ -167,6 +169,7 @@ static struct zleparam {
     { "ISEARCHMATCH_START", PM_INTEGER, GSU(isearchmatchstart_gsu), NULL },
     { "ISEARCHMATCH_END", PM_INTEGER, GSU(isearchmatchend_gsu), NULL },
     { "ISEARCHMATCH_ACTIVE", PM_INTEGER | PM_READONLY, GSU(isearchmatchactive_gsu), NULL },
+    { "ISEARCH_MATCH", PM_SCALAR | PM_READONLY, GSU(isearchmatch_gsu), NULL },
     { "SUFFIX_START", PM_INTEGER, GSU(suffixstart_gsu), NULL },
     { "SUFFIX_END", PM_INTEGER, GSU(suffixend_gsu), NULL },
     { "SUFFIX_ACTIVE", PM_INTEGER | PM_READONLY, GSU(suffixactive_gsu), NULL },
@@ -876,3 +879,26 @@ get_zle_state(UNUSED(Param pm))
 
     return zle_state;
 }
+
+/**/
+static char *
+get_isearchmatch(UNUSED(Param pm))
+{
+    Param pm_BUFFER;
+    const char *val_BUFFER;
+    char *val;
+    size_t nbytes;
+
+    /* ### TODO: Maybe just call get_buffer() directly without going through paramtab? */
+    pm_BUFFER  = (Param) paramtab->getnode(paramtab, "BUFFER");
+    val_BUFFER = pm_BUFFER->gsu.s->getfn(pm_BUFFER); /* heap allocated */
+
+    if (! isearch_active)
+	/* TODO: what to do? */;
+
+    nbytes = isearch_endpos - isearch_startpos;
+    val = zhalloc(nbytes + 1 /* NUL */);
+    strncpy(val, &val_BUFFER[isearch_startpos], nbytes);
+    val[nbytes] = '\0';
+    return val;
+}