In the status bar, show the diagnostic under the cursor
This commit is contained in:
parent
941d935c4a
commit
8b5089c759
5 changed files with 95 additions and 3 deletions
|
@ -780,10 +780,14 @@ impl Buffer {
|
||||||
Ok(Operation::UpdateDiagnostics(self.diagnostics.clone()))
|
Ok(Operation::UpdateDiagnostics(self.diagnostics.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostics_in_range<'a, T: 'a + ToOffset>(
|
pub fn diagnostics_in_range<'a, T, O>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range<T>,
|
range: Range<T>,
|
||||||
) -> impl Iterator<Item = (Range<Point>, &Diagnostic)> + 'a {
|
) -> impl Iterator<Item = (Range<O>, &Diagnostic)> + 'a
|
||||||
|
where
|
||||||
|
T: 'a + ToOffset,
|
||||||
|
O: 'a + FromAnchor,
|
||||||
|
{
|
||||||
let content = self.content();
|
let content = self.content();
|
||||||
self.diagnostics
|
self.diagnostics
|
||||||
.intersecting_ranges(range, content, true)
|
.intersecting_ranges(range, content, true)
|
||||||
|
|
|
@ -95,6 +95,10 @@ pub struct StatusBar {
|
||||||
pub container: ContainerStyle,
|
pub container: ContainerStyle,
|
||||||
pub height: f32,
|
pub height: f32,
|
||||||
pub cursor_position: TextStyle,
|
pub cursor_position: TextStyle,
|
||||||
|
pub diagnostic_error: TextStyle,
|
||||||
|
pub diagnostic_warning: TextStyle,
|
||||||
|
pub diagnostic_information: TextStyle,
|
||||||
|
pub diagnostic_hint: TextStyle,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Default)]
|
#[derive(Deserialize, Default)]
|
||||||
|
|
|
@ -7,7 +7,7 @@ use gpui::{
|
||||||
elements::*, fonts::TextStyle, AppContext, Entity, ModelHandle, RenderContext, Subscription,
|
elements::*, fonts::TextStyle, AppContext, Entity, ModelHandle, RenderContext, Subscription,
|
||||||
Task, View, ViewContext, ViewHandle,
|
Task, View, ViewContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use language::{Buffer, File as _};
|
use language::{Buffer, Diagnostic, DiagnosticSeverity, File as _};
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use project::{ProjectPath, Worktree};
|
use project::{ProjectPath, Worktree};
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
@ -240,3 +240,81 @@ impl StatusItemView for CursorPosition {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct DiagnosticMessage {
|
||||||
|
settings: watch::Receiver<Settings>,
|
||||||
|
diagnostic: Option<Diagnostic>,
|
||||||
|
_observe_active_editor: Option<Subscription>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DiagnosticMessage {
|
||||||
|
pub fn new(settings: watch::Receiver<Settings>) -> Self {
|
||||||
|
Self {
|
||||||
|
diagnostic: None,
|
||||||
|
settings,
|
||||||
|
_observe_active_editor: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) {
|
||||||
|
let editor = editor.read(cx);
|
||||||
|
let cursor_position = editor
|
||||||
|
.selections::<usize>(cx)
|
||||||
|
.max_by_key(|selection| selection.id)
|
||||||
|
.unwrap()
|
||||||
|
.head();
|
||||||
|
let new_diagnostic = editor
|
||||||
|
.buffer()
|
||||||
|
.read(cx)
|
||||||
|
.diagnostics_in_range::<usize, usize>(cursor_position..cursor_position)
|
||||||
|
.min_by_key(|(range, diagnostic)| (diagnostic.severity, range.len()))
|
||||||
|
.map(|(_, diagnostic)| diagnostic.clone());
|
||||||
|
if new_diagnostic != self.diagnostic {
|
||||||
|
self.diagnostic = new_diagnostic;
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Entity for DiagnosticMessage {
|
||||||
|
type Event = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View for DiagnosticMessage {
|
||||||
|
fn ui_name() -> &'static str {
|
||||||
|
"DiagnosticMessage"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||||
|
if let Some(diagnostic) = &self.diagnostic {
|
||||||
|
let theme = &self.settings.borrow().theme.workspace.status_bar;
|
||||||
|
let style = match diagnostic.severity {
|
||||||
|
DiagnosticSeverity::ERROR => theme.diagnostic_error.clone(),
|
||||||
|
DiagnosticSeverity::WARNING => theme.diagnostic_warning.clone(),
|
||||||
|
DiagnosticSeverity::INFORMATION => theme.diagnostic_information.clone(),
|
||||||
|
DiagnosticSeverity::HINT => theme.diagnostic_hint.clone(),
|
||||||
|
_ => Default::default(),
|
||||||
|
};
|
||||||
|
Label::new(diagnostic.message.replace('\n', " "), style).boxed()
|
||||||
|
} else {
|
||||||
|
Empty::new().boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StatusItemView for DiagnosticMessage {
|
||||||
|
fn set_active_pane_item(
|
||||||
|
&mut self,
|
||||||
|
active_pane_item: Option<&dyn crate::ItemViewHandle>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
if let Some(editor) = active_pane_item.and_then(|item| item.to_any().downcast::<Editor>()) {
|
||||||
|
self._observe_active_editor = Some(cx.observe(&editor, Self::update));
|
||||||
|
self.update(editor, cx);
|
||||||
|
} else {
|
||||||
|
self.diagnostic = Default::default();
|
||||||
|
self._observe_active_editor = None;
|
||||||
|
}
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -350,8 +350,10 @@ impl Workspace {
|
||||||
cx.focus(&pane);
|
cx.focus(&pane);
|
||||||
|
|
||||||
let cursor_position = cx.add_view(|_| items::CursorPosition::new(params.settings.clone()));
|
let cursor_position = cx.add_view(|_| items::CursorPosition::new(params.settings.clone()));
|
||||||
|
let diagnostic = cx.add_view(|_| items::DiagnosticMessage::new(params.settings.clone()));
|
||||||
let status_bar = cx.add_view(|cx| {
|
let status_bar = cx.add_view(|cx| {
|
||||||
let mut status_bar = StatusBar::new(&pane, params.settings.clone(), cx);
|
let mut status_bar = StatusBar::new(&pane, params.settings.clone(), cx);
|
||||||
|
status_bar.add_left_item(diagnostic, cx);
|
||||||
status_bar.add_right_item(cursor_position, cx);
|
status_bar.add_right_item(cursor_position, cx);
|
||||||
status_bar
|
status_bar
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,6 +64,10 @@ border = { width = 1, color = "$border.0", left = true }
|
||||||
padding = { left = 6, right = 6 }
|
padding = { left = 6, right = 6 }
|
||||||
height = 24
|
height = 24
|
||||||
cursor_position = "$text.2"
|
cursor_position = "$text.2"
|
||||||
|
diagnostic_error = { extends = "$text.2", color = "$status.bad" }
|
||||||
|
diagnostic_warning = { extends = "$text.2", color = "$status.warn" }
|
||||||
|
diagnostic_information = { extends = "$text.2", color = "$status.info" }
|
||||||
|
diagnostic_hint = { extends = "$text.2", color = "$status.info" }
|
||||||
|
|
||||||
[panel]
|
[panel]
|
||||||
padding = { top = 12, left = 12, bottom = 12, right = 12 }
|
padding = { top = 12, left = 12, bottom = 12, right = 12 }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue