diagnostics: Reduce cloning of DiagnosticEntry (#39193)
Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
@@ -6,7 +6,7 @@ use assistant_slash_command::{
|
|||||||
use fuzzy::{PathMatch, StringMatchCandidate};
|
use fuzzy::{PathMatch, StringMatchCandidate};
|
||||||
use gpui::{App, Entity, Task, WeakEntity};
|
use gpui::{App, Entity, Task, WeakEntity};
|
||||||
use language::{
|
use language::{
|
||||||
Anchor, BufferSnapshot, DiagnosticEntry, DiagnosticSeverity, LspAdapterDelegate,
|
Anchor, BufferSnapshot, DiagnosticEntryRef, DiagnosticSeverity, LspAdapterDelegate,
|
||||||
OffsetRangeExt, ToOffset,
|
OffsetRangeExt, ToOffset,
|
||||||
};
|
};
|
||||||
use project::{DiagnosticSummary, PathMatchCandidateSet, Project};
|
use project::{DiagnosticSummary, PathMatchCandidateSet, Project};
|
||||||
@@ -367,7 +367,7 @@ pub fn collect_buffer_diagnostics(
|
|||||||
|
|
||||||
fn collect_diagnostic(
|
fn collect_diagnostic(
|
||||||
output: &mut SlashCommandOutput,
|
output: &mut SlashCommandOutput,
|
||||||
entry: &DiagnosticEntry<Anchor>,
|
entry: &DiagnosticEntryRef<'_, Anchor>,
|
||||||
snapshot: &BufferSnapshot,
|
snapshot: &BufferSnapshot,
|
||||||
include_warnings: bool,
|
include_warnings: bool,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use gpui::{
|
|||||||
InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Subscription,
|
InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Subscription,
|
||||||
Task, WeakEntity, Window, actions, div,
|
Task, WeakEntity, Window, actions, div,
|
||||||
};
|
};
|
||||||
use language::{Buffer, DiagnosticEntry, Point};
|
use language::{Buffer, DiagnosticEntry, DiagnosticEntryRef, Point};
|
||||||
use project::{
|
use project::{
|
||||||
DiagnosticSummary, Event, Project, ProjectItem, ProjectPath,
|
DiagnosticSummary, Event, Project, ProjectItem, ProjectPath,
|
||||||
project_settings::{DiagnosticSeverity, ProjectSettings},
|
project_settings::{DiagnosticSeverity, ProjectSettings},
|
||||||
@@ -350,7 +350,7 @@ impl BufferDiagnosticsEditor {
|
|||||||
grouped
|
grouped
|
||||||
.entry(entry.diagnostic.group_id)
|
.entry(entry.diagnostic.group_id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.push(DiagnosticEntry {
|
.push(DiagnosticEntryRef {
|
||||||
range: entry.range.to_point(&buffer_snapshot),
|
range: entry.range.to_point(&buffer_snapshot),
|
||||||
diagnostic: entry.diagnostic,
|
diagnostic: entry.diagnostic,
|
||||||
})
|
})
|
||||||
@@ -560,13 +560,16 @@ impl BufferDiagnosticsEditor {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_diagnostics(&mut self, diagnostics: &Vec<DiagnosticEntry<Anchor>>) {
|
fn set_diagnostics(&mut self, diagnostics: &[DiagnosticEntryRef<'_, Anchor>]) {
|
||||||
self.diagnostics = diagnostics.clone();
|
self.diagnostics = diagnostics
|
||||||
|
.iter()
|
||||||
|
.map(DiagnosticEntryRef::to_owned)
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn diagnostics_are_unchanged(
|
fn diagnostics_are_unchanged(
|
||||||
&self,
|
&self,
|
||||||
diagnostics: &Vec<DiagnosticEntry<Anchor>>,
|
diagnostics: &Vec<DiagnosticEntryRef<'_, Anchor>>,
|
||||||
snapshot: &BufferSnapshot,
|
snapshot: &BufferSnapshot,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if self.diagnostics.len() != diagnostics.len() {
|
if self.diagnostics.len() != diagnostics.len() {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use editor::{
|
|||||||
hover_popover::diagnostics_markdown_style,
|
hover_popover::diagnostics_markdown_style,
|
||||||
};
|
};
|
||||||
use gpui::{AppContext, Entity, Focusable, WeakEntity};
|
use gpui::{AppContext, Entity, Focusable, WeakEntity};
|
||||||
use language::{BufferId, Diagnostic, DiagnosticEntry};
|
use language::{BufferId, Diagnostic, DiagnosticEntryRef};
|
||||||
use lsp::DiagnosticSeverity;
|
use lsp::DiagnosticSeverity;
|
||||||
use markdown::{Markdown, MarkdownElement};
|
use markdown::{Markdown, MarkdownElement};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
@@ -24,7 +24,7 @@ pub struct DiagnosticRenderer;
|
|||||||
|
|
||||||
impl DiagnosticRenderer {
|
impl DiagnosticRenderer {
|
||||||
pub fn diagnostic_blocks_for_group(
|
pub fn diagnostic_blocks_for_group(
|
||||||
diagnostic_group: Vec<DiagnosticEntry<Point>>,
|
diagnostic_group: Vec<DiagnosticEntryRef<'_, Point>>,
|
||||||
buffer_id: BufferId,
|
buffer_id: BufferId,
|
||||||
diagnostics_editor: Option<Arc<dyn DiagnosticsToolbarEditor>>,
|
diagnostics_editor: Option<Arc<dyn DiagnosticsToolbarEditor>>,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
@@ -35,7 +35,7 @@ impl DiagnosticRenderer {
|
|||||||
else {
|
else {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
let primary = diagnostic_group[primary_ix].clone();
|
let primary = &diagnostic_group[primary_ix];
|
||||||
let group_id = primary.diagnostic.group_id;
|
let group_id = primary.diagnostic.group_id;
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
for entry in diagnostic_group.iter() {
|
for entry in diagnostic_group.iter() {
|
||||||
@@ -123,7 +123,7 @@ impl DiagnosticRenderer {
|
|||||||
impl editor::DiagnosticRenderer for DiagnosticRenderer {
|
impl editor::DiagnosticRenderer for DiagnosticRenderer {
|
||||||
fn render_group(
|
fn render_group(
|
||||||
&self,
|
&self,
|
||||||
diagnostic_group: Vec<DiagnosticEntry<Point>>,
|
diagnostic_group: Vec<DiagnosticEntryRef<'_, Point>>,
|
||||||
buffer_id: BufferId,
|
buffer_id: BufferId,
|
||||||
snapshot: EditorSnapshot,
|
snapshot: EditorSnapshot,
|
||||||
editor: WeakEntity<Editor>,
|
editor: WeakEntity<Editor>,
|
||||||
@@ -152,19 +152,15 @@ impl editor::DiagnosticRenderer for DiagnosticRenderer {
|
|||||||
|
|
||||||
fn render_hover(
|
fn render_hover(
|
||||||
&self,
|
&self,
|
||||||
diagnostic_group: Vec<DiagnosticEntry<Point>>,
|
diagnostic_group: Vec<DiagnosticEntryRef<'_, Point>>,
|
||||||
range: Range<Point>,
|
range: Range<Point>,
|
||||||
buffer_id: BufferId,
|
buffer_id: BufferId,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Option<Entity<Markdown>> {
|
) -> Option<Entity<Markdown>> {
|
||||||
let blocks = Self::diagnostic_blocks_for_group(diagnostic_group, buffer_id, None, cx);
|
let blocks = Self::diagnostic_blocks_for_group(diagnostic_group, buffer_id, None, cx);
|
||||||
blocks.into_iter().find_map(|block| {
|
blocks
|
||||||
if block.initial_range == range {
|
.into_iter()
|
||||||
Some(block.markdown)
|
.find_map(|block| (block.initial_range == range).then(|| block.markdown))
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_link(
|
fn open_link(
|
||||||
@@ -189,7 +185,7 @@ pub(crate) struct DiagnosticBlock {
|
|||||||
impl DiagnosticBlock {
|
impl DiagnosticBlock {
|
||||||
pub fn render_block(&self, editor: WeakEntity<Editor>, bcx: &BlockContext) -> AnyElement {
|
pub fn render_block(&self, editor: WeakEntity<Editor>, bcx: &BlockContext) -> AnyElement {
|
||||||
let cx = &bcx.app;
|
let cx = &bcx.app;
|
||||||
let status_colors = bcx.app.theme().status();
|
let status_colors = cx.theme().status();
|
||||||
|
|
||||||
let max_width = bcx.em_width * 120.;
|
let max_width = bcx.em_width * 120.;
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ use gpui::{
|
|||||||
Subscription, Task, WeakEntity, Window, actions, div,
|
Subscription, Task, WeakEntity, Window, actions, div,
|
||||||
};
|
};
|
||||||
use language::{
|
use language::{
|
||||||
Bias, Buffer, BufferRow, BufferSnapshot, DiagnosticEntry, Point, ToTreeSitterPoint,
|
Bias, Buffer, BufferRow, BufferSnapshot, DiagnosticEntry, DiagnosticEntryRef, Point,
|
||||||
|
ToTreeSitterPoint,
|
||||||
};
|
};
|
||||||
use project::{
|
use project::{
|
||||||
DiagnosticSummary, Project, ProjectPath,
|
DiagnosticSummary, Project, ProjectPath,
|
||||||
@@ -412,8 +413,8 @@ impl ProjectDiagnosticsEditor {
|
|||||||
|
|
||||||
fn diagnostics_are_unchanged(
|
fn diagnostics_are_unchanged(
|
||||||
&self,
|
&self,
|
||||||
existing: &Vec<DiagnosticEntry<text::Anchor>>,
|
existing: &[DiagnosticEntry<text::Anchor>],
|
||||||
new: &Vec<DiagnosticEntry<text::Anchor>>,
|
new: &[DiagnosticEntryRef<'_, text::Anchor>],
|
||||||
snapshot: &BufferSnapshot,
|
snapshot: &BufferSnapshot,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if existing.len() != new.len() {
|
if existing.len() != new.len() {
|
||||||
@@ -457,7 +458,13 @@ impl ProjectDiagnosticsEditor {
|
|||||||
}) {
|
}) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.diagnostics.insert(buffer_id, diagnostics.clone());
|
this.diagnostics.insert(
|
||||||
|
buffer_id,
|
||||||
|
diagnostics
|
||||||
|
.iter()
|
||||||
|
.map(DiagnosticEntryRef::to_owned)
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
false
|
false
|
||||||
})?;
|
})?;
|
||||||
if unchanged {
|
if unchanged {
|
||||||
@@ -469,7 +476,7 @@ impl ProjectDiagnosticsEditor {
|
|||||||
grouped
|
grouped
|
||||||
.entry(entry.diagnostic.group_id)
|
.entry(entry.diagnostic.group_id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.push(DiagnosticEntry {
|
.push(DiagnosticEntryRef {
|
||||||
range: entry.range.to_point(&buffer_snapshot),
|
range: entry.range.to_point(&buffer_snapshot),
|
||||||
diagnostic: entry.diagnostic,
|
diagnostic: entry.diagnostic,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ use workspace::{StatusItemView, ToolbarItemEvent, Workspace, item::ItemHandle};
|
|||||||
|
|
||||||
use crate::{Deploy, IncludeWarnings, ProjectDiagnosticsEditor};
|
use crate::{Deploy, IncludeWarnings, ProjectDiagnosticsEditor};
|
||||||
|
|
||||||
|
/// The status bar item that displays diagnostic counts.
|
||||||
pub struct DiagnosticIndicator {
|
pub struct DiagnosticIndicator {
|
||||||
summary: project::DiagnosticSummary,
|
summary: project::DiagnosticSummary,
|
||||||
active_editor: Option<WeakEntity<Editor>>,
|
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
current_diagnostic: Option<Diagnostic>,
|
current_diagnostic: Option<Diagnostic>,
|
||||||
|
active_editor: Option<WeakEntity<Editor>>,
|
||||||
_observe_active_editor: Option<Subscription>,
|
_observe_active_editor: Option<Subscription>,
|
||||||
|
|
||||||
diagnostics_update: Task<()>,
|
diagnostics_update: Task<()>,
|
||||||
diagnostic_summary_update: Task<()>,
|
diagnostic_summary_update: Task<()>,
|
||||||
}
|
}
|
||||||
@@ -73,10 +75,9 @@ impl Render for DiagnosticIndicator {
|
|||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.on_click(cx.listener(|this, _, window, cx| {
|
.on_click(
|
||||||
this.go_to_next_diagnostic(window, cx);
|
cx.listener(|this, _, window, cx| this.go_to_next_diagnostic(window, cx)),
|
||||||
}))
|
),
|
||||||
.into_any_element(),
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -177,7 +178,8 @@ impl DiagnosticIndicator {
|
|||||||
.filter(|entry| !entry.range.is_empty())
|
.filter(|entry| !entry.range.is_empty())
|
||||||
.min_by_key(|entry| (entry.diagnostic.severity, entry.range.len()))
|
.min_by_key(|entry| (entry.diagnostic.severity, entry.range.len()))
|
||||||
.map(|entry| entry.diagnostic);
|
.map(|entry| entry.diagnostic);
|
||||||
if new_diagnostic != self.current_diagnostic {
|
if new_diagnostic != self.current_diagnostic.as_ref() {
|
||||||
|
let new_diagnostic = new_diagnostic.cloned();
|
||||||
self.diagnostics_update =
|
self.diagnostics_update =
|
||||||
cx.spawn_in(window, async move |diagnostics_indicator, cx| {
|
cx.spawn_in(window, async move |diagnostics_indicator, cx| {
|
||||||
cx.background_executor()
|
cx.background_executor()
|
||||||
|
|||||||
@@ -75,12 +75,9 @@ impl Render for ToolbarControls {
|
|||||||
&ToggleDiagnosticsRefresh,
|
&ToggleDiagnosticsRefresh,
|
||||||
))
|
))
|
||||||
.on_click(cx.listener(move |toolbar_controls, _, _, cx| {
|
.on_click(cx.listener(move |toolbar_controls, _, _, cx| {
|
||||||
match toolbar_controls.editor() {
|
if let Some(editor) = toolbar_controls.editor() {
|
||||||
Some(editor) => {
|
editor.stop_updating(cx);
|
||||||
editor.stop_updating(cx);
|
cx.notify();
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
@@ -95,11 +92,10 @@ impl Render for ToolbarControls {
|
|||||||
&ToggleDiagnosticsRefresh,
|
&ToggleDiagnosticsRefresh,
|
||||||
))
|
))
|
||||||
.on_click(cx.listener({
|
.on_click(cx.listener({
|
||||||
move |toolbar_controls, _, window, cx| match toolbar_controls
|
move |toolbar_controls, _, window, cx| {
|
||||||
.editor()
|
if let Some(editor) = toolbar_controls.editor() {
|
||||||
{
|
editor.refresh_diagnostics(window, cx)
|
||||||
Some(editor) => editor.refresh_diagnostics(window, cx),
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
@@ -110,9 +106,10 @@ impl Render for ToolbarControls {
|
|||||||
.icon_color(warning_color)
|
.icon_color(warning_color)
|
||||||
.shape(IconButtonShape::Square)
|
.shape(IconButtonShape::Square)
|
||||||
.tooltip(Tooltip::text(warning_tooltip))
|
.tooltip(Tooltip::text(warning_tooltip))
|
||||||
.on_click(cx.listener(|this, _, window, cx| match &this.editor {
|
.on_click(cx.listener(|this, _, window, cx| {
|
||||||
Some(editor) => editor.toggle_warnings(window, cx),
|
if let Some(editor) = &this.editor {
|
||||||
None => {}
|
editor.toggle_warnings(window, cx)
|
||||||
|
}
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ use itertools::{Either, Itertools};
|
|||||||
use language::{
|
use language::{
|
||||||
AutoindentMode, BlockCommentConfig, BracketMatch, BracketPair, Buffer, BufferRow,
|
AutoindentMode, BlockCommentConfig, BracketMatch, BracketPair, Buffer, BufferRow,
|
||||||
BufferSnapshot, Capability, CharClassifier, CharKind, CharScopeContext, CodeLabel, CursorShape,
|
BufferSnapshot, Capability, CharClassifier, CharKind, CharScopeContext, CodeLabel, CursorShape,
|
||||||
DiagnosticEntry, DiffOptions, EditPredictionsMode, EditPreview, HighlightedText, IndentKind,
|
DiagnosticEntryRef, DiffOptions, EditPredictionsMode, EditPreview, HighlightedText, IndentKind,
|
||||||
IndentSize, Language, OffsetRangeExt, Point, Runnable, RunnableRange, Selection, SelectionGoal,
|
IndentSize, Language, OffsetRangeExt, Point, Runnable, RunnableRange, Selection, SelectionGoal,
|
||||||
TextObject, TransactionId, TreeSitterOptions, WordsQuery,
|
TextObject, TransactionId, TreeSitterOptions, WordsQuery,
|
||||||
language_settings::{
|
language_settings::{
|
||||||
@@ -404,7 +404,7 @@ pub fn set_blame_renderer(renderer: impl BlameRenderer + 'static, cx: &mut App)
|
|||||||
pub trait DiagnosticRenderer {
|
pub trait DiagnosticRenderer {
|
||||||
fn render_group(
|
fn render_group(
|
||||||
&self,
|
&self,
|
||||||
diagnostic_group: Vec<DiagnosticEntry<Point>>,
|
diagnostic_group: Vec<DiagnosticEntryRef<'_, Point>>,
|
||||||
buffer_id: BufferId,
|
buffer_id: BufferId,
|
||||||
snapshot: EditorSnapshot,
|
snapshot: EditorSnapshot,
|
||||||
editor: WeakEntity<Editor>,
|
editor: WeakEntity<Editor>,
|
||||||
@@ -413,7 +413,7 @@ pub trait DiagnosticRenderer {
|
|||||||
|
|
||||||
fn render_hover(
|
fn render_hover(
|
||||||
&self,
|
&self,
|
||||||
diagnostic_group: Vec<DiagnosticEntry<Point>>,
|
diagnostic_group: Vec<DiagnosticEntryRef<'_, Point>>,
|
||||||
range: Range<Point>,
|
range: Range<Point>,
|
||||||
buffer_id: BufferId,
|
buffer_id: BufferId,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
@@ -15970,11 +15970,11 @@ impl Editor {
|
|||||||
active_group_id = Some(active_group.group_id);
|
active_group_id = Some(active_group.group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filtered(
|
fn filtered<'a>(
|
||||||
snapshot: EditorSnapshot,
|
snapshot: EditorSnapshot,
|
||||||
severity: GoToDiagnosticSeverityFilter,
|
severity: GoToDiagnosticSeverityFilter,
|
||||||
diagnostics: impl Iterator<Item = DiagnosticEntry<usize>>,
|
diagnostics: impl Iterator<Item = DiagnosticEntryRef<'a, usize>>,
|
||||||
) -> impl Iterator<Item = DiagnosticEntry<usize>> {
|
) -> impl Iterator<Item = DiagnosticEntryRef<'a, usize>> {
|
||||||
diagnostics
|
diagnostics
|
||||||
.filter(move |entry| severity.matches(entry.diagnostic.severity))
|
.filter(move |entry| severity.matches(entry.diagnostic.severity))
|
||||||
.filter(|entry| entry.range.start != entry.range.end)
|
.filter(|entry| entry.range.start != entry.range.end)
|
||||||
@@ -15998,7 +15998,7 @@ impl Editor {
|
|||||||
.filter(|entry| entry.range.start >= selection.start),
|
.filter(|entry| entry.range.start >= selection.start),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut found: Option<DiagnosticEntry<usize>> = None;
|
let mut found: Option<DiagnosticEntryRef<usize>> = None;
|
||||||
if direction == Direction::Prev {
|
if direction == Direction::Prev {
|
||||||
'outer: for prev_diagnostics in [before.collect::<Vec<_>>(), after.collect::<Vec<_>>()]
|
'outer: for prev_diagnostics in [before.collect::<Vec<_>>(), after.collect::<Vec<_>>()]
|
||||||
{
|
{
|
||||||
@@ -17521,7 +17521,7 @@ impl Editor {
|
|||||||
fn activate_diagnostics(
|
fn activate_diagnostics(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer_id: BufferId,
|
buffer_id: BufferId,
|
||||||
diagnostic: DiagnosticEntry<usize>,
|
diagnostic: DiagnosticEntryRef<'_, usize>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
@@ -17710,7 +17710,7 @@ impl Editor {
|
|||||||
.map(|(line, _)| line)
|
.map(|(line, _)| line)
|
||||||
.map(SharedString::new)
|
.map(SharedString::new)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
SharedString::from(diagnostic_entry.diagnostic.message)
|
SharedString::new(&*diagnostic_entry.diagnostic.message)
|
||||||
});
|
});
|
||||||
let start_anchor = snapshot.anchor_before(diagnostic_entry.range.start);
|
let start_anchor = snapshot.anchor_before(diagnostic_entry.range.start);
|
||||||
let (Ok(i) | Err(i)) = inline_diagnostics
|
let (Ok(i) | Err(i)) = inline_diagnostics
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ fn show_hover(
|
|||||||
this.update(cx, |_, cx| cx.observe(&markdown, |_, _, cx| cx.notify()))?;
|
this.update(cx, |_, cx| cx.observe(&markdown, |_, _, cx| cx.notify()))?;
|
||||||
|
|
||||||
let local_diagnostic = DiagnosticEntry {
|
let local_diagnostic = DiagnosticEntry {
|
||||||
diagnostic: local_diagnostic.diagnostic,
|
diagnostic: local_diagnostic.diagnostic.to_owned(),
|
||||||
range: snapshot
|
range: snapshot
|
||||||
.buffer_snapshot
|
.buffer_snapshot
|
||||||
.anchor_before(local_diagnostic.range.start)
|
.anchor_before(local_diagnostic.range.start)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
DebuggerTextObject, LanguageScope, Outline, OutlineConfig, RunnableCapture, RunnableTag,
|
DebuggerTextObject, LanguageScope, Outline, OutlineConfig, RunnableCapture, RunnableTag,
|
||||||
TextObject, TreeSitterOptions,
|
TextObject, TreeSitterOptions,
|
||||||
diagnostic_set::{DiagnosticEntry, DiagnosticGroup},
|
diagnostic_set::{DiagnosticEntry, DiagnosticEntryRef, DiagnosticGroup},
|
||||||
language_settings::{LanguageSettings, language_settings},
|
language_settings::{LanguageSettings, language_settings},
|
||||||
outline::OutlineItem,
|
outline::OutlineItem,
|
||||||
syntax_map::{
|
syntax_map::{
|
||||||
@@ -4519,7 +4519,7 @@ impl BufferSnapshot {
|
|||||||
&'a self,
|
&'a self,
|
||||||
search_range: Range<T>,
|
search_range: Range<T>,
|
||||||
reversed: bool,
|
reversed: bool,
|
||||||
) -> impl 'a + Iterator<Item = DiagnosticEntry<O>>
|
) -> impl 'a + Iterator<Item = DiagnosticEntryRef<'a, O>>
|
||||||
where
|
where
|
||||||
T: 'a + Clone + ToOffset,
|
T: 'a + Clone + ToOffset,
|
||||||
O: 'a + FromAnchor,
|
O: 'a + FromAnchor,
|
||||||
@@ -4552,11 +4552,13 @@ impl BufferSnapshot {
|
|||||||
})?;
|
})?;
|
||||||
iterators[next_ix]
|
iterators[next_ix]
|
||||||
.next()
|
.next()
|
||||||
.map(|DiagnosticEntry { range, diagnostic }| DiagnosticEntry {
|
.map(
|
||||||
diagnostic,
|
|DiagnosticEntryRef { range, diagnostic }| DiagnosticEntryRef {
|
||||||
range: FromAnchor::from_anchor(&range.start, self)
|
diagnostic,
|
||||||
..FromAnchor::from_anchor(&range.end, self),
|
range: FromAnchor::from_anchor(&range.start, self)
|
||||||
})
|
..FromAnchor::from_anchor(&range.end, self),
|
||||||
|
},
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4572,7 +4574,7 @@ impl BufferSnapshot {
|
|||||||
pub fn diagnostic_groups(
|
pub fn diagnostic_groups(
|
||||||
&self,
|
&self,
|
||||||
language_server_id: Option<LanguageServerId>,
|
language_server_id: Option<LanguageServerId>,
|
||||||
) -> Vec<(LanguageServerId, DiagnosticGroup<Anchor>)> {
|
) -> Vec<(LanguageServerId, DiagnosticGroup<'_, Anchor>)> {
|
||||||
let mut groups = Vec::new();
|
let mut groups = Vec::new();
|
||||||
|
|
||||||
if let Some(language_server_id) = language_server_id {
|
if let Some(language_server_id) = language_server_id {
|
||||||
@@ -4603,7 +4605,7 @@ impl BufferSnapshot {
|
|||||||
pub fn diagnostic_group<O>(
|
pub fn diagnostic_group<O>(
|
||||||
&self,
|
&self,
|
||||||
group_id: usize,
|
group_id: usize,
|
||||||
) -> impl Iterator<Item = DiagnosticEntry<O>> + '_
|
) -> impl Iterator<Item = DiagnosticEntryRef<'_, O>> + use<'_, O>
|
||||||
where
|
where
|
||||||
O: FromAnchor + 'static,
|
O: FromAnchor + 'static,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,19 +34,66 @@ pub struct DiagnosticEntry<T> {
|
|||||||
pub diagnostic: Diagnostic,
|
pub diagnostic: Diagnostic,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A single diagnostic in a set. Generic over its range type, because
|
||||||
|
/// the diagnostics are stored internally as [`Anchor`]s, but can be
|
||||||
|
/// resolved to different coordinates types like [`usize`] byte offsets or
|
||||||
|
/// [`Point`](gpui::Point)s.
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
|
||||||
|
pub struct DiagnosticEntryRef<'a, T> {
|
||||||
|
/// The range of the buffer where the diagnostic applies.
|
||||||
|
pub range: Range<T>,
|
||||||
|
/// The information about the diagnostic.
|
||||||
|
pub diagnostic: &'a Diagnostic,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: PartialEq> PartialEq<DiagnosticEntry<T>> for DiagnosticEntryRef<'_, T> {
|
||||||
|
fn eq(&self, other: &DiagnosticEntry<T>) -> bool {
|
||||||
|
self.range == other.range && *self.diagnostic == other.diagnostic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: PartialEq> PartialEq<DiagnosticEntryRef<'_, T>> for DiagnosticEntry<T> {
|
||||||
|
fn eq(&self, other: &DiagnosticEntryRef<'_, T>) -> bool {
|
||||||
|
self.range == other.range && self.diagnostic == *other.diagnostic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> DiagnosticEntryRef<'_, T> {
|
||||||
|
pub fn to_owned(&self) -> DiagnosticEntry<T> {
|
||||||
|
DiagnosticEntry {
|
||||||
|
range: self.range.clone(),
|
||||||
|
diagnostic: self.diagnostic.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DiagnosticEntryRef<'a, Anchor> {
|
||||||
|
/// Converts the [DiagnosticEntry] to a different buffer coordinate type.
|
||||||
|
pub fn resolve<O: FromAnchor>(
|
||||||
|
&self,
|
||||||
|
buffer: &text::BufferSnapshot,
|
||||||
|
) -> DiagnosticEntryRef<'a, O> {
|
||||||
|
DiagnosticEntryRef {
|
||||||
|
range: O::from_anchor(&self.range.start, buffer)
|
||||||
|
..O::from_anchor(&self.range.end, buffer),
|
||||||
|
diagnostic: &self.diagnostic,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A group of related diagnostics, ordered by their start position
|
/// A group of related diagnostics, ordered by their start position
|
||||||
/// in the buffer.
|
/// in the buffer.
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct DiagnosticGroup<T> {
|
pub struct DiagnosticGroup<'a, T> {
|
||||||
/// The diagnostics.
|
/// The diagnostics.
|
||||||
pub entries: Vec<DiagnosticEntry<T>>,
|
pub entries: Vec<DiagnosticEntryRef<'a, T>>,
|
||||||
/// The index into `entries` where the primary diagnostic is stored.
|
/// The index into `entries` where the primary diagnostic is stored.
|
||||||
pub primary_ix: usize,
|
pub primary_ix: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DiagnosticGroup<Anchor> {
|
impl<'a> DiagnosticGroup<'a, Anchor> {
|
||||||
/// Converts the entries in this [`DiagnosticGroup`] to a different buffer coordinate type.
|
/// Converts the entries in this [`DiagnosticGroup`] to a different buffer coordinate type.
|
||||||
pub fn resolve<O: FromAnchor>(&self, buffer: &text::BufferSnapshot) -> DiagnosticGroup<O> {
|
pub fn resolve<O: FromAnchor>(&self, buffer: &text::BufferSnapshot) -> DiagnosticGroup<'a, O> {
|
||||||
DiagnosticGroup {
|
DiagnosticGroup {
|
||||||
entries: self
|
entries: self
|
||||||
.entries
|
.entries
|
||||||
@@ -84,6 +131,23 @@ impl DiagnosticEntry<PointUtf16> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl DiagnosticEntryRef<'_, PointUtf16> {
|
||||||
|
/// Returns a raw LSP diagnostic used to provide diagnostic context to LSP
|
||||||
|
/// codeAction request
|
||||||
|
pub fn to_lsp_diagnostic_stub(&self) -> Result<lsp::Diagnostic> {
|
||||||
|
let range = range_to_lsp(self.range.clone())?;
|
||||||
|
|
||||||
|
Ok(lsp::Diagnostic {
|
||||||
|
range,
|
||||||
|
code: self.diagnostic.code.clone(),
|
||||||
|
severity: Some(self.diagnostic.severity),
|
||||||
|
source: self.diagnostic.source.clone(),
|
||||||
|
message: self.diagnostic.message.clone(),
|
||||||
|
data: self.diagnostic.data.clone(),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DiagnosticSet {
|
impl DiagnosticSet {
|
||||||
/// Constructs a [DiagnosticSet] from a sequence of entries, ordered by
|
/// Constructs a [DiagnosticSet] from a sequence of entries, ordered by
|
||||||
@@ -138,7 +202,7 @@ impl DiagnosticSet {
|
|||||||
buffer: &'a text::BufferSnapshot,
|
buffer: &'a text::BufferSnapshot,
|
||||||
inclusive: bool,
|
inclusive: bool,
|
||||||
reversed: bool,
|
reversed: bool,
|
||||||
) -> impl 'a + Iterator<Item = DiagnosticEntry<O>>
|
) -> impl 'a + Iterator<Item = DiagnosticEntryRef<'a, O>>
|
||||||
where
|
where
|
||||||
T: 'a + ToOffset,
|
T: 'a + ToOffset,
|
||||||
O: FromAnchor,
|
O: FromAnchor,
|
||||||
@@ -179,10 +243,10 @@ impl DiagnosticSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds all of this set's diagnostic groups to the given output vector.
|
/// Adds all of this set's diagnostic groups to the given output vector.
|
||||||
pub fn groups(
|
pub fn groups<'a>(
|
||||||
&self,
|
&'a self,
|
||||||
language_server_id: LanguageServerId,
|
language_server_id: LanguageServerId,
|
||||||
output: &mut Vec<(LanguageServerId, DiagnosticGroup<Anchor>)>,
|
output: &mut Vec<(LanguageServerId, DiagnosticGroup<'a, Anchor>)>,
|
||||||
buffer: &text::BufferSnapshot,
|
buffer: &text::BufferSnapshot,
|
||||||
) {
|
) {
|
||||||
let mut groups = HashMap::default();
|
let mut groups = HashMap::default();
|
||||||
@@ -190,7 +254,10 @@ impl DiagnosticSet {
|
|||||||
groups
|
groups
|
||||||
.entry(entry.diagnostic.group_id)
|
.entry(entry.diagnostic.group_id)
|
||||||
.or_insert(Vec::new())
|
.or_insert(Vec::new())
|
||||||
.push(entry.clone());
|
.push(DiagnosticEntryRef {
|
||||||
|
range: entry.range.clone(),
|
||||||
|
diagnostic: &entry.diagnostic,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let start_ix = output.len();
|
let start_ix = output.len();
|
||||||
@@ -224,7 +291,7 @@ impl DiagnosticSet {
|
|||||||
&'a self,
|
&'a self,
|
||||||
group_id: usize,
|
group_id: usize,
|
||||||
buffer: &'a text::BufferSnapshot,
|
buffer: &'a text::BufferSnapshot,
|
||||||
) -> impl 'a + Iterator<Item = DiagnosticEntry<O>> {
|
) -> impl 'a + Iterator<Item = DiagnosticEntryRef<'a, O>> {
|
||||||
self.iter()
|
self.iter()
|
||||||
.filter(move |entry| entry.diagnostic.group_id == group_id)
|
.filter(move |entry| entry.diagnostic.group_id == group_id)
|
||||||
.map(|entry| entry.resolve(buffer))
|
.map(|entry| entry.resolve(buffer))
|
||||||
@@ -247,11 +314,14 @@ impl sum_tree::Item for DiagnosticEntry<Anchor> {
|
|||||||
|
|
||||||
impl DiagnosticEntry<Anchor> {
|
impl DiagnosticEntry<Anchor> {
|
||||||
/// Converts the [DiagnosticEntry] to a different buffer coordinate type.
|
/// Converts the [DiagnosticEntry] to a different buffer coordinate type.
|
||||||
pub fn resolve<O: FromAnchor>(&self, buffer: &text::BufferSnapshot) -> DiagnosticEntry<O> {
|
pub fn resolve<'a, O: FromAnchor>(
|
||||||
DiagnosticEntry {
|
&'a self,
|
||||||
|
buffer: &text::BufferSnapshot,
|
||||||
|
) -> DiagnosticEntryRef<'a, O> {
|
||||||
|
DiagnosticEntryRef {
|
||||||
range: O::from_anchor(&self.range.start, buffer)
|
range: O::from_anchor(&self.range.start, buffer)
|
||||||
..O::from_anchor(&self.range.end, buffer),
|
..O::from_anchor(&self.range.end, buffer),
|
||||||
diagnostic: self.diagnostic.clone(),
|
diagnostic: &self.diagnostic,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ use util::serde::default_true;
|
|||||||
|
|
||||||
pub use buffer::Operation;
|
pub use buffer::Operation;
|
||||||
pub use buffer::*;
|
pub use buffer::*;
|
||||||
pub use diagnostic_set::{DiagnosticEntry, DiagnosticGroup};
|
pub use diagnostic_set::{DiagnosticEntry, DiagnosticEntryRef, DiagnosticGroup};
|
||||||
pub use language_registry::{
|
pub use language_registry::{
|
||||||
AvailableLanguage, BinaryStatus, LanguageNotFound, LanguageQueries, LanguageRegistry,
|
AvailableLanguage, BinaryStatus, LanguageNotFound, LanguageQueries, LanguageRegistry,
|
||||||
QUERY_FILENAME_PREFIXES,
|
QUERY_FILENAME_PREFIXES,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use gpui::{App, AppContext as _, Context, Entity, EntityId, EventEmitter, Task};
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{
|
use language::{
|
||||||
AutoindentMode, Buffer, BufferChunks, BufferRow, BufferSnapshot, Capability, CharClassifier,
|
AutoindentMode, Buffer, BufferChunks, BufferRow, BufferSnapshot, Capability, CharClassifier,
|
||||||
CharKind, CharScopeContext, Chunk, CursorShape, DiagnosticEntry, DiskState, File,
|
CharKind, CharScopeContext, Chunk, CursorShape, DiagnosticEntryRef, DiskState, File,
|
||||||
IndentGuideSettings, IndentSize, Language, LanguageScope, OffsetRangeExt, OffsetUtf16, Outline,
|
IndentGuideSettings, IndentSize, Language, LanguageScope, OffsetRangeExt, OffsetUtf16, Outline,
|
||||||
OutlineItem, Point, PointUtf16, Selection, TextDimension, TextObject, ToOffset as _,
|
OutlineItem, Point, PointUtf16, Selection, TextDimension, TextObject, ToOffset as _,
|
||||||
ToPoint as _, TransactionId, TreeSitterOptions, Unclipped,
|
ToPoint as _, TransactionId, TreeSitterOptions, Unclipped,
|
||||||
@@ -6007,7 +6007,7 @@ impl MultiBufferSnapshot {
|
|||||||
&self,
|
&self,
|
||||||
buffer_id: BufferId,
|
buffer_id: BufferId,
|
||||||
group_id: usize,
|
group_id: usize,
|
||||||
) -> impl Iterator<Item = DiagnosticEntry<Point>> + '_ {
|
) -> impl Iterator<Item = DiagnosticEntryRef<'_, Point>> + '_ {
|
||||||
self.lift_buffer_metadata(Point::zero()..self.max_point(), move |buffer, range| {
|
self.lift_buffer_metadata(Point::zero()..self.max_point(), move |buffer, range| {
|
||||||
if buffer.remote_id() != buffer_id {
|
if buffer.remote_id() != buffer_id {
|
||||||
return None;
|
return None;
|
||||||
@@ -6016,16 +6016,16 @@ impl MultiBufferSnapshot {
|
|||||||
buffer
|
buffer
|
||||||
.diagnostics_in_range(range, false)
|
.diagnostics_in_range(range, false)
|
||||||
.filter(move |diagnostic| diagnostic.diagnostic.group_id == group_id)
|
.filter(move |diagnostic| diagnostic.diagnostic.group_id == group_id)
|
||||||
.map(move |DiagnosticEntry { diagnostic, range }| (range, diagnostic)),
|
.map(move |DiagnosticEntryRef { diagnostic, range }| (range, diagnostic)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|(range, diagnostic, _)| DiagnosticEntry { diagnostic, range })
|
.map(|(range, diagnostic, _)| DiagnosticEntryRef { diagnostic, range })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostics_in_range<'a, T>(
|
pub fn diagnostics_in_range<'a, T>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range<T>,
|
range: Range<T>,
|
||||||
) -> impl Iterator<Item = DiagnosticEntry<T>> + 'a
|
) -> impl Iterator<Item = DiagnosticEntryRef<'a, T>> + 'a
|
||||||
where
|
where
|
||||||
T: 'a
|
T: 'a
|
||||||
+ text::ToOffset
|
+ text::ToOffset
|
||||||
@@ -6042,13 +6042,13 @@ impl MultiBufferSnapshot {
|
|||||||
.map(|entry| (entry.range, entry.diagnostic)),
|
.map(|entry| (entry.range, entry.diagnostic)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|(range, diagnostic, _)| DiagnosticEntry { diagnostic, range })
|
.map(|(range, diagnostic, _)| DiagnosticEntryRef { diagnostic, range })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostics_with_buffer_ids_in_range<'a, T>(
|
pub fn diagnostics_with_buffer_ids_in_range<'a, T>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range<T>,
|
range: Range<T>,
|
||||||
) -> impl Iterator<Item = (BufferId, DiagnosticEntry<T>)> + 'a
|
) -> impl Iterator<Item = (BufferId, DiagnosticEntryRef<'a, T>)> + 'a
|
||||||
where
|
where
|
||||||
T: 'a
|
T: 'a
|
||||||
+ text::ToOffset
|
+ text::ToOffset
|
||||||
@@ -6065,7 +6065,7 @@ impl MultiBufferSnapshot {
|
|||||||
.map(|entry| (entry.range, entry.diagnostic)),
|
.map(|entry| (entry.range, entry.diagnostic)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|(range, diagnostic, b)| (b.buffer_id, DiagnosticEntry { diagnostic, range }))
|
.map(|(range, diagnostic, b)| (b.buffer_id, DiagnosticEntryRef { diagnostic, range }))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_ancestor<T: ToOffset>(
|
pub fn syntax_ancestor<T: ToOffset>(
|
||||||
|
|||||||
@@ -20,9 +20,10 @@ use git2::RepositoryInitOptions;
|
|||||||
use gpui::{App, BackgroundExecutor, SemanticVersion, UpdateGlobal};
|
use gpui::{App, BackgroundExecutor, SemanticVersion, UpdateGlobal};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{
|
use language::{
|
||||||
Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, DiskState, FakeLspAdapter,
|
Diagnostic, DiagnosticEntry, DiagnosticEntryRef, DiagnosticSet, DiagnosticSourceKind,
|
||||||
LanguageConfig, LanguageMatcher, LanguageName, LineEnding, ManifestName, ManifestProvider,
|
DiskState, FakeLspAdapter, LanguageConfig, LanguageMatcher, LanguageName, LineEnding,
|
||||||
ManifestQuery, OffsetRangeExt, Point, ToPoint, ToolchainList, ToolchainLister,
|
ManifestName, ManifestProvider, ManifestQuery, OffsetRangeExt, Point, ToPoint, ToolchainList,
|
||||||
|
ToolchainLister,
|
||||||
language_settings::{LanguageSettingsContent, language_settings},
|
language_settings::{LanguageSettingsContent, language_settings},
|
||||||
tree_sitter_rust, tree_sitter_typescript,
|
tree_sitter_rust, tree_sitter_typescript,
|
||||||
};
|
};
|
||||||
@@ -1847,9 +1848,9 @@ async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
diagnostics,
|
diagnostics,
|
||||||
&[DiagnosticEntry {
|
&[DiagnosticEntryRef {
|
||||||
range: Point::new(0, 9)..Point::new(0, 10),
|
range: Point::new(0, 9)..Point::new(0, 10),
|
||||||
diagnostic: Diagnostic {
|
diagnostic: &Diagnostic {
|
||||||
severity: lsp::DiagnosticSeverity::ERROR,
|
severity: lsp::DiagnosticSeverity::ERROR,
|
||||||
message: "undefined variable 'A'".to_string(),
|
message: "undefined variable 'A'".to_string(),
|
||||||
group_id: 0,
|
group_id: 0,
|
||||||
@@ -2024,7 +2025,7 @@ async fn test_restarting_server_with_diagnostics_published(cx: &mut gpui::TestAp
|
|||||||
buffer
|
buffer
|
||||||
.snapshot()
|
.snapshot()
|
||||||
.diagnostics_in_range::<_, usize>(0..1, false)
|
.diagnostics_in_range::<_, usize>(0..1, false)
|
||||||
.map(|entry| entry.diagnostic.message)
|
.map(|entry| entry.diagnostic.message.clone())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
["the message".to_string()]
|
["the message".to_string()]
|
||||||
);
|
);
|
||||||
@@ -2050,7 +2051,7 @@ async fn test_restarting_server_with_diagnostics_published(cx: &mut gpui::TestAp
|
|||||||
buffer
|
buffer
|
||||||
.snapshot()
|
.snapshot()
|
||||||
.diagnostics_in_range::<_, usize>(0..1, false)
|
.diagnostics_in_range::<_, usize>(0..1, false)
|
||||||
.map(|entry| entry.diagnostic.message)
|
.map(|entry| entry.diagnostic.message.clone())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
Vec::<String>::new(),
|
Vec::<String>::new(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use ui::{h_flex, prelude::*};
|
|||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
pub trait StatusItemView: Render {
|
pub trait StatusItemView: Render {
|
||||||
|
/// Event callback that is triggered when the active pane item changes.
|
||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&mut self,
|
&mut self,
|
||||||
active_pane_item: Option<&dyn crate::ItemHandle>,
|
active_pane_item: Option<&dyn crate::ItemHandle>,
|
||||||
|
|||||||
Reference in New Issue
Block a user