mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-07 20:39:04 +03:00
Scrollbar markers for cursors (#10816)
How it looks: https://github.com/zed-industries/zed/assets/2101250/f564111c-1019-4442-b8a6-de338e12b12e This PR adds cursor markers to the scrollbar. They work similar to VSCode: 1. A cursor marker takes the whole scrollbar width. 2. It's always 2px high. 3. It uses the player's `cursor` color, so it may be helpful in the collaboration mode. There's a setting to switch cursor markers on/off: ```json { "scrollbar": { "cursors": true } } ``` Implementation details: - Unlike other markers, cursor markers are displayed synchronously. Otherwise they don't feel smooth and sometimes freez on prolonged up/down navigation. - Cursor markers are automatically switched off when it's more than 100 of them. - The minimum (non-cursor) marker height is now 5px. It allows the user to see other markers under the cursor marker. - The way the minimum height is imposed on markers has changed a bit to keep consistency between markers of different types. - Selected symbol markers use less vibrant color (`info` faded out a little). Release Notes: - Added displaying of cursor markers in the scrollbar. They can be switched on/off by the `scrollbar.cursors` setting.
This commit is contained in:
parent
848bb97ba7
commit
1aa9c868d4
@ -155,6 +155,8 @@
|
|||||||
// 4. Never show the scrollbar:
|
// 4. Never show the scrollbar:
|
||||||
// "never"
|
// "never"
|
||||||
"show": "auto",
|
"show": "auto",
|
||||||
|
// Whether to show cursor positions in the scrollbar.
|
||||||
|
"cursors": true,
|
||||||
// Whether to show git diff indicators in the scrollbar.
|
// Whether to show git diff indicators in the scrollbar.
|
||||||
"git_diff": true,
|
"git_diff": true,
|
||||||
// Whether to show buffer search results in the scrollbar.
|
// Whether to show buffer search results in the scrollbar.
|
||||||
|
@ -61,6 +61,7 @@ pub struct Scrollbar {
|
|||||||
pub selected_symbol: bool,
|
pub selected_symbol: bool,
|
||||||
pub search_results: bool,
|
pub search_results: bool,
|
||||||
pub diagnostics: bool,
|
pub diagnostics: bool,
|
||||||
|
pub cursors: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||||
@ -206,6 +207,10 @@ pub struct ScrollbarContent {
|
|||||||
///
|
///
|
||||||
/// Default: true
|
/// Default: true
|
||||||
pub diagnostics: Option<bool>,
|
pub diagnostics: Option<bool>,
|
||||||
|
/// Whether to show cursor positions in the scrollbar.
|
||||||
|
///
|
||||||
|
/// Default: true
|
||||||
|
pub cursors: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gutter related settings
|
/// Gutter related settings
|
||||||
|
@ -18,6 +18,7 @@ use crate::{
|
|||||||
SelectPhase, Selection, SoftWrap, ToPoint, CURSORS_VISIBLE_FOR, MAX_LINE_LEN,
|
SelectPhase, Selection, SoftWrap, ToPoint, CURSORS_VISIBLE_FOR, MAX_LINE_LEN,
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use client::ParticipantIndex;
|
||||||
use collections::{BTreeMap, HashMap};
|
use collections::{BTreeMap, HashMap};
|
||||||
use git::{blame::BlameEntry, diff::DiffHunkStatus, Oid};
|
use git::{blame::BlameEntry, diff::DiffHunkStatus, Oid};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
@ -45,7 +46,7 @@ use std::{
|
|||||||
cmp::{self, max, Ordering},
|
cmp::{self, max, Ordering},
|
||||||
fmt::Write,
|
fmt::Write,
|
||||||
iter, mem,
|
iter, mem,
|
||||||
ops::Range,
|
ops::{Deref, Range},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use sum_tree::Bias;
|
use sum_tree::Bias;
|
||||||
@ -770,13 +771,7 @@ impl EditorElement {
|
|||||||
collaboration_hub.as_ref(),
|
collaboration_hub.as_ref(),
|
||||||
cx,
|
cx,
|
||||||
) {
|
) {
|
||||||
let selection_style = if let Some(participant_index) = selection.participant_index {
|
let selection_style = Self::get_participant_color(selection.participant_index, cx);
|
||||||
cx.theme()
|
|
||||||
.players()
|
|
||||||
.color_for_participant(participant_index.0)
|
|
||||||
} else {
|
|
||||||
cx.theme().players().absent()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Don't re-render the leader's selections, since the local selections
|
// Don't re-render the leader's selections, since the local selections
|
||||||
// match theirs.
|
// match theirs.
|
||||||
@ -875,8 +870,42 @@ impl EditorElement {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_cursors(
|
||||||
|
&self,
|
||||||
|
snapshot: &EditorSnapshot,
|
||||||
|
cx: &mut WindowContext,
|
||||||
|
) -> Vec<(Anchor, Hsla)> {
|
||||||
|
let editor = self.editor.read(cx);
|
||||||
|
let mut cursors = Vec::<(Anchor, Hsla)>::new();
|
||||||
|
let mut skip_local = false;
|
||||||
|
// Remote cursors
|
||||||
|
if let Some(collaboration_hub) = &editor.collaboration_hub {
|
||||||
|
for remote_selection in snapshot.remote_selections_in_range(
|
||||||
|
&(Anchor::min()..Anchor::max()),
|
||||||
|
collaboration_hub.deref(),
|
||||||
|
cx,
|
||||||
|
) {
|
||||||
|
let color = Self::get_participant_color(remote_selection.participant_index, cx);
|
||||||
|
cursors.push((remote_selection.selection.head(), color.cursor));
|
||||||
|
if Some(remote_selection.peer_id) == editor.leader_peer_id {
|
||||||
|
skip_local = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Local cursors
|
||||||
|
if !skip_local {
|
||||||
|
editor.selections.disjoint.iter().for_each(|selection| {
|
||||||
|
cursors.push((selection.head(), cx.theme().players().local().cursor));
|
||||||
|
});
|
||||||
|
if let Some(ref selection) = editor.selections.pending_anchor() {
|
||||||
|
cursors.push((selection.head(), cx.theme().players().local().cursor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursors
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn layout_cursors(
|
fn layout_visible_cursors(
|
||||||
&self,
|
&self,
|
||||||
snapshot: &EditorSnapshot,
|
snapshot: &EditorSnapshot,
|
||||||
selections: &[(PlayerColor, Vec<SelectionLayout>)],
|
selections: &[(PlayerColor, Vec<SelectionLayout>)],
|
||||||
@ -1015,6 +1044,7 @@ impl EditorElement {
|
|||||||
bounds: Bounds<Pixels>,
|
bounds: Bounds<Pixels>,
|
||||||
scroll_position: gpui::Point<f32>,
|
scroll_position: gpui::Point<f32>,
|
||||||
rows_per_page: f32,
|
rows_per_page: f32,
|
||||||
|
non_visible_cursors: bool,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) -> Option<ScrollbarLayout> {
|
) -> Option<ScrollbarLayout> {
|
||||||
let scrollbar_settings = EditorSettings::get_global(cx).scrollbar;
|
let scrollbar_settings = EditorSettings::get_global(cx).scrollbar;
|
||||||
@ -1034,6 +1064,9 @@ impl EditorElement {
|
|||||||
// Diagnostics
|
// Diagnostics
|
||||||
(is_singleton && scrollbar_settings.diagnostics && snapshot.buffer_snapshot.has_diagnostics())
|
(is_singleton && scrollbar_settings.diagnostics && snapshot.buffer_snapshot.has_diagnostics())
|
||||||
||
|
||
|
||||||
|
// Cursors out of sight
|
||||||
|
non_visible_cursors
|
||||||
|
||
|
||||||
// Scrollmanager
|
// Scrollmanager
|
||||||
editor.scroll_manager.scrollbars_visible()
|
editor.scroll_manager.scrollbars_visible()
|
||||||
}
|
}
|
||||||
@ -1323,6 +1356,17 @@ impl EditorElement {
|
|||||||
Some(button)
|
Some(button)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_participant_color(
|
||||||
|
participant_index: Option<ParticipantIndex>,
|
||||||
|
cx: &WindowContext,
|
||||||
|
) -> PlayerColor {
|
||||||
|
if let Some(index) = participant_index {
|
||||||
|
cx.theme().players().color_for_participant(index.0)
|
||||||
|
} else {
|
||||||
|
cx.theme().players().absent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn calculate_relative_line_numbers(
|
fn calculate_relative_line_numbers(
|
||||||
&self,
|
&self,
|
||||||
buffer_rows: Vec<Option<u32>>,
|
buffer_rows: Vec<Option<u32>>,
|
||||||
@ -2478,7 +2522,7 @@ impl EditorElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn paint_cursors(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
|
fn paint_cursors(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
|
||||||
for cursor in &mut layout.cursors {
|
for cursor in &mut layout.visible_cursors {
|
||||||
cursor.paint(layout.content_origin, cx);
|
cursor.paint(layout.content_origin, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2504,11 +2548,13 @@ impl EditorElement {
|
|||||||
cx.theme().colors().scrollbar_track_border,
|
cx.theme().colors().scrollbar_track_border,
|
||||||
));
|
));
|
||||||
|
|
||||||
// Refresh scrollbar markers in the background. Below, we paint whatever markers have already been computed.
|
let fast_markers =
|
||||||
self.refresh_scrollbar_markers(layout, scrollbar_layout, cx);
|
self.collect_fast_scrollbar_markers(layout, scrollbar_layout, cx);
|
||||||
|
// Refresh slow scrollbar markers in the background. Below, we paint whatever markers have already been computed.
|
||||||
|
self.refresh_slow_scrollbar_markers(layout, scrollbar_layout, cx);
|
||||||
|
|
||||||
let markers = self.editor.read(cx).scrollbar_marker_state.markers.clone();
|
let markers = self.editor.read(cx).scrollbar_marker_state.markers.clone();
|
||||||
for marker in markers.iter() {
|
for marker in markers.iter().chain(&fast_markers) {
|
||||||
let mut marker = marker.clone();
|
let mut marker = marker.clone();
|
||||||
marker.bounds.origin += scrollbar_layout.hitbox.origin;
|
marker.bounds.origin += scrollbar_layout.hitbox.origin;
|
||||||
cx.paint_quad(marker);
|
cx.paint_quad(marker);
|
||||||
@ -2615,7 +2661,34 @@ impl EditorElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refresh_scrollbar_markers(
|
fn collect_fast_scrollbar_markers(
|
||||||
|
&self,
|
||||||
|
layout: &EditorLayout,
|
||||||
|
scrollbar_layout: &ScrollbarLayout,
|
||||||
|
cx: &mut WindowContext,
|
||||||
|
) -> Vec<PaintQuad> {
|
||||||
|
const LIMIT: usize = 100;
|
||||||
|
if !EditorSettings::get_global(cx).scrollbar.cursors || layout.cursors.len() > LIMIT {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
let cursor_ranges = layout
|
||||||
|
.cursors
|
||||||
|
.iter()
|
||||||
|
.map(|cursor| {
|
||||||
|
let point = cursor
|
||||||
|
.0
|
||||||
|
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||||
|
ColoredRange {
|
||||||
|
start: point.row(),
|
||||||
|
end: point.row(),
|
||||||
|
color: cursor.1,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
scrollbar_layout.marker_quads_for_ranges(cursor_ranges, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refresh_slow_scrollbar_markers(
|
||||||
&self,
|
&self,
|
||||||
layout: &EditorLayout,
|
layout: &EditorLayout,
|
||||||
scrollbar_layout: &ScrollbarLayout,
|
scrollbar_layout: &ScrollbarLayout,
|
||||||
@ -2675,7 +2748,8 @@ impl EditorElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
marker_quads.extend(
|
marker_quads.extend(
|
||||||
scrollbar_layout.marker_quads_for_ranges(marker_row_ranges, 0),
|
scrollbar_layout
|
||||||
|
.marker_quads_for_ranges(marker_row_ranges, Some(0)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2691,6 +2765,10 @@ impl EditorElement {
|
|||||||
if (is_search_highlights && scrollbar_settings.search_results)
|
if (is_search_highlights && scrollbar_settings.search_results)
|
||||||
|| (is_symbol_occurrences && scrollbar_settings.selected_symbol)
|
|| (is_symbol_occurrences && scrollbar_settings.selected_symbol)
|
||||||
{
|
{
|
||||||
|
let mut color = theme.status().info;
|
||||||
|
if is_symbol_occurrences {
|
||||||
|
color.fade_out(0.5);
|
||||||
|
}
|
||||||
let marker_row_ranges =
|
let marker_row_ranges =
|
||||||
background_ranges.into_iter().map(|range| {
|
background_ranges.into_iter().map(|range| {
|
||||||
let display_start = range
|
let display_start = range
|
||||||
@ -2702,12 +2780,12 @@ impl EditorElement {
|
|||||||
ColoredRange {
|
ColoredRange {
|
||||||
start: display_start.row(),
|
start: display_start.row(),
|
||||||
end: display_end.row(),
|
end: display_end.row(),
|
||||||
color: theme.status().info,
|
color,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
marker_quads.extend(
|
marker_quads.extend(
|
||||||
scrollbar_layout
|
scrollbar_layout
|
||||||
.marker_quads_for_ranges(marker_row_ranges, 1),
|
.marker_quads_for_ranges(marker_row_ranges, Some(1)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2749,7 +2827,8 @@ impl EditorElement {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
marker_quads.extend(
|
marker_quads.extend(
|
||||||
scrollbar_layout.marker_quads_for_ranges(marker_row_ranges, 2),
|
scrollbar_layout
|
||||||
|
.marker_quads_for_ranges(marker_row_ranges, Some(2)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3514,10 +3593,10 @@ impl Element for EditorElement {
|
|||||||
let start_row = scroll_position.y as u32;
|
let start_row = scroll_position.y as u32;
|
||||||
let height_in_lines = bounds.size.height / line_height;
|
let height_in_lines = bounds.size.height / line_height;
|
||||||
let max_row = snapshot.max_point().row();
|
let max_row = snapshot.max_point().row();
|
||||||
|
let end_row = cmp::min(
|
||||||
// Add 1 to ensure selections bleed off screen
|
(scroll_position.y + height_in_lines).ceil() as u32,
|
||||||
let end_row =
|
max_row + 1,
|
||||||
1 + cmp::min((scroll_position.y + height_in_lines).ceil() as u32, max_row);
|
);
|
||||||
|
|
||||||
let buffer_rows = snapshot
|
let buffer_rows = snapshot
|
||||||
.buffer_rows(start_row)
|
.buffer_rows(start_row)
|
||||||
@ -3671,7 +3750,9 @@ impl Element for EditorElement {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let cursors = self.layout_cursors(
|
let cursors = self.collect_cursors(&snapshot, cx);
|
||||||
|
|
||||||
|
let visible_cursors = self.layout_visible_cursors(
|
||||||
&snapshot,
|
&snapshot,
|
||||||
&selections,
|
&selections,
|
||||||
start_row..end_row,
|
start_row..end_row,
|
||||||
@ -3686,8 +3767,14 @@ impl Element for EditorElement {
|
|||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
let scrollbar_layout =
|
let scrollbar_layout = self.layout_scrollbar(
|
||||||
self.layout_scrollbar(&snapshot, bounds, scroll_position, height_in_lines, cx);
|
&snapshot,
|
||||||
|
bounds,
|
||||||
|
scroll_position,
|
||||||
|
height_in_lines,
|
||||||
|
cursors.len() > visible_cursors.len(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
let folds = cx.with_element_id(Some("folds"), |cx| {
|
let folds = cx.with_element_id(Some("folds"), |cx| {
|
||||||
self.layout_folds(
|
self.layout_folds(
|
||||||
@ -3829,6 +3916,7 @@ impl Element for EditorElement {
|
|||||||
folds,
|
folds,
|
||||||
blocks,
|
blocks,
|
||||||
cursors,
|
cursors,
|
||||||
|
visible_cursors,
|
||||||
selections,
|
selections,
|
||||||
mouse_context_menu,
|
mouse_context_menu,
|
||||||
code_actions_indicator,
|
code_actions_indicator,
|
||||||
@ -3917,7 +4005,8 @@ pub struct EditorLayout {
|
|||||||
blocks: Vec<BlockLayout>,
|
blocks: Vec<BlockLayout>,
|
||||||
highlighted_ranges: Vec<(Range<DisplayPoint>, Hsla)>,
|
highlighted_ranges: Vec<(Range<DisplayPoint>, Hsla)>,
|
||||||
redacted_ranges: Vec<Range<DisplayPoint>>,
|
redacted_ranges: Vec<Range<DisplayPoint>>,
|
||||||
cursors: Vec<CursorLayout>,
|
cursors: Vec<(Anchor, Hsla)>,
|
||||||
|
visible_cursors: Vec<CursorLayout>,
|
||||||
selections: Vec<(PlayerColor, Vec<SelectionLayout>)>,
|
selections: Vec<(PlayerColor, Vec<SelectionLayout>)>,
|
||||||
max_row: u32,
|
max_row: u32,
|
||||||
code_actions_indicator: Option<AnyElement>,
|
code_actions_indicator: Option<AnyElement>,
|
||||||
@ -3950,7 +4039,8 @@ struct ScrollbarLayout {
|
|||||||
|
|
||||||
impl ScrollbarLayout {
|
impl ScrollbarLayout {
|
||||||
const BORDER_WIDTH: Pixels = px(1.0);
|
const BORDER_WIDTH: Pixels = px(1.0);
|
||||||
const MIN_MARKER_HEIGHT: Pixels = px(2.0);
|
const LINE_MARKER_HEIGHT: Pixels = px(2.0);
|
||||||
|
const MIN_MARKER_HEIGHT: Pixels = px(5.0);
|
||||||
const MIN_THUMB_HEIGHT: Pixels = px(20.0);
|
const MIN_THUMB_HEIGHT: Pixels = px(20.0);
|
||||||
|
|
||||||
fn thumb_bounds(&self) -> Bounds<Pixels> {
|
fn thumb_bounds(&self) -> Bounds<Pixels> {
|
||||||
@ -3969,19 +4059,43 @@ impl ScrollbarLayout {
|
|||||||
fn marker_quads_for_ranges(
|
fn marker_quads_for_ranges(
|
||||||
&self,
|
&self,
|
||||||
row_ranges: impl IntoIterator<Item = ColoredRange<u32>>,
|
row_ranges: impl IntoIterator<Item = ColoredRange<u32>>,
|
||||||
column: usize,
|
column: Option<usize>,
|
||||||
) -> Vec<PaintQuad> {
|
) -> Vec<PaintQuad> {
|
||||||
let column_width =
|
struct MinMax {
|
||||||
px(((self.hitbox.size.width - ScrollbarLayout::BORDER_WIDTH).0 / 3.0).floor());
|
min: Pixels,
|
||||||
|
max: Pixels,
|
||||||
|
}
|
||||||
|
let (x_range, height_limit) = if let Some(column) = column {
|
||||||
|
let column_width = px(((self.hitbox.size.width - Self::BORDER_WIDTH).0 / 3.0).floor());
|
||||||
|
let start = Self::BORDER_WIDTH + (column as f32 * column_width);
|
||||||
|
let end = start + column_width;
|
||||||
|
(
|
||||||
|
Range { start, end },
|
||||||
|
MinMax {
|
||||||
|
min: Self::MIN_MARKER_HEIGHT,
|
||||||
|
max: px(f32::MAX),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
Range {
|
||||||
|
start: Self::BORDER_WIDTH,
|
||||||
|
end: self.hitbox.size.width,
|
||||||
|
},
|
||||||
|
MinMax {
|
||||||
|
min: Self::LINE_MARKER_HEIGHT,
|
||||||
|
max: Self::LINE_MARKER_HEIGHT,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let left_x = ScrollbarLayout::BORDER_WIDTH + (column as f32 * column_width);
|
let row_to_y = |row: u32| row as f32 * self.row_height;
|
||||||
let right_x = left_x + column_width;
|
let mut pixel_ranges = row_ranges
|
||||||
|
|
||||||
let mut background_pixel_ranges = row_ranges
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|range| {
|
.map(|range| {
|
||||||
let start_y = range.start as f32 * self.row_height;
|
let start_y = row_to_y(range.start);
|
||||||
let end_y = (range.end + 1) as f32 * self.row_height;
|
let end_y = row_to_y(range.end)
|
||||||
|
+ self.row_height.max(height_limit.min).min(height_limit.max);
|
||||||
ColoredRange {
|
ColoredRange {
|
||||||
start: start_y,
|
start: start_y,
|
||||||
end: end_y,
|
end: end_y,
|
||||||
@ -3991,24 +4105,21 @@ impl ScrollbarLayout {
|
|||||||
.peekable();
|
.peekable();
|
||||||
|
|
||||||
let mut quads = Vec::new();
|
let mut quads = Vec::new();
|
||||||
while let Some(mut pixel_range) = background_pixel_ranges.next() {
|
while let Some(mut pixel_range) = pixel_ranges.next() {
|
||||||
pixel_range.end = pixel_range
|
while let Some(next_pixel_range) = pixel_ranges.peek() {
|
||||||
.end
|
if pixel_range.end >= next_pixel_range.start - px(1.0)
|
||||||
.max(pixel_range.start + Self::MIN_MARKER_HEIGHT);
|
|
||||||
while let Some(next_pixel_range) = background_pixel_ranges.peek() {
|
|
||||||
if pixel_range.end >= next_pixel_range.start
|
|
||||||
&& pixel_range.color == next_pixel_range.color
|
&& pixel_range.color == next_pixel_range.color
|
||||||
{
|
{
|
||||||
pixel_range.end = next_pixel_range.end.max(pixel_range.end);
|
pixel_range.end = next_pixel_range.end.max(pixel_range.end);
|
||||||
background_pixel_ranges.next();
|
pixel_ranges.next();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let bounds = Bounds::from_corners(
|
let bounds = Bounds::from_corners(
|
||||||
point(left_x, pixel_range.start),
|
point(x_range.start, pixel_range.start),
|
||||||
point(right_x, pixel_range.end),
|
point(x_range.end, pixel_range.end),
|
||||||
);
|
);
|
||||||
quads.push(quad(
|
quads.push(quad(
|
||||||
bounds,
|
bounds,
|
||||||
|
@ -217,6 +217,7 @@ List of `string` values
|
|||||||
```json
|
```json
|
||||||
"scrollbar": {
|
"scrollbar": {
|
||||||
"show": "auto",
|
"show": "auto",
|
||||||
|
"cursors": true,
|
||||||
"git_diff": true,
|
"git_diff": true,
|
||||||
"search_results": true,
|
"search_results": true,
|
||||||
"selected_symbol": true,
|
"selected_symbol": true,
|
||||||
@ -264,6 +265,16 @@ List of `string` values
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Cursor Indicators
|
||||||
|
|
||||||
|
- Description: Whether to show cursor positions in the scrollbar.
|
||||||
|
- Setting: `cursors`
|
||||||
|
- Default: `true`
|
||||||
|
|
||||||
|
**Options**
|
||||||
|
|
||||||
|
`boolean` values
|
||||||
|
|
||||||
### Git Diff Indicators
|
### Git Diff Indicators
|
||||||
|
|
||||||
- Description: Whether to show git diff indicators in the scrollbar.
|
- Description: Whether to show git diff indicators in the scrollbar.
|
||||||
|
Loading…
Reference in New Issue
Block a user