Skip to content

Commit a9c1686

Browse files
authored
Handle key events in non-interactive mode, too (#819)
1 parent 17aa6f1 commit a9c1686

File tree

2 files changed

+52
-25
lines changed

2 files changed

+52
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131
- `CodeSegment` and `RomSegment` have been merged into a single `Segment` struct (#796)
3232
- `IdfBootloaderFormat` has had its constructor's parameters reduced/simplified (#798)
3333
- Update flash size when creating the app partition (#797)
34+
- `--non-interactive` may now react to key events (user input, Ctrl-C, Ctrl-R) if possible (#819)
3435

3536
### Fixed
3637

espflash/src/cli/monitor/mod.rs

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ pub fn monitor(
8080
pid: u16,
8181
monitor_args: MonitorConfigArgs,
8282
) -> miette::Result<()> {
83-
if !monitor_args.non_interactive {
84-
println!("Commands:");
85-
println!(" CTRL+R Reset chip");
86-
println!(" CTRL+C Exit");
87-
println!();
88-
} else if !monitor_args.no_reset {
83+
println!("Commands:");
84+
println!(" CTRL+R Reset chip");
85+
println!(" CTRL+C Exit");
86+
println!();
87+
88+
if monitor_args.non_interactive && !monitor_args.no_reset {
8989
reset_after_flash(&mut serial, pid).into_diagnostic()?;
9090
}
9191

@@ -139,30 +139,56 @@ pub fn monitor(
139139
// Don't forget to flush the writer!
140140
stdout.flush().ok();
141141

142-
if !monitor_args.non_interactive && poll(Duration::from_secs(0)).into_diagnostic()? {
143-
if let Event::Key(key) = read().into_diagnostic()? {
144-
if key.kind == KeyEventKind::Press {
145-
if key.modifiers.contains(KeyModifiers::CONTROL) {
146-
match key.code {
147-
KeyCode::Char('c') => break,
148-
KeyCode::Char('r') => {
149-
reset_after_flash(&mut serial, pid).into_diagnostic()?;
150-
continue;
151-
}
152-
_ => {}
153-
}
154-
}
155-
156-
if let Some(bytes) = handle_key_event(key) {
157-
serial.write_all(&bytes).into_diagnostic()?;
158-
serial.flush().into_diagnostic()?;
159-
}
142+
if !handle_user_input(&mut serial, pid, monitor_args.non_interactive)? {
143+
break;
144+
}
145+
}
146+
147+
Ok(())
148+
}
149+
150+
/// Handle user input from the terminal.
151+
///
152+
/// Returns `true` if the program should continue running, `false` if it should
153+
/// exit.
154+
fn handle_user_input(serial: &mut Port, pid: u16, non_interactive: bool) -> Result<bool> {
155+
let key = match key_event().into_diagnostic() {
156+
Ok(Some(event)) => event,
157+
Ok(None) => return Ok(true),
158+
Err(_) if non_interactive => return Ok(true),
159+
Err(err) => return Err(err),
160+
};
161+
162+
if key.kind == KeyEventKind::Press {
163+
if key.modifiers.contains(KeyModifiers::CONTROL) {
164+
match key.code {
165+
KeyCode::Char('c') => return Ok(false),
166+
KeyCode::Char('r') => {
167+
reset_after_flash(serial, pid).into_diagnostic()?;
168+
return Ok(true);
160169
}
170+
_ => {}
161171
}
162172
}
173+
174+
if let Some(bytes) = handle_key_event(key) {
175+
serial.write_all(&bytes).into_diagnostic()?;
176+
serial.flush().into_diagnostic()?;
177+
}
163178
}
164179

165-
Ok(())
180+
Ok(true)
181+
}
182+
183+
fn key_event() -> std::io::Result<Option<KeyEvent>> {
184+
if !poll(Duration::ZERO)? {
185+
return Ok(None);
186+
}
187+
188+
match read()? {
189+
Event::Key(key) => Ok(Some(key)),
190+
_ => Ok(None),
191+
}
166192
}
167193

168194
fn deduce_log_format(elf: Option<&[u8]>) -> LogFormat {

0 commit comments

Comments
 (0)