Combine Text alias rename with guarded diagram navigation

This commit is contained in:
2026-09-12 17:27:08 -07:00
parent 4db1ef543c
commit 208268c8aa
40 changed files with 9766 additions and 19 deletions
+60 -4
View File
@@ -10,6 +10,7 @@ mod hosted;
mod reference_authoring;
#[cfg(test)]
mod review_navigation_tests;
pub(crate) mod source_rename;
mod source_symbols;
#[cfg(test)]
mod transition_context_tests;
@@ -436,6 +437,8 @@ pub enum Message {
crate::source_navigation::SymbolEvent,
),
SourceSymbolsReady(crate::source_navigation::Completion),
SourceRename(source_rename::Event),
SourceRenameReady(source_rename::Completion),
DiagramUsage(crate::diagram_usage::Event),
DiagramUsagesReady(crate::diagram_usage::Completion),
DiagramRevealViewport(crate::diagram_usage::Context, u64, iced::Size),
@@ -521,6 +524,7 @@ pub struct App {
pub source_navigation: crate::source_navigation::State,
source_find_instance: Id,
pub source_symbols: crate::source_navigation::SymbolState,
pub source_rename: source_rename::State,
pub(crate) diagram_usages: Option<crate::diagram_usage::Panel>,
pub(crate) diagram_navigation_focus: Option<crate::diagram_usage::Focus>,
source_diagram_job: Option<Id>,
@@ -640,6 +644,7 @@ impl App {
source_navigation: crate::source_navigation::State::default(),
source_find_instance: Id::new_v4(),
source_symbols: crate::source_navigation::SymbolState::default(),
source_rename: source_rename::State::default(),
diagram_usages: None,
diagram_navigation_focus: None,
source_diagram_job: None,
@@ -691,19 +696,37 @@ impl App {
|| self.behavior.has_pending()
}
fn sync_source(&mut self) {
self.sync_source_with_alias_editor(None);
}
fn sync_source_with_alias_editor(&mut self, hint: Option<source_rename::EditorRefresh<'_>>) {
self.source_workspace.accept(self.document.bundle());
self.show_source_file(false);
self.show_source_file_with_alias_editor(false, hint);
self.source_diagnostics = self.document.compiled().diagnostics.clone();
self.source_version += 1;
self.lint_requested = None;
}
fn show_source_file(&mut self, restore_cursor: bool) {
self.show_source_file_with_alias_editor(restore_cursor, None);
}
fn show_source_file_with_alias_editor(
&mut self,
restore_cursor: bool,
hint: Option<source_rename::EditorRefresh<'_>>,
) {
self.source_symbols.reveal = None;
self.source_tree.reveal(&self.source_workspace.active);
self.source_select_line = false;
let source = self.source_workspace.text().to_owned();
self.source_navigation.refresh(&source);
self.source_editor = text_editor::Content::with_text(&source);
if !hint.is_some_and(|hint| {
hint.apply(
&mut self.source_editor,
&self.source_workspace.active,
&source,
)
}) {
self.source_editor = text_editor::Content::with_text(&source);
}
self.source_snapshot = Arc::from(source);
self.source_jump = restore_cursor
.then(|| {
@@ -748,6 +771,9 @@ impl App {
}
}
fn sync(&mut self) {
self.sync_with_alias_editor(None);
}
fn sync_with_alias_editor(&mut self, hint: Option<source_rename::EditorRefresh<'_>>) {
self.explorer_index = crate::explorer::Index::new(self.project(), self.layer);
self.model_issues = validate(self.project());
self.normalize_creation();
@@ -777,7 +803,7 @@ impl App {
.map(|d| d.id);
}
self.refresh_draft();
self.sync_source();
self.sync_source_with_alias_editor(hint);
}
fn normalize_creation(&mut self) {
if !self.create_kind.supports(self.layer) {
@@ -970,6 +996,7 @@ impl App {
let source_version = self.source_version + 1;
let lint_running = self.lint_running;
let navigation_in_flight = self.source_symbols.in_flight;
let rename_in_flight = self.source_rename.in_flight;
let diagram_lookup_in_flight = self.diagram_lookup_in_flight;
let guide = std::mem::take(&mut self.guide);
let mut hosted = std::mem::take(&mut self.hosted);
@@ -983,6 +1010,7 @@ impl App {
self.source_version = source_version;
self.lint_running = lint_running;
self.source_symbols.in_flight = navigation_in_flight;
self.source_rename.in_flight = rename_in_flight;
self.diagram_lookup_in_flight = diagram_lookup_in_flight;
self.guide = guide;
self.path = path;
@@ -1146,7 +1174,9 @@ impl App {
|| self.diagram_usages.is_some()
|| self.behavior.source_active()
|| (self.page == Page::Text
&& (self.source_symbols.open || self.source_navigation.open)
&& (self.source_symbols.open
|| self.source_navigation.open
|| self.source_rename.open())
&& self.architecture.is_none()),
)
.map(|()| Message::Escape),
@@ -1194,6 +1224,13 @@ impl App {
])
}
pub fn update(&mut self, message: Message) -> Task<Message> {
// Reject stale rename intents before camera/reveal reconciliation or
// source interaction can disturb a newer navigation destination.
if let Message::SourceRename(event) = &message
&& !self.source_rename_envelope(event)
{
return Task::none();
}
let usage_viewport = self.diagram_reveal_viewport(&message);
let window_resized = matches!(&message, Message::WindowResized(_));
// Reject stale measurements before legacy viewport handlers can change
@@ -1346,6 +1383,9 @@ impl App {
if let Message::SourceSymbolsReady(completion) = message {
return self.source_symbols_ready(completion);
}
if let Message::SourceRenameReady(completion) = message {
return self.source_rename_ready(completion);
}
if let Message::DiagramUsagesReady(completion) = message {
return self.diagram_usages_ready(completion);
}
@@ -1567,6 +1607,18 @@ impl App {
{
return Task::none();
}
if self.source_rename.open() {
if matches!(
message,
Message::Escape | Message::Request(Pending::Close(_))
) {
self.close_source_rename();
return Task::none();
}
if !modal_event && !matches!(message, Message::SourceRename(_)) {
return Task::none();
}
}
if matches!(
message,
Message::Page(_) | Message::Layer(_) | Message::Diagram(_)
@@ -1611,6 +1663,7 @@ impl App {
self.last_workspace_page = self.page;
}
let mut task = self.handle(message);
self.refresh_source_rename_context();
self.reconcile_reference_chooser();
self.route_state_diagram_workspace();
if self.page != Page::Home {
@@ -3210,6 +3263,7 @@ impl App {
if self.pending_recovery.as_ref() != Some(&receipt.target) {
return Task::none();
}
self.invalidate_source_rename("Disk recovery changed this source context. Your replacement is retained; close and invoke Rename again.");
self.pending_recovery = None;
self.source_diagnostics
.retain(|issue| issue.diagnostic.code != "pending_save");
@@ -3297,6 +3351,8 @@ impl App {
Message::SourceViewport(ticket) => return self.source_viewport(ticket),
Message::SourceFindClose(..) => return Task::none(), // update checks and unwraps it
Message::SourceSymbols(_, event) => return self.source_symbol_event(event),
Message::SourceRename(event) => return self.source_rename_event(event),
Message::SourceRenameReady(completion) => return self.source_rename_ready(completion),
Message::SourceSymbolsReady(completion) => {
return self.source_symbols_ready(completion);
}