on master help sign in
fixed async loop
commit065cbcee9e63703e5ffb3a2c044ed0b49a2b7fff authorJan Hrastnik <jan.hrastnik2@gmail.com> dateSun 7 Jun 2020, 14:11 (6 years ago) parent2985398
3 files changed+137−33
.gitignore+1 helix-term/src/editor.rs+36−33 helix-term/src/test.rs+100
.gitignore+1
@@ -1 +1,2 @@
11target
2+helix-term/rustfmt.toml
helix-term/src/editor.rs+36−33
@@ -1,14 +1,15 @@
1−use std::io::{self, stdout, Write};
2−use std::path::PathBuf;
3−
41use crossterm::{
52 cursor,
63 cursor::position,
7− event::{self, read, Event, KeyCode, KeyEvent},
4+ event::{self, read, Event, EventStream, KeyCode, KeyEvent},
85 execute, queue, style,
96 terminal::{self, disable_raw_mode, enable_raw_mode},
107 Result,
118};
9+use futures::{future::FutureExt, select, StreamExt};
10+use std::io::{self, stdout, Write};
11+use std::path::PathBuf;
12+use std::time::Duration;
1213
1314const HELP: &str = r#"
1415 - Use q to quit
@@ -20,40 +21,40 @@ pub struct Editor {
2021}
2122
2223impl Editor {
23− pub fn read_char() -> Result<char> {
24− loop {
25− if let Ok(Event::Key(KeyEvent {
26− code: KeyCode::Char(c),
27− ..
28− })) = event::read()
29− {
30− return Ok(c);
31− }
32− }
33− }
34−
35− pub async fn print_events() -> Result<()> {
24+ pub async fn print_events() {
25+ let mut reader = EventStream::new();
3626 loop {
3727 // Handle key events
38− match Editor::read_char()? {
39− 'h' => execute!(io::stdout(), cursor::MoveLeft(1))?,
40− 'j' => execute!(io::stdout(), cursor::MoveDown(1))?,
41− 'k' => execute!(io::stdout(), cursor::MoveUp(1))?,
42− 'l' => execute!(io::stdout(), cursor::MoveRight(1))?,
43− 'q' => {
44− execute!(
45− io::stdout(),
46− style::ResetColor,
47− cursor::Show,
48− terminal::LeaveAlternateScreen
49− )?;
50− break;
28+ let mut event = reader.next().await;
29+ match event {
30+ Some(Ok(x)) => {
31+ if let Event::Key(KeyEvent {
32+ code: KeyCode::Char(c),
33+ ..
34+ }) = x
35+ {
36+ match c {
37+ 'h' => execute!(io::stdout(), cursor::MoveLeft(1)).unwrap(),
38+ 'j' => execute!(io::stdout(), cursor::MoveDown(1)).unwrap(),
39+ 'k' => execute!(io::stdout(), cursor::MoveUp(1)).unwrap(),
40+ 'l' => execute!(io::stdout(), cursor::MoveRight(1)).unwrap(),
41+ 'q' => {
42+ execute!(
43+ io::stdout(),
44+ style::ResetColor,
45+ cursor::Show,
46+ terminal::LeaveAlternateScreen
47+ );
48+ break;
49+ }
50+ _ => println!("{:?}", x),
51+ }
52+ }
5153 }
52− _ => println!("use 'q' to quit."),
54+ Some(Err(x)) => panic!(x),
55+ None => break,
5356 }
5457 }
55−
56− Ok(())
5758 }
5859
5960 pub fn run() -> Result<()> {
@@ -85,6 +86,8 @@ impl Editor {
8586 // Send a shutdown signal.
8687 drop(s);
8788
89+ execute!(stdout, terminal::LeaveAlternateScreen)?;
90+
8891 // Wait for threads to finish.
8992 for t in threads {
9093 t.join().unwrap();
helix-term/src/test.rsnew file+100
@@ -0,0 +1,100 @@
1+//! Demonstrates how to read events asynchronously with async-std.
2+//!
3+//! cargo run --features="event-stream" --example event-stream-async-std
4+
5+use std::{
6+ io::{stdout, Write},
7+ time::Duration,
8+};
9+
10+use futures::{future::FutureExt, select, StreamExt};
11+use smol::Timer;
12+// use futures_timer::Delay;
13+
14+use crossterm::{
15+ cursor::position,
16+ event::{DisableMouseCapture, EnableMouseCapture, Event, EventStream, KeyCode},
17+ execute,
18+ terminal::{disable_raw_mode, enable_raw_mode},
19+ Result,
20+};
21+
22+const HELP: &str = r#"EventStream based on futures::Stream with async-std
23+ - Keyboard, mouse and terminal resize events enabled
24+ - Prints "." every second if there's no event
25+ - Hit "c" to print current cursor position
26+ - Use Esc to quit
27+"#;
28+
29+async fn print_events() {
30+ let mut reader = EventStream::new();
31+
32+ loop {
33+ let mut delay = Timer::after(Duration::from_millis(1_000)).fuse();
34+ let mut event = reader.next().fuse();
35+
36+ select! {
37+ _ = delay => { println!(".\r"); },
38+ maybe_event = event => {
39+ match maybe_event {
40+ Some(Ok(event)) => {
41+ println!("Event::{:?}\r", event);
42+
43+ if event == Event::Key(KeyCode::Char('c').into()) {
44+ println!("Cursor position: {:?}\r", position());
45+
46+ }
47+
48+ println!("test");
49+
50+ if event == Event::Key(KeyCode::Esc.into()) {
51+ break;
52+ }
53+ }
54+ Some(Err(e)) => println!("Error: {:?}\r", e),
55+ None => break,
56+ }
57+ }
58+ };
59+ }
60+}
61+
62+fn main() -> Result<()> {
63+ println!("{}", HELP);
64+
65+ enable_raw_mode()?;
66+
67+ let mut stdout = stdout();
68+ execute!(stdout, EnableMouseCapture)?;
69+
70+ use std::thread;
71+
72+ // Same number of threads as there are CPU cores.
73+ let num_threads = num_cpus::get().max(1);
74+
75+ // A channel that sends the shutdown signal.
76+ let (s, r) = piper::chan::<()>(0);
77+ let mut threads = Vec::new();
78+
79+ // Create an executor thread pool.
80+ for _ in 0..num_threads {
81+ // Spawn an executor thread that waits for the shutdown signal.
82+ let r = r.clone();
83+ threads.push(thread::spawn(move || smol::run(r.recv())));
84+ }
85+
86+ // No need to `run()`, now we can just block on the main future.
87+ smol::block_on(print_events());
88+
89+ // Send a shutdown signal.
90+ drop(s);
91+
92+ // Wait for threads to finish.
93+ for t in threads {
94+ t.join().unwrap();
95+ }
96+
97+ execute!(stdout, DisableMouseCapture)?;
98+
99+ disable_raw_mode()
100+}