已合并
fix(diff): 文件修改列表统一显示 workspace 相对路径 #465
fix(diff): 文件修改列表统一显示 workspace 相对路径 #465
已合并
Echo0314创建于 4 天前
共 1 个文件变更+26-3
@@ -1,6 +1,6 @@
1use std::collections::{BTreeMap, HashMap};1use std::collections::{BTreeMap, HashMap};
2use std::fs;2use std::fs;
3-use std::path::{Path, PathBuf};3+use std::path::{Component, Path, PathBuf};
4 4 
5use serde::{Deserialize, Serialize};5use serde::{Deserialize, Serialize};
6 6 
@@ -338,8 +338,12 @@ impl SessionDiffTracker {
338 }338 }
339 339 
340 pub fn display_file_path(&self, file_path: &str) -> String {340 pub fn display_file_path(&self, file_path: &str) -> String {
341- let path = Path::new(file_path);341+ // Tool calls report both absolute and workspace-relative paths. Resolve
342- if let Ok(relative) = path.strip_prefix(&self.workspace) {342+ // either form under the workspace, then compare the two lexically: no
343+ // filesystem access here, this runs for every visible entry each frame.
344+ let workspace = lexical_path(&self.workspace);
345+ let absolute = lexical_path(&resolve_workspace_file_path(&workspace, file_path));
346+ if let Ok(relative) = absolute.strip_prefix(&workspace) {
343 let display = relative.display().to_string();347 let display = relative.display().to_string();
344 if !display.is_empty() {348 if !display.is_empty() {
345 return display;349 return display;
@@ -461,6 +465,25 @@ pub fn file_change_delta_from_tool_args(tool: &str, args_preview: &str) -> Optio
461 })465 })
462}466}
463 467 
468+/// Lexically normalize a path: drop `.` components and collapse `..` where it can
469+/// be resolved without touching the filesystem (symlinks are NOT resolved).
470+fn lexical_path(path: &Path) -> PathBuf {
471+ let mut out = PathBuf::new();
472+ for component in path.components() {
473+ match component {
474+ Component::CurDir => {}
475+ Component::ParentDir => {
476+ let popped = out.pop();
477+ if !popped {
478+ out.push(component.as_os_str());
479+ }
480+ }
481+ other => out.push(other.as_os_str()),
482+ }
483+ }
484+ out
485+}
486+ 
464fn resolve_workspace_file_path(workspace: &Path, file_path: &str) -> PathBuf {487fn resolve_workspace_file_path(workspace: &Path, file_path: &str) -> PathBuf {
465 let path = Path::new(file_path);488 let path = Path::new(file_path);
466 if path.is_absolute() {489 if path.is_absolute() {