Async task to wait for key events on a non-raw terminal and translate them into events for the console or the machine.
(on_key_tx: Sender<Key>)
| 191 | /// Async task to wait for key events on a non-raw terminal and translate them into events for |
| 192 | /// the console or the machine. |
| 193 | async fn stdio_key_handler(on_key_tx: Sender<Key>) { |
| 194 | // TODO(jmmv): We should probably install a signal handler here to capture SIGINT and |
| 195 | // funnel it to the Machine via signals_rx, as we do in the raw_key_handler. This would |
| 196 | // help ensure both consoles behave in the same way, but there is strictly no need for this |
| 197 | // because, when we do not configure the terminal in raw mode, we aren't capturing CTRL+C |
| 198 | // and the default system handler will work. |
| 199 | |
| 200 | let mut buffer = VecDeque::default(); |
| 201 | |
| 202 | let mut done = false; |
| 203 | while !done { |
| 204 | if on_key_tx.is_closed() { |
| 205 | break; |
| 206 | } |
| 207 | |
| 208 | let key = match read_key_from_stdin(&mut buffer) { |
| 209 | Ok(key) => key, |
| 210 | Err(_) => { |
| 211 | // There is not much we can do if we get an error from stdin. |
| 212 | Key::Unknown |
| 213 | } |
| 214 | }; |
| 215 | |
| 216 | done = key == Key::EofOrDelete; |
| 217 | |
| 218 | // This should never fail but can if the receiver outruns the console because we don't |
| 219 | // await for the handler to terminate (which we cannot do safely because `Drop` is not |
| 220 | // async). |
| 221 | if on_key_tx.send(key).await.is_err() { |
| 222 | break; |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | on_key_tx.close(); |
| 227 | } |
| 228 | |
| 229 | /// Flushes the console, which has already been written to via `lock`, if syncing is enabled. |
| 230 | fn maybe_flush(&self, mut lock: StdoutLock<'_>) -> io::Result<()> { |
nothing calls this directly
no test coverage detected