zsh-workers
 help / Atom feed
* PATCH: function copy
@ 2019-07-15 20:00 Peter Stephenson
  2019-07-15 20:23 ` Sebastian Gniazdowski
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Peter Stephenson @ 2019-07-15 20:00 UTC (permalink / raw)
  To: Zsh hackers list

I've had this lying around for a while, wondering if there's more to it,
but I can't think of it.

The point is that it's very easy internally to provide an interface to
tweak standard functions to add arbitrary code before and after --- we
have most of the support for this internally, and just lack the means to
add a different name for a function, which this adds.

The idiom is going to be something like

functions -c _std_fn _my_fn
_std_fn() {
  # do stuff here
  _my_fn "$@"
  # do stuff here
}

Previously to get this effect you've had to hack around with autoloads
or re-evaluating functions with kludged-in strings, or whatever, which
is inefficient and bug-prone.

pws


commit 82403cf95822a791ce6cff7ba6bb8abc74876d97
Author: Peter Stephenson <p.w.stephenson@ntlworld.com>
Date:   Wed Apr 10 20:54:52 2019 +0100

    Copy functions using functions -c old new.
    Documentation and test.

diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index d7b6e88fa..9eee30d46 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -858,10 +858,11 @@ point numbers are not permitted.
 )
 findex(functions)
 xitem(tt(functions) [ {tt(PLUS())|tt(-)}tt(UkmtTuWz) ] [ tt(-x) var(num) ] [ var(name) ... ])
+xitem(tt(functions -c) var(oldfn) var(newfn))
 xitem(tt(functions -M) [tt(-s)] var(mathfn) [ var(min) [ var(max) [ var(shellfn) ] ] ])
 xitem(tt(functions -M) [ tt(-m) var(pattern) ... ])
 item(tt(functions +M) [ tt(-m) ] var(mathfn) ... )(
-Equivalent to tt(typeset -f), with the exception of the tt(-x),
+Equivalent to tt(typeset -f), with the exception of the tt(-c), tt(-x),
 tt(-M) and tt(-W) options.  For tt(functions -u) and tt(functions -U),
 see tt(autoload), which provides additional options.
 
@@ -875,6 +876,14 @@ function or functions only.  The option is turned off at the start of
 nested functions (apart from anonoymous functions) unless the called
 function also has the tt(-W) attribute.
 
+The tt(-c) option causes var(oldfn) to be copied to var(newfn).  The
+copy is efficiently handled internally by reference counting.  If
+var(oldfn) was marked for autoload it is first loaded and if this
+fails the copy fails.  Either function may subsequently be redefined
+without affecting the other.  A typical idiom is that var(oldfn) is the
+name of a library shell function which is then redefined to call
+tt(newfn), thereby installing a modified version of the function.
+
 Use of the tt(-M) option may not be combined with any of the options
 handled by tt(typeset -f).
 
diff --git a/Src/builtin.c b/Src/builtin.c
index 7db36c41b..5b95cc4fd 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -74,7 +74,7 @@ static struct builtin builtins[] =
     BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "aAdDe:EfiIlLmnpPrRt:W", NULL),
     BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
     BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlp:%rtux", "E"),
-    BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmMstTuUWx:z", NULL),
+    BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "ckmMstTuUWx:z", NULL),
     BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
     BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
     BUILTIN("hash", BINF_MAGICEQUALS, bin_hash, 0, -1, 0, "Ldfmrv", NULL),
@@ -3248,11 +3248,50 @@ bin_functions(char *name, char **argv, Options ops, int func)
 
     if ((off & PM_UNDEFINED) || (OPT_ISSET(ops,'k') && OPT_ISSET(ops,'z')) ||
        (OPT_ISSET(ops,'x') && !OPT_HASARG(ops,'x')) ||
-       (OPT_MINUS(ops,'X') && (OPT_ISSET(ops,'m') || !scriptname))) {
+       (OPT_MINUS(ops,'X') && (OPT_ISSET(ops,'m') || !scriptname)) ||
+       (OPT_ISSET(ops,'c') && (OPT_ISSET(ops,'x') || OPT_ISSET(ops,'X') ||
+                               OPT_ISSET(ops,'m')))) {
        zwarnnam(name, "invalid option(s)");
        return 1;
     }
 
+    if (OPT_ISSET(ops,'c')) {
+       Shfunc newsh;
+       if (!*argv || !argv[1] || argv[2]) {
+           zwarnnam(name, "-c: requires two arguments");
+           return 1;
+       }
+       shf = (Shfunc) shfunctab->getnode(shfunctab, *argv);
+       if (!shf) {
+           zwarnnam(name, "no such funciton: %s", *argv);
+           return 1;
+       }
+       if (shf->node.flags & PM_UNDEFINED) {
+           if (shf->funcdef) {
+               freeeprog(shf->funcdef);
+               shf->funcdef = &dummy_eprog;
+           }
+           shf = loadautofn(shf, 1, 0, 0);
+           if (!shf)
+               return 1;
+       }
+       newsh = zalloc(sizeof(*newsh));
+       memcpy(newsh, shf, sizeof(*newsh));
+       if (newsh->node.flags & PM_LOADDIR) {
+           /* Expand original location of autoloaded file */
+           newsh->node.flags &= ~PM_LOADDIR;
+           newsh->filename = tricat(shf->filename, "/", shf->node.nam);
+       } else
+           newsh->filename = ztrdup(shf->filename);
+       newsh->funcdef->nref++;
+       if (newsh->redir)
+           newsh->redir->nref++;
+       if (shf->sticky)
+           newsh->sticky = sticky_emulation_dup(sticky, 0);
+       shfunctab->addnode(shfunctab, ztrdup(argv[1]), &newsh->node);
+       return 0;
+    }
+
     if (OPT_ISSET(ops,'x')) {
        char *eptr;
        expand = (int)zstrtol(OPT_ARG(ops,'x'), &eptr, 10);
diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst
index 3aaf7fb4a..407fc471f 100644
--- a/Test/C04funcdef.ztst
+++ b/Test/C04funcdef.ztst
@@ -503,7 +503,7 @@
   not_trashed() { print This function was not trashed; }
   autoload -Uz /foo/bar/not_trashed
   not_trashed
-0:autoload with absolute path doesn't trash loaded function
+0:autoload with absolute path does not trash loaded function
 >This function was not trashed
 
   # keep spec from getting loaded in parent shell for simplicity
@@ -542,6 +542,73 @@
 0:autoload containing dash
 >this should run automatically
 
+  tbc() {
+     print This function is called $0.
+  }
+  tbc
+  functions -c tbc newcopy
+  newcopy
+  unfunction tbc
+  newcopy
+0:functions -c
+>This function is called tbc.
+>This function is called newcopy.
+>This function is called newcopy.
+
+  (
+    fpath=(.)
+    print >tbc_auto 'print This autoloaded function is called $0.'
+    autoload -Uz tbc_auto
+    functions -c tbc_auto newcopy_auto
+    newcopy_auto
+    tbc_auto
+  )
+0:functions -c with autoload
+>This autoloaded function is called newcopy_auto.
+>This autoloaded function is called tbc_auto.
+
+  (
+    fpath=(.)
+    print >tbc_redef "print This is the core of the old function."
+    autoload -Uz tbc_redef
+    functions -c tbc_redef tbc_original
+    tbc_redef() {
+       print About to call the original.
+       tbc_original
+       print Stopped calling the original because once is enough.
+    }
+    tbc_redef
+  )
+0:function -c with redefinition
+>About to call the original.
+>This is the core of the old function.
+>Stopped calling the original because once is enough.
+
+  (
+    fpath=(.)
+    print >line_info '\nprint -P "%1x:%I is where we are."'
+    autoload -Uz line_info
+    functions -c line_info preserve_file
+    preserve_file
+  )
+0:functions -c preserves file information
+>line_info:2 is where we are.
+
+  (
+    fpath=(.)
+    print >func_info '\nprint -P "%N:%i is where we are."'
+    autoload -Uz func_info
+    functions -c func_info change_output
+    change_output
+  )
+0:functions -c updates non-file function information
+>change_output:2 is where we are.
+
+  autoload -Uz cant_autoload_for_copying
+  functions -c cant_autoload_for_copying not_copied
+1:functions -c gracefully rejects failed autoload
+?(eval):2: cant_autoload_for_copying: function definition file not found
+
 %clean
 
  rm -f file.in file.out


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

* Re: PATCH: function copy
  2019-07-15 20:00 PATCH: function copy Peter Stephenson
@ 2019-07-15 20:23 ` Sebastian Gniazdowski
  2019-07-15 21:25   ` Peter Stephenson
  2019-07-15 21:42 ` Bart Schaefer
  2019-08-03 18:58 ` Peter Stephenson
  2 siblings, 1 reply; 11+ messages in thread
From: Sebastian Gniazdowski @ 2019-07-15 20:23 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list

On Mon, 15 Jul 2019 at 22:01, Peter Stephenson
<p.w.stephenson@ntlworld.com> wrote:
> +    if (OPT_ISSET(ops,'c')) {
> +       Shfunc newsh;
> +       if (!*argv || !argv[1] || argv[2]) {
> +           zwarnnam(name, "-c: requires two arguments");
> +           return 1;
> +       }

I'm probably wrong, as the tests should caught that up, but should the
"argv[2]" in the line:

> +       if (!*argv || !argv[1] || argv[2]) {

actually say "!argv[2]"?

Hmm.. There's probably a shift-like operation in bin_functions, which
makes the check argv[2] be actually for an third argument?

-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

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

* Re: PATCH: function copy
  2019-07-15 20:23 ` Sebastian Gniazdowski
@ 2019-07-15 21:25   ` Peter Stephenson
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Stephenson @ 2019-07-15 21:25 UTC (permalink / raw)
  To: Zsh hackers list

On Mon, 2019-07-15 at 22:23 +0200, Sebastian Gniazdowski wrote:
> On Mon, 15 Jul 2019 at 22:01, Peter Stephenson
> <p.w.stephenson@ntlworld.com> wrote:
> > +    if (OPT_ISSET(ops,'c')) {
> > +       Shfunc newsh;
> > +       if (!*argv || !argv[1] || argv[2]) {
> > +           zwarnnam(name, "-c: requires two arguments");
> > +           return 1;
> > +       }
> 
> I'm probably wrong, as the tests should caught that up, but should the
> "argv[2]" in the line:
> 
> > +       if (!*argv || !argv[1] || argv[2]) {
> 
> actually say "!argv[2]"?

It it's an error if argument zero is empty, or argument one is empty, or
argument two is non-empty.

pws


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

* Re: PATCH: function copy
  2019-07-15 20:00 PATCH: function copy Peter Stephenson
  2019-07-15 20:23 ` Sebastian Gniazdowski
@ 2019-07-15 21:42 ` Bart Schaefer
  2019-07-15 21:51   ` Sebastian Gniazdowski
  2019-07-16  8:56   ` Peter Stephenson
  2019-08-03 18:58 ` Peter Stephenson
  2 siblings, 2 replies; 11+ messages in thread
From: Bart Schaefer @ 2019-07-15 21:42 UTC (permalink / raw)
  To: Zsh hackers list

On Mon, Jul 15, 2019 at 1:00 PM Peter Stephenson
<p.w.stephenson@ntlworld.com> wrote:
>
> I've had this lying around for a while, wondering if there's more to it,
> but I can't think of it.
>
> The point is that it's very easy internally to provide an interface to
> tweak standard functions to add arbitrary code before and after --- we
> have most of the support for this internally, and just lack the means to
> add a different name for a function, which this adds.

Emacs calls this "advice" and allows before/around/after variations
which can be added without having to redefine the existing function.
I have a half-finished (that may be optimistic) module to provide this
for ZLE widgets.  Handling the before/after is not too bad, but for
"around" you need a way to say "call the original function HERE" which
you can then embed in another function that becomes the "around" (and
which is called in place of the original everywhere except HERE).

The other thing that would be really helpful in order to do it "your
way" would be local functions, so that when the calling context exits,
_std_fn reverts to its old definition and _my_fn disappears.  Hacking
this by making the entire $functions array local is error-prone.

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

* Re: PATCH: function copy
  2019-07-15 21:42 ` Bart Schaefer
@ 2019-07-15 21:51   ` Sebastian Gniazdowski
  2019-07-15 22:08     ` Bart Schaefer
  2019-07-16  8:56   ` Peter Stephenson
  1 sibling, 1 reply; 11+ messages in thread
From: Sebastian Gniazdowski @ 2019-07-15 21:51 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh hackers list

On Mon, 15 Jul 2019 at 23:43, Bart Schaefer <schaefer@brasslantern.com> wrote:
> Emacs calls this "advice" and allows before/around/after variations
> which can be added without having to redefine the existing function.
> I have a half-finished (that may be optimistic) module to provide this
> for ZLE widgets.  Handling the before/after is not too bad, but for

I have a somewhat related idea which i will now invoke because of the
nice use case it has – a module to add before and after set/get hooks
for parameters. Think about an after-set hook for BUFFER, being the
z-sy-h/f-sy-h _zsh_highlight function, which does the highlighting.
This might be an even better approach than the zle-line-pre-redraw
hook.

-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

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

* Re: PATCH: function copy
  2019-07-15 21:51   ` Sebastian Gniazdowski
@ 2019-07-15 22:08     ` Bart Schaefer
  0 siblings, 0 replies; 11+ messages in thread
From: Bart Schaefer @ 2019-07-15 22:08 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Zsh hackers list

On Mon, Jul 15, 2019 at 2:51 PM Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
>
> I have a somewhat related idea which i will now invoke because of the
> nice use case it has – a module to add before and after set/get hooks
> for parameters.

Ksh has a syntax for this: ${varname.hookname} IIRC.  The difficulty
with adopting this is that zsh's lexer has the definition of an
"identifier" fairly deeply embedded, it is nontrivial to add "." as a
valid character only when inside curly braces.

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

* Re: PATCH: function copy
  2019-07-15 21:42 ` Bart Schaefer
  2019-07-15 21:51   ` Sebastian Gniazdowski
@ 2019-07-16  8:56   ` Peter Stephenson
  2019-07-16 16:55     ` Philippe Troin
  2019-07-16 19:06     ` Bart Schaefer
  1 sibling, 2 replies; 11+ messages in thread
From: Peter Stephenson @ 2019-07-16  8:56 UTC (permalink / raw)
  To: zsh-workers

On Mon, 2019-07-15 at 14:42 -0700, Bart Schaefer wrote:
> On Mon, Jul 15, 2019 at 1:00 PM Peter Stephenson
> <p.w.stephenson@ntlworld.com> wrote:
> > 
> > 
> > I've had this lying around for a while, wondering if there's more to it,
> > but I can't think of it.
> > 
> > The point is that it's very easy internally to provide an interface to
> > tweak standard functions to add arbitrary code before and after --- we
> > have most of the support for this internally, and just lack the means to
> > add a different name for a function, which this adds.
> Emacs calls this "advice" and allows before/around/after variations
> which can be added without having to redefine the existing function.
> I have a half-finished (that may be optimistic) module to provide this
> for ZLE widgets.  Handling the before/after is not too bad, but for
> "around" you need a way to say "call the original function HERE" which
> you can then embed in another function that becomes the "around" (and
> which is called in place of the original everywhere except HERE).

That's basically what I showed in my example.

functions -c _std_fn _my_fn
_std_fn() {
  # do stuff here
  _my_fn "$@"
  # do stuff here
}

I think you're implying you'd rather not have an additional function
name to deal with, i.e. the HERE is indicated in some other fashion.
That's quite hard to fit into zsh syntax.

> The other thing that would be really helpful in order to do it "your
> way" would be local functions, so that when the calling context exits,
> _std_fn reverts to its old definition and _my_fn disappears.  Hacking
> this by making the entire $functions array local is error-prone.

That's another feature that's also quite bug-prone to implement ---
we've had a zillion problems just with local variables which have
been there for ages --- but at least if it's internal it's just
a single implementation.

pws



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

* Re: PATCH: function copy
  2019-07-16  8:56   ` Peter Stephenson
@ 2019-07-16 16:55     ` Philippe Troin
  2019-07-16 19:06     ` Bart Schaefer
  1 sibling, 0 replies; 11+ messages in thread
From: Philippe Troin @ 2019-07-16 16:55 UTC (permalink / raw)
  To: zsh-workers

On Tue, 2019-07-16 at 09:56 +0100, Peter Stephenson wrote:
> On Mon, 2019-07-15 at 14:42 -0700, Bart Schaefer wrote:
> > On Mon, Jul 15, 2019 at 1:00 PM Peter Stephenson
> > <p.w.stephenson@ntlworld.com> wrote:
> > >  
> > >  
> > > I've had this lying around for a while, wondering if there's more
> > > to it,
> > > but I can't think of it.
> > >  
> > > The point is that it's very easy internally to provide an
> > > interface to
> > > tweak standard functions to add arbitrary code before and after
> > > --- we
> > > have most of the support for this internally, and just lack the
> > > means to
> > > add a different name for a function, which this adds.
> > Emacs calls this "advice" and allows before/around/after variations
> > which can be added without having to redefine the existing
> > function.
> > I have a half-finished (that may be optimistic) module to provide
> > this
> > for ZLE widgets.  Handling the before/after is not too bad, but for
> > "around" you need a way to say "call the original function HERE"
> > which
> > you can then embed in another function that becomes the "around"
> > (and
> > which is called in place of the original everywhere except HERE).
> 
> That's basically what I showed in my example.
> 
> functions -c _std_fn _my_fn
> _std_fn() {
>   # do stuff here
>   _my_fn "$@"
>   # do stuff here
> }

I've been using the following hackish idioms:

   % foo() { print foo $@; }
   % () {
        local func=$functions[foo]
        eval "foo() { print before foo; { $func }; print after foo }"
     }
   % foo bar
   before foo
   foo bar
   after foo

   and

   % functions[foo_copy]=$functions[foo]

   Of course these cause reparsing of the function body, so "function -c"
   may still make sense.
   I like the idea of a full advising system.

   Phil.


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

* Re: PATCH: function copy
  2019-07-16  8:56   ` Peter Stephenson
  2019-07-16 16:55     ` Philippe Troin
@ 2019-07-16 19:06     ` Bart Schaefer
  2019-07-16 19:11       ` Bart Schaefer
  1 sibling, 1 reply; 11+ messages in thread
From: Bart Schaefer @ 2019-07-16 19:06 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

On Tue, Jul 16, 2019 at 1:56 AM Peter Stephenson
<p.stephenson@samsung.com> wrote:
>
> On Mon, 2019-07-15 at 14:42 -0700, Bart Schaefer wrote:
>
> > "around" you need a way to say "call the original function HERE" which
> > you can then embed in another function that becomes the "around" (and
> > which is called in place of the original everywhere except HERE).
>
> I think you're implying you'd rather not have an additional function
> name to deal with, i.e. the HERE is indicated in some other fashion.
> That's quite hard to fit into zsh syntax.

There doesn't need to be any special syntax, just some special name
linking, e.g.:

_my_fn() {
  # do stuff here
  _orig_fn "$@"
  # do stuff here
}
advice-around _std_fn _my_fn _orig_fn
advice-around _other_fn _my_fn _orig_fn

and "advice-around" would arrange that any time either _std_fn or
_other_fn was called, the name _orig_fn would temporary be linked to
either _std_fn or _other_fn (as appropriate to whichever one was being
replaced), and then _my_fn would be invoked.  At the end of _my_fn the
temporary name _orig_fn would evaporate.  This allows the same advice
to be linked to multiple functions without having to copy all of them,
etc.

For ordinary functions this is the same as doing something like

_my_fn() {
  local _orig_fn=$1
  shift
  # do stuff here
  $_orig_fn "$@"
  #do stuff here
}
alias _std_fn="_my_fn _std_fn"
alias _other_fn="_my_fn _other_fn"

except you don't have to worry about whether aliases are going to
expand or what order to define them or having the extra argument to
shift off, etc.  For widget functions, though, there's a lot more to
do to be able to invoke a widget properly in the middle of _my_fn,
especially if the original widget is a builtin.

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

* Re: PATCH: function copy
  2019-07-16 19:06     ` Bart Schaefer
@ 2019-07-16 19:11       ` Bart Schaefer
  0 siblings, 0 replies; 11+ messages in thread
From: Bart Schaefer @ 2019-07-16 19:11 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

One other thought ...

On Tue, Jul 16, 2019 at 12:06 PM Bart Schaefer
<schaefer@brasslantern.com> wrote:
>
> On Tue, Jul 16, 2019 at 1:56 AM Peter Stephenson
> <p.stephenson@samsung.com> wrote:
> >
> > On Mon, 2019-07-15 at 14:42 -0700, Bart Schaefer wrote:
> >
> > > "around" you need a way to say "call the original function HERE"
> >
> > I think you're implying you'd rather not have an additional function
>
> There doesn't need to be any special syntax, just some special name
> linking

The other significant thing about "not have an additional function" is
that ideally _my_fn and _orig_fn would occur at the same locallevel,
that is, the call to the original function would not push a new
parameter context onto the stack but would instead behave as if you'd
eval'd the source text of the advised function.

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

* Re: PATCH: function copy
  2019-07-15 20:00 PATCH: function copy Peter Stephenson
  2019-07-15 20:23 ` Sebastian Gniazdowski
  2019-07-15 21:42 ` Bart Schaefer
@ 2019-08-03 18:58 ` Peter Stephenson
  2 siblings, 0 replies; 11+ messages in thread
From: Peter Stephenson @ 2019-08-03 18:58 UTC (permalink / raw)
  To: zsh-workers

On Mon, 2019-07-15 at 21:00 +0100, Peter Stephenson wrote:
> I've had this lying around for a while, wondering if there's more to it,
> but I can't think of it.
> 
> The point is that it's very easy internally to provide an interface to
> tweak standard functions to add arbitrary code before and after --- we
> have most of the support for this internally, and just lack the means to
> add a different name for a function, which this adds.

Now I've finally got a few minutes...

Didn't hear any arugments against committing this fairly self-contained
patch mostly using existing features, so I'll do that.  Obviously, I
understand this isn't the be all and end all of the subject but it's all
I have to contribute.

pws


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

end of thread, back to index

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-15 20:00 PATCH: function copy Peter Stephenson
2019-07-15 20:23 ` Sebastian Gniazdowski
2019-07-15 21:25   ` Peter Stephenson
2019-07-15 21:42 ` Bart Schaefer
2019-07-15 21:51   ` Sebastian Gniazdowski
2019-07-15 22:08     ` Bart Schaefer
2019-07-16  8:56   ` Peter Stephenson
2019-07-16 16:55     ` Philippe Troin
2019-07-16 19:06     ` Bart Schaefer
2019-07-16 19:11       ` Bart Schaefer
2019-08-03 18:58 ` Peter Stephenson

zsh-workers

Archives are clonable: git clone --mirror http://inbox.vuxu.org/zsh-workers

Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.workers


AGPL code for this site: git clone https://public-inbox.org/ public-inbox