Detailed changes
@@ -184,6 +184,8 @@
"z f": "editor::FoldSelectedRanges",
"z shift-m": "editor::FoldAll",
"z shift-r": "editor::UnfoldAll",
+ "z l": "vim::ColumnRight",
+ "z h": "vim::ColumnLeft",
"shift-z shift-q": ["pane::CloseActiveItem", { "save_intent": "skip" }],
"shift-z shift-z": ["pane::CloseActiveItem", { "save_intent": "save_all" }],
// Count support
@@ -7739,8 +7739,7 @@ impl Element for EditorElement {
let line_height = style.text.line_height_in_pixels(window.rem_size());
let em_width = window.text_system().em_width(font_id, font_size).unwrap();
let em_advance = window.text_system().em_advance(font_id, font_size).unwrap();
-
- let glyph_grid_cell = size(em_width, line_height);
+ let glyph_grid_cell = size(em_advance, line_height);
let gutter_dimensions = snapshot
.gutter_dimensions(
@@ -8299,7 +8298,7 @@ impl Element for EditorElement {
MultiBufferRow(end_anchor.to_point(&snapshot.buffer_snapshot).row);
let scroll_max = point(
- ((scroll_width - editor_content_width) / em_width).max(0.0),
+ ((scroll_width - editor_content_width) / em_advance).max(0.0),
max_scroll_top,
);
@@ -8311,7 +8310,7 @@ impl Element for EditorElement {
start_row,
editor_content_width,
scroll_width,
- em_width,
+ em_advance,
&line_layouts,
cx,
)
@@ -8326,10 +8325,9 @@ impl Element for EditorElement {
});
let scroll_pixel_position = point(
- scroll_position.x * em_width,
+ scroll_position.x * em_advance,
scroll_position.y * line_height,
);
-
let indent_guides = self.layout_indent_guides(
content_origin,
text_hitbox.origin,
@@ -9454,7 +9452,7 @@ impl PositionMap {
let scroll_position = self.snapshot.scroll_position();
let position = position - text_bounds.origin;
let y = position.y.max(px(0.)).min(self.size.height);
- let x = position.x + (scroll_position.x * self.em_width);
+ let x = position.x + (scroll_position.x * self.em_advance);
let row = ((y / self.line_height) + scroll_position.y) as u32;
let (column, x_overshoot_after_line_end) = if let Some(line) = self
@@ -669,12 +669,23 @@ impl Editor {
return;
}
- let cur_position = self.scroll_position(cx);
+ let mut current_position = self.scroll_position(cx);
let Some(visible_line_count) = self.visible_line_count() else {
return;
};
- let new_pos = cur_position + point(0., amount.lines(visible_line_count));
- self.set_scroll_position(new_pos, window, cx);
+
+ // If the scroll position is currently at the left edge of the document
+ // (x == 0.0) and the intent is to scroll right, the gutter's margin
+ // should first be added to the current position, otherwise the cursor
+ // will end at the column position minus the margin, which looks off.
+ if current_position.x == 0.0 && amount.columns() > 0. {
+ if let Some(last_position_map) = &self.last_position_map {
+ current_position.x += self.gutter_dimensions.margin / last_position_map.em_advance;
+ }
+ }
+ let new_position =
+ current_position + point(amount.columns(), amount.lines(visible_line_count));
+ self.set_scroll_position(new_position, window, cx);
}
/// Returns an ordering. The newest selection is:
@@ -5,6 +5,8 @@ use ui::{Pixels, px};
pub enum ScrollDirection {
Upwards,
Downwards,
+ Rightwards,
+ Leftwards,
}
impl ScrollDirection {
@@ -19,6 +21,8 @@ pub enum ScrollAmount {
Line(f32),
// Scroll N pages (positive is towards the end of the document)
Page(f32),
+ // Scroll N columns (positive is towards the right of the document)
+ Column(f32),
}
impl ScrollAmount {
@@ -32,6 +36,15 @@ impl ScrollAmount {
}
(visible_line_count * count).trunc()
}
+ Self::Column(_count) => 0.0,
+ }
+ }
+
+ pub fn columns(&self) -> f32 {
+ match self {
+ Self::Line(_count) => 0.0,
+ Self::Page(_count) => 0.0,
+ Self::Column(count) => *count,
}
}
@@ -39,6 +52,12 @@ impl ScrollAmount {
match self {
ScrollAmount::Line(x) => px(line_height.0 * x),
ScrollAmount::Page(x) => px(height.0 * x),
+ // This function seems to only be leveraged by the popover that is
+ // displayed by the editor when, for example, viewing a function's
+ // documentation. Right now that only supports vertical scrolling,
+ // so I'm leaving this at 0.0 for now to try and make it clear that
+ // this should not have an impact on that?
+ ScrollAmount::Column(_) => px(0.0),
}
}
@@ -53,6 +72,8 @@ impl ScrollAmount {
match self {
Self::Line(amount) if amount.is_sign_positive() => ScrollDirection::Downwards,
Self::Page(amount) if amount.is_sign_positive() => ScrollDirection::Downwards,
+ Self::Column(amount) if amount.is_sign_positive() => ScrollDirection::Rightwards,
+ Self::Column(amount) if amount.is_sign_negative() => ScrollDirection::Leftwards,
_ => ScrollDirection::Upwards,
}
}
@@ -10,7 +10,16 @@ use settings::Settings;
actions!(
vim,
- [LineUp, LineDown, ScrollUp, ScrollDown, PageUp, PageDown]
+ [
+ LineUp,
+ LineDown,
+ ColumnRight,
+ ColumnLeft,
+ ScrollUp,
+ ScrollDown,
+ PageUp,
+ PageDown
+ ]
);
pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
@@ -20,6 +29,14 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
Vim::action(editor, cx, |vim, _: &LineUp, window, cx| {
vim.scroll(false, window, cx, |c| ScrollAmount::Line(-c.unwrap_or(1.)))
});
+ Vim::action(editor, cx, |vim, _: &ColumnRight, window, cx| {
+ vim.scroll(false, window, cx, |c| ScrollAmount::Column(c.unwrap_or(1.)))
+ });
+ Vim::action(editor, cx, |vim, _: &ColumnLeft, window, cx| {
+ vim.scroll(false, window, cx, |c| {
+ ScrollAmount::Column(-c.unwrap_or(1.))
+ })
+ });
Vim::action(editor, cx, |vim, _: &PageDown, window, cx| {
vim.scroll(false, window, cx, |c| ScrollAmount::Page(c.unwrap_or(1.)))
});