zsh-workers
 help / color / mirror / code / Atom feed
* kill-region hook
@ 2009-01-30  0:07 Michal Maruska
  2009-01-30 10:02 ` Peter Stephenson
  2009-01-30 19:59 ` Stephane Chazelas
  0 siblings, 2 replies; 3+ messages in thread
From: Michal Maruska @ 2009-01-30  0:07 UTC (permalink / raw)
  To: Zsh Hackers' List

[-- Attachment #1: Type: text/plain, Size: 533 bytes --]


Hello,

I would like to have a hook (a shell function) run when "kill-buffer" is
populated.
Motivation: I would use it to promote the string to X selection (via
an Escape sequence of rxvt).

I changed the cuttext function to call callhookfunc.
I made a function to do WideChar->Locale-encoding conversion, but I'm not sure if that is a
zsh way to do it.

Then I found zlelineasstring, but I don't understand what metafy is about (it's
called in zlelineasstring to modify the C string somehow).

Can anybody help?  Patch enclosed.



[-- Attachment #2: selection --]
[-- Type: application/octet-stream, Size: 2476 bytes --]

Index: zsh-4.3.9/Src/Zle/zle_utils.c
===================================================================
--- zsh-4.3.9.orig/Src/Zle/zle_utils.c	2009-01-29 21:28:33.297880363 +0100
+++ zsh-4.3.9/Src/Zle/zle_utils.c	2009-01-30 00:58:23.437186220 +0100
@@ -494,6 +494,8 @@
   cuttext(zleline + i, ct, flags);
 }
 
+static size_t zstring_as_cstring(const ZLE_STRING_T zs, char** res, size_t len);
+
 /*
  * As cut, but explicitly supply the text together with its length.
  */
@@ -574,12 +576,68 @@
 	ZS_memcpy(cutbuf.buf + cutbuf.len, line, ct);
 	cutbuf.len += ct;
     }
+    {  /* Invoke kill_region_hook with the cutbuf text as the only argument. */
+        char* arg;
+        size_t size;
+        LinkList hookargs = newlinklist();
+
+        arg = zlelineasstring(cutbuf.buf, cutbuf.len, 0, NULL, NULL, 0);
+/*        size = zstring_as_cstring(cutbuf.buf, &arg, cutbuf.len); */
+
+        if (size < 0) {
+            zbeep();
+        } else {
+            addlinknode(hookargs, "kill_region_hook");
+            addlinknode(hookargs, arg);
+            int retval;
+            callhookfunc("kill_region_hook", hookargs, 0, &retval); /* NULL */
+            /* zfree(arg, size);*/
+            free(arg);
+        }
+    }
     if(vilinerange)
 	cutbuf.flags |= CUTBUFFER_LINE;
     else
 	cutbuf.flags &= ~CUTBUFFER_LINE;
 }
 
+/* Convert the (sub)zstring ZS of lenght LEN, to a C-string allocated in *RES;
+ * following the Locale setting.
+ * Returns the size (of the allocated memory) or -1 if conversion failed. */
+
+static size_t
+zstring_as_cstring(const ZLE_STRING_T zs, char** res, size_t len)
+{
+#ifdef MULTIBYTE_SUPPORT
+    /* mmc: there is a difference between: "const wchar_t*" and "const ZLE_STRING_T"
+     *      so I use the cur variable: */
+    const wchar_t* cur = zs;
+    size_t size = wcsnrtombs(NULL, &cur, len, 0, NULL) + 1;
+    cur = zs;
+    if (size < 0)
+            return -1;
+#else
+    size_t size = len + 1;
+#endif  /* MULTIBYTE_SUPPORT */
+
+    *res = zalloc(size);
+#ifdef MULTIBYTE_SUPPORT
+    size_t s = wcsnrtombs(*res, &cur, len, size -1, NULL);
+    if (s<0)                    /* impossible here? */
+        {
+            zfree(*res, size);
+            return -1;
+        }
+#else
+    memcpy(*res, zs, size);
+#endif  /* MULTIBYTE_SUPPORT */
+    (*res)[size]=0;
+
+    return size+1;
+}
+
+
+
 /*
  * Now we're back in the world of zlecs where we need to keep
  * track of whether we're on a combining character.

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

* Re: kill-region hook
  2009-01-30  0:07 kill-region hook Michal Maruska
@ 2009-01-30 10:02 ` Peter Stephenson
  2009-01-30 19:59 ` Stephane Chazelas
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Stephenson @ 2009-01-30 10:02 UTC (permalink / raw)
  To: Zsh Hackers' List

On Fri, 30 Jan 2009 01:07:32 +0100
Michal Maruska <michal@ruska.it> wrote:
> Then I found zlelineasstring, but I don't understand what metafy is about
> (it's called in zlelineasstring to modify the C string somehow).

There are two representations of strings: ZLE_STRING_T is in terms of wide
characters and is used for editing functions, a "metafied" character string
is used elswhere in the shell.  The latter is basically an ordinary
null-terminated string, but with the special Meta character embedded in it
that indicates that the following character is not special and should be
xor'd with 32 to get the normal character (hence Meta followed by space
represents and embedded null character that does not terminate the
string).  zlelineasstring() and stringaszleline() convert between the two
representations.  We only use ordinary ("unmetafied") C strings for
interacting with the outside world (a particular example is for filenames
passed to system functions).

The other thing you need to be aware of is memory allocation: it's not
always clear in the shell whether things should be allocated permanently
using zalloc() and relatives or on the heap for freeing at the end of the
current command execution using zhalloc().  You can work it out by looking
at enough code, but possibly not just from the immediate context.
So if you're converting a string for permanent storage you'd use the
former, if you converting it for temporarily working on it and then
converting it back you'd probably use the heap (though you can of course
allocate it and free it, which is slower but does mean memory doesn't build
up if the operation is repeated).  There's some description of this in
Src/mem.c.

One upshot of that is that zlelineasstring() is probably the right thing to
call, but I think you're temporary function argument list for the hook is
coming from heap memory (newlinklist() is off the heap, unlike
znewlinklist(), and you're not freeing it), so you need the final argument 1 to
zlelineasstring().  Your size is now uninitialised, but I don't think
you'll need it.

Otherwise it looks roughly OK, but I'd have to look a bit more than I have
time for at the moment to see if it's in the most logical place to catch
operations on the cut buffer and kill ring, and if you're extracting the
right bits of the cut buffer.

-- 
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] 3+ messages in thread

* Re: kill-region hook
  2009-01-30  0:07 kill-region hook Michal Maruska
  2009-01-30 10:02 ` Peter Stephenson
@ 2009-01-30 19:59 ` Stephane Chazelas
  1 sibling, 0 replies; 3+ messages in thread
From: Stephane Chazelas @ 2009-01-30 19:59 UTC (permalink / raw)
  To: Michal Maruska; +Cc: Zsh Hackers' List

On Fri, Jan 30, 2009 at 01:07:32AM +0100, Michal Maruska wrote:
> 
> Hello,
> 
> I would like to have a hook (a shell function) run when "kill-buffer" is
> populated.
> Motivation: I would use it to promote the string to X selection (via
> an Escape sequence of rxvt).
[...]

Note that I once did something like that:
http://stchaz.free.fr/mouse.zsh
I had to wrap most widgets that use the killring.

-- 
Stéphane


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

end of thread, other threads:[~2009-01-30 19:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-30  0:07 kill-region hook Michal Maruska
2009-01-30 10:02 ` Peter Stephenson
2009-01-30 19:59 ` Stephane Chazelas

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).