refactor(tui/history): add history_*_and_maybe_merge API and adopt in exec flow

- Add  and
- Use in exec completion paths to encapsulate merge heuristics
- Continue to centralize invalidation/redraw in helpers

Validated with ./build-fast.sh (no warnings).
This commit is contained in:
James Peter
2025-09-02 17:43:11 +10:00
parent 9fb2563cbb
commit 23b1d3ec8d
2 changed files with 16 additions and 11 deletions
+13
View File
@@ -1592,6 +1592,19 @@ impl ChatWidget<'_> {
}
}
// History merge API: consolidates exec/tool merge logic
fn history_push_and_maybe_merge(&mut self, cell: impl HistoryCell + 'static) {
// For push, add_to_history already contains merge heuristics for Exec/Tool cells.
self.add_to_history(cell);
}
fn history_replace_and_maybe_merge(&mut self, idx: usize, cell: Box<dyn HistoryCell>) {
// Replace at index, then attempt standard exec merge with previous cell.
self.history_replace_at(idx, cell);
// Merge only if the new cell is an Exec with output (completed) or a MergedExec.
crate::chatwidget::exec_tools::try_merge_completed_exec_at(self, idx);
}
/// Clean up faded-out animation cells
fn process_animation_cleanup(&mut self) {
// With trait-based cells, we can't easily detect and clean up specific cell types
+3 -11
View File
@@ -428,13 +428,8 @@ pub(super) fn handle_exec_end_now(chat: &mut ChatWidget<'_>, ev: ExecCommandEndE
})
.unwrap_or(false);
if is_match {
if let Some(c) = completed_opt.take() { chat.history_replace_at(idx, Box::new(c)); }
let pre_len = chat.history_cells.len();
if let Some(c) = completed_opt.take() { chat.history_replace_and_maybe_merge(idx, Box::new(c)); }
replaced = true;
try_merge_completed_exec_at(chat, idx);
if chat.history_cells.len() == pre_len {
chat.request_redraw();
}
}
}
if !replaced {
@@ -446,17 +441,14 @@ pub(super) fn handle_exec_end_now(chat: &mut ChatWidget<'_>, ev: ExecCommandEndE
}
}
if let Some(i) = found {
if let Some(c) = completed_opt.take() { chat.history_replace_at(i, Box::new(c)); }
let pre_len = chat.history_cells.len();
if let Some(c) = completed_opt.take() { chat.history_replace_and_maybe_merge(i, Box::new(c)); }
replaced = true;
try_merge_completed_exec_at(chat, i);
if chat.history_cells.len() == pre_len { chat.request_redraw(); }
}
}
}
if !replaced {
if let Some(c) = completed_opt.take() { chat.history_push(c); }
if let Some(c) = completed_opt.take() { chat.history_push_and_maybe_merge(c); }
}
if exit_code == 0 {