Deduplicate path names in the project diagnostics view
This commit is contained in:
parent
a9937ee8be
commit
b5ee095da9
5 changed files with 120 additions and 88 deletions
|
@ -1,10 +1,10 @@
|
||||||
pub mod items;
|
pub mod items;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use collections::{HashMap, HashSet, BTreeSet};
|
use collections::{BTreeSet, HashMap, HashSet};
|
||||||
use editor::{
|
use editor::{
|
||||||
context_header_renderer, diagnostic_block_renderer, diagnostic_header_renderer,
|
diagnostic_block_renderer, diagnostic_style,
|
||||||
display_map::{BlockDisposition, BlockId, BlockProperties},
|
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,10 +12,10 @@ use gpui::{
|
||||||
action, elements::*, keymap::Binding, AppContext, Entity, ModelHandle, MutableAppContext,
|
action, elements::*, keymap::Binding, AppContext, Entity, ModelHandle, MutableAppContext,
|
||||||
RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle,
|
RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use language::{Bias, Buffer, DiagnosticEntry, Point, Selection, SelectionGoal};
|
use language::{Bias, Buffer, Diagnostic, DiagnosticEntry, Point, Selection, SelectionGoal};
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use project::{Project, ProjectPath, WorktreeId};
|
use project::{Project, ProjectPath, WorktreeId};
|
||||||
use std::{cmp::Ordering, mem, ops::Range};
|
use std::{cmp::Ordering, mem, ops::Range, sync::Arc};
|
||||||
use util::TryFutureExt;
|
use util::TryFutureExt;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
|
@ -48,12 +48,18 @@ struct ProjectDiagnosticsEditor {
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
editor: ViewHandle<Editor>,
|
editor: ViewHandle<Editor>,
|
||||||
excerpts: ModelHandle<MultiBuffer>,
|
excerpts: ModelHandle<MultiBuffer>,
|
||||||
path_states: Vec<(ProjectPath, Vec<DiagnosticGroupState>)>,
|
path_states: Vec<PathState>,
|
||||||
paths_to_update: HashMap<WorktreeId, BTreeSet<ProjectPath>>,
|
paths_to_update: HashMap<WorktreeId, BTreeSet<ProjectPath>>,
|
||||||
build_settings: BuildSettings,
|
build_settings: BuildSettings,
|
||||||
settings: watch::Receiver<workspace::Settings>,
|
settings: watch::Receiver<workspace::Settings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PathState {
|
||||||
|
path: ProjectPath,
|
||||||
|
header: Option<BlockId>,
|
||||||
|
diagnostic_groups: Vec<DiagnosticGroupState>,
|
||||||
|
}
|
||||||
|
|
||||||
struct DiagnosticGroupState {
|
struct DiagnosticGroupState {
|
||||||
primary_diagnostic: DiagnosticEntry<language::Anchor>,
|
primary_diagnostic: DiagnosticEntry<language::Anchor>,
|
||||||
primary_excerpt_ix: usize,
|
primary_excerpt_ix: usize,
|
||||||
|
@ -208,11 +214,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_excerpts(
|
fn update_excerpts(&self, paths: BTreeSet<ProjectPath>, cx: &mut ViewContext<Self>) {
|
||||||
&self,
|
|
||||||
paths: BTreeSet<ProjectPath>,
|
|
||||||
cx: &mut ViewContext<Self>,
|
|
||||||
) {
|
|
||||||
let project = self.model.read(cx).project.clone();
|
let project = self.model.read(cx).project.clone();
|
||||||
cx.spawn(|this, mut cx| {
|
cx.spawn(|this, mut cx| {
|
||||||
async move {
|
async move {
|
||||||
|
@ -220,9 +222,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
let buffer = project
|
let buffer = project
|
||||||
.update(&mut cx, |project, cx| project.open_buffer(path.clone(), cx))
|
.update(&mut cx, |project, cx| project.open_buffer(path.clone(), cx))
|
||||||
.await?;
|
.await?;
|
||||||
this.update(&mut cx, |view, cx| {
|
this.update(&mut cx, |view, cx| view.populate_excerpts(path, buffer, cx))
|
||||||
view.populate_excerpts(path, buffer, cx)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
Result::<_, anyhow::Error>::Ok(())
|
Result::<_, anyhow::Error>::Ok(())
|
||||||
}
|
}
|
||||||
|
@ -239,32 +239,39 @@ impl ProjectDiagnosticsEditor {
|
||||||
) {
|
) {
|
||||||
let was_empty = self.path_states.is_empty();
|
let was_empty = self.path_states.is_empty();
|
||||||
let snapshot = buffer.read(cx).snapshot();
|
let snapshot = buffer.read(cx).snapshot();
|
||||||
let path_ix = match self
|
let path_ix = match self.path_states.binary_search_by_key(&&path, |e| &e.path) {
|
||||||
.path_states
|
|
||||||
.binary_search_by_key(&&path, |e| &e.0)
|
|
||||||
{
|
|
||||||
Ok(ix) => ix,
|
Ok(ix) => ix,
|
||||||
Err(ix) => {
|
Err(ix) => {
|
||||||
self.path_states
|
self.path_states.insert(
|
||||||
.insert(ix, (path.clone(), Default::default()));
|
ix,
|
||||||
|
PathState {
|
||||||
|
path: path.clone(),
|
||||||
|
header: None,
|
||||||
|
diagnostic_groups: Default::default(),
|
||||||
|
},
|
||||||
|
);
|
||||||
ix
|
ix
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut prev_excerpt_id = if path_ix > 0 {
|
let mut prev_excerpt_id = if path_ix > 0 {
|
||||||
let prev_path_last_group = &self.path_states[path_ix - 1].1.last().unwrap();
|
let prev_path_last_group = &self.path_states[path_ix - 1]
|
||||||
|
.diagnostic_groups
|
||||||
|
.last()
|
||||||
|
.unwrap();
|
||||||
prev_path_last_group.excerpts.last().unwrap().clone()
|
prev_path_last_group.excerpts.last().unwrap().clone()
|
||||||
} else {
|
} else {
|
||||||
ExcerptId::min()
|
ExcerptId::min()
|
||||||
};
|
};
|
||||||
|
|
||||||
let groups = &mut self.path_states[path_ix].1;
|
let path_state = &mut self.path_states[path_ix];
|
||||||
let mut groups_to_add = Vec::new();
|
let mut groups_to_add = Vec::new();
|
||||||
let mut group_ixs_to_remove = Vec::new();
|
let mut group_ixs_to_remove = Vec::new();
|
||||||
let mut blocks_to_add = Vec::new();
|
let mut blocks_to_add = Vec::new();
|
||||||
let mut blocks_to_remove = HashSet::default();
|
let mut blocks_to_remove = HashSet::default();
|
||||||
|
let mut first_excerpt_id = None;
|
||||||
let excerpts_snapshot = self.excerpts.update(cx, |excerpts, excerpts_cx| {
|
let excerpts_snapshot = self.excerpts.update(cx, |excerpts, excerpts_cx| {
|
||||||
let mut old_groups = groups.iter().enumerate().peekable();
|
let mut old_groups = path_state.diagnostic_groups.iter().enumerate().peekable();
|
||||||
let mut new_groups = snapshot
|
let mut new_groups = snapshot
|
||||||
.diagnostic_groups()
|
.diagnostic_groups()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -273,17 +280,17 @@ impl ProjectDiagnosticsEditor {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut to_insert = None;
|
let mut to_insert = None;
|
||||||
let mut to_invalidate = None;
|
let mut to_remove = None;
|
||||||
let mut to_keep = None;
|
let mut to_keep = None;
|
||||||
match (old_groups.peek(), new_groups.peek()) {
|
match (old_groups.peek(), new_groups.peek()) {
|
||||||
(None, None) => break,
|
(None, None) => break,
|
||||||
(None, Some(_)) => to_insert = new_groups.next(),
|
(None, Some(_)) => to_insert = new_groups.next(),
|
||||||
(Some(_), None) => to_invalidate = old_groups.next(),
|
(Some(_), None) => to_remove = old_groups.next(),
|
||||||
(Some((_, old_group)), Some(new_group)) => {
|
(Some((_, old_group)), Some(new_group)) => {
|
||||||
let old_primary = &old_group.primary_diagnostic;
|
let old_primary = &old_group.primary_diagnostic;
|
||||||
let new_primary = &new_group.entries[new_group.primary_ix];
|
let new_primary = &new_group.entries[new_group.primary_ix];
|
||||||
match compare_diagnostics(old_primary, new_primary, &snapshot) {
|
match compare_diagnostics(old_primary, new_primary, &snapshot) {
|
||||||
Ordering::Less => to_invalidate = old_groups.next(),
|
Ordering::Less => to_remove = old_groups.next(),
|
||||||
Ordering::Equal => {
|
Ordering::Equal => {
|
||||||
to_keep = old_groups.next();
|
to_keep = old_groups.next();
|
||||||
new_groups.next();
|
new_groups.next();
|
||||||
|
@ -331,6 +338,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
);
|
);
|
||||||
|
|
||||||
prev_excerpt_id = excerpt_id.clone();
|
prev_excerpt_id = excerpt_id.clone();
|
||||||
|
first_excerpt_id.get_or_insert_with(|| prev_excerpt_id.clone());
|
||||||
group_state.excerpts.push(excerpt_id.clone());
|
group_state.excerpts.push(excerpt_id.clone());
|
||||||
let header_position = (excerpt_id.clone(), language::Anchor::min());
|
let header_position = (excerpt_id.clone(), language::Anchor::min());
|
||||||
|
|
||||||
|
@ -343,9 +351,8 @@ impl ProjectDiagnosticsEditor {
|
||||||
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: 3,
|
height: 2,
|
||||||
render: diagnostic_header_renderer(
|
render: diagnostic_header_renderer(
|
||||||
buffer.clone(),
|
|
||||||
header,
|
header,
|
||||||
true,
|
true,
|
||||||
self.build_settings.clone(),
|
self.build_settings.clone(),
|
||||||
|
@ -394,12 +401,13 @@ impl ProjectDiagnosticsEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
groups_to_add.push(group_state);
|
groups_to_add.push(group_state);
|
||||||
} else if let Some((group_ix, group_state)) = to_invalidate {
|
} else if let Some((group_ix, group_state)) = to_remove {
|
||||||
excerpts.remove_excerpts(group_state.excerpts.iter(), excerpts_cx);
|
excerpts.remove_excerpts(group_state.excerpts.iter(), excerpts_cx);
|
||||||
group_ixs_to_remove.push(group_ix);
|
group_ixs_to_remove.push(group_ix);
|
||||||
blocks_to_remove.extend(group_state.blocks.iter().copied());
|
blocks_to_remove.extend(group_state.blocks.iter().copied());
|
||||||
} else if let Some((_, group)) = to_keep {
|
} else if let Some((_, group)) = to_keep {
|
||||||
prev_excerpt_id = group.excerpts.last().unwrap().clone();
|
prev_excerpt_id = group.excerpts.last().unwrap().clone();
|
||||||
|
first_excerpt_id.get_or_insert_with(|| prev_excerpt_id.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,32 +415,43 @@ impl ProjectDiagnosticsEditor {
|
||||||
});
|
});
|
||||||
|
|
||||||
self.editor.update(cx, |editor, cx| {
|
self.editor.update(cx, |editor, cx| {
|
||||||
|
blocks_to_remove.extend(path_state.header);
|
||||||
editor.remove_blocks(blocks_to_remove, cx);
|
editor.remove_blocks(blocks_to_remove, cx);
|
||||||
|
let header_block = first_excerpt_id.map(|excerpt_id| BlockProperties {
|
||||||
|
position: excerpts_snapshot.anchor_in_excerpt(excerpt_id, language::Anchor::min()),
|
||||||
|
height: 2,
|
||||||
|
render: path_header_renderer(buffer, self.build_settings.clone()),
|
||||||
|
disposition: BlockDisposition::Above,
|
||||||
|
});
|
||||||
let mut block_ids = editor
|
let mut block_ids = editor
|
||||||
.insert_blocks(
|
.insert_blocks(
|
||||||
blocks_to_add.into_iter().map(|block| {
|
header_block
|
||||||
let (excerpt_id, text_anchor) = block.position;
|
.into_iter()
|
||||||
BlockProperties {
|
.chain(blocks_to_add.into_iter().map(|block| {
|
||||||
position: excerpts_snapshot.anchor_in_excerpt(excerpt_id, text_anchor),
|
let (excerpt_id, text_anchor) = block.position;
|
||||||
height: block.height,
|
BlockProperties {
|
||||||
render: block.render,
|
position: excerpts_snapshot
|
||||||
disposition: block.disposition,
|
.anchor_in_excerpt(excerpt_id, text_anchor),
|
||||||
}
|
height: block.height,
|
||||||
}),
|
render: block.render,
|
||||||
|
disposition: block.disposition,
|
||||||
|
}
|
||||||
|
})),
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
|
path_state.header = block_ids.next();
|
||||||
for group_state in &mut groups_to_add {
|
for group_state in &mut groups_to_add {
|
||||||
group_state.blocks = block_ids.by_ref().take(group_state.block_count).collect();
|
group_state.blocks = block_ids.by_ref().take(group_state.block_count).collect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for ix in group_ixs_to_remove.into_iter().rev() {
|
for ix in group_ixs_to_remove.into_iter().rev() {
|
||||||
groups.remove(ix);
|
path_state.diagnostic_groups.remove(ix);
|
||||||
}
|
}
|
||||||
groups.extend(groups_to_add);
|
path_state.diagnostic_groups.extend(groups_to_add);
|
||||||
groups.sort_unstable_by(|a, b| {
|
path_state.diagnostic_groups.sort_unstable_by(|a, b| {
|
||||||
let range_a = &a.primary_diagnostic.range;
|
let range_a = &a.primary_diagnostic.range;
|
||||||
let range_b = &b.primary_diagnostic.range;
|
let range_b = &b.primary_diagnostic.range;
|
||||||
range_a
|
range_a
|
||||||
|
@ -442,7 +461,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
.then_with(|| range_a.end.cmp(&range_b.end, &snapshot).unwrap())
|
.then_with(|| range_a.end.cmp(&range_b.end, &snapshot).unwrap())
|
||||||
});
|
});
|
||||||
|
|
||||||
if groups.is_empty() {
|
if path_state.diagnostic_groups.is_empty() {
|
||||||
self.path_states.remove(path_ix);
|
self.path_states.remove(path_ix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +470,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
let mut selections;
|
let mut selections;
|
||||||
let new_excerpt_ids_by_selection_id;
|
let new_excerpt_ids_by_selection_id;
|
||||||
if was_empty {
|
if was_empty {
|
||||||
groups = self.path_states.first()?.1.as_slice();
|
groups = self.path_states.first()?.diagnostic_groups.as_slice();
|
||||||
new_excerpt_ids_by_selection_id = [(0, ExcerptId::min())].into_iter().collect();
|
new_excerpt_ids_by_selection_id = [(0, ExcerptId::min())].into_iter().collect();
|
||||||
selections = vec![Selection {
|
selections = vec![Selection {
|
||||||
id: 0,
|
id: 0,
|
||||||
|
@ -461,7 +480,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
goal: SelectionGoal::None,
|
goal: SelectionGoal::None,
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
groups = self.path_states.get(path_ix)?.1.as_slice();
|
groups = self.path_states.get(path_ix)?.diagnostic_groups.as_slice();
|
||||||
new_excerpt_ids_by_selection_id = editor.refresh_selections(cx);
|
new_excerpt_ids_by_selection_id = editor.refresh_selections(cx);
|
||||||
selections = editor.local_selections::<usize>(cx);
|
selections = editor.local_selections::<usize>(cx);
|
||||||
}
|
}
|
||||||
|
@ -575,6 +594,57 @@ impl workspace::ItemView for ProjectDiagnosticsEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn path_header_renderer(buffer: ModelHandle<Buffer>, build_settings: BuildSettings) -> RenderBlock {
|
||||||
|
Arc::new(move |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()
|
||||||
|
};
|
||||||
|
Label::new(file_path, settings.style.text.clone())
|
||||||
|
.aligned()
|
||||||
|
.left()
|
||||||
|
.contained()
|
||||||
|
.with_padding_left(cx.line_number_x)
|
||||||
|
.expanded()
|
||||||
|
.boxed()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn diagnostic_header_renderer(
|
||||||
|
diagnostic: Diagnostic,
|
||||||
|
is_valid: bool,
|
||||||
|
build_settings: BuildSettings,
|
||||||
|
) -> RenderBlock {
|
||||||
|
Arc::new(move |cx| {
|
||||||
|
let settings = build_settings(cx);
|
||||||
|
let mut text_style = settings.style.text.clone();
|
||||||
|
let diagnostic_style = diagnostic_style(diagnostic.severity, is_valid, &settings.style);
|
||||||
|
text_style.color = diagnostic_style.text;
|
||||||
|
Text::new(diagnostic.message.clone(), text_style)
|
||||||
|
.with_soft_wrap(false)
|
||||||
|
.aligned()
|
||||||
|
.left()
|
||||||
|
.contained()
|
||||||
|
.with_style(diagnostic_style.header)
|
||||||
|
.with_padding_left(cx.line_number_x)
|
||||||
|
.expanded()
|
||||||
|
.boxed()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn context_header_renderer(build_settings: BuildSettings) -> RenderBlock {
|
||||||
|
Arc::new(move |cx| {
|
||||||
|
let settings = build_settings(cx);
|
||||||
|
let text_style = settings.style.text.clone();
|
||||||
|
Label::new("…".to_string(), text_style)
|
||||||
|
.contained()
|
||||||
|
.with_padding_left(cx.line_number_x)
|
||||||
|
.boxed()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn compare_diagnostics<L: language::ToOffset, R: language::ToOffset>(
|
fn compare_diagnostics<L: language::ToOffset, R: language::ToOffset>(
|
||||||
lhs: &DiagnosticEntry<L>,
|
lhs: &DiagnosticEntry<L>,
|
||||||
rhs: &DiagnosticEntry<R>,
|
rhs: &DiagnosticEntry<R>,
|
||||||
|
|
|
@ -69,6 +69,7 @@ where
|
||||||
pub struct BlockContext<'a> {
|
pub struct BlockContext<'a> {
|
||||||
pub cx: &'a AppContext,
|
pub cx: &'a AppContext,
|
||||||
pub anchor_x: f32,
|
pub anchor_x: f32,
|
||||||
|
pub line_number_x: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
@ -939,7 +940,7 @@ mod tests {
|
||||||
start_row..start_row + block.height(),
|
start_row..start_row + block.height(),
|
||||||
block.column(),
|
block.column(),
|
||||||
block
|
block
|
||||||
.render(&BlockContext { cx, anchor_x: 0. })
|
.render(&BlockContext { cx, anchor_x: 0., line_number_x: 0., })
|
||||||
.name()
|
.name()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
|
|
@ -3851,47 +3851,6 @@ pub fn diagnostic_block_renderer(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostic_header_renderer(
|
|
||||||
buffer: ModelHandle<Buffer>,
|
|
||||||
diagnostic: Diagnostic,
|
|
||||||
is_valid: bool,
|
|
||||||
build_settings: BuildSettings,
|
|
||||||
) -> RenderBlock {
|
|
||||||
Arc::new(move |cx| {
|
|
||||||
let settings = build_settings(cx);
|
|
||||||
let mut text_style = settings.style.text.clone();
|
|
||||||
let diagnostic_style = diagnostic_style(diagnostic.severity, is_valid, &settings.style);
|
|
||||||
text_style.color = diagnostic_style.text;
|
|
||||||
let file_path = if let Some(file) = buffer.read(&**cx).file() {
|
|
||||||
file.path().to_string_lossy().to_string()
|
|
||||||
} else {
|
|
||||||
"untitled".to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
Flex::column()
|
|
||||||
.with_child(
|
|
||||||
Text::new(diagnostic.message.clone(), text_style)
|
|
||||||
.with_soft_wrap(false)
|
|
||||||
.boxed(),
|
|
||||||
)
|
|
||||||
.with_child(Label::new(file_path, settings.style.text.clone()).boxed())
|
|
||||||
.aligned()
|
|
||||||
.left()
|
|
||||||
.contained()
|
|
||||||
.with_style(diagnostic_style.header)
|
|
||||||
.expanded()
|
|
||||||
.boxed()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn context_header_renderer(build_settings: BuildSettings) -> RenderBlock {
|
|
||||||
Arc::new(move |cx| {
|
|
||||||
let settings = build_settings(cx);
|
|
||||||
let text_style = settings.style.text.clone();
|
|
||||||
Label::new("...".to_string(), text_style).boxed()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn diagnostic_style(
|
pub fn diagnostic_style(
|
||||||
severity: DiagnosticSeverity,
|
severity: DiagnosticSeverity,
|
||||||
valid: bool,
|
valid: bool,
|
||||||
|
|
|
@ -624,6 +624,7 @@ impl EditorElement {
|
||||||
rows: Range<u32>,
|
rows: Range<u32>,
|
||||||
snapshot: &EditorSnapshot,
|
snapshot: &EditorSnapshot,
|
||||||
width: f32,
|
width: f32,
|
||||||
|
line_number_x: f32,
|
||||||
text_x: f32,
|
text_x: f32,
|
||||||
line_height: f32,
|
line_height: f32,
|
||||||
style: &EditorStyle,
|
style: &EditorStyle,
|
||||||
|
@ -647,7 +648,7 @@ impl EditorElement {
|
||||||
.x_for_index(block.column() as usize)
|
.x_for_index(block.column() as usize)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut element = block.render(&BlockContext { cx, anchor_x });
|
let mut element = block.render(&BlockContext { cx, anchor_x, line_number_x, });
|
||||||
element.layout(
|
element.layout(
|
||||||
SizeConstraint {
|
SizeConstraint {
|
||||||
min: Vector2F::zero(),
|
min: Vector2F::zero(),
|
||||||
|
@ -812,6 +813,7 @@ impl Element for EditorElement {
|
||||||
start_row..end_row,
|
start_row..end_row,
|
||||||
&snapshot,
|
&snapshot,
|
||||||
size.x(),
|
size.x(),
|
||||||
|
gutter_padding,
|
||||||
gutter_width + text_offset.x(),
|
gutter_width + text_offset.x(),
|
||||||
line_height,
|
line_height,
|
||||||
&style,
|
&style,
|
||||||
|
|
|
@ -187,7 +187,7 @@ corner_radius = 6
|
||||||
|
|
||||||
[project_panel]
|
[project_panel]
|
||||||
extends = "$panel"
|
extends = "$panel"
|
||||||
padding.top = 6 # ($workspace.tab.height - $project_panel.entry.height) / 2
|
padding.top = 6 # ($workspace.tab.height - $project_panel.entry.height) / 2
|
||||||
|
|
||||||
[project_panel.entry]
|
[project_panel.entry]
|
||||||
text = "$text.1"
|
text = "$text.1"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue