TUIのオーバーホール実装
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
//! File content cache for the Edit renderer.
|
||||
//!
|
||||
//! Holds `path → content` for every file the TUI has observed via a
|
||||
//! successful Read (where `ToolResult.output` contains the file body),
|
||||
//! Write (where `args.content` is the new body), or Edit (which mutates
|
||||
//! the cached body in-place). The cache is purely a display-side view —
|
||||
//! it has no opinion on what the filesystem actually contains.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FileCache {
|
||||
contents: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl FileCache {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn put(&mut self, path: impl Into<String>, content: impl Into<String>) {
|
||||
self.contents.insert(path.into(), content.into());
|
||||
}
|
||||
|
||||
pub fn get(&self, path: &str) -> Option<&str> {
|
||||
self.contents.get(path).map(String::as_str)
|
||||
}
|
||||
|
||||
/// Apply an Edit-style substitution. When `old` is unique in the
|
||||
/// cached content we swap it for `new`; otherwise we leave the
|
||||
/// cache untouched (the TUI can't reliably reconstruct the new
|
||||
/// state in that case).
|
||||
pub fn apply_edit(&mut self, path: &str, old: &str, new: &str) {
|
||||
let Some(current) = self.contents.get(path) else {
|
||||
return;
|
||||
};
|
||||
// Only swap when `old` appears exactly once — mirrors the
|
||||
// tool's own precondition and keeps the cache from diverging
|
||||
// when ambiguity would otherwise force a guess.
|
||||
let mut occurrences = current.match_indices(old);
|
||||
let first = occurrences.next();
|
||||
let second = occurrences.next();
|
||||
if let (Some((idx, matched)), None) = (first, second) {
|
||||
let end = idx + matched.len();
|
||||
let mut buf = String::with_capacity(current.len() - old.len() + new.len());
|
||||
buf.push_str(¤t[..idx]);
|
||||
buf.push_str(new);
|
||||
buf.push_str(¤t[end..]);
|
||||
self.contents.insert(path.to_owned(), buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user