feat: enhance workspace management and history tracking in application state
This commit is contained in:
+15
-5
@@ -72,6 +72,7 @@ pub struct InputState {
|
||||
pub autocomplete_candidates: Vec<String>,
|
||||
pub autocomplete_idx: usize,
|
||||
pub autocomplete_visible: bool,
|
||||
pub history_file: Option<PathBuf>,
|
||||
}
|
||||
|
||||
const COMMANDS: &[&str] = &[
|
||||
@@ -110,6 +111,7 @@ impl InputState {
|
||||
autocomplete_candidates: Vec::new(),
|
||||
autocomplete_idx: 0,
|
||||
autocomplete_visible: false,
|
||||
history_file: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,14 +221,22 @@ impl InputState {
|
||||
}
|
||||
}
|
||||
|
||||
/// Submit the current buffer: push it to history, clear the buffer,
|
||||
/// and return the submitted text.
|
||||
///
|
||||
/// Return: the text that was in the buffer before clearing.
|
||||
pub fn submit(&mut self) -> String {
|
||||
let result = self.buffer.clone();
|
||||
if !result.is_empty() {
|
||||
self.history.push(result.clone());
|
||||
if self.history.last() != Some(&result) {
|
||||
self.history.push(result.clone());
|
||||
if let Some(ref path) = self.history_file {
|
||||
if let Ok(mut file) = std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(path)
|
||||
{
|
||||
use std::io::Write;
|
||||
let _ = writeln!(file, "{}", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.history_idx = None;
|
||||
}
|
||||
self.buffer.clear();
|
||||
|
||||
+29
-1
@@ -104,7 +104,7 @@ impl AppStateRest {
|
||||
tracing::warn!("[state] session_dir has no file_name component, using empty session_id");
|
||||
String::new()
|
||||
});
|
||||
let state = AppStateRest {
|
||||
let mut state = AppStateRest {
|
||||
|
||||
settings,
|
||||
app_config,
|
||||
@@ -133,6 +133,34 @@ impl AppStateRest {
|
||||
quit: false,
|
||||
};
|
||||
|
||||
// Load project-specific history
|
||||
let base_dir = state.memory_dir.parent().unwrap_or(&state.memory_dir);
|
||||
if let Some(root) = state.workspace_roots.first() {
|
||||
if let Ok(abs_root) = std::fs::canonicalize(root) {
|
||||
use sha2::Digest;
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(abs_root.to_string_lossy().as_bytes());
|
||||
let hash_hex = format!("{:x}", hasher.finalize());
|
||||
let folder_name = abs_root.file_name()
|
||||
.map(|n| n.to_string_lossy().to_string())
|
||||
.unwrap_or_else(|| "root".to_string());
|
||||
let history_filename = format!("{}-{}.txt", folder_name, &hash_hex[..8]);
|
||||
let history_dir = base_dir.join("history");
|
||||
let _ = std::fs::create_dir_all(&history_dir);
|
||||
let history_file = history_dir.join(history_filename);
|
||||
|
||||
if let Ok(content) = std::fs::read_to_string(&history_file) {
|
||||
let history: Vec<String> = content
|
||||
.lines()
|
||||
.map(|s| s.to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect();
|
||||
state.input.history = history;
|
||||
}
|
||||
state.input.history_file = Some(history_file);
|
||||
}
|
||||
}
|
||||
|
||||
// Fire-and-forget background LSP provisioning.
|
||||
//
|
||||
// Flow: spawn OS thread -> provision_all() probes/installs every
|
||||
|
||||
Reference in New Issue
Block a user