mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-21 03:18:47 +03:00
parent
f798be6e27
commit
790aa5d476
@ -98,6 +98,7 @@
|
||||
// Whether to show selections in the scrollbar.
|
||||
"selections": true
|
||||
},
|
||||
"relative_line_numbers": false,
|
||||
// Inlay hint related settings
|
||||
"inlay_hints": {
|
||||
// Global switch to toggle hints on and off, switched off by default.
|
||||
|
@ -9,6 +9,7 @@ pub struct EditorSettings {
|
||||
pub show_completions_on_input: bool,
|
||||
pub use_on_type_format: bool,
|
||||
pub scrollbar: Scrollbar,
|
||||
pub relative_line_numbers: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
@ -34,6 +35,7 @@ pub struct EditorSettingsContent {
|
||||
pub show_completions_on_input: Option<bool>,
|
||||
pub use_on_type_format: Option<bool>,
|
||||
pub scrollbar: Option<ScrollbarContent>,
|
||||
pub relative_line_numbers: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
|
@ -1439,10 +1439,47 @@ impl EditorElement {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn calculate_relative_line_numbers(
|
||||
&self,
|
||||
rows: &Range<u32>,
|
||||
buffer_rows: &Vec<Option<u32>>,
|
||||
relative_to: Option<u32>,
|
||||
) -> HashMap<usize, u32> {
|
||||
let mut relative_rows: HashMap<usize, u32> = Default::default();
|
||||
if let Some(relative_to) = relative_to {
|
||||
let head_idx = (relative_to - rows.start) as usize;
|
||||
let mut delta = 1;
|
||||
let mut i = head_idx + 1;
|
||||
while i < buffer_rows.len() {
|
||||
if buffer_rows[i].is_some() {
|
||||
relative_rows.insert(i, delta);
|
||||
delta += 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
delta = 1;
|
||||
i = head_idx;
|
||||
while i > 0 && buffer_rows[i].is_none() {
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
while i > 0 {
|
||||
i -= 1;
|
||||
if buffer_rows[i].is_some() {
|
||||
relative_rows.insert(i, delta);
|
||||
delta += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
relative_rows
|
||||
}
|
||||
|
||||
fn layout_line_numbers(
|
||||
&self,
|
||||
rows: Range<u32>,
|
||||
active_rows: &BTreeMap<u32, bool>,
|
||||
newest_selection_head: Option<DisplayPoint>,
|
||||
is_singleton: bool,
|
||||
snapshot: &EditorSnapshot,
|
||||
cx: &ViewContext<Editor>,
|
||||
@ -1455,21 +1492,33 @@ impl EditorElement {
|
||||
let mut line_number_layouts = Vec::with_capacity(rows.len());
|
||||
let mut fold_statuses = Vec::with_capacity(rows.len());
|
||||
let mut line_number = String::new();
|
||||
for (ix, row) in snapshot
|
||||
let is_relative = settings::get::<EditorSettings>(cx).relative_line_numbers;
|
||||
let relative_to = if is_relative {
|
||||
newest_selection_head.map(|head| head.row())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let buffer_rows = snapshot
|
||||
.buffer_rows(rows.start)
|
||||
.take((rows.end - rows.start) as usize)
|
||||
.enumerate()
|
||||
{
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let relative_rows = self.calculate_relative_line_numbers(&rows, &buffer_rows, relative_to);
|
||||
|
||||
for (ix, row) in buffer_rows.iter().enumerate() {
|
||||
let display_row = rows.start + ix as u32;
|
||||
let (active, color) = if active_rows.contains_key(&display_row) {
|
||||
(true, style.line_number_active)
|
||||
} else {
|
||||
(false, style.line_number)
|
||||
};
|
||||
if let Some(buffer_row) = row {
|
||||
if let Some(buffer_row) = *row {
|
||||
if include_line_numbers {
|
||||
line_number.clear();
|
||||
write!(&mut line_number, "{}", buffer_row + 1).unwrap();
|
||||
let default_number = buffer_row + 1;
|
||||
let number = relative_rows.get(&ix).unwrap_or(&default_number);
|
||||
write!(&mut line_number, "{}", number).unwrap();
|
||||
line_number_layouts.push(Some(cx.text_layout_cache().layout_str(
|
||||
&line_number,
|
||||
style.text.font_size,
|
||||
@ -2296,6 +2345,7 @@ impl Element<Editor> for EditorElement {
|
||||
let (line_number_layouts, fold_statuses) = self.layout_line_numbers(
|
||||
start_row..end_row,
|
||||
&active_rows,
|
||||
newest_selection_head,
|
||||
is_singleton,
|
||||
&snapshot,
|
||||
cx,
|
||||
@ -3054,7 +3104,6 @@ mod tests {
|
||||
#[gpui::test]
|
||||
fn test_layout_line_numbers(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let editor = cx
|
||||
.add_window(|cx| {
|
||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
||||
@ -3066,10 +3115,28 @@ mod tests {
|
||||
let layouts = editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
element
|
||||
.layout_line_numbers(0..6, &Default::default(), false, &snapshot, cx)
|
||||
.layout_line_numbers(0..6, &Default::default(), None, false, &snapshot, cx)
|
||||
.0
|
||||
});
|
||||
assert_eq!(layouts.len(), 6);
|
||||
|
||||
let relative_rows = editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
|
||||
let rows = 0..6;
|
||||
let buffer_rows = snapshot
|
||||
.buffer_rows(rows.start)
|
||||
.take((rows.end - rows.start) as usize)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
element.calculate_relative_line_numbers(&rows, &buffer_rows, Some(3))
|
||||
});
|
||||
assert_eq!(relative_rows[&0], 3);
|
||||
assert_eq!(relative_rows[&1], 2);
|
||||
assert_eq!(relative_rows[&2], 1);
|
||||
// current line has no relative number
|
||||
assert_eq!(relative_rows[&4], 1);
|
||||
assert_eq!(relative_rows[&5], 2);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
Loading…
Reference in New Issue
Block a user