diff --git a/crates/sem-cli/src/formatters/terminal.rs b/crates/sem-cli/src/formatters/terminal.rs index ccc24691..b5ebf696 100644 --- a/crates/sem-cli/src/formatters/terminal.rs +++ b/crates/sem-cli/src/formatters/terminal.rs @@ -104,12 +104,21 @@ pub fn format_terminal(result: &DiffResult, verbose: bool) -> String { }; let type_label = format!("{:<10}", change.entity_type); - let name_display = if let Some(ref old_name) = change.old_entity_name { + let base_name = if let Some(ref old_name) = change.old_entity_name { format!("{old_name} -> {}", change.entity_name) } else { change.entity_name.clone() }; - let name_label = format!("{:<25}", name_display); + let display_name = match &change.parent_name { + Some(p) => format!("{p}::{base_name}"), + None => base_name, + }; + let truncated = if display_name.len() > 25 { + format!("{}…", display_name.char_indices().nth(24).map(|(i, _)| &display_name[..i]).unwrap_or(&display_name)) + } else { + display_name + }; + let name_label = format!("{:<25}", truncated); lines.push(format!( "{} {} {} {} {}", diff --git a/crates/sem-core/src/model/change.rs b/crates/sem-core/src/model/change.rs index 63dfd8d7..2b145785 100644 --- a/crates/sem-core/src/model/change.rs +++ b/crates/sem-core/src/model/change.rs @@ -35,6 +35,8 @@ pub struct SemanticChange { pub entity_name: String, #[serde(default)] pub entity_line: usize, + #[serde(skip_serializing_if = "Option::is_none")] + pub parent_name: Option, pub file_path: String, #[serde(skip_serializing_if = "Option::is_none")] pub old_entity_name: Option, diff --git a/crates/sem-core/src/model/identity.rs b/crates/sem-core/src/model/identity.rs index 5df71378..8fa03d50 100644 --- a/crates/sem-core/src/model/identity.rs +++ b/crates/sem-core/src/model/identity.rs @@ -3,6 +3,12 @@ use std::collections::{HashMap, HashSet}; use super::change::{ChangeType, SemanticChange}; use super::entity::SemanticEntity; +/// Extracts the leaf name from a parent_id string (last "::" segment). +fn parent_name(entity: &SemanticEntity) -> Option { + let pid = entity.parent_id.as_ref()?; + pid.rsplit("::").next().map(String::from) +} + pub struct MatchResult { pub changes: Vec, } @@ -43,6 +49,7 @@ fn make_change( entity_type: primary.entity_type.clone(), entity_name: primary.name.clone(), entity_line: primary.start_line, + parent_name: parent_name(primary), file_path: primary.file_path.clone(), old_entity_name: before_entity.and_then(|b| { (b.name != after_entity.name).then(|| b.name.clone()) diff --git a/crates/sem-core/src/parser/differ.rs b/crates/sem-core/src/parser/differ.rs index 4ea6c02c..546ab47b 100644 --- a/crates/sem-core/src/parser/differ.rs +++ b/crates/sem-core/src/parser/differ.rs @@ -249,6 +249,7 @@ fn detect_orphan_changes( entity_type: "orphan".to_string(), entity_name: "module-level".to_string(), entity_line: 0, + parent_name: None, file_path: file.file_path.clone(), old_entity_name: None, old_file_path: None,