Restyle diagnostic headers

This commit is contained in:
Antonio Scandurra 2022-01-25 12:23:24 +01:00
parent b319bda70d
commit e7ec016350
5 changed files with 176 additions and 49 deletions

View file

@ -3,7 +3,7 @@ pub mod items;
use anyhow::Result; use anyhow::Result;
use collections::{BTreeSet, HashMap, HashSet}; use collections::{BTreeSet, HashMap, HashSet};
use editor::{ use editor::{
diagnostic_block_renderer, diagnostic_style, diagnostic_block_renderer,
display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock}, display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock},
items::BufferItemHandle, items::BufferItemHandle,
Autoscroll, BuildSettings, Editor, ExcerptId, ExcerptProperties, MultiBuffer, ToOffset, Autoscroll, BuildSettings, Editor, ExcerptId, ExcerptProperties, MultiBuffer, ToOffset,
@ -12,7 +12,7 @@ use gpui::{
action, elements::*, keymap::Binding, AnyViewHandle, AppContext, Entity, ModelHandle, action, elements::*, keymap::Binding, AnyViewHandle, AppContext, Entity, ModelHandle,
MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle,
}; };
use language::{Bias, Buffer, Diagnostic, DiagnosticEntry, Point, Selection, SelectionGoal}; use language::{Bias, Buffer, DiagnosticEntry, Point, Selection, SelectionGoal};
use postage::watch; use postage::watch;
use project::{Project, ProjectPath}; use project::{Project, ProjectPath};
use std::{ use std::{
@ -345,16 +345,14 @@ impl ProjectDiagnosticsEditor {
if is_first_excerpt_for_group { if is_first_excerpt_for_group {
is_first_excerpt_for_group = false; is_first_excerpt_for_group = false;
let primary = &group.entries[group.primary_ix].diagnostic; let primary = &group.entries[group.primary_ix].diagnostic;
let mut header = primary.clone(); let message =
header.message =
primary.message.split('\n').next().unwrap().to_string(); primary.message.split('\n').next().unwrap().to_string();
group_state.block_count += 1; group_state.block_count += 1;
blocks_to_add.push(BlockProperties { blocks_to_add.push(BlockProperties {
position: header_position, position: header_position,
height: 2, height: 2,
render: diagnostic_header_renderer( render: diagnostic_header_renderer(
header, message,
true,
self.build_settings.clone(), self.build_settings.clone(),
), ),
disposition: BlockDisposition::Above, disposition: BlockDisposition::Above,
@ -651,41 +649,105 @@ impl workspace::ItemView for ProjectDiagnosticsEditor {
fn path_header_renderer(buffer: ModelHandle<Buffer>, build_settings: BuildSettings) -> RenderBlock { fn path_header_renderer(buffer: ModelHandle<Buffer>, build_settings: BuildSettings) -> RenderBlock {
Arc::new(move |cx| { Arc::new(move |cx| {
let settings = build_settings(cx); let settings = build_settings(cx);
let file_path = if let Some(file) = buffer.read(&**cx).file() {
file.path().to_string_lossy().to_string()
} else {
"untitled".to_string()
};
let mut text_style = settings.style.text.clone();
let style = settings.style.diagnostic_path_header; let style = settings.style.diagnostic_path_header;
text_style.color = style.text;
Label::new(file_path, text_style) let mut filename = None;
let mut path = None;
if let Some(file) = buffer.read(&**cx).file() {
filename = file
.path()
.file_name()
.map(|f| f.to_string_lossy().to_string());
path = file
.path()
.parent()
.map(|p| p.to_string_lossy().to_string());
}
Flex::row()
.with_child(
Label::new(
filename.unwrap_or_else(|| "untitled".to_string()),
style.filename.text.clone(),
)
.contained()
.with_style(style.filename.container)
.boxed(),
)
.with_children(path.map(|path| {
Label::new(path, style.path.text.clone())
.contained()
.with_style(style.path.container)
.boxed()
}))
.aligned() .aligned()
.left() .left()
.contained() .contained()
.with_style(style.header) .with_style(style.container)
.with_padding_left(cx.line_number_x) .with_padding_left(cx.line_number_x)
.expanded() .expanded()
.named("path header block") .named("path header block")
}) })
} }
fn diagnostic_header_renderer( fn diagnostic_header_renderer(message: String, build_settings: BuildSettings) -> RenderBlock {
diagnostic: Diagnostic, enum Run {
is_valid: bool, Text(Range<usize>),
build_settings: BuildSettings, Code(Range<usize>),
) -> RenderBlock { }
let mut prev_ix = 0;
let mut inside_block = false;
let mut runs = Vec::new();
for (backtick_ix, _) in message.match_indices('`') {
if backtick_ix > prev_ix {
if inside_block {
runs.push(Run::Code(prev_ix..backtick_ix));
} else {
runs.push(Run::Text(prev_ix..backtick_ix));
}
}
inside_block = !inside_block;
prev_ix = backtick_ix + 1;
}
if prev_ix < message.len() {
if inside_block {
runs.push(Run::Code(prev_ix..message.len()));
} else {
runs.push(Run::Text(prev_ix..message.len()));
}
}
Arc::new(move |cx| { Arc::new(move |cx| {
let settings = build_settings(cx); let settings = build_settings(cx);
let mut text_style = settings.style.text.clone(); let style = &settings.style.diagnostic_header;
let diagnostic_style = diagnostic_style(diagnostic.severity, is_valid, &settings.style);
text_style.color = diagnostic_style.text; Flex::row()
Text::new(diagnostic.message.clone(), text_style) .with_children(runs.iter().map(|run| {
.with_soft_wrap(false) let container_style;
.aligned() let text_style;
.left() let range;
match run {
Run::Text(run_range) => {
container_style = Default::default();
text_style = style.text.clone();
range = run_range.clone();
}
Run::Code(run_range) => {
container_style = style.highlighted_text.container;
text_style = style.highlighted_text.text.clone();
range = run_range.clone();
}
}
Label::new(message[range].to_string(), text_style)
.contained() .contained()
.with_style(diagnostic_style.header) .with_style(container_style)
.aligned()
.boxed()
}))
.contained()
.with_style(style.container)
.with_padding_left(cx.line_number_x) .with_padding_left(cx.line_number_x)
.expanded() .expanded()
.named("diagnostic header") .named("diagnostic header")

View file

@ -3814,8 +3814,7 @@ impl EditorSettings {
let font_id = font_cache let font_id = font_cache
.select_font(font_family_id, &font_properties) .select_font(font_family_id, &font_properties)
.unwrap(); .unwrap();
EditorStyle { let text = gpui::fonts::TextStyle {
text: gpui::fonts::TextStyle {
font_family_name, font_family_name,
font_family_id, font_family_id,
font_id, font_id,
@ -3823,7 +3822,9 @@ impl EditorSettings {
color: gpui::color::Color::from_u32(0xff0000ff), color: gpui::color::Color::from_u32(0xff0000ff),
font_properties, font_properties,
underline: None, underline: None,
}, };
EditorStyle {
text: text.clone(),
placeholder_text: None, placeholder_text: None,
background: Default::default(), background: Default::default(),
gutter_background: Default::default(), gutter_background: Default::default(),
@ -3834,7 +3835,25 @@ impl EditorSettings {
selection: Default::default(), selection: Default::default(),
guest_selections: Default::default(), guest_selections: Default::default(),
syntax: Default::default(), syntax: Default::default(),
diagnostic_path_header: Default::default(), diagnostic_path_header: theme::DiagnosticPathHeader {
container: Default::default(),
filename: theme::ContainedText {
container: Default::default(),
text: text.clone(),
},
path: theme::ContainedText {
container: Default::default(),
text: text.clone(),
},
},
diagnostic_header: theme::DiagnosticHeader {
container: Default::default(),
text: text.clone(),
highlighted_text: theme::ContainedText {
container: Default::default(),
text: text.clone(),
},
},
error_diagnostic: Default::default(), error_diagnostic: Default::default(),
invalid_error_diagnostic: Default::default(), invalid_error_diagnostic: Default::default(),
warning_diagnostic: Default::default(), warning_diagnostic: Default::default(),

View file

@ -251,7 +251,8 @@ pub struct EditorStyle {
pub line_number_active: Color, pub line_number_active: Color,
pub guest_selections: Vec<SelectionStyle>, pub guest_selections: Vec<SelectionStyle>,
pub syntax: Arc<SyntaxTheme>, pub syntax: Arc<SyntaxTheme>,
pub diagnostic_path_header: DiagnosticStyle, pub diagnostic_path_header: DiagnosticPathHeader,
pub diagnostic_header: DiagnosticHeader,
pub error_diagnostic: DiagnosticStyle, pub error_diagnostic: DiagnosticStyle,
pub invalid_error_diagnostic: DiagnosticStyle, pub invalid_error_diagnostic: DiagnosticStyle,
pub warning_diagnostic: DiagnosticStyle, pub warning_diagnostic: DiagnosticStyle,
@ -262,6 +263,22 @@ pub struct EditorStyle {
pub invalid_hint_diagnostic: DiagnosticStyle, pub invalid_hint_diagnostic: DiagnosticStyle,
} }
#[derive(Clone, Deserialize, Default)]
pub struct DiagnosticPathHeader {
#[serde(flatten)]
pub container: ContainerStyle,
pub filename: ContainedText,
pub path: ContainedText,
}
#[derive(Clone, Deserialize, Default)]
pub struct DiagnosticHeader {
#[serde(flatten)]
pub container: ContainerStyle,
pub text: TextStyle,
pub highlighted_text: ContainedText,
}
#[derive(Copy, Clone, Deserialize, Default)] #[derive(Copy, Clone, Deserialize, Default)]
pub struct DiagnosticStyle { pub struct DiagnosticStyle {
pub text: Color, pub text: Color,
@ -317,7 +334,25 @@ impl InputEditorStyle {
line_number_active: Default::default(), line_number_active: Default::default(),
guest_selections: Default::default(), guest_selections: Default::default(),
syntax: Default::default(), syntax: Default::default(),
diagnostic_path_header: Default::default(), diagnostic_path_header: DiagnosticPathHeader {
container: Default::default(),
filename: ContainedText {
container: Default::default(),
text: self.text.clone(),
},
path: ContainedText {
container: Default::default(),
text: self.text.clone(),
},
},
diagnostic_header: DiagnosticHeader {
container: Default::default(),
text: self.text.clone(),
highlighted_text: ContainedText {
container: Default::default(),
text: self.text.clone(),
},
},
error_diagnostic: Default::default(), error_diagnostic: Default::default(),
invalid_error_diagnostic: Default::default(), invalid_error_diagnostic: Default::default(),
warning_diagnostic: Default::default(), warning_diagnostic: Default::default(),

View file

@ -257,9 +257,21 @@ invalid_information_diagnostic = { text = "$text.3.color" }
invalid_hint_diagnostic = { text = "$text.3.color" } invalid_hint_diagnostic = { text = "$text.3.color" }
[editor.diagnostic_path_header] [editor.diagnostic_path_header]
text = "$text.0.color" filename = { extends = "$text.0", size = 14 }
header.background = "#ffffff08" path = { extends = "$text.1", size = 14, margin.left = 4 }
header.border = { width = 1, top = true, color = "$border.0" }
[editor.diagnostic_header]
background = "$state.active_line"
border = { width = 1, top = true, bottom = true, color = "$border.0" }
text = { extends = "$text.1", size = 14 }
[editor.diagnostic_header.highlighted_text]
extends = "$editor.diagnostic_header.text"
color = "$text.0.color"
background = "#ffffff1f"
padding.left = 3
padding.right = 3
corner_radius = 3
[editor.error_diagnostic] [editor.error_diagnostic]
text = "$status.bad" text = "$status.bad"

View file

@ -1,12 +1,12 @@
extends = "_base" extends = "_base"
[surface] [surface]
0 = "#222324" 0 = "#222222"
1 = "#141516" 1 = "#0f0b0c"
2 = "#131415" 2 = "#131415"
[border] [border]
0 = "#0F1011" 0 = "#000000B2"
[text] [text]
0 = { extends = "$text.base", color = "#ffffff" } 0 = { extends = "$text.base", color = "#ffffff" }
@ -36,7 +36,7 @@ warn = "#faca50"
bad = "#b7372e" bad = "#b7372e"
[state] [state]
active_line = "#00000033" active_line = "#161313"
highlighted_line = "#faca5033" highlighted_line = "#faca5033"
hover = "#00000033" hover = "#00000033"
@ -50,7 +50,6 @@ comment = "#6a9955"
property = "#4e94ce" property = "#4e94ce"
variant = "#4fc1ff" variant = "#4fc1ff"
constant = "#9cdcfe" constant = "#9cdcfe"
title = { color = "#9cdcfe", weight = "bold" } title = { color = "#9cdcfe", weight = "bold" }
emphasis = "#4ec9b0" emphasis = "#4ec9b0"
"emphasis.strong" = { color = "#4ec9b0", weight = "bold" } "emphasis.strong" = { color = "#4ec9b0", weight = "bold" }