Better prompt behaviour

This commit is contained in:
Joshua Barretto 2025-06-09 16:49:07 +01:00
parent 67dac456af
commit 0bd78521e3
3 changed files with 28 additions and 5 deletions

View file

@ -123,6 +123,14 @@ impl Buffer {
})
}
pub fn clear(&mut self) {
self.text.chars.clear();
// Reset cursors
self.cursors.values_mut().for_each(|cursor| {
*cursor = Cursor::default();
});
}
pub fn move_cursor(
&mut self,
cursor_id: CursorId,

View file

@ -47,9 +47,10 @@ impl Element<CanEnd> for Prompt {
Some(Action::Cancel) => Ok(Resp::end(None)),
Some(Action::Go) => {
if let Some(action) = self.get_action() {
Ok(Resp::end(action))
self.buffer.clear();
Ok(Resp::handled(action))
} else {
Ok(Resp::end(Action::Show(format!(
Ok(Resp::handled(Action::Show(format!(
"unknown command `{}`",
self.buffer.text.to_string()
))))
@ -75,8 +76,18 @@ pub struct Show {
impl Element<CanEnd> for Show {
fn handle(&mut self, state: &mut State, event: Event) -> Result<Resp<CanEnd>, Event> {
match event.to_action(|e| e.to_continue()) {
match event.to_action(|e| {
e.to_cancel()
.or_else(|| e.to_continue())
.or_else(|| e.to_char().map(Action::Char))
}) {
// Shows cannot be cancelled, so pass the cancel along to the parent task
Some(Action::Cancel) => Ok(Resp::end(Some(Action::Cancel))),
// A continue ends the show
Some(Action::Continue) => Ok(Resp::end(None)),
// Pass attempts to type to the parent prompt task
// TODO: Don't assume that a `Show` is always the child of the prompt
Some(Action::Char(c)) => Ok(Resp::end(Some(Action::Char(c)))),
_ => Ok(Resp::handled(None)),
}
}

View file

@ -54,7 +54,11 @@ impl Element<CanEnd> for Root {
if resp.should_end() {
self.tasks.truncate(task_idx);
}
break resp.action;
if let Some(action) = resp.action {
event = Event::Action(action);
} else {
break None;
}
}
Err(e) => event = e,
}
@ -101,7 +105,7 @@ impl Visual for Root {
let task_has_focus = matches!(self.tasks.last(), Some(Task::Prompt(_)));
// Display status bar
let status_size = if let Some(Task::Prompt(p)) = self.tasks.last_mut() {
let status_size = if let Some(Task::Prompt(p)) = self.tasks.first_mut() {
frame
.rect([0, frame.size()[1].saturating_sub(3)], [frame.size()[0], 3])
.with(|frame| p.render(state, frame));