mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-16 00:47:39 +03:00
Highlight active row(s) in the gutter
This commit is contained in:
parent
372d2ccb6d
commit
3abed88c76
@ -14,7 +14,6 @@ modal_match_border = 0x000000
|
||||
modal_match_text = 0xcccccc
|
||||
modal_match_text_highlight = 0x18a3ff
|
||||
|
||||
|
||||
[editor]
|
||||
background = 0x1c1d1e
|
||||
gutter_background = 0x1c1d1e
|
||||
|
@ -5,6 +5,7 @@ pub mod movement;
|
||||
|
||||
use crate::{
|
||||
settings::{Settings, StyleId, Theme},
|
||||
time::ReplicaId,
|
||||
util::{post_inc, Bias},
|
||||
workspace,
|
||||
worktree::{File, Worktree},
|
||||
@ -26,6 +27,7 @@ use smallvec::SmallVec;
|
||||
use smol::Timer;
|
||||
use std::{
|
||||
cmp::{self, Ordering},
|
||||
collections::HashSet,
|
||||
fmt::Write,
|
||||
iter::FromIterator,
|
||||
mem,
|
||||
@ -461,6 +463,10 @@ impl Editor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replica_id(&self, cx: &AppContext) -> ReplicaId {
|
||||
self.buffer.read(cx).replica_id()
|
||||
}
|
||||
|
||||
pub fn buffer(&self) -> &ModelHandle<Buffer> {
|
||||
&self.buffer
|
||||
}
|
||||
@ -2350,27 +2356,28 @@ impl Snapshot {
|
||||
|
||||
pub fn layout_line_numbers(
|
||||
&self,
|
||||
viewport_height: f32,
|
||||
rows: Range<u32>,
|
||||
active_rows: &HashSet<u32>,
|
||||
font_cache: &FontCache,
|
||||
layout_cache: &TextLayoutCache,
|
||||
theme: &Theme,
|
||||
) -> Result<Vec<Option<text_layout::Line>>> {
|
||||
let font_id = font_cache.select_font(self.font_family, &FontProperties::new())?;
|
||||
|
||||
let start_row = self.scroll_position().y() as usize;
|
||||
let end_row = cmp::min(
|
||||
self.display_snapshot.max_point().row() as usize,
|
||||
start_row + (viewport_height / self.line_height(font_cache)).ceil() as usize,
|
||||
);
|
||||
let line_count = end_row - start_row + 1;
|
||||
|
||||
let mut layouts = Vec::with_capacity(line_count);
|
||||
let mut layouts = Vec::with_capacity(rows.len());
|
||||
let mut line_number = String::new();
|
||||
for (buffer_row, soft_wrapped) in self
|
||||
for (ix, (buffer_row, soft_wrapped)) in self
|
||||
.display_snapshot
|
||||
.buffer_rows(start_row as u32)
|
||||
.take(line_count)
|
||||
.buffer_rows(rows.start)
|
||||
.take((rows.end - rows.start) as usize)
|
||||
.enumerate()
|
||||
{
|
||||
let display_row = rows.start + ix as u32;
|
||||
let color = if active_rows.contains(&display_row) {
|
||||
theme.editor.line_number_active.0
|
||||
} else {
|
||||
theme.editor.line_number.0
|
||||
};
|
||||
if soft_wrapped {
|
||||
layouts.push(None);
|
||||
} else {
|
||||
@ -2379,7 +2386,7 @@ impl Snapshot {
|
||||
layouts.push(Some(layout_cache.layout_str(
|
||||
&line_number,
|
||||
self.font_size,
|
||||
&[(line_number.len(), font_id, theme.editor.line_number.0)],
|
||||
&[(line_number.len(), font_id, color)],
|
||||
)));
|
||||
}
|
||||
}
|
||||
@ -2482,6 +2489,14 @@ impl Snapshot {
|
||||
)],
|
||||
))
|
||||
}
|
||||
|
||||
pub fn prev_row_boundary(&self, point: DisplayPoint) -> (DisplayPoint, Point) {
|
||||
self.display_snapshot.prev_row_boundary(point)
|
||||
}
|
||||
|
||||
pub fn next_row_boundary(&self, point: DisplayPoint) -> (DisplayPoint, Point) {
|
||||
self.display_snapshot.next_row_boundary(point)
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_scroll_position(
|
||||
@ -2792,7 +2807,13 @@ mod tests {
|
||||
let layouts = editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.snapshot(cx)
|
||||
.layout_line_numbers(1000.0, &font_cache, &layout_cache, &settings.borrow().theme)
|
||||
.layout_line_numbers(
|
||||
0..6,
|
||||
&Default::default(),
|
||||
&font_cache,
|
||||
&layout_cache,
|
||||
&settings.borrow().theme,
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
assert_eq!(layouts.len(), 6);
|
||||
|
@ -14,7 +14,7 @@ use gpui::{
|
||||
};
|
||||
use json::json;
|
||||
use smallvec::SmallVec;
|
||||
use std::{cmp::Ordering, ops::Range};
|
||||
use std::{cmp::Ordering, collections::HashSet, ops::Range};
|
||||
use std::{
|
||||
cmp::{self},
|
||||
collections::HashMap,
|
||||
@ -387,6 +387,46 @@ impl Element for EditorElement {
|
||||
(autoscroll_horizontally, snapshot)
|
||||
});
|
||||
|
||||
let scroll_position = snapshot.scroll_position();
|
||||
let start_row = scroll_position.y() as u32;
|
||||
let scroll_top = scroll_position.y() * line_height;
|
||||
let end_row = ((scroll_top + size.y()) / line_height).ceil() as u32 + 1; // Add 1 to ensure selections bleed off screen
|
||||
|
||||
let mut selections = HashMap::new();
|
||||
let mut active_rows = HashSet::new();
|
||||
self.update_view(cx.app, |view, cx| {
|
||||
let replica_id = view.replica_id(cx);
|
||||
for selection_set_id in view.active_selection_sets(cx).collect::<Vec<_>>() {
|
||||
let mut set = Vec::new();
|
||||
for selection in view.selections_in_range(
|
||||
selection_set_id,
|
||||
DisplayPoint::new(start_row, 0)..DisplayPoint::new(end_row, 0),
|
||||
cx,
|
||||
) {
|
||||
set.push(selection.clone());
|
||||
if selection_set_id.replica_id == replica_id {
|
||||
let mut selection_start;
|
||||
let mut selection_end;
|
||||
if selection.start < selection.end {
|
||||
selection_start = selection.start;
|
||||
selection_end = selection.end;
|
||||
} else {
|
||||
selection_start = selection.end;
|
||||
selection_end = selection.start;
|
||||
};
|
||||
selection_start = snapshot.prev_row_boundary(selection_start).0;
|
||||
selection_end = snapshot.next_row_boundary(selection_end).0;
|
||||
active_rows.extend(
|
||||
cmp::max(selection_start.row(), start_row)
|
||||
..=cmp::min(selection_end.row(), end_row),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
selections.insert(selection_set_id.replica_id, set);
|
||||
}
|
||||
});
|
||||
|
||||
let line_number_layouts = if snapshot.gutter_visible {
|
||||
let settings = self
|
||||
.view
|
||||
@ -396,7 +436,8 @@ impl Element for EditorElement {
|
||||
.settings
|
||||
.borrow();
|
||||
match snapshot.layout_line_numbers(
|
||||
size.y(),
|
||||
start_row..end_row,
|
||||
&active_rows,
|
||||
cx.font_cache,
|
||||
cx.text_layout_cache,
|
||||
&settings.theme,
|
||||
@ -411,11 +452,6 @@ impl Element for EditorElement {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let scroll_position = snapshot.scroll_position();
|
||||
let start_row = scroll_position.y() as u32;
|
||||
let scroll_top = scroll_position.y() * line_height;
|
||||
let end_row = ((scroll_top + size.y()) / line_height).ceil() as u32 + 1; // Add 1 to ensure selections bleed off screen
|
||||
|
||||
let mut max_visible_line_width = 0.0;
|
||||
let line_layouts = match snapshot.layout_lines(start_row..end_row, font_cache, layout_cache)
|
||||
{
|
||||
@ -434,21 +470,6 @@ impl Element for EditorElement {
|
||||
}
|
||||
};
|
||||
|
||||
let mut selections = HashMap::new();
|
||||
self.update_view(cx.app, |view, cx| {
|
||||
for selection_set_id in view.active_selection_sets(cx).collect::<Vec<_>>() {
|
||||
selections.insert(
|
||||
selection_set_id.replica_id,
|
||||
view.selections_in_range(
|
||||
selection_set_id,
|
||||
DisplayPoint::new(start_row, 0)..DisplayPoint::new(end_row, 0),
|
||||
cx,
|
||||
)
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
let mut layout = LayoutState {
|
||||
size,
|
||||
gutter_size,
|
||||
|
Loading…
Reference in New Issue
Block a user