zsh-workers
 help / color / mirror / code / Atom feed
* Re: Shift-Insert overwrites ZLE CUTBUFFER
       [not found]                   ` <20161031161605.23af1751@pwslap01u.europe.root.pri>
@ 2016-11-09 17:27                     ` Bart Schaefer
  2016-11-10 16:21                       ` Oliver Kiddle
  0 siblings, 1 reply; 8+ messages in thread
From: Bart Schaefer @ 2016-11-09 17:27 UTC (permalink / raw)
  To: zsh-workers

Moving this to -workers ...

On Oct 31,  4:56pm, Oliver Kiddle wrote:
}
} Associating it with the existing cut/paste features at least puts
} it in a logical and memorable place, at least once you're aware of
} the feature. And if you know about things like yank-pop or vi "0
} then it is not so likely to be bothersome. But I'd be open to
} something better.

On Oct 31,  4:16pm, Peter Stephenson wrote:
}
} I'm not particularly bothered either way, but $ZLE_PASTED suggest
} itself.

An idea that I just had, spawned in part by Oliver's change to
"print -v" behavior when the target variable is declared as an array:

If ZLE_PASTED has been declared, then the pasted text is copied there
instead of into CUTBUFFER.  If it's been declared as an array, it
acts similarly to $killring, i.e., the pasted text is unshifted to
the front and the last element is dropped.


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

* Re: Shift-Insert overwrites ZLE CUTBUFFER
  2016-11-09 17:27                     ` Shift-Insert overwrites ZLE CUTBUFFER Bart Schaefer
@ 2016-11-10 16:21                       ` Oliver Kiddle
  2016-11-10 17:17                         ` Bart Schaefer
  0 siblings, 1 reply; 8+ messages in thread
From: Oliver Kiddle @ 2016-11-10 16:21 UTC (permalink / raw)
  To: zsh-workers

Bart wrote:
>
> On Oct 31,  4:56pm, Oliver Kiddle wrote:
> }
> } Associating it with the existing cut/paste features at least puts
> } it in a logical and memorable place, at least once you're aware of
> } the feature. And if you know about things like yank-pop or vi "0
> } then it is not so likely to be bothersome. But I'd be open to
> } something better.
>
> On Oct 31,  4:16pm, Peter Stephenson wrote:
> }
> } I'm not particularly bothered either way, but $ZLE_PASTED suggest
> } itself.

A variable isn't an especially convenient place for the text given
that it is mostly useful interactively. You can't do anything useful
without writing custom shell widgets and if you're going to be
writing custom shell widgets, you might just as well write one to
wrap bracketed-paste and stuff the text into a variable.

> An idea that I just had, spawned in part by Oliver's change to
> "print -v" behavior when the target variable is declared as an array:

The array would at least then serve as a simple one-liner to disable
the use of the CUTBUFFER if it turns out that it bothers a lot of
people.

I've mostly found the feature useful with an explicit vi buffer
and that behaviour is easily preserved while changing the rest.

Does emacs perhaps have anything analagous to the vi buffers? (It
appears to be a vim thing to call them registers as I've been doing).
Would there be any sense in putting it in the kill ring but not in
the CUTBUFFER so yank-pop is needed to grab it.

Oliver


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

* Re: Shift-Insert overwrites ZLE CUTBUFFER
  2016-11-10 16:21                       ` Oliver Kiddle
@ 2016-11-10 17:17                         ` Bart Schaefer
  2016-11-15 21:41                           ` Oliver Kiddle
  0 siblings, 1 reply; 8+ messages in thread
From: Bart Schaefer @ 2016-11-10 17:17 UTC (permalink / raw)
  To: zsh-workers

On Nov 10,  5:21pm, Oliver Kiddle wrote:
}
} Does emacs perhaps have anything analagous to the vi buffers? (It
} appears to be a vim thing to call them registers as I've been doing).

IIRC vi called them buffers and vim borrowed the term register from
emacs.  So yes, emacs does have a whole suite of register operations,
none of which are present in zsh (which in fairness was based on a
much older version of emacs and for obvious reasons hasn't attempted
to track anything but the most straightforward editing operations).

You can of course use zsh's vi buffer operations as a simple subset
of emacs register commands.  As with vi, emacs registers are named
by a single character.  There are some special-case operations for
treating registers as values for POINT (zsh CURSOR) and incrementing
or decrementing numbers stored in registers, etc.

A useful addition to zsh/zleparameter would be a special hash of
register-to-content mappings (emacs calls this register-alist).

} Would there be any sense in putting it in the kill ring but not in
} the CUTBUFFER so yank-pop is needed to grab it.

That'd be a little strange in that it changes the order of the kill
ring with respect to the two most recent kills.  It also makes it a
bit more confusing for a user-definded widget to access the content
of the last paste if for some reason it was wanted, but not much.

E.g.

    if [[ $LASTWIDGET == *bracketed-paste ]]
    then
	# Used to be in $CUTBUFFER but now
	local pasted_text=$killring[1]
	# ...
    fi


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

* Re: Shift-Insert overwrites ZLE CUTBUFFER
  2016-11-10 17:17                         ` Bart Schaefer
@ 2016-11-15 21:41                           ` Oliver Kiddle
  2016-11-15 22:07                             ` Bart Schaefer
  0 siblings, 1 reply; 8+ messages in thread
From: Oliver Kiddle @ 2016-11-15 21:41 UTC (permalink / raw)
  To: zsh-workers

On 10 Nov, Bart wrote:
> A useful addition to zsh/zleparameter would be a special hash of
> register-to-content mappings (emacs calls this register-alist).

The following patch adds this under the name "registers" and in
zle_params.c rather than zleparameter. That seemed more consistent with,
e.g. killring. It means that it is only available when ZLE is active
which it wouldn't really need to be (the same goes for killring) but
there are advantages to that too. For what it's worth, I think the term
"registers" is better than "buffers" and it'd be good to use the same
ones with emacs style widgets. What does the "alist" part of the emacs name
denote.

It contains just the registers 'a' to 'z' for now. Including the
numbered registers would just be a duplication of killring/CUTBUFFER.
(except the yank register - "0).

Why does makezleparams set pm->level to locallevel + 1? That seems
wrong. What does the + 1 achieve?

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 21681e5..a10c2d0 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -991,6 +991,11 @@ and tt(zle_highlight); see
 ifzman(the section CHARACTER HIGHLIGHTING below)\
 ifnzman(noderef(Character Highlighting)) for details.
 )
+vindex(registers)
+item(tt(registers) (associative array))(
+The contents of each of the `named' vi buffers. These are typically set
+using tt(vi-set-buffer) followed by a delete, change or yank command.
+)
 vindex(SUFFIX_ACTIVE)
 vindex(SUFFIX_START)
 vindex(SUFFIX_END)
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index c6387bf..2400bfb 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -118,6 +118,12 @@ static const struct gsu_integer suffixactive_gsu =
 
 static const struct gsu_array killring_gsu =
 { get_killring, set_killring, unset_killring };
+
+static const struct gsu_scalar register_gsu =
+{ strgetfn, set_register, unset_register };
+static const struct gsu_hash registers_gsu =
+{ hashgetfn, set_registers, zleunsetfn };
+
 /* implementation is in zle_refresh.c */
 static const struct gsu_array region_highlight_gsu =
 { get_region_highlight, set_region_highlight, unset_region_highlight };
@@ -181,6 +187,7 @@ mod_export void
 makezleparams(int ro)
 {
     struct zleparam *zp;
+    Param reg_param;
 
     for(zp = zleparams; zp->name; zp++) {
 	Param pm = createparam(zp->name, (zp->type |PM_SPECIAL|PM_REMOVABLE|
@@ -206,6 +213,11 @@ makezleparams(int ro)
 	if ((zp->type & PM_UNSET) && (zmod.flags & (MOD_MULT|MOD_TMULT)))
 	    pm->node.flags &= ~PM_UNSET;
     }
+
+    reg_param = createspecialhash("registers", get_registers, &scan_registers,
+	    PM_LOCAL|PM_REMOVABLE);
+    reg_param->gsu.h = &registers_gsu;
+    reg_param->level = locallevel + 1;
 }
 
 /* Special unset function for ZLE special parameters: act like the standard *
@@ -712,6 +724,93 @@ unset_killring(Param pm, int exp)
     }
 }
 
+/**/
+static void
+set_register(Param pm, char *value)
+{
+    int n = 0;
+
+    if (!pm->node.nam || *pm->node.nam < 'a' || *pm->node.nam > 'z' ||
+	    pm->node.nam[1]) {
+	zerr("invalid zle register: %s", pm->node.nam);
+	return;
+    }
+
+    Cutbuffer reg = &vibuf[*pm->node.nam - 'a'];
+    if (*value)
+	reg->buf = stringaszleline(value, 0, &n, NULL, NULL);
+    reg->len = n;
+}
+
+/**/
+static void
+unset_register(Param pm, UNUSED(int exp))
+{
+    set_register(pm, "");
+}
+
+/**/
+static void
+scan_registers(UNUSED(HashTable ht), ScanFunc func, int flags)
+{
+    int i;
+    struct param pm;
+
+    memset((void *)&pm, 0, sizeof(struct param));
+    pm.node.flags = PM_SCALAR | PM_READONLY;
+    pm.gsu.s = &nullsetscalar_gsu;
+
+    for (i = 0; i < 26; i++) {
+	pm.node.nam = zhalloc(2);
+	*pm.node.nam = 'a' + i;
+	pm.node.nam[1] = '\0';
+	pm.u.str = zlelineasstring(vibuf[i].buf, vibuf[i].len, 0, NULL, NULL, 1);
+	func(&pm.node, flags);
+    }
+}
+
+/**/
+static HashNode
+get_registers(UNUSED(HashTable ht), const char *name)
+{
+    Param pm = (Param) hcalloc(sizeof(struct param));
+    pm->node.nam = dupstring(name);
+    pm->node.flags = PM_SCALAR;
+    pm->gsu.s = &register_gsu;
+
+    if (*name < 'a' || *name > 'z' || name[1]) {
+	pm->u.str = dupstring("");
+	pm->node.flags |= (PM_UNSET|PM_SPECIAL);
+    } else {
+	int reg = *name - 'a';
+	pm->u.str = zlelineasstring(vibuf[reg].buf, vibuf[reg].len, 0, NULL, NULL, 1);
+    }
+    return &pm->node;
+}
+
+/**/
+static void
+set_registers(UNUSED(Param pm), HashTable ht)
+{
+    int i;
+    HashNode hn;
+
+    if (!ht)
+        return;
+
+    for (i = 0; i < ht->hsize; i++)
+        for (hn = ht->nodes[i]; hn; hn = hn->next) {
+            struct value v;
+            v.isarr = v.flags = v.start = 0;
+            v.end = -1;
+            v.arr = NULL;
+            v.pm = (Param) hn;
+
+	    set_register(v.pm, getstrvalue(&v));
+        }
+    deleteparamtable(ht);
+}
+
 static void
 set_prepost(ZLE_STRING_T *textvar, int *lenvar, char *x)
 {


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

* Re: Shift-Insert overwrites ZLE CUTBUFFER
  2016-11-15 21:41                           ` Oliver Kiddle
@ 2016-11-15 22:07                             ` Bart Schaefer
  2016-11-17 16:53                               ` Oliver Kiddle
  0 siblings, 1 reply; 8+ messages in thread
From: Bart Schaefer @ 2016-11-15 22:07 UTC (permalink / raw)
  To: zsh-workers

On Nov 15, 10:41pm, Oliver Kiddle wrote:
} Subject: Re: Shift-Insert overwrites ZLE CUTBUFFER
}
} On 10 Nov, Bart wrote:
} > A useful addition to zsh/zleparameter would be a special hash of
} > register-to-content mappings (emacs calls this register-alist).
} 
} The following patch adds this under the name "registers" [...]
} For what it's worth, I think the term
} "registers" is better than "buffers" and it'd be good to use the same
} ones with emacs style widgets.

I don't have any particular quibble with this, except that the names
of the vi-widgets all refer to "buffers" and it would be annoying to
change them.  As a thought, could use the terms "killring buffer" for
1-9 and "register buffer" for a-z, when updating documentation.

(Although it's possible to expand the killring to more than 9 elements
by assigning directly to the variable.)

} What does the "alist" part of the emacs name denote.

For practical purposes, it means the same as ${(kv)registers} after
your patch:  a list of alternating key-value elements.

} It contains just the registers 'a' to 'z' for now. Including the
} numbered registers would just be a duplication of killring/CUTBUFFER.
} (except the yank register - "0).

Aside: If the numbered registers duplicate $killring, how is it there
are 9 numbered registers but the killring defaults to only 8 elements?

} Why does makezleparams set pm->level to locallevel + 1? That seems
} wrong. What does the + 1 achieve?

The parameters are created before the function for any user-defined
widget is called, but are defined as being local to the scope of the
user-defined widget.  Or at least that's my understanding, it's been
a while since I walked through the flow.  Anyway, the point is that
the ZLE parameters hide (rather than refer to) any existing parameter
of the same name, and are always local.


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

* Re: Shift-Insert overwrites ZLE CUTBUFFER
  2016-11-15 22:07                             ` Bart Schaefer
@ 2016-11-17 16:53                               ` Oliver Kiddle
  2016-11-18  3:16                                 ` Bart Schaefer
  0 siblings, 1 reply; 8+ messages in thread
From: Oliver Kiddle @ 2016-11-17 16:53 UTC (permalink / raw)
  To: zsh-workers

On 10 Nov, Bart wrote:
> emacs.  So yes, emacs does have a whole suite of register operations,
> none of which are present in zsh (which in fairness was based on a

Would it be useful to add some of those operations given that it
might share much of the existing code that's there for vi (given a
few compromises)?

Coming back to the original point of this thread, would it make
sense to instead put the bracketed-paste text in a register? (g)Vim's
nearest equivalents are "* for the X selection, "+ for secondary
selection and "~ which allows drag and drop. I wonder that if we
want "*, it'd be better handled by allowing external commands like
xclip, xsel or pbcopy to be hooked in. Maybe "~ then? Emacs allows
basically any character to be used for a register which wouldn't
really allow for any special ones unless we ignore that.

With the paste in a register, we might want at least the emacs
insert-register widget along with copy-to-register. Frustratingly,
emacs' insert-register leaves the cursor to the left of the inserted
text making it less suitable as i_Ctrl-R in vim.

Both emacs and vi use the registers for storing macros. I don't
really miss macros in zsh (and have bound q to something else) but
bash has them. Storing a POINT is analagous to a vi mark. In zsh,
I find vi marks are mostly useful for bookmarking history lines and
it'd seem reasonable to offer that for emacs mode too. marks are
stored separately from buffers but I'm not sure that the separate
namespace would really matter.

> change them.  As a thought, could use the terms "killring buffer" for
> 1-9 and "register buffer" for a-z, when updating documentation.

I quite like that. Would mean that anyone searching for either register
or buffer would find what they're looking for.

> (Although it's possible to expand the killring to more than 9 elements
> by assigning directly to the variable.)

> Aside: If the numbered registers duplicate $killring, how is it there
> are 9 numbered registers but the killring defaults to only 8 elements?

Actually it seems the numbered vi buffers are quite separate from the
killring and there are slightly different rules about what goes into
them. So I should probably put the numbered registers in the registers
special parameter after all.

> The parameters are created before the function for any user-defined
> widget is called, but are defined as being local to the scope of the

That makes sense. Thanks

Oliver


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

* Re: Shift-Insert overwrites ZLE CUTBUFFER
  2016-11-17 16:53                               ` Oliver Kiddle
@ 2016-11-18  3:16                                 ` Bart Schaefer
  2016-11-20 22:32                                   ` Oliver Kiddle
  0 siblings, 1 reply; 8+ messages in thread
From: Bart Schaefer @ 2016-11-18  3:16 UTC (permalink / raw)
  To: zsh-workers

On Nov 17,  5:53pm, Oliver Kiddle wrote:
} Subject: Re: Shift-Insert overwrites ZLE CUTBUFFER
}
} On 10 Nov, Bart wrote:
} > emacs.  So yes, emacs does have a whole suite of register operations,
} > none of which are present in zsh (which in fairness was based on a
} 
} Would it be useful to add some of those operations given that it
} might share much of the existing code that's there for vi (given a
} few compromises)?

It'd probably suffice to create widget aliases giving the existing
vi widgets the corresponding emacs names, except special cases that
you have already noted.

} Coming back to the original point of this thread, would it make
} sense to instead put the bracketed-paste text in a register?

I don't have a strong opinion here.  As noted, if this were a real
GUI-aware emacs, the act of *copying* the text would have set the
cutbuffer, so it makes sense to me to put it there on the paste
action (the first real chance we have to sync up with the global
clipboard state).  It's more that people aren't used to having a
copy-paste affect their shell that way that is causing an issue,
than the logic of the operation (I think, someone will probably
contradict me).

I'm not going to respond in detail to your musings about emacs
register operations; my only thought is that we're supposed to be
maintaining a shell here, not re-implementing several editors.


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

* Re: Shift-Insert overwrites ZLE CUTBUFFER
  2016-11-18  3:16                                 ` Bart Schaefer
@ 2016-11-20 22:32                                   ` Oliver Kiddle
  0 siblings, 0 replies; 8+ messages in thread
From: Oliver Kiddle @ 2016-11-20 22:32 UTC (permalink / raw)
  To: zsh-workers

On 17 Nov, Bart wrote:
> } Coming back to the original point of this thread, would it make
> } sense to instead put the bracketed-paste text in a register?
>
> ..., so it makes sense to me to put it there on the paste
> action (the first real chance we have to sync up with the global
> clipboard state).  It's more that people aren't used to having a
> copy-paste affect their shell that way that is causing an issue,
> than the logic of the operation (I think, someone will probably
> contradict me).

Let's leave it as it is then. We can always come back to it if it really
ends up bothering a lot of people. And even that might reduce as more
programs support bracketed-paste and expectations change.

> I'm not going to respond in detail to your musings about emacs
> register operations; my only thought is that we're supposed to be
> maintaining a shell here, not re-implementing several editors.

I take your point. The emacs register widgets don't take much more than
about three lines each to do as shell widgets anyway. The main thing I
actually care about is that if we were to add emacs register widgets,
that it should use the same buffers (and marks) so that people can mix
and match with the vi widgets.

Anyway, as the 0-9 vi registers are quite separate from the emacs
killring (yanks only go into "0), they should be added to the new
associative array - patch for that follows.

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index fe6a7e9..e6b315a 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -993,7 +993,7 @@ ifnzman(noderef(Character Highlighting)) for details.
 )
 vindex(registers)
 item(tt(registers) (associative array))(
-The contents of each of the `named' vi register buffers. These are
+The contents of each of the vi register buffers. These are
 typically set using tt(vi-set-buffer) followed by a delete, change or
 yank command.
 )
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index cb8dac8..78e7835 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -729,15 +729,22 @@ static void
 set_register(Param pm, char *value)
 {
     int n = 0;
+    int offset = -1;
     Cutbuffer reg;
 
-    if (!pm->node.nam || *pm->node.nam < 'a' || *pm->node.nam > 'z' ||
-	    pm->node.nam[1]) {
+    if (!pm->node.nam || pm->node.nam[1])
+	;
+    else if (*pm->node.nam >= '0' && *pm->node.nam <= '9')
+	offset = '0' - 26;
+    else if (*pm->node.nam >= 'a' && *pm->node.nam <= 'z')
+	offset = 'a';
+
+    if (offset == -1) {
 	zerr("invalid zle register: %s", pm->node.nam);
 	return;
     }
 
-    reg = &vibuf[*pm->node.nam - 'a'];
+    reg = &vibuf[*pm->node.nam - offset];
     if (*value)
 	reg->buf = stringaszleline(value, 0, &n, NULL, NULL);
     reg->len = n;
@@ -755,18 +762,21 @@ static void
 scan_registers(UNUSED(HashTable ht), ScanFunc func, int flags)
 {
     int i;
+    char ch;
     struct param pm;
 
     memset((void *)&pm, 0, sizeof(struct param));
     pm.node.flags = PM_SCALAR | PM_READONLY;
     pm.gsu.s = &nullsetscalar_gsu;
 
-    for (i = 0; i < 26; i++) {
+    for (i = 0, ch = 'a'; i < 36; i++) {
 	pm.node.nam = zhalloc(2);
-	*pm.node.nam = 'a' + i;
+	*pm.node.nam = ch;
 	pm.node.nam[1] = '\0';
 	pm.u.str = zlelineasstring(vibuf[i].buf, vibuf[i].len, 0, NULL, NULL, 1);
 	func(&pm.node, flags);
+	if (ch++ == 'z')
+	    ch = '0';
     }
 }
 
@@ -775,17 +785,24 @@ static HashNode
 get_registers(UNUSED(HashTable ht), const char *name)
 {
     Param pm = (Param) hcalloc(sizeof(struct param));
+    int reg = -1;
     pm->node.nam = dupstring(name);
     pm->node.flags = PM_SCALAR;
     pm->gsu.s = &register_gsu;
 
-    if (*name < 'a' || *name > 'z' || name[1]) {
+    if (name[1])
+       ;
+    else if (*name >= '0' && *name <= '9')
+	reg = *name - '0' + 26;
+    else if (*name >= 'a' && *name <= 'z')
+	reg = *name - 'a';
+
+    if (reg == -1) {
 	pm->u.str = dupstring("");
 	pm->node.flags |= (PM_UNSET|PM_SPECIAL);
-    } else {
-	int reg = *name - 'a';
+    } else
 	pm->u.str = zlelineasstring(vibuf[reg].buf, vibuf[reg].len, 0, NULL, NULL, 1);
-    }
+
     return &pm->node;
 }
 


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

end of thread, other threads:[~2016-11-23 21:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAMtVo_PG_fd62V1FZ4r7fRUragzzS6H4McN5sO1=hhY=6DR6Yg@mail.gmail.com>
     [not found] ` <161025091249.ZM7232@torch.brasslantern.com>
     [not found]   ` <CAMtVo_N6qOQr++Amzn11+m3pkOxjc908mwFUerur77+OWd92uw@mail.gmail.com>
     [not found]     ` <161026090133.ZM11120@torch.brasslantern.com>
     [not found]       ` <CAMtVo_P09j6fyJytA21iu_qOom6bCTvJEWn-dXTBX97Bp00Sdg@mail.gmail.com>
     [not found]         ` <161026165138.ZM12130@torch.brasslantern.com>
     [not found]           ` <87h97x36sa.fsf@lwm.klanderman.net>
     [not found]             ` <161027133523.ZM15655@torch.brasslantern.com>
     [not found]               ` <43312.1477929414@hydra.kiddle.eu>
     [not found]                 ` <CGME20161031160350epcas3p4849616fbcc05783a9966320a28ed731c@epcas3p4.samsung.com>
     [not found]                   ` <20161031161605.23af1751@pwslap01u.europe.root.pri>
2016-11-09 17:27                     ` Shift-Insert overwrites ZLE CUTBUFFER Bart Schaefer
2016-11-10 16:21                       ` Oliver Kiddle
2016-11-10 17:17                         ` Bart Schaefer
2016-11-15 21:41                           ` Oliver Kiddle
2016-11-15 22:07                             ` Bart Schaefer
2016-11-17 16:53                               ` Oliver Kiddle
2016-11-18  3:16                                 ` Bart Schaefer
2016-11-20 22:32                                   ` Oliver Kiddle

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