Package: meli

I hope to update rust-termion to version 4 soon, I was able to
patch meli to build with the new version, but the patches were
quite involved so you might want to run things by upstream
and/or test that the package still works correctly.

Debdiff is attatched.

diff -Nru meli-0.8.12+dfsg/debian/changelog meli-0.8.12+dfsg/debian/changelog
--- meli-0.8.12+dfsg/debian/changelog   2025-12-05 19:17:31.000000000 +0000
+++ meli-0.8.12+dfsg/debian/changelog   2025-12-16 22:46:37.000000000 +0000
@@ -1,3 +1,10 @@
+meli (0.8.12+dfsg-9.1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Add patches for termion 4.
+
+ -- Peter Michael Green <[email protected]>  Tue, 16 Dec 2025 22:46:37 +0000
+
 meli (0.8.12+dfsg-9) unstable; urgency=medium
 
   * add patch 1001_async-fn-stream
diff -Nru meli-0.8.12+dfsg/debian/control meli-0.8.12+dfsg/debian/control
--- meli-0.8.12+dfsg/debian/control     2025-12-05 13:41:53.000000000 +0000
+++ meli-0.8.12+dfsg/debian/control     2025-12-16 22:46:37.000000000 +0000
@@ -65,7 +65,7 @@
  librust-structopt-0.3-dev,
  librust-syn-1+default-dev,
  librust-tempfile-3+default-dev,
- librust-termion-1+default-dev,
+ librust-termion-4+default-dev,
  librust-toml-0.8+display-dev,
  librust-toml-0.8+parse-dev,
  librust-toml-0.8+preserve-order-dev,
diff -Nru meli-0.8.12+dfsg/debian/patches/2005_termion_2.patch 
meli-0.8.12+dfsg/debian/patches/2005_termion_2.patch
--- meli-0.8.12+dfsg/debian/patches/2005_termion_2.patch        1970-01-01 
00:00:00.000000000 +0000
+++ meli-0.8.12+dfsg/debian/patches/2005_termion_2.patch        2025-12-16 
22:34:26.000000000 +0000
@@ -0,0 +1,35 @@
+Description: Support termion 2
+ Replaces AlternateScreen::from with into_alternate_screen per the
+ upstream migration guide.
+Author: Peter Michael Green <[email protected]>
+
+--- meli-0.8.12+dfsg.orig/meli/Cargo.toml
++++ meli-0.8.12+dfsg/meli/Cargo.toml
+@@ -44,7 +44,7 @@ signal-hook-registry = { version = "1.2.
+ smallvec = { version = "^1.5.0", features = ["serde"] }
+ structopt = { version = "0.3.26", default-features = false }
+ # svg_crate = { version = "^0.13", optional = true, package = "svg" }
+-termion = { version = "1.5.1", default-features = false }
++termion = { version = "2", default-features = false }
+ toml = { version = "0.8", default-features = false, features = 
["display","preserve_order","parse"] }
+ xdg = { version = "2.1.0" }
+ 
+--- meli-0.8.12+dfsg.orig/meli/src/terminal/screen.rs
++++ meli-0.8.12+dfsg/meli/src/terminal/screen.rs
+@@ -375,6 +375,7 @@ impl Screen<Tty> {
+     }
+ 
+     pub fn switch_to_alternate_screen(&mut self, context: &crate::Context) {
++        use crate::termion::screen::IntoAlternateScreen;
+         let mut stdout = BufWriter::with_capacity(
+             240 * 80,
+             Box::new(std::io::stdout()) as Box<dyn std::io::Write>,
+@@ -414,7 +415,7 @@ impl Screen<Tty> {
+         )
+         .unwrap();
+ 
+-        self.display.stdout = 
Some(AlternateScreen::from(stdout.into_raw_mode().unwrap()));
++        self.display.stdout = 
Some(stdout.into_raw_mode().unwrap().into_alternate_screen().unwrap());
+         self.flush();
+     }
+ 
diff -Nru meli-0.8.12+dfsg/debian/patches/2006_termion_3.patch 
meli-0.8.12+dfsg/debian/patches/2006_termion_3.patch
--- meli-0.8.12+dfsg/debian/patches/2006_termion_3.patch        1970-01-01 
00:00:00.000000000 +0000
+++ meli-0.8.12+dfsg/debian/patches/2006_termion_3.patch        2025-12-16 
22:43:44.000000000 +0000
@@ -0,0 +1,96 @@
+Description: Support termion 3
+ Termion 3 was tricky, "RawTerminal" now requires AsFd in addition to
+ Write. To accomodate this we create a Wrapper around BufWriter that
+ implements AsFd.
+Author: Peter Michael Green <[email protected]>
+
+Index: meli-0.8.12+dfsg/meli/src/terminal/screen.rs
+===================================================================
+--- meli-0.8.12+dfsg.orig/meli/src/terminal/screen.rs
++++ meli-0.8.12+dfsg/meli/src/terminal/screen.rs
+@@ -36,8 +36,59 @@ use crate::{
+     Attr, Context, ThemeAttribute,
+ };
+ 
++use std::os::fd::AsFd;
++use std::os::fd::BorrowedFd;
++use std::cell::RefCell;
++use std::os::fd::AsRawFd;
++
++// by implementing this trait one asserts that writing
++// to the writer will not close the underlying Fd.
++pub (crate) unsafe trait WriteAsFd: std::io::Write + AsFd {}
++
++unsafe impl WriteAsFd for Box<(dyn WriteAsFd)> {}
++unsafe impl WriteAsFd for std::io::Stdout {}
++
++pub (crate) struct BufWriterWithFd<W: WriteAsFd> {
++    inner: RefCell<BufWriter<W>>
++}
++
++// a buffered writer that allows access to the FD of the inner writer.
++// requesting the FD will flush the buffered writer.
++impl <W: WriteAsFd> BufWriterWithFd<W> {
++    pub fn with_capacity(capacity: usize, inner: W) -> BufWriterWithFd<W> {
++        Self { inner: BufWriter::with_capacity(capacity, inner).into() }
++    }
++}
++
++impl <W: WriteAsFd> std::io::Write for BufWriterWithFd<W> {
++    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
++        self.inner.get_mut().write(buf)
++    }
++    fn flush(&mut self) -> std::io::Result<()> {
++        self.inner.get_mut().flush()
++    }
++    fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> 
std::io::Result<usize> {
++        self.inner.get_mut().write_vectored(bufs)
++    }
++    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
++        self.inner.get_mut().write_all(buf)
++    }
++    fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> 
std::io::Result<()> {
++        self.inner.get_mut().write_fmt(args)
++    }
++}
++
++impl <W: WriteAsFd> AsFd for BufWriterWithFd<W> {
++    fn as_fd(&self) -> BorrowedFd<'_> {
++        self.inner.borrow_mut().flush();
++        // Safety: we only use interior mutability to flush the bufwriter, 
and we have asserted
++        // that writing to the underlying writer does not close the 
underlying fd.
++        unsafe { 
BorrowedFd::borrow_raw(self.inner.borrow_mut().get_ref().as_fd().as_raw_fd()) }
++    }
++}
++
+ pub type StateStdout = termion::screen::AlternateScreen<
+-    termion::raw::RawTerminal<BufWriter<Box<dyn Write + 'static>>>,
++    termion::raw::RawTerminal<BufWriterWithFd<Box<dyn WriteAsFd + 'static>>>,
+ >;
+ 
+ type DrawHorizontalSegmentFn =
+@@ -376,9 +427,9 @@ impl Screen<Tty> {
+ 
+     pub fn switch_to_alternate_screen(&mut self, context: &crate::Context) {
+         use crate::termion::screen::IntoAlternateScreen;
+-        let mut stdout = BufWriter::with_capacity(
++        let mut stdout = BufWriterWithFd::with_capacity(
+             240 * 80,
+-            Box::new(std::io::stdout()) as Box<dyn std::io::Write>,
++            Box::new(std::io::stdout()) as Box<dyn WriteAsFd>,
+         );
+ 
+         write!(
+Index: meli-0.8.12+dfsg/meli/Cargo.toml
+===================================================================
+--- meli-0.8.12+dfsg.orig/meli/Cargo.toml
++++ meli-0.8.12+dfsg/meli/Cargo.toml
+@@ -44,7 +44,7 @@ signal-hook-registry = { version = "1.2.
+ smallvec = { version = "^1.5.0", features = ["serde"] }
+ structopt = { version = "0.3.26", default-features = false }
+ # svg_crate = { version = "^0.13", optional = true, package = "svg" }
+-termion = { version = "2", default-features = false }
++termion = { version = "3", default-features = false }
+ toml = { version = "0.8", default-features = false, features = 
["display","preserve_order","parse"] }
+ xdg = { version = "2.1.0" }
+ 
diff -Nru meli-0.8.12+dfsg/debian/patches/2007_termion_4.patch 
meli-0.8.12+dfsg/debian/patches/2007_termion_4.patch
--- meli-0.8.12+dfsg/debian/patches/2007_termion_4.patch        1970-01-01 
00:00:00.000000000 +0000
+++ meli-0.8.12+dfsg/debian/patches/2007_termion_4.patch        2025-12-16 
22:46:37.000000000 +0000
@@ -0,0 +1,88 @@
+Description: Support termion 3
+ Termion 4 added "WheelLeft" and "WheelRight" buttons, this patch makes
+ the conversion from a termion mouse event to a meli one falible and
+ ignores events that cannot be converted.
+Author: Peter Michael Green <[email protected]>
+Index: meli-0.8.12+dfsg/meli/Cargo.toml
+===================================================================
+--- meli-0.8.12+dfsg.orig/meli/Cargo.toml
++++ meli-0.8.12+dfsg/meli/Cargo.toml
+@@ -44,7 +44,7 @@ signal-hook-registry = { version = "1.2.
+ smallvec = { version = "^1.5.0", features = ["serde"] }
+ structopt = { version = "0.3.26", default-features = false }
+ # svg_crate = { version = "^0.13", optional = true, package = "svg" }
+-termion = { version = "3", default-features = false }
++termion = { version = "4", default-features = false }
+ toml = { version = "0.8", default-features = false, features = 
["display","preserve_order","parse"] }
+ xdg = { version = "2.1.0" }
+ 
+Index: meli-0.8.12+dfsg/meli/src/terminal/keys.rs
+===================================================================
+--- meli-0.8.12+dfsg.orig/meli/src/terminal/keys.rs
++++ meli-0.8.12+dfsg/meli/src/terminal/keys.rs
+@@ -98,13 +98,14 @@ pub enum MouseEvent {
+     Hold(u16, u16),
+ }
+ 
+-impl From<TermionMouseEvent> for MouseEvent {
+-    fn from(val: TermionMouseEvent) -> Self {
++impl TryFrom<TermionMouseEvent> for MouseEvent {
++    type Error = &'static str;
++    fn try_from(val: TermionMouseEvent) -> Result<Self, Self::Error> {
+         use TermionMouseEvent::*;
+         match val {
+-            Press(btn, a, b) => Self::Press(btn.into(), a, b),
+-            Release(a, b) => Self::Release(a, b),
+-            Hold(a, b) => Self::Hold(a, b),
++            Press(btn, a, b) => Ok(Self::Press(btn.try_into()?, a, b)),
++            Release(a, b) => Ok(Self::Release(a, b)),
++            Hold(a, b) => Ok(Self::Hold(a, b)),
+         }
+     }
+ }
+@@ -127,17 +128,27 @@ pub enum MouseButton {
+     ///
+     /// This event is typically only used with [`MouseEvent::Press`].
+     WheelDown,
++    /// Mouse wheel is going up.
++    ///
++    /// This event is typically only used with [`MouseEvent::Press`].
++    WheelLeft,
++    /// Mouse wheel is going down.
++    ///
++    /// This event is typically only used with [`MouseEvent::Press`].
++    WheelRight,
+ }
+ 
+-impl From<TermionMouseButton> for MouseButton {
+-    fn from(val: TermionMouseButton) -> Self {
++impl TryFrom<TermionMouseButton> for MouseButton {
++    type Error = &'static str;
++    fn try_from(val: TermionMouseButton) -> Result<Self, Self::Error> {
+         use TermionMouseButton::*;
+         match val {
+-            Left => Self::Left,
+-            Right => Self::Right,
+-            Middle => Self::Middle,
+-            WheelUp => Self::WheelUp,
+-            WheelDown => Self::WheelDown,
++            Left => Ok(Self::Left),
++            Right => Ok(Self::Right),
++            Middle => Ok(Self::Middle),
++            WheelUp => Ok(Self::WheelUp),
++            WheelDown => Ok(Self::WheelDown),
++            _ => Err("unknown mouse button"),
+         }
+     }
+ }
+@@ -364,7 +375,9 @@ pub fn get_events(
+                                     continue 'poll_while;
+                                 }
+                             (Ok((TEvent::Mouse(mev), bytes)), 
InputMode::Normal) => {
+-                                closure((Key::Mouse(mev.into()), bytes));
++                                if let Ok(mev) = mev.try_into() { //ignore 
mouse events that cannot be converted.
++                                    closure((Key::Mouse(mev), bytes));
++                                }
+                                 continue 'poll_while;
+                                 }
+                             (Ok((TEvent::Unsupported(ref k,), _)), 
InputMode::Normal) if k.as_slice() == [27, 91, 63] => {
diff -Nru meli-0.8.12+dfsg/debian/patches/series 
meli-0.8.12+dfsg/debian/patches/series
--- meli-0.8.12+dfsg/debian/patches/series      2025-12-05 13:37:11.000000000 
+0000
+++ meli-0.8.12+dfsg/debian/patches/series      2025-12-16 22:13:06.000000000 
+0000
@@ -9,3 +9,6 @@
 2003_unicode.patch
 2004_no_hardcode_defaults.patch
 2004_no_jmap_server_test.patch
+2005_termion_2.patch
+2006_termion_3.patch
+2007_termion_4.patch

Reply via email to