Skip to content

Commit

Permalink
migrate from crossterm 0.13.3 to crossterm 0.14.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Canop committed Dec 15, 2019
1 parent 9682c0a commit afd55cb
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 89 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,4 +1,8 @@

<a name="v0.8.3"></a>
### v0.8.3 - 2019-12-15
- port to crossterm 0.14

<a name="v0.8.2"></a>
### v0.8.2 - 2019-11-29
- skin.print_expander makes using a text template less verbose
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "termimad"
version = "0.8.2"
version = "0.8.3"
authors = ["dystroy <denys.seguret@gmail.com>"]
repository = "https://github.com/Canop/termimad"
description = "Markdown Renderer for the Terminal"
Expand All @@ -13,7 +13,7 @@ readme = "README.md"
[dependencies]
lazy_static = "1.4"
minimad = "0.5.2"
crossterm = "0.13.2"
crossterm = "0.14.0"
crossbeam = "0.7"
thiserror = "1.0.4"

Expand Down
19 changes: 12 additions & 7 deletions examples/scrollable/main.rs
Expand Up @@ -4,9 +4,14 @@
use crossterm::{
cursor::Hide,
cursor::Show,
input::{input, InputEvent::*, KeyEvent::*},
event::{
self,
Event,
KeyEvent,
KeyCode::*,
},
queue,
screen::{EnterAlternateScreen, LeaveAlternateScreen, RawScreen},
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
style::Color::*,
};
use std::io::{stderr, Write};
Expand All @@ -15,17 +20,16 @@ use termimad::*;
fn run_app(skin: MadSkin) -> Result<()> {
let mut w = stderr(); // we could also have used stdout
queue!(w, EnterAlternateScreen)?;
let _raw = RawScreen::into_raw_mode()?;
terminal::enable_raw_mode()?;
queue!(w, Hide)?; // hiding the cursor
let mut area = Area::full_screen();
//area.pad(1, 1); // let's add some margin
area.pad_for_max_width(120); // we don't want a too wide text column
let mut view = MadView::from(MD.to_owned(), area, skin);
let mut events = input().read_sync();
loop {
view.write_on(&mut w)?;
if let Some(Keyboard(key)) = events.next() {
match key {
w.flush()?;
if let Ok(Event::Key(KeyEvent{code, ..})) = event::read() {
match code {
Up => view.try_scroll_lines(-1),
Down => view.try_scroll_lines(1),
PageUp => view.try_scroll_pages(-1),
Expand All @@ -34,6 +38,7 @@ fn run_app(skin: MadSkin) -> Result<()> {
}
}
}
terminal::disable_raw_mode()?;
queue!(w, Show)?; // we must restore the cursor
queue!(w, LeaveAlternateScreen)?;
w.flush()?;
Expand Down
24 changes: 16 additions & 8 deletions examples/stderr/main.rs
Expand Up @@ -5,10 +5,15 @@
//!

use crossterm::{
event::{
self,
Event,
KeyEvent,
KeyCode::*,
},
cursor,
input::{input, InputEvent::*, KeyEvent::*},
queue,
screen::{EnterAlternateScreen, LeaveAlternateScreen, RawScreen},
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
style::Color::*,
};
use termimad::*;
Expand Down Expand Up @@ -42,19 +47,21 @@ where
W: std::io::Write,
{
queue!(w, EnterAlternateScreen)?;
let _raw = RawScreen::into_raw_mode()?;
terminal::enable_raw_mode()?;
queue!(w, cursor::Hide)?; // hiding the cursor
let mut area = Area::full_screen();
area.pad(1, 1); // let's add some margin
area.pad_for_max_width(120); // we don't want a too wide text column
let mut view = MadView::from(MARKDOWN.to_owned(), area, skin);
let mut events = input().read_sync();
let mut user_char = None;
loop {
view.write_on(w)?;
w.flush()?;
if let Some(Keyboard(key)) = events.next() {
match key {
if let Ok(Event::Key(KeyEvent{code, modifiers})) = event::read() {
if !modifiers.is_empty() {
continue;
}
match code {
Up => view.try_scroll_lines(-1),
Down => view.try_scroll_lines(1),
PageUp => view.try_scroll_pages(-1),
Expand All @@ -67,6 +74,7 @@ where
}
}
}
terminal::disable_raw_mode()?;
queue!(w, cursor::Show)?; // we must restore the cursor
queue!(w, LeaveAlternateScreen)?;
w.flush()?;
Expand All @@ -81,10 +89,10 @@ fn main() {
skin.scrollbar.thumb.set_fg(AnsiValue(178));

let mut stderr = std::io::stderr();
match run_app(skin, &mut stderr).unwrap() {
match run_app(skin.clone(), &mut stderr).unwrap() {
Some('1') => print!(".."),
Some('2') => print!("/"),
Some('3') => print!("~"),
_ => println!("{}", MARKDOWN),
_ => skin.print_text(MARKDOWN),
}
}
42 changes: 35 additions & 7 deletions src/events/event.rs
@@ -1,26 +1,54 @@
use crossterm::input::{InputEvent, KeyEvent, MouseButton, MouseEvent};
use crossterm;

/// a valid user event
#[derive(Debug, Clone)]
pub enum Event {
Key(KeyEvent),

Key(crossterm::event::KeyEvent),

Click(u16, u16),

RightClick(u16, u16),

DoubleClick(u16, u16),

/// terminal was resized. Contains the new dimensions
Resize(u16, u16),

/// mouse wheel turns. contains -1 if up or 1 if down
Wheel(i32),
}

impl Event {
pub fn from_crossterm_event(crossterm_event: Option<InputEvent>) -> Option<Event> {
/// convert a crossterm event into a termimad one.
///
/// To get a double-click you'll either need to use a termimad event-source
/// or to do the computation yourself.
pub fn from_crossterm_event(
crossterm_event: crossterm::Result<crossterm::event::Event>
) -> Option<Event> {
match crossterm_event {
Some(InputEvent::Keyboard(key)) => Some(Event::Key(key)),
Some(InputEvent::Mouse(MouseEvent::Release(x, y))) => Some(Event::Click(x, y)),
Some(InputEvent::Mouse(MouseEvent::Press(MouseButton::WheelUp, _, _))) => {
Ok(crossterm::event::Event::Key(key)) => {
Some(Event::Key(key))
}
Ok(crossterm::event::Event::Mouse(crossterm::event::MouseEvent::Up(button, x, y, ..))) => {
match button {
crossterm::event::MouseButton::Left => Some(Event::Click(x, y)),
crossterm::event::MouseButton::Right => Some(Event::RightClick(x, y)),
_ => None
}
}
Ok(crossterm::event::Event::Resize(w, h)) => {
Some(Event::Resize(w, h))
}
Ok(crossterm::event::Event::Mouse(crossterm::event::MouseEvent::ScrollUp(..))) => {
Some(Event::Wheel(-1))
}
Some(InputEvent::Mouse(MouseEvent::Press(MouseButton::WheelDown, _, _))) => {
Ok(crossterm::event::Event::Mouse(crossterm::event::MouseEvent::ScrollDown(..))) => {
Some(Event::Wheel(1))
}
_ => None,
}
}
}

64 changes: 27 additions & 37 deletions src/events/event_source.rs
@@ -1,16 +1,22 @@
use crossbeam::channel::{unbounded, Receiver, Sender};
use crossterm::{
input::{self, TerminalInput},
screen::RawScreen,
};
use std::sync::{
atomic::{AtomicUsize, Ordering},
Arc,
use {
crate::{
errors::Error,
events::Event,
},
crossbeam::channel::{unbounded, Receiver, Sender},
crossterm::{
self,
terminal,
},
std::{
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
thread,
time::{Duration, Instant},
}
};
use std::thread;
use std::time::{Duration, Instant};

use crate::{errors::Error, events::Event};

const DOUBLE_CLICK_MAX_DURATION: Duration = Duration::from_millis(700);

Expand Down Expand Up @@ -38,42 +44,22 @@ pub struct EventSource {
rx_events: Receiver<Event>,
tx_quit: Sender<bool>,
event_count: Arc<AtomicUsize>,
_raw_screen: RawScreen, // leaves raw screen on drop
}

impl EventSource {
/// create a new source
///
/// If desired, mouse support must be separately
/// enabled:
/// ```
/// use crossterm::{input::EnableMouseCapture, queue};
/// # use std::io::Write;
/// # let mut w = std::io::stdout();
/// queue!(w, EnableMouseCapture).unwrap();
///
/// ```
/// and disabled:
/// ```
/// use crossterm::{input::DisableMouseCapture, queue};
/// # use std::io::Write;
/// # let mut w = std::io::stdout();
/// queue!(w, DisableMouseCapture).unwrap();
///
/// ```
/// If desired, mouse support must be enabled and desabled in crossterm.
pub fn new() -> Result<EventSource, Error> {
let (tx_events, rx_events) = unbounded();
let (tx_quit, rx_quit) = unbounded();
let event_count = Arc::new(AtomicUsize::new(0));
let internal_event_count = Arc::clone(&event_count);
let _raw_screen = RawScreen::into_raw_mode()?;
let input = TerminalInput::new();
terminal::enable_raw_mode()?;
let mut last_event: Option<TimedEvent> = None;
let mut crossterm_events = input.read_sync();
thread::spawn(move || {
loop {
let crossterm_event = crossterm_events.next();
if let Some(mut event) = Event::from_crossterm_event(crossterm_event) {
if let Some(mut event) = Event::from_crossterm_event(crossterm::event::read()) {
// save the event, and maybe change it
// (may change a click into a double-click)
if let Event::Click(x, y) = event {
Expand All @@ -93,7 +79,6 @@ impl EventSource {
tx_events.send(event).unwrap();
let quit = rx_quit.recv().unwrap();
if quit {
input::stop_reading_thread();
return;
}
}
Expand All @@ -103,7 +88,6 @@ impl EventSource {
rx_events,
tx_quit,
event_count,
_raw_screen,
})
}

Expand All @@ -126,3 +110,9 @@ impl EventSource {
self.rx_events.clone()
}
}

impl Drop for EventSource {
fn drop(&mut self) {
terminal::disable_raw_mode().unwrap();
}
}
1 change: 0 additions & 1 deletion src/fit.rs
Expand Up @@ -149,7 +149,6 @@ mod fit_tests {
Composite,
};
use crate::{
MadSkin,
Fitter,
FmtComposite,
};
Expand Down
2 changes: 1 addition & 1 deletion src/line_style.rs
Expand Up @@ -9,7 +9,7 @@ use crate::compound_style::CompoundStyle;
/// It's made of
/// - the base style of the compounds
/// - the alignment
#[derive(Default)]
#[derive(Default, Clone)]
pub struct LineStyle {
pub compound_style: CompoundStyle,
pub align: Alignment,
Expand Down
1 change: 1 addition & 0 deletions src/scrollbar_style.rs
Expand Up @@ -6,6 +6,7 @@ use crate::styled_char::StyledChar;
///
/// For the default styling only the fg color is defined
/// and the char is ▐ but everything can be changed.
#[derive(Clone)]
pub struct ScrollBarStyle {
pub track: StyledChar,
pub thumb: StyledChar,
Expand Down
1 change: 1 addition & 0 deletions src/skin.rs
Expand Up @@ -20,6 +20,7 @@ use crate::views::TextView;

/// A skin defining how a parsed mardkown appears on the terminal
/// (fg and bg colors, bold, italic, underline, etc.)
#[derive(Clone)]
pub struct MadSkin {
pub paragraph: LineStyle,
pub bold: CompoundStyle,
Expand Down
1 change: 1 addition & 0 deletions src/styled_char.rs
Expand Up @@ -10,6 +10,7 @@ use crate::errors::Result;

/// A modifiable character which can be easily written or repeated. Can
/// be used for bullets, horizontal rules or quote marks.
#[derive(Clone)]
pub struct StyledChar {
compound_style: CompoundStyle,
nude_char: char,
Expand Down

0 comments on commit afd55cb

Please sign in to comment.