From b24fe512e41296a7af0c6cff20b6a37fcf720e26 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 12 Nov 2019 06:21:51 -0500 Subject: make contents_diff include bell state i don't think it makes sense for contents_formatted to include this --- CHANGELOG.md | 2 ++ src/screen.rs | 18 ++++++++++++++++-- src/term.rs | 20 ++++++++++++++++++++ tests/control.rs | 16 ++++++++++++++++ tests/escape.rs | 19 +++++++++++++++++++ 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c268b6c..1dca708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ * Clearing a cell now sets all of that cell's attributes to the current attribute set, since different terminals render different things for an empty cell based on the attributes. +* `Screen::contents_diff` now includes audible and visual bells when + appropriate. ## [0.4.0] - 2019-11-08 diff --git a/src/screen.rs b/src/screen.rs index c2eaf0e..d4613f0 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -246,6 +246,12 @@ impl Screen { prev.attrs, ); self.attrs.write_escape_code_diff(contents, &prev_attrs); + if self.audible_bell_count != prev.audible_bell_count { + crate::term::AudibleBell::default().write_buf(contents); + } + if self.visual_bell_count != prev.visual_bell_count { + crate::term::VisualBell::default().write_buf(contents); + } } /// Returns a sequence of terminal byte streams sufficient to turn the @@ -307,18 +313,26 @@ impl Screen { &self.icon_name } - /// Returns the total number of audible bells seen so far. + /// Returns a value which changes every time an audible bell is received. /// /// Typically you would store this number after each call to `process`, /// and trigger an audible bell whenever it changes. + /// + /// You shouldn't rely on the exact value returned here, since the exact + /// value will not be maintained by `contents_formatted` or + /// `contents_diff`. pub fn audible_bell_count(&self) -> usize { self.audible_bell_count } - /// Returns the total number of visual bells seen so far. + /// Returns a value which changes every time an visual bell is received. /// /// Typically you would store this number after each call to `process`, /// and trigger an visual bell whenever it changes. + /// + /// You shouldn't rely on the exact value returned here, since the exact + /// value will not be maintained by `contents_formatted` or + /// `contents_diff`. pub fn visual_bell_count(&self) -> usize { self.visual_bell_count } diff --git a/src/term.rs b/src/term.rs index 1e69d07..c988702 100644 --- a/src/term.rs +++ b/src/term.rs @@ -344,3 +344,23 @@ impl BufWrite for MoveFromTo { } } } + +#[derive(Default, Debug)] +#[must_use = "this struct does nothing unless you call write_buf"] +pub struct AudibleBell; + +impl BufWrite for AudibleBell { + fn write_buf(&self, buf: &mut Vec) { + buf.push(b'\x07'); + } +} + +#[derive(Default, Debug)] +#[must_use = "this struct does nothing unless you call write_buf"] +pub struct VisualBell; + +impl BufWrite for VisualBell { + fn write_buf(&self, buf: &mut Vec) { + buf.extend_from_slice(b"\x1bg"); + } +} diff --git a/tests/control.rs b/tests/control.rs index aba6915..8372cea 100644 --- a/tests/control.rs +++ b/tests/control.rs @@ -5,15 +5,31 @@ fn bel() { let mut parser = vt100::Parser::default(); assert_eq!(parser.screen().audible_bell_count(), 0); + let screen = parser.screen().clone(); parser.process(b"\x07"); assert_eq!(parser.screen().audible_bell_count(), 1); assert_eq!(parser.screen().audible_bell_count(), 1); + assert_eq!(parser.screen().contents_diff(&screen), b"\x07"); + let screen = parser.screen().clone(); parser.process(b"\x07"); assert_eq!(parser.screen().audible_bell_count(), 2); + assert_eq!(parser.screen().contents_diff(&screen), b"\x07"); + let screen = parser.screen().clone(); parser.process(b"\x07\x07\x07"); assert_eq!(parser.screen().audible_bell_count(), 5); + assert_eq!(parser.screen().contents_diff(&screen), b"\x07"); + + let screen = parser.screen().clone(); + parser.process(b"foo"); + assert_eq!(parser.screen().audible_bell_count(), 5); + assert_eq!(parser.screen().contents_diff(&screen), b"foo"); + + let screen = parser.screen().clone(); + parser.process(b"ba\x07r"); + assert_eq!(parser.screen().audible_bell_count(), 6); + assert_eq!(parser.screen().contents_diff(&screen), b"bar\x07"); } #[test] diff --git a/tests/escape.rs b/tests/escape.rs index e08a402..96ee762 100644 --- a/tests/escape.rs +++ b/tests/escape.rs @@ -125,13 +125,32 @@ fn ris() { fn vb() { let mut parser = vt100::Parser::default(); assert_eq!(parser.screen().visual_bell_count(), 0); + + let screen = parser.screen().clone(); parser.process(b"\x1bg"); assert_eq!(parser.screen().visual_bell_count(), 1); assert_eq!(parser.screen().visual_bell_count(), 1); + assert_eq!(parser.screen().contents_diff(&screen), b"\x1bg"); + + let screen = parser.screen().clone(); parser.process(b"\x1bg"); assert_eq!(parser.screen().visual_bell_count(), 2); + assert_eq!(parser.screen().contents_diff(&screen), b"\x1bg"); + + let screen = parser.screen().clone(); parser.process(b"\x1bg\x1bg\x1bg"); assert_eq!(parser.screen().visual_bell_count(), 5); + assert_eq!(parser.screen().contents_diff(&screen), b"\x1bg"); + + let screen = parser.screen().clone(); + parser.process(b"foo"); + assert_eq!(parser.screen().visual_bell_count(), 5); + assert_eq!(parser.screen().contents_diff(&screen), b"foo"); + + let screen = parser.screen().clone(); + parser.process(b"ba\x1bgr"); + assert_eq!(parser.screen().visual_bell_count(), 6); + assert_eq!(parser.screen().contents_diff(&screen), b"bar\x1bg"); } #[test] -- cgit v1.2.3