Integrate diagnostic decorations and current-source Text input boundaries

This commit is contained in:
2026-09-13 04:47:30 -07:00
parent 16904398db
commit 92ff99eb54
98 changed files with 35959 additions and 208 deletions
@@ -11,7 +11,7 @@ use iced::{
widget::{button, column, container, scrollable, text, tooltip},
};
pub(super) fn panel(app: &App) -> Element<'_, Message> {
pub(super) fn panel(app: &App, current: bool) -> Element<'_, Message> {
use crate::app::text_workspace::{DrawerTab, Event};
use std::collections::BTreeSet;
let state = &app.source_symbols;
@@ -22,7 +22,7 @@ pub(super) fn panel(app: &App) -> Element<'_, Message> {
content = content.push(text(notice.clone()).size(12));
}
if visible && let Some(results) = &state.results {
let stale = results.stamp.snapshot != app.source_key();
let stale = !current;
let enabled = !stale && app.source_navigation_available();
let files: BTreeSet<_> = results
.definitions
+14 -4
View File
@@ -15,6 +15,7 @@ pub(crate) const STRIP_HEIGHT: f32 = 42.;
pub(crate) const FIND_HEIGHT: f32 = 36.;
pub(crate) const DRAWER_HEIGHT: f32 = 180.;
pub(crate) const STATUS_HEIGHT: f32 = 22.;
const EDITOR_PADDING: f32 = 16.;
/// The caller supplies one persistent diagnostic Guard, including when hidden
/// (None publication and empty child). References is empty while hidden; its
@@ -23,6 +24,7 @@ pub(super) fn view<'a>(
app: &'a App,
references: Element<'a, Message>,
problems: Element<'a, Message>,
references_current: bool,
) -> Element<'a, Message> {
let tab = app.text_workspace.drawer();
let measured_drawer = Rc::new(Cell::new(DRAWER_HEIGHT));
@@ -63,12 +65,19 @@ pub(super) fn view<'a>(
})
.font(Font::MONOSPACE)
.size(14)
.padding(16)
.padding(EDITOR_PADDING)
.height(Fill)
.highlight_with::<crate::highlight::ArcadiaHighlighter>(
app.source_snapshot.clone(),
crate::highlight::format,
);
let editor = crate::source_annotations::Decorations::new(
editor,
&app.source_editor,
app.source_annotation_snapshot(),
iced::Padding::new(EDITOR_PADDING),
app.source_navigation_available(),
);
let editor = widget::sensor(editor)
.key((
app.source_workspace.active.clone(),
@@ -84,7 +93,7 @@ pub(super) fn view<'a>(
});
let (errors, warnings) = diagnostic_counts(app);
let summary: Element<'a, Message> = match tab {
Some(DrawerTab::References) => reference_summary(app),
Some(DrawerTab::References) => reference_summary(app, references_current),
Some(DrawerTab::Problems) => text(format!(
"{errors} source errors · {warnings} warnings · choose a location for details"
))
@@ -306,6 +315,7 @@ fn find_bar(app: &App) -> Element<'_, Message> {
fn reference_summary<'a, Renderer: iced::advanced::text::Renderer + 'a>(
app: &'a App,
current: bool,
) -> Element<'a, Message, iced::Theme, Renderer> {
let Some(results) = &app.source_symbols.results else {
return text(if app.source_symbols.in_flight.is_some() {
@@ -326,7 +336,7 @@ fn reference_summary<'a, Renderer: iced::advanced::text::Renderer + 'a>(
results.total_definitions, results.total_references
);
let mut flags = Vec::new();
if results.stamp.snapshot != app.source_key() {
if !current {
flags.push("Stale");
}
if results.scope.partial() {
@@ -1104,7 +1114,7 @@ mod tests {
}
#[cfg(all(test, debug_assertions))]
mod summary_visibility_tests;
pub(crate) mod summary_visibility_tests;
/// The same retained layout and Alt+PageDown publisher as the production view;
/// only its five content slots are inert for this CPU integration witness.
@@ -117,6 +117,7 @@ const FLAGS: [&str; 5] = ["Stale", "Partial", "Collision", "Detached", "Unverifi
fn draw_and_check_flags(
content: Element<'_, Message, iced::Theme, Recorder>,
width: f32,
flags: &[&str],
) -> Vec<String> {
let viewport = Rectangle::with_size(Size::new(width, 24.));
let mut renderer = Recorder {
@@ -143,7 +144,7 @@ fn draw_and_check_flags(
&viewport,
);
let mut failures = Vec::new();
for flag in FLAGS {
for &flag in flags {
for byte in 0..flag.len() {
let matching: Vec<_> = renderer
.clusters
@@ -221,14 +222,18 @@ fn all_reference_exceptions_fit_allocated_width_with_wide_alias_and_large_counts
omitted_references: 100_000,
}));
for width in [840., 720.] {
let positive = draw_and_check_flags(reference_summary(&app), width);
let positive = draw_and_check_flags(
reference_summary(&app, app.source_results_current()),
width,
&FLAGS,
);
assert!(
positive.is_empty(),
"reserved flags, width {width}, alias {alias:?}: {positive:?}"
);
// Observe the exact old presentation without predicting font widths.
// This is emitted under --nocapture, whether it clips or fits.
let old = draw_and_check_flags(old_summary(old_value.clone()), width);
let old = draw_and_check_flags(old_summary(old_value.clone()), width, &FLAGS);
println!(
"old alias-first summary width={width} alias={alias:?}: {} missing/clipped flag-byte checks; first={:?}",
old.len(),
@@ -240,9 +245,18 @@ fn all_reference_exceptions_fit_allocated_width_with_wide_alias_and_large_counts
// bound: require the same evaluator to reject a clipped old-style paragraph.
// This is not evidence of a production/native overflow at 840 pixels.
let stress = format!("@{} · {}", "W".repeat(256), FLAGS.join(" · "));
let rejected = draw_and_check_flags(old_summary(stress), 720.);
let rejected = draw_and_check_flags(old_summary(stress), 720., &FLAGS);
assert!(
!rejected.is_empty(),
"negative control must detect missing/clipped warning text"
);
}
pub(crate) fn rendered_stale(app: &App) -> bool {
draw_and_check_flags(
reference_summary(app, app.source_results_current()),
720.,
&["Stale"],
)
.is_empty()
}