From: jbenden <jbenden@users.noreply.github.com>
To: ml@inbox.vuxu.org
Subject: Re: [PR PATCH] [Updated] New package: wezterm-20220905_1
Date: Wed, 16 Nov 2022 19:16:20 +0100 [thread overview]
Message-ID: <20221116181620.BQmPH3VB6skm5sgDOoxfFNAHAQRhA-5fT_P2KCt4BJI@z> (raw)
In-Reply-To: <gh-mailinglist-notifications-41a7ca26-5023-4802-975b-f1789d68868e-void-packages-36903@inbox.vuxu.org>
[-- Attachment #1: Type: text/plain, Size: 669 bytes --]
There is an updated pull request by jbenden against master on the void-packages repository
https://github.com/jbenden/void-packages wezterm
https://github.com/void-linux/void-packages/pull/36903
New package: wezterm-20220905_1
#### Testing the changes
- I tested the changes in this PR: **YES**
#### New package
- This new package conforms to the [quality requirements](https://github.com/void-linux/void-packages/blob/master/Manual.md#quality-requirements): **YES**
#### Local build testing
- I built this PR locally for my native architecture, (`x86_64`-`glibc`)
A patch file from https://github.com/void-linux/void-packages/pull/36903.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-wezterm-36903.patch --]
[-- Type: text/x-diff, Size: 13995 bytes --]
From 8771c5fb78965a451e229e87831d6a9e2dca9762 Mon Sep 17 00:00:00 2001
From: Joseph Benden <joe@benden.us>
Date: Sun, 24 Apr 2022 10:16:12 -0700
Subject: [PATCH] New package: wezterm-20220905_1
Fixes: #35721
Signed-off-by: Joseph Benden <joe@benden.us>
---
srcpkgs/wezterm-terminfo | 1 +
srcpkgs/wezterm/patches/0001-32bit.patch | 232 ++++++++++++++++++
.../patches/0002-remove-distro-fonts.patch | 22 ++
srcpkgs/wezterm/template | 60 +++++
srcpkgs/wezterm/update | 2 +
5 files changed, 317 insertions(+)
create mode 120000 srcpkgs/wezterm-terminfo
create mode 100644 srcpkgs/wezterm/patches/0001-32bit.patch
create mode 100644 srcpkgs/wezterm/patches/0002-remove-distro-fonts.patch
create mode 100644 srcpkgs/wezterm/template
create mode 100644 srcpkgs/wezterm/update
diff --git a/srcpkgs/wezterm-terminfo b/srcpkgs/wezterm-terminfo
new file mode 120000
index 000000000000..37d60f7b3b71
--- /dev/null
+++ b/srcpkgs/wezterm-terminfo
@@ -0,0 +1 @@
+wezterm
\ No newline at end of file
diff --git a/srcpkgs/wezterm/patches/0001-32bit.patch b/srcpkgs/wezterm/patches/0001-32bit.patch
new file mode 100644
index 000000000000..d374a275d235
--- /dev/null
+++ b/srcpkgs/wezterm/patches/0001-32bit.patch
@@ -0,0 +1,232 @@
+From 7b904f05eb4de9ed44d2068355a571b117eba0e1 Mon Sep 17 00:00:00 2001
+From: Wez Furlong <wez@wezfurlong.org>
+Date: Sat, 15 Oct 2022 16:45:02 -0700
+Subject: [PATCH] termwiz: fixup for 32-bit systems
+
+I noticed from https://github.com/void-linux/void-packages/pull/36903
+that 32-bit systems were failing to pass the test suite.
+
+Running `cargo test --target i686-unknown-linux-gnu -- --nocapture
+teeny_string` showed that we were faulting in the teenystring code
+and digging a bit deeper showed that it was because our assumptions
+about the high bits were wrong for 32-bit systems.
+
+Fix this by making TeenyString based around a u64 rather than usize
+so that we guarantee its size on all current systems.
+---
+ Cargo.lock | 1 -
+ termwiz/Cargo.toml | 1 -
+ termwiz/src/cell.rs | 87 ++++++++++++++-------------------------------
+ 3 files changed, 26 insertions(+), 63 deletions(-)
+
+diff --git a/Cargo.lock b/Cargo.lock
+index 4f976535be..243e3a2b24 100644
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -4739,7 +4739,6 @@ dependencies = [
+ "base64",
+ "bitflags",
+ "cassowary",
+- "cfg-if 1.0.0",
+ "criterion",
+ "env_logger",
+ "filedescriptor",
+diff --git a/termwiz/Cargo.toml b/termwiz/Cargo.toml
+index d8d7ab543c..e843bac261 100644
+--- a/termwiz/Cargo.toml
++++ b/termwiz/Cargo.toml
+@@ -15,7 +15,6 @@ readme = "README.md"
+ base64 = "0.13"
+ bitflags = "1.3"
+ cassowary = {version="0.3", optional=true}
+-cfg-if = "1.0"
+ anyhow = "1.0"
+ filedescriptor = { version="0.8", path = "../filedescriptor" }
+ finl_unicode = "1.1"
+diff --git a/termwiz/src/cell.rs b/termwiz/src/cell.rs
+index ddf38a93bb..70d6099dd0 100644
+--- a/termwiz/src/cell.rs
++++ b/termwiz/src/cell.rs
+@@ -590,7 +590,7 @@ where
+ s.serialize(serializer)
+ }
+
+-/// TeenyString encodes string storage in a single machine word.
++/// TeenyString encodes string storage in a single u64.
+ /// The scheme is simple but effective: strings that encode into a
+ /// byte slice that is 1 less byte than the machine word size can
+ /// be encoded directly into the usize bits stored in the struct.
+@@ -603,60 +603,40 @@ where
+ /// calling grapheme_column_width; if it is set, then the TeenyString
+ /// has length 2, otherwise, it has length 1 (we don't allow zero-length
+ /// strings).
+-struct TeenyString(usize);
++struct TeenyString(u64);
+ struct TeenyStringHeap {
+ bytes: Vec<u8>,
+ width: usize,
+ }
+
+ impl TeenyString {
+- const fn marker_mask() -> usize {
++ const fn marker_mask() -> u64 {
+ if cfg!(target_endian = "little") {
+- cfg_if::cfg_if! {
+- if #[cfg(target_pointer_width = "64")] {
+- 0x80000000_00000000
+- } else if #[cfg(target_pointer_width = "32")] {
+- 0x80000000
+- } else if #[cfg(target_pointer_width = "16")] {
+- 0x8000
+- } else {
+- panic!("unsupported target");
+- }
+- }
++ 0x80000000_00000000
+ } else {
+ 0x1
+ }
+ }
+
+- const fn double_wide_mask() -> usize {
++ const fn double_wide_mask() -> u64 {
+ if cfg!(target_endian = "little") {
+- cfg_if::cfg_if! {
+- if #[cfg(target_pointer_width = "64")] {
+- 0xc0000000_00000000
+- } else if #[cfg(target_pointer_width = "32")] {
+- 0xc0000000
+- } else if #[cfg(target_pointer_width = "16")] {
+- 0xc000
+- } else {
+- panic!("unsupported target");
+- }
+- }
++ 0xc0000000_00000000
+ } else {
+ 0x3
+ }
+ }
+
+- const fn is_marker_bit_set(word: usize) -> bool {
++ const fn is_marker_bit_set(word: u64) -> bool {
+ let mask = Self::marker_mask();
+ word & mask == mask
+ }
+
+- const fn is_double_width(word: usize) -> bool {
++ const fn is_double_width(word: u64) -> bool {
+ let mask = Self::double_wide_mask();
+ word & mask == mask
+ }
+
+- const fn set_marker_bit(word: usize, width: usize) -> usize {
++ const fn set_marker_bit(word: u64, width: usize) -> u64 {
+ if width > 1 {
+ word | Self::double_wide_mask()
+ } else {
+@@ -689,18 +669,18 @@ impl TeenyString {
+ let len = bytes.len();
+ let width = width.unwrap_or_else(|| grapheme_column_width(s, unicode_version));
+
+- if len < std::mem::size_of::<usize>() {
++ if len < std::mem::size_of::<u64>() {
+ debug_assert!(width < 3);
+
+- let mut word = 0usize;
++ let mut word = 0u64;
+ unsafe {
+ std::ptr::copy_nonoverlapping(
+ bytes.as_ptr(),
+- &mut word as *mut usize as *mut u8,
++ &mut word as *mut u64 as *mut u8,
+ len,
+ );
+ }
+- let word = Self::set_marker_bit(word, width);
++ let word = Self::set_marker_bit(word as u64, width);
+ Self(word)
+ } else {
+ let vec = Box::new(TeenyStringHeap {
+@@ -708,35 +688,15 @@ impl TeenyString {
+ width,
+ });
+ let ptr = Box::into_raw(vec);
+- Self(ptr as usize)
++ Self(ptr as u64)
+ }
+ }
+
+ pub const fn space() -> Self {
+ Self(if cfg!(target_endian = "little") {
+- cfg_if::cfg_if! {
+- if #[cfg(target_pointer_width = "64")] {
+- 0x80000000_00000020
+- } else if #[cfg(target_pointer_width = "32")] {
+- 0x80000020
+- } else if #[cfg(target_pointer_width = "16")] {
+- 0x8020
+- } else {
+- panic!("unsupported target");
+- }
+- }
++ 0x80000000_00000020
+ } else {
+- cfg_if::cfg_if! {
+- if #[cfg(target_pointer_width = "64")] {
+- 0x20000000_00000001
+- } else if #[cfg(target_pointer_width = "32")] {
+- 0x20000001
+- } else if #[cfg(target_pointer_width = "16")] {
+- 0x2001
+- } else {
+- panic!("unsupported target");
+- }
+- }
++ 0x20000000_00000001
+ })
+ }
+
+@@ -753,7 +713,7 @@ impl TeenyString {
+ 1
+ }
+ } else {
+- let heap = self.0 as *const usize as *const TeenyStringHeap;
++ let heap = self.0 as *const u64 as *const TeenyStringHeap;
+ unsafe { (*heap).width }
+ }
+ }
+@@ -766,17 +726,17 @@ impl TeenyString {
+
+ pub fn as_bytes(&self) -> &[u8] {
+ if Self::is_marker_bit_set(self.0) {
+- let bytes = &self.0 as *const usize as *const u8;
++ let bytes = &self.0 as *const u64 as *const u8;
+ let bytes =
+- unsafe { std::slice::from_raw_parts(bytes, std::mem::size_of::<usize>() - 1) };
++ unsafe { std::slice::from_raw_parts(bytes, std::mem::size_of::<u64>() - 1) };
+ let len = bytes
+ .iter()
+ .position(|&b| b == 0)
+- .unwrap_or(std::mem::size_of::<usize>() - 1);
++ .unwrap_or(std::mem::size_of::<u64>() - 1);
+
+ &bytes[0..len]
+ } else {
+- let heap = self.0 as *const usize as *const TeenyStringHeap;
++ let heap = self.0 as *const u64 as *const TeenyStringHeap;
+ unsafe { (*heap).bytes.as_slice() }
+ }
+ }
+@@ -1072,6 +1032,11 @@ mod test {
+
+ #[test]
+ fn teeny_string() {
++ assert!(
++ std::mem::size_of::<usize>() <= std::mem::size_of::<u64>(),
++ "if a pointer doesn't fit in u64 then we need to change TeenyString"
++ );
++
+ let s = TeenyString::from_char('a');
+ assert_eq!(s.as_bytes(), &[b'a']);
+
diff --git a/srcpkgs/wezterm/patches/0002-remove-distro-fonts.patch b/srcpkgs/wezterm/patches/0002-remove-distro-fonts.patch
new file mode 100644
index 000000000000..1d8e21384ae9
--- /dev/null
+++ b/srcpkgs/wezterm/patches/0002-remove-distro-fonts.patch
@@ -0,0 +1,22 @@
+--- a/wezterm-font/src/parser.rs 2022-09-05 10:28:02.000000000 -0700
++++ b/wezterm-font/src/parser.rs 2022-10-24 09:06:02.529054286 -0700
+@@ -715,19 +715,6 @@
+ font!("../../assets/fonts/JetBrainsMono-Regular.ttf"),
+ font!("../../assets/fonts/JetBrainsMono-ThinItalic.ttf"),
+ font!("../../assets/fonts/JetBrainsMono-Thin.ttf"),
+- font!("../../assets/fonts/Roboto-Black.ttf"),
+- font!("../../assets/fonts/Roboto-BlackItalic.ttf"),
+- font!("../../assets/fonts/Roboto-Bold.ttf"),
+- font!("../../assets/fonts/Roboto-BoldItalic.ttf"),
+- font!("../../assets/fonts/Roboto-Italic.ttf"),
+- font!("../../assets/fonts/Roboto-Light.ttf"),
+- font!("../../assets/fonts/Roboto-LightItalic.ttf"),
+- font!("../../assets/fonts/Roboto-Medium.ttf"),
+- font!("../../assets/fonts/Roboto-MediumItalic.ttf"),
+- font!("../../assets/fonts/Roboto-Regular.ttf"),
+- font!("../../assets/fonts/Roboto-Thin.ttf"),
+- font!("../../assets/fonts/Roboto-ThinItalic.ttf"),
+- font!("../../assets/fonts/NotoColorEmoji.ttf"),
+ font!("../../assets/fonts/Symbols-Nerd-Font-Mono.ttf"),
+ font!("../../assets/fonts/LastResortHE-Regular.ttf"),
+ ] {
diff --git a/srcpkgs/wezterm/template b/srcpkgs/wezterm/template
new file mode 100644
index 000000000000..487b920f160c
--- /dev/null
+++ b/srcpkgs/wezterm/template
@@ -0,0 +1,60 @@
+# Template file for 'wezterm'
+pkgname=wezterm
+version=20220905
+revision=1
+_srcver=${version}-102802-7d4b8249
+archs="x86_64* i686* aarch64* arm*" # ring
+build_style=cargo
+configure_args="--no-default-features --features wezterm-gui/distro-defaults,wayland"
+hostmakedepends="pkg-config"
+makedepends="fontconfig-devel freetype-devel harfbuzz-devel openssl-devel
+ libX11-devel libxkbcommon-devel wayland-devel xcb-util-devel
+ xcb-util-image-devel xcb-util-keysyms-devel xcb-util-wm-devel"
+depends="noto-fonts-emoji fonts-roboto-ttf"
+short_desc="GPU-accelerated cross-platform terminal emulator and multiplexer"
+maintainer="Joseph Benden <joe@benden.us>"
+license="MIT"
+homepage="https://wezfurlong.org/wezterm/"
+changelog="https://wezfurlong.org/wezterm/changelog.html"
+distfiles="https://github.com/wez/wezterm/releases/download/${_srcver}/wezterm-${_srcver}-src.tar.gz"
+checksum="5898af2bb2dbedcae2648764d5b7abd3d98b0aa3d05d171b09e0e3f76b7dd545"
+nocross=yes # ftbfs in libgit+libssh
+
+do_check() {
+ # NOTE: cannot use build_style cargo do_check because of --release flag.
+ # NOTE: e2e::sftp is skipped due to missing ssh
+ # NOTE: shapecache::test::ligatures_jetbrains is skipped due to removal of fonts
+ cargo test --target ${RUST_TARGET} --workspace --locked -- \
+ --skip e2e::sftp \
+ --skip shapecache::test::ligatures_jetbrains
+}
+
+do_install() {
+ vbin target/${RUST_TARGET}/release/wezterm
+ vbin target/${RUST_TARGET}/release/wezterm-gui
+ vbin target/${RUST_TARGET}/release/wezterm-mux-server
+ vbin target/${RUST_TARGET}/release/strip-ansi-escapes
+
+ vinstall assets/shell-integration/wezterm.sh 644 etc/profile.d org_wezfurlong_wezterm.sh
+ vinstall assets/icon/terminal.png 644 usr/share/icons/hicolor/128x128/apps org.wezfurlong.wezterm.png
+ vinstall assets/icon/wezterm-icon.svg 644 usr/share/icons/hicolor/scalable/apps org.wezfurlong.wezterm.svg
+ vinstall assets/wezterm.desktop 644 usr/share/applications org.wezfurlong.wezterm.desktop
+ vinstall assets/wezterm.appdata.xml 644 usr/share/metainfo org.wezfurlong.wezterm.appdata.xml
+
+ vcompletion assets/shell-completion/bash bash
+ vcompletion assets/shell-completion/fish fish
+ vcompletion assets/shell-completion/zsh zsh
+
+ vmkdir usr/share/terminfo
+ tic -sx -o ${DESTDIR}/usr/share/terminfo termwiz/data/wezterm.terminfo
+
+ vdoc README.md
+ vlicense LICENSE.md
+}
+
+wezterm-terminfo_package() {
+ short_desc+=" - terminfo data"
+ pkg_install() {
+ vmove usr/share/terminfo
+ }
+}
diff --git a/srcpkgs/wezterm/update b/srcpkgs/wezterm/update
new file mode 100644
index 000000000000..4d2ef98f356b
--- /dev/null
+++ b/srcpkgs/wezterm/update
@@ -0,0 +1,2 @@
+site="https://github.com/wez/wezterm/releases"
+pattern='/tags/\K[\d.]+(?=-\d+-[a-f0-9]+.tar.gz)'
next prev parent reply other threads:[~2022-11-16 18:16 UTC|newest]
Thread overview: 114+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-28 19:30 [PR PATCH] New package: wezterm-20220408_1 jbenden
2022-04-28 20:03 ` [PR PATCH] [Updated] " jbenden
2022-04-28 22:01 ` jbenden
2022-04-28 23:46 ` classabbyamp
2022-04-28 23:46 ` classabbyamp
2022-04-29 7:06 ` [PR PATCH] [Updated] " jbenden
2022-04-29 10:30 ` [PR REVIEW] " paper42
2022-04-29 10:30 ` paper42
2022-04-29 19:21 ` [PR PATCH] [Updated] " jbenden
2022-04-29 20:58 ` [PR REVIEW] " jbenden
2022-04-29 21:06 ` classabbyamp
2022-04-29 21:28 ` jbenden
2022-06-25 19:14 ` [PR PATCH] [Updated] " jbenden
2022-06-25 20:24 ` [PR REVIEW] " classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:24 ` classabbyamp
2022-06-25 20:25 ` classabbyamp
2022-06-25 20:26 ` classabbyamp
2022-07-09 20:40 ` [PR PATCH] [Updated] " jbenden
2022-07-09 20:43 ` [PR REVIEW] " jbenden
2022-07-09 20:43 ` jbenden
2022-07-09 21:52 ` jbenden
2022-09-25 12:08 ` auronandace
2022-09-25 17:01 ` [PR PATCH] [Updated] " jbenden
2022-09-25 17:05 ` jbenden
2022-09-25 18:09 ` jbenden
2022-10-15 21:54 ` [PR PATCH] [Updated] " jbenden
2022-10-15 22:11 ` [PR REVIEW] " paper42
2022-10-15 23:49 ` wez
2022-10-16 22:21 ` [PR PATCH] [Updated] " jbenden
2022-10-16 22:27 ` [PR REVIEW] " classabbyamp
2022-10-17 22:57 ` jbenden
2022-10-17 23:11 ` [PR PATCH] [Updated] " jbenden
2022-10-17 23:12 ` [PR REVIEW] " jbenden
2022-10-17 23:13 ` [PR PATCH] [Updated] " jbenden
2022-10-17 23:20 ` [PR REVIEW] " classabbyamp
2022-10-17 23:37 ` paper42
2022-10-17 23:47 ` jbenden
2022-10-18 1:02 ` [PR PATCH] [Updated] " jbenden
2022-10-18 1:02 ` [PR REVIEW] " jbenden
2022-10-18 1:03 ` jbenden
2022-10-18 1:04 ` [PR PATCH] [Updated] " jbenden
2022-10-20 15:43 ` jbenden
2022-10-20 17:33 ` jbenden
2022-10-21 3:03 ` jbenden
2022-10-24 1:14 ` [PR REVIEW] " classabbyamp
2022-10-24 1:14 ` classabbyamp
2022-10-24 1:14 ` classabbyamp
2022-10-24 1:16 ` classabbyamp
2022-10-24 1:17 ` classabbyamp
2022-10-24 1:20 ` classabbyamp
2022-10-24 1:21 ` classabbyamp
2022-10-24 1:27 ` classabbyamp
2022-10-24 17:54 ` [PR PATCH] [Updated] " jbenden
2022-10-24 18:09 ` jbenden
2022-10-24 18:27 ` [PR REVIEW] " classabbyamp
2022-10-24 21:07 ` [PR PATCH] [Updated] " jbenden
2022-10-24 23:14 ` [PR REVIEW] " jbenden
2022-10-24 23:19 ` jbenden
2022-10-25 0:35 ` classabbyamp
2022-10-25 19:39 ` [PR PATCH] [Updated] " jbenden
2022-10-25 19:43 ` [PR REVIEW] " classabbyamp
2022-10-25 19:43 ` jbenden
2022-10-25 19:45 ` [PR PATCH] [Updated] " jbenden
2022-10-27 22:48 ` [PR REVIEW] New package: wezterm-20220905_1 classabbyamp
2022-10-27 22:48 ` classabbyamp
2022-10-27 22:50 ` classabbyamp
2022-10-28 1:06 ` [PR PATCH] [Updated] " jbenden
2022-10-28 1:25 ` classabbyamp
2022-10-28 2:02 ` [PR PATCH] [Updated] " jbenden
2022-10-28 9:21 ` [PR REVIEW] " paper42
2022-10-28 9:21 ` paper42
2022-10-28 15:11 ` [PR PATCH] [Updated] " jbenden
2022-10-28 15:11 ` [PR REVIEW] " jbenden
2022-10-28 15:12 ` jbenden
2022-11-08 3:39 ` vikigenius
2022-11-09 19:41 ` [PR REVIEW] " classabbyamp
2022-11-10 15:37 ` [PR PATCH] [Updated] " jbenden
2022-11-14 22:34 ` classabbyamp
2022-11-14 22:59 ` paper42
2022-11-14 23:26 ` [PR REVIEW] " classabbyamp
2022-11-14 23:29 ` classabbyamp
2022-11-15 1:22 ` classabbyamp
2022-11-15 1:22 ` classabbyamp
2022-11-15 1:22 ` classabbyamp
2022-11-15 1:22 ` classabbyamp
2022-11-15 1:22 ` classabbyamp
2022-11-15 1:25 ` classabbyamp
2022-11-15 3:25 ` classabbyamp
2022-11-16 16:55 ` jbenden
2022-11-16 16:55 ` jbenden
2022-11-16 16:57 ` jbenden
2022-11-16 16:58 ` jbenden
2022-11-16 17:07 ` [PR PATCH] [Updated] " jbenden
2022-11-16 17:08 ` [PR REVIEW] " jbenden
2022-11-16 17:43 ` classabbyamp
2022-11-16 17:48 ` jbenden
2022-11-16 18:16 ` jbenden [this message]
2022-11-16 18:17 ` classabbyamp
2022-11-16 18:17 ` classabbyamp
2022-11-16 18:22 ` jbenden
2022-11-16 18:29 ` [PR PATCH] [Updated] " jbenden
2022-11-16 21:15 ` [PR REVIEW] " classabbyamp
2022-11-16 21:15 ` classabbyamp
2022-11-17 15:41 ` [PR PATCH] [Updated] " jbenden
2022-11-17 16:37 ` jbenden
2022-11-17 18:32 ` [PR PATCH] [Merged]: " classabbyamp
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221116181620.BQmPH3VB6skm5sgDOoxfFNAHAQRhA-5fT_P2KCt4BJI@z \
--to=jbenden@users.noreply.github.com \
--cc=ml@inbox.vuxu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).