1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use crate::common::{Result, Text};
use crate::config::Config;
use crate::events::Event;
use crate::state::State;
use crate::ui::Canvas;
use async_std::channel::Receiver;
use async_std::io;
use async_std::prelude::*;
use std::time::Instant;
pub async fn task<W>(config: Config, outbound: W, mut recv: Receiver<Event>) -> Result<Option<Text>>
where
W: io::Write + Send + Unpin + 'static,
{
log::trace!("starting screen");
let mut last_timestamp = Instant::now();
let mut render: bool;
let mut selection = None;
let mut state = State::new();
let mut canvas = Canvas::new(&config, outbound).await?;
canvas.render(&state).await?;
while let Some(event) = recv.next().await {
render = false;
match event {
Event::Search(prompt) => {
log::trace!("printing prompt: {:?}", prompt);
last_timestamp = prompt.timestamp();
state.set_search(prompt);
render = true;
}
Event::Flush((matches, len)) => {
log::trace!("flushing matches");
state.set_matches((matches, len));
render = true;
}
Event::SearchDone((matches, len, timestamp)) => {
if timestamp >= last_timestamp {
log::trace!("printing new search results");
state.set_matches((matches, len));
render = true;
}
}
Event::Up => {
log::trace!("moving selection up");
state.select_up();
render = true;
}
Event::Down => {
log::trace!("moving selection down");
state.select_down();
render = true;
}
Event::Done => {
selection = state.selection();
break;
}
Event::Exit => break,
_ => (),
};
if render {
canvas.render(&state).await?;
}
}
log::trace!("screen done");
Ok(selection)
}