Compare commits
9 Commits
main
...
feat/relat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbf860f90d | ||
|
|
51e9cf22e1 | ||
|
|
1095b709e2 | ||
|
|
0e933afa28 | ||
|
|
ffa83fd605 | ||
|
|
300bec9303 | ||
|
|
da7811ee89 | ||
|
|
ae263b78e2 | ||
|
|
38d4a7b7c0 |
@@ -593,6 +593,8 @@
|
||||
// happens when a user holds the alt or option key while scrolling.
|
||||
"fast_scroll_sensitivity": 4.0,
|
||||
"relative_line_numbers": false,
|
||||
// Whether to show relative line numbers for wrapped lines as well as buffer lines.
|
||||
"relative_line_numbers_for_wrapped_lines": false,
|
||||
// If 'search_wrap' is disabled, search result do not wrap around the end of the file.
|
||||
"search_wrap": true,
|
||||
// Search options to enable by default when opening new project and buffer searches.
|
||||
|
||||
@@ -1024,6 +1024,7 @@ impl Iterator for WrapRows<'_> {
|
||||
multibuffer_row: None,
|
||||
diff_status,
|
||||
expand_info: None,
|
||||
wrapped_buffer_row: buffer_row.buffer_row,
|
||||
}
|
||||
} else {
|
||||
buffer_row
|
||||
|
||||
@@ -34,6 +34,7 @@ pub struct EditorSettings {
|
||||
pub scroll_sensitivity: f32,
|
||||
pub fast_scroll_sensitivity: f32,
|
||||
pub relative_line_numbers: bool,
|
||||
pub relative_line_numbers_for_wrapped_lines: bool,
|
||||
pub seed_search_query_from_cursor: SeedQuerySetting,
|
||||
pub use_smartcase_search: bool,
|
||||
pub multi_cursor_modifier: MultiCursorModifier,
|
||||
@@ -234,6 +235,9 @@ impl Settings for EditorSettings {
|
||||
scroll_sensitivity: editor.scroll_sensitivity.unwrap(),
|
||||
fast_scroll_sensitivity: editor.fast_scroll_sensitivity.unwrap(),
|
||||
relative_line_numbers: editor.relative_line_numbers.unwrap(),
|
||||
relative_line_numbers_for_wrapped_lines: editor
|
||||
.relative_line_numbers_for_wrapped_lines
|
||||
.unwrap(),
|
||||
seed_search_query_from_cursor: editor.seed_search_query_from_cursor.unwrap(),
|
||||
use_smartcase_search: editor.use_smartcase_search.unwrap(),
|
||||
multi_cursor_modifier: editor.multi_cursor_modifier.unwrap(),
|
||||
|
||||
@@ -763,8 +763,14 @@ impl EditorElement {
|
||||
.row;
|
||||
if line_numbers
|
||||
.get(&MultiBufferRow(multi_buffer_row))
|
||||
.and_then(|line_number| line_number.hitbox.as_ref())
|
||||
.is_some_and(|hitbox| hitbox.contains(&event.position))
|
||||
.is_some_and(|line_layout| {
|
||||
line_layout.segments.iter().any(|segment| {
|
||||
segment
|
||||
.hitbox
|
||||
.as_ref()
|
||||
.is_some_and(|hitbox| hitbox.contains(&event.position))
|
||||
})
|
||||
})
|
||||
{
|
||||
let line_offset_from_top = display_row - position_map.scroll_position.y as u32;
|
||||
|
||||
@@ -3143,6 +3149,7 @@ impl EditorElement {
|
||||
snapshot: &EditorSnapshot,
|
||||
rows: &Range<DisplayRow>,
|
||||
relative_to: Option<DisplayRow>,
|
||||
use_display_offset: bool,
|
||||
) -> HashMap<DisplayRow, DisplayRowDelta> {
|
||||
let mut relative_rows: HashMap<DisplayRow, DisplayRowDelta> = Default::default();
|
||||
let Some(relative_to) = relative_to else {
|
||||
@@ -3152,6 +3159,7 @@ impl EditorElement {
|
||||
let start = rows.start.min(relative_to);
|
||||
let end = rows.end.max(relative_to);
|
||||
|
||||
// todo!() can we pass this in?
|
||||
let buffer_rows = snapshot
|
||||
.row_infos(start)
|
||||
.take(1 + end.minus(start) as usize)
|
||||
@@ -3160,8 +3168,15 @@ impl EditorElement {
|
||||
let head_idx = relative_to.minus(start);
|
||||
let mut delta = 1;
|
||||
let mut i = head_idx + 1;
|
||||
let should_count_line = |row_info: &RowInfo| {
|
||||
if use_display_offset {
|
||||
row_info.buffer_row.is_some() || row_info.wrapped_buffer_row.is_some()
|
||||
} else {
|
||||
row_info.buffer_row.is_some()
|
||||
}
|
||||
};
|
||||
while i < buffer_rows.len() as u32 {
|
||||
if buffer_rows[i as usize].buffer_row.is_some() {
|
||||
if should_count_line(&buffer_rows[i as usize]) {
|
||||
if rows.contains(&DisplayRow(i + start.0)) {
|
||||
relative_rows.insert(DisplayRow(i + start.0), delta);
|
||||
}
|
||||
@@ -3171,13 +3186,13 @@ impl EditorElement {
|
||||
}
|
||||
delta = 1;
|
||||
i = head_idx.min(buffer_rows.len() as u32 - 1);
|
||||
while i > 0 && buffer_rows[i as usize].buffer_row.is_none() {
|
||||
while i > 0 && buffer_rows[i as usize].buffer_row.is_none() && !use_display_offset {
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
while i > 0 {
|
||||
i -= 1;
|
||||
if buffer_rows[i as usize].buffer_row.is_some() {
|
||||
if should_count_line(&buffer_rows[i as usize]) {
|
||||
if rows.contains(&DisplayRow(i + start.0)) {
|
||||
relative_rows.insert(DisplayRow(i + start.0), delta);
|
||||
}
|
||||
@@ -3209,95 +3224,120 @@ impl EditorElement {
|
||||
return Arc::default();
|
||||
}
|
||||
|
||||
let (newest_selection_head, is_relative) = self.editor.update(cx, |editor, cx| {
|
||||
let newest_selection_head = newest_selection_head.unwrap_or_else(|| {
|
||||
let newest = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx));
|
||||
SelectionLayout::new(
|
||||
newest,
|
||||
editor.selections.line_mode(),
|
||||
editor.cursor_shape,
|
||||
&snapshot.display_snapshot,
|
||||
true,
|
||||
true,
|
||||
None,
|
||||
let (newest_selection_head, is_relative, use_relative_for_wrapped_lines) =
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
let newest_selection_head = newest_selection_head.unwrap_or_else(|| {
|
||||
let newest = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx));
|
||||
SelectionLayout::new(
|
||||
newest,
|
||||
editor.selections.line_mode(),
|
||||
editor.cursor_shape,
|
||||
&snapshot.display_snapshot,
|
||||
true,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.head
|
||||
});
|
||||
let is_relative = editor.should_use_relative_line_numbers(cx);
|
||||
let use_relative_for_wrapped_lines = is_relative
|
||||
&& EditorSettings::get_global(cx).relative_line_numbers_for_wrapped_lines;
|
||||
(
|
||||
newest_selection_head,
|
||||
is_relative,
|
||||
use_relative_for_wrapped_lines,
|
||||
)
|
||||
.head
|
||||
});
|
||||
let is_relative = editor.should_use_relative_line_numbers(cx);
|
||||
(newest_selection_head, is_relative)
|
||||
});
|
||||
|
||||
let relative_to = if is_relative {
|
||||
Some(newest_selection_head.row())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let relative_rows = self.calculate_relative_line_numbers(snapshot, &rows, relative_to);
|
||||
let relative_rows = self.calculate_relative_line_numbers(
|
||||
snapshot,
|
||||
&rows,
|
||||
relative_to,
|
||||
use_relative_for_wrapped_lines,
|
||||
);
|
||||
let mut line_number = String::new();
|
||||
let line_numbers = buffer_rows
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(ix, row_info)| {
|
||||
let display_row = DisplayRow(rows.start.0 + ix as u32);
|
||||
line_number.clear();
|
||||
let non_relative_number = row_info.buffer_row? + 1;
|
||||
let number = relative_rows
|
||||
.get(&display_row)
|
||||
.unwrap_or(&non_relative_number);
|
||||
write!(&mut line_number, "{number}").unwrap();
|
||||
if row_info
|
||||
.diff_status
|
||||
.is_some_and(|status| status.is_deleted())
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let segments = buffer_rows.iter().enumerate().flat_map(|(ix, row_info)| {
|
||||
let display_row = DisplayRow(rows.start.0 + ix as u32);
|
||||
line_number.clear();
|
||||
let non_relative_number = if use_relative_for_wrapped_lines {
|
||||
row_info.buffer_row.or(row_info.wrapped_buffer_row)? + 1
|
||||
} else {
|
||||
row_info.buffer_row? + 1
|
||||
};
|
||||
let number = relative_rows
|
||||
.get(&display_row)
|
||||
.unwrap_or(&non_relative_number);
|
||||
write!(&mut line_number, "{number}").unwrap();
|
||||
if row_info
|
||||
.diff_status
|
||||
.is_some_and(|status| status.is_deleted())
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let color = active_rows
|
||||
.get(&display_row)
|
||||
.map(|spec| {
|
||||
if spec.breakpoint {
|
||||
cx.theme().colors().debugger_accent
|
||||
} else {
|
||||
cx.theme().colors().editor_active_line_number
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| cx.theme().colors().editor_line_number);
|
||||
let shaped_line =
|
||||
self.shape_line_number(SharedString::from(&line_number), color, window);
|
||||
let scroll_top = scroll_position.y * ScrollPixelOffset::from(line_height);
|
||||
let line_origin = gutter_hitbox.map(|hitbox| {
|
||||
hitbox.origin
|
||||
+ point(
|
||||
hitbox.size.width - shaped_line.width - gutter_dimensions.right_padding,
|
||||
ix as f32 * line_height
|
||||
- Pixels::from(scroll_top % ScrollPixelOffset::from(line_height)),
|
||||
)
|
||||
});
|
||||
|
||||
#[cfg(not(test))]
|
||||
let hitbox = line_origin.map(|line_origin| {
|
||||
window.insert_hitbox(
|
||||
Bounds::new(line_origin, size(shaped_line.width, line_height)),
|
||||
HitboxBehavior::Normal,
|
||||
let color = active_rows
|
||||
.get(&display_row)
|
||||
.map(|spec| {
|
||||
if spec.breakpoint {
|
||||
cx.theme().colors().debugger_accent
|
||||
} else {
|
||||
cx.theme().colors().editor_active_line_number
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| cx.theme().colors().editor_line_number);
|
||||
let shaped_line =
|
||||
self.shape_line_number(SharedString::from(&line_number), color, window);
|
||||
let scroll_top = scroll_position.y * ScrollPixelOffset::from(line_height);
|
||||
let line_origin = gutter_hitbox.map(|hitbox| {
|
||||
hitbox.origin
|
||||
+ point(
|
||||
hitbox.size.width - shaped_line.width - gutter_dimensions.right_padding,
|
||||
ix as f32 * line_height
|
||||
- Pixels::from(scroll_top % ScrollPixelOffset::from(line_height)),
|
||||
)
|
||||
});
|
||||
#[cfg(test)]
|
||||
let hitbox = {
|
||||
let _ = line_origin;
|
||||
None
|
||||
};
|
||||
});
|
||||
|
||||
let multi_buffer_row = DisplayPoint::new(display_row, 0).to_point(snapshot).row;
|
||||
let multi_buffer_row = MultiBufferRow(multi_buffer_row);
|
||||
let line_number = LineNumberLayout {
|
||||
shaped_line,
|
||||
hitbox,
|
||||
};
|
||||
Some((multi_buffer_row, line_number))
|
||||
})
|
||||
.collect();
|
||||
#[cfg(not(test))]
|
||||
let hitbox = line_origin.map(|line_origin| {
|
||||
window.insert_hitbox(
|
||||
Bounds::new(line_origin, size(shaped_line.width, line_height)),
|
||||
HitboxBehavior::Normal,
|
||||
)
|
||||
});
|
||||
#[cfg(test)]
|
||||
let hitbox = {
|
||||
let _ = line_origin;
|
||||
None
|
||||
};
|
||||
|
||||
let segment = LineNumberSegment {
|
||||
shaped_line,
|
||||
hitbox,
|
||||
};
|
||||
|
||||
let buffer_row = DisplayPoint::new(display_row, 0).to_point(snapshot).row;
|
||||
let multi_buffer_row = MultiBufferRow(buffer_row);
|
||||
|
||||
Some((multi_buffer_row, segment))
|
||||
});
|
||||
|
||||
let mut line_numbers: HashMap<MultiBufferRow, LineNumberLayout> = HashMap::default();
|
||||
for (buffer_row, segment) in segments {
|
||||
line_numbers
|
||||
.entry(buffer_row)
|
||||
.or_insert_with(|| LineNumberLayout {
|
||||
segments: Default::default(),
|
||||
})
|
||||
.segments
|
||||
.push(segment);
|
||||
}
|
||||
Arc::new(line_numbers)
|
||||
}
|
||||
|
||||
@@ -5846,34 +5886,36 @@ impl EditorElement {
|
||||
let line_height = layout.position_map.line_height;
|
||||
window.set_cursor_style(CursorStyle::Arrow, &layout.gutter_hitbox);
|
||||
|
||||
for LineNumberLayout {
|
||||
shaped_line,
|
||||
hitbox,
|
||||
} in layout.line_numbers.values()
|
||||
{
|
||||
let Some(hitbox) = hitbox else {
|
||||
continue;
|
||||
};
|
||||
for line_layout in layout.line_numbers.values() {
|
||||
for LineNumberSegment {
|
||||
shaped_line,
|
||||
hitbox,
|
||||
} in &line_layout.segments
|
||||
{
|
||||
let Some(hitbox) = hitbox else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(()) = (if !is_singleton && hitbox.is_hovered(window) {
|
||||
let color = cx.theme().colors().editor_hover_line_number;
|
||||
let Some(()) = (if !is_singleton && hitbox.is_hovered(window) {
|
||||
let color = cx.theme().colors().editor_hover_line_number;
|
||||
|
||||
let line = self.shape_line_number(shaped_line.text.clone(), color, window);
|
||||
line.paint(hitbox.origin, line_height, window, cx).log_err()
|
||||
} else {
|
||||
shaped_line
|
||||
.paint(hitbox.origin, line_height, window, cx)
|
||||
.log_err()
|
||||
}) else {
|
||||
continue;
|
||||
};
|
||||
let line = self.shape_line_number(shaped_line.text.clone(), color, window);
|
||||
line.paint(hitbox.origin, line_height, window, cx).log_err()
|
||||
} else {
|
||||
shaped_line
|
||||
.paint(hitbox.origin, line_height, window, cx)
|
||||
.log_err()
|
||||
}) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// In singleton buffers, we select corresponding lines on the line number click, so use | -like cursor.
|
||||
// In multi buffers, we open file at the line number clicked, so use a pointing hand cursor.
|
||||
if is_singleton {
|
||||
window.set_cursor_style(CursorStyle::IBeam, hitbox);
|
||||
} else {
|
||||
window.set_cursor_style(CursorStyle::PointingHand, hitbox);
|
||||
// In singleton buffers, we select corresponding lines on the line number click, so use | -like cursor.
|
||||
// In multi buffers, we open file at the line number clicked, so use a pointing hand cursor.
|
||||
if is_singleton {
|
||||
window.set_cursor_style(CursorStyle::IBeam, hitbox);
|
||||
} else {
|
||||
window.set_cursor_style(CursorStyle::PointingHand, hitbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9783,11 +9825,17 @@ impl EditorLayout {
|
||||
}
|
||||
}
|
||||
|
||||
struct LineNumberLayout {
|
||||
#[derive(Debug)]
|
||||
struct LineNumberSegment {
|
||||
shaped_line: ShapedLine,
|
||||
hitbox: Option<Hitbox>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct LineNumberLayout {
|
||||
segments: SmallVec<[LineNumberSegment; 1]>,
|
||||
}
|
||||
|
||||
struct ColoredRange<T> {
|
||||
start: T,
|
||||
end: T,
|
||||
@@ -10851,6 +10899,7 @@ mod tests {
|
||||
&snapshot,
|
||||
&(DisplayRow(0)..DisplayRow(6)),
|
||||
Some(DisplayRow(3)),
|
||||
false,
|
||||
)
|
||||
})
|
||||
.unwrap();
|
||||
@@ -10869,6 +10918,7 @@ mod tests {
|
||||
&snapshot,
|
||||
&(DisplayRow(3)..DisplayRow(6)),
|
||||
Some(DisplayRow(1)),
|
||||
false,
|
||||
)
|
||||
})
|
||||
.unwrap();
|
||||
@@ -10885,6 +10935,7 @@ mod tests {
|
||||
&snapshot,
|
||||
&(DisplayRow(0)..DisplayRow(3)),
|
||||
Some(DisplayRow(6)),
|
||||
false,
|
||||
)
|
||||
})
|
||||
.unwrap();
|
||||
@@ -10894,6 +10945,81 @@ mod tests {
|
||||
assert_eq!(relative_rows[&DisplayRow(2)], 3);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_shape_line_numbers_wrapping(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
let window = cx.add_window(|window, cx| {
|
||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
||||
Editor::new(EditorMode::full(), buffer, None, window, cx)
|
||||
});
|
||||
|
||||
update_test_language_settings(cx, |s| {
|
||||
s.defaults.preferred_line_length = Some(5 as u32);
|
||||
s.defaults.soft_wrap = Some(language_settings::SoftWrap::PreferredLineLength);
|
||||
});
|
||||
|
||||
let editor = window.root(cx).unwrap();
|
||||
let style = cx.update(|cx| editor.read(cx).style().unwrap().clone());
|
||||
let line_height = window
|
||||
.update(cx, |_, window, _| {
|
||||
style.text.line_height_in_pixels(window.rem_size())
|
||||
})
|
||||
.unwrap();
|
||||
let element = EditorElement::new(&editor, style);
|
||||
let snapshot = window
|
||||
.update(cx, |editor, window, cx| editor.snapshot(window, cx))
|
||||
.unwrap();
|
||||
|
||||
let layouts = cx
|
||||
.update_window(*window, |_, window, cx| {
|
||||
element.layout_line_numbers(
|
||||
None,
|
||||
GutterDimensions {
|
||||
left_padding: Pixels::ZERO,
|
||||
right_padding: Pixels::ZERO,
|
||||
width: px(30.0),
|
||||
margin: Pixels::ZERO,
|
||||
git_blame_entries_width: None,
|
||||
},
|
||||
line_height,
|
||||
gpui::Point::default(),
|
||||
DisplayRow(0)..DisplayRow(6),
|
||||
&(0..6)
|
||||
.map(|row| RowInfo {
|
||||
buffer_row: Some(row),
|
||||
..Default::default()
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
&BTreeMap::default(),
|
||||
Some(DisplayPoint::new(DisplayRow(0), 0)),
|
||||
&snapshot,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(layouts.len(), 3);
|
||||
|
||||
let relative_rows = window
|
||||
.update(cx, |editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
element.calculate_relative_line_numbers(
|
||||
&snapshot,
|
||||
&(DisplayRow(0)..DisplayRow(6)),
|
||||
Some(DisplayRow(3)),
|
||||
true,
|
||||
)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(relative_rows[&DisplayRow(0)], 3);
|
||||
assert_eq!(relative_rows[&DisplayRow(1)], 2);
|
||||
assert_eq!(relative_rows[&DisplayRow(2)], 1);
|
||||
// current line has no relative number
|
||||
assert_eq!(relative_rows[&DisplayRow(4)], 1);
|
||||
assert_eq!(relative_rows[&DisplayRow(5)], 2);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_vim_visual_selections(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -11007,7 +11133,13 @@ mod tests {
|
||||
state
|
||||
.line_numbers
|
||||
.get(&MultiBufferRow(0))
|
||||
.map(|line_number| line_number.shaped_line.text.as_ref()),
|
||||
.map(|line_number| line_number
|
||||
.segments
|
||||
.first()
|
||||
.unwrap()
|
||||
.shaped_line
|
||||
.text
|
||||
.as_ref()),
|
||||
Some("1")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -395,6 +395,7 @@ pub struct RowInfo {
|
||||
pub multibuffer_row: Option<MultiBufferRow>,
|
||||
pub diff_status: Option<buffer_diff::DiffHunkStatus>,
|
||||
pub expand_info: Option<ExpandInfo>,
|
||||
pub wrapped_buffer_row: Option<u32>,
|
||||
}
|
||||
|
||||
/// A slice into a [`Buffer`] that is being edited in a [`MultiBuffer`].
|
||||
@@ -7497,6 +7498,7 @@ impl Iterator for MultiBufferRows<'_> {
|
||||
multibuffer_row: Some(MultiBufferRow(0)),
|
||||
diff_status: None,
|
||||
expand_info: None,
|
||||
wrapped_buffer_row: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7554,6 +7556,7 @@ impl Iterator for MultiBufferRows<'_> {
|
||||
buffer_row: Some(last_row),
|
||||
multibuffer_row: Some(multibuffer_row),
|
||||
diff_status: None,
|
||||
wrapped_buffer_row: None,
|
||||
expand_info,
|
||||
});
|
||||
} else {
|
||||
@@ -7598,6 +7601,7 @@ impl Iterator for MultiBufferRows<'_> {
|
||||
.diff_hunk_status
|
||||
.filter(|_| self.point < region.range.end),
|
||||
expand_info,
|
||||
wrapped_buffer_row: None,
|
||||
});
|
||||
self.point += Point::new(1, 0);
|
||||
result
|
||||
|
||||
@@ -31,6 +31,7 @@ fn test_empty_singleton(cx: &mut App) {
|
||||
multibuffer_row: Some(MultiBufferRow(0)),
|
||||
diff_status: None,
|
||||
expand_info: None,
|
||||
wrapped_buffer_row: None,
|
||||
}]
|
||||
);
|
||||
}
|
||||
@@ -2431,6 +2432,8 @@ impl ReferenceMultibuffer {
|
||||
buffer_id: region.buffer_id,
|
||||
diff_status: region.status,
|
||||
buffer_row,
|
||||
wrapped_buffer_row: None,
|
||||
|
||||
multibuffer_row: Some(MultiBufferRow(
|
||||
text[..ix].matches('\n').count() as u32
|
||||
)),
|
||||
|
||||
@@ -94,6 +94,10 @@ pub struct EditorSettingsContent {
|
||||
///
|
||||
/// Default: false
|
||||
pub relative_line_numbers: Option<bool>,
|
||||
/// Whether to show relative line numbers for wrapped lines (visual lines) rather than just buffer lines.
|
||||
///
|
||||
/// Default: false
|
||||
pub relative_line_numbers_for_wrapped_lines: Option<bool>,
|
||||
/// When to populate a new search's query based on the text under the cursor.
|
||||
///
|
||||
/// Default: always
|
||||
|
||||
@@ -278,6 +278,7 @@ impl VsCodeSettings {
|
||||
"relative" => Some(true),
|
||||
_ => None,
|
||||
}),
|
||||
relative_line_numbers_for_wrapped_lines: None,
|
||||
rounded_selection: self.read_bool("editor.roundedSelection"),
|
||||
scroll_beyond_last_line: None,
|
||||
scroll_sensitivity: self.read_f32("editor.mouseWheelScrollSensitivity"),
|
||||
|
||||
Reference in New Issue
Block a user