feat(state): Alirkan mention_index lewat ToolCtx dan AppStateRest, bangun index di background thread
Menambahkan field mention_index: MentionIndex ke ToolCtx/ToolCtxBuilder dan AppStateRest, mengikuti pola dir_cache yang sudah ada. AppStateRest::new() sekarang men-spawn thread background yang men-walk setiap workspace root via ignore::Walk, membangun daftar path file (dengan prefix [N] untuk root selain yang pertama) dan mengisi mention_index — data ini yang akan dipakai fitur autocomplete @file-mention.
This commit is contained in:
+42
-1
@@ -9,7 +9,7 @@ use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use super::misc::{DirCache, InputState, MiscState, ScrollState};
|
||||
use super::misc::{DirCache, InputState, MentionIndex, MiscState, ScrollState};
|
||||
use super::runtime::{SessionRuntime, TurnEvent};
|
||||
use super::types::{Origin, Toast, TranscriptCache};
|
||||
use crate::app::lsp::LspManager;
|
||||
@@ -54,6 +54,7 @@ pub struct AppStateRest {
|
||||
pub memory_dir: PathBuf,
|
||||
pub worktrees_dir: PathBuf,
|
||||
pub dir_cache: Arc<RwLock<DirCache>>,
|
||||
pub mention_index: MentionIndex,
|
||||
pub edit_log: EditLog,
|
||||
pub session_runtime: Option<SessionRuntime>,
|
||||
pub sessions: Vec<crate::model::session::Session>,
|
||||
@@ -110,6 +111,7 @@ impl AppStateRest {
|
||||
turn_in_flight: Arc::new(Mutex::new(false)),
|
||||
abort_flag: Arc::new(std::sync::atomic::AtomicBool::new(false)),
|
||||
dir_cache: Arc::new(RwLock::new(dir_cache)),
|
||||
mention_index: MentionIndex::new(),
|
||||
edit_log: EditLog::new(session_dir),
|
||||
session_runtime: Some(SessionRuntime::new(session_dir.to_path_buf())),
|
||||
workflow_engine: WorkflowEngine::new(),
|
||||
@@ -204,6 +206,44 @@ impl AppStateRest {
|
||||
});
|
||||
}
|
||||
|
||||
// Fire-and-forget background file index build for `@file` mention
|
||||
// autocomplete.
|
||||
//
|
||||
// Flow: spawn OS thread -> `ignore::Walk` each workspace root,
|
||||
// collecting file paths (workspace-index-prefixed for roots beyond
|
||||
// the first, matching `resolve_path`'s `[N]path` convention) -> stop
|
||||
// once 50,000 entries are collected -> store the result in
|
||||
// `mention_index`.
|
||||
//
|
||||
// Why a raw thread and not a background tokio task: there is no
|
||||
// persistent async runtime driving the render loop, and this is
|
||||
// blocking filesystem I/O -- a dedicated thread keeps startup
|
||||
// non-blocking. Not joined, same rationale as the LSP provisioning
|
||||
// thread above: a slow/huge repo must not delay the TUI appearing.
|
||||
{
|
||||
let mention_index = state.mention_index.clone();
|
||||
let roots = state.workspace_roots.clone();
|
||||
std::thread::spawn(move || {
|
||||
const MAX_MENTION_ENTRIES: usize = 50_000;
|
||||
let mut paths = Vec::new();
|
||||
'roots: for (i, root) in roots.iter().enumerate() {
|
||||
for entry in ignore::Walk::new(root).flatten() {
|
||||
if !entry.path().is_file() {
|
||||
continue;
|
||||
}
|
||||
let rel = entry.path().strip_prefix(root).unwrap_or(entry.path());
|
||||
let rel_str = rel.display().to_string();
|
||||
let formatted = if i == 0 { rel_str } else { format!("[{i}]{rel_str}") };
|
||||
paths.push(formatted);
|
||||
if paths.len() >= MAX_MENTION_ENTRIES {
|
||||
break 'roots;
|
||||
}
|
||||
}
|
||||
}
|
||||
mention_index.set(paths);
|
||||
});
|
||||
}
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
@@ -278,6 +318,7 @@ impl AppStateRest {
|
||||
memory_dir: self.memory_dir.clone(),
|
||||
worktrees_dir: self.worktrees_dir.clone(),
|
||||
dir_cache: self.dir_cache.clone(),
|
||||
mention_index: self.mention_index.clone(),
|
||||
origin,
|
||||
graduated_checks: Vec::new(),
|
||||
lsp_manager: self.lsp_manager.clone(),
|
||||
|
||||
@@ -47,6 +47,7 @@ pub struct ToolCtx {
|
||||
pub memory_dir: PathBuf,
|
||||
pub worktrees_dir: PathBuf,
|
||||
pub dir_cache: std::sync::Arc<tokio::sync::RwLock<super::app::state::misc::DirCache>>,
|
||||
pub mention_index: super::app::state::misc::MentionIndex,
|
||||
pub origin: crate::app::state::types::Origin,
|
||||
pub graduated_checks: Vec<GraduatedCheck>,
|
||||
pub lsp_manager: Arc<Mutex<crate::app::lsp::LspManager>>,
|
||||
@@ -94,6 +95,7 @@ pub struct ToolCtxBuilder {
|
||||
pub memory_dir: PathBuf,
|
||||
pub worktrees_dir: PathBuf,
|
||||
pub dir_cache: std::sync::Arc<tokio::sync::RwLock<super::app::state::misc::DirCache>>,
|
||||
pub mention_index: super::app::state::misc::MentionIndex,
|
||||
pub origin: crate::app::state::types::Origin,
|
||||
pub graduated_checks: Vec<GraduatedCheck>,
|
||||
pub lsp_manager: Arc<Mutex<crate::app::lsp::LspManager>>,
|
||||
@@ -110,6 +112,7 @@ impl Default for ToolCtxBuilder {
|
||||
memory_dir: PathBuf::new(),
|
||||
worktrees_dir: PathBuf::new(),
|
||||
dir_cache: std::sync::Arc::new(tokio::sync::RwLock::new(super::app::state::misc::DirCache::new())),
|
||||
mention_index: super::app::state::misc::MentionIndex::new(),
|
||||
origin: crate::app::state::types::Origin::Main,
|
||||
graduated_checks: Vec::new(),
|
||||
lsp_manager: Arc::new(Mutex::new(crate::app::lsp::LspManager::new())),
|
||||
@@ -138,6 +141,7 @@ impl ToolCtxBuilder {
|
||||
memory_dir: self.memory_dir,
|
||||
worktrees_dir: self.worktrees_dir,
|
||||
dir_cache: self.dir_cache,
|
||||
mention_index: self.mention_index,
|
||||
origin: self.origin,
|
||||
graduated_checks: self.graduated_checks,
|
||||
lsp_manager: self.lsp_manager,
|
||||
|
||||
Reference in New Issue
Block a user