Files
oak-gpui/crates/editor/src/scroll/scroll_amount.rs
T
e9252a7a74 editor: Context menu aside scrolling (#35985)
Add support for scrolling the contents rendered aside an
`editor::code_context_menus::CodeContextMenu` by introducing the
`scroll_aside` method.

For now this method is only implemented for the
`CodeContextMenu::Completions` variant, which will scroll the aside
contents for an `editor::code_context_menus::CompletionsMenu` element,
as a `ScrollHandle` is added to the aside content that is rendered.

In order to be possible to trigger this via keybindings, a new editor
action is introduced, `ContextMenuScrollAside`, which accepts a number
of lines or pages to scroll the content by.

Lastly, the default keymaps for both MacOS and Linux, as well as for
Zed's vim mode, are updated to ensure that the following keybindings are
supported when a completion menu is open and the completion item's
documentation is rendered aside:

- `ctrl-e`
- `ctrl-y`
- `ctrl-d`
- `ctrl-u`

### Recording


https://github.com/user-attachments/assets/02043763-87ea-46f5-9768-00e907127b69

---

Closes #13194 

Release Notes:

- Added support for scrolling the documentation panel shown alongside
the completion menu in the editor with `cltr-d`, `ctrl-u`, `ctrl-e` and
`ctrl-y`

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: MrSubidubi <finn@zed.dev>
2025-08-29 20:23:44 +00:00

83 lines
2.8 KiB
Rust

use serde::Deserialize;
use ui::{Pixels, px};
#[derive(Debug)]
pub enum ScrollDirection {
Upwards,
Downwards,
Rightwards,
Leftwards,
}
impl ScrollDirection {
pub fn is_upwards(&self) -> bool {
matches!(self, ScrollDirection::Upwards)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
pub enum ScrollAmount {
// Scroll N lines (positive is towards the end of the document)
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),
// Scroll N page width (positive is towards the right of the document)
PageWidth(f32),
}
impl ScrollAmount {
pub fn lines(&self, mut visible_line_count: f32) -> f32 {
match self {
Self::Line(count) => *count,
Self::Page(count) => {
// for full pages subtract one to leave an anchor line
if self.is_full_page() {
visible_line_count -= 1.0
}
(visible_line_count * count).trunc()
}
Self::Column(_count) => 0.0,
Self::PageWidth(_count) => 0.0,
}
}
pub fn columns(&self, visible_column_count: f32) -> f32 {
match self {
Self::Line(_count) => 0.0,
Self::Page(_count) => 0.0,
Self::Column(count) => *count,
Self::PageWidth(count) => (visible_column_count * count).trunc(),
}
}
pub fn pixels(&self, line_height: Pixels, height: Pixels) -> Pixels {
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),
ScrollAmount::PageWidth(_) => px(0.0),
}
}
pub fn is_full_page(&self) -> bool {
matches!(self, ScrollAmount::Page(count) if count.abs() == 1.0)
}
pub fn direction(&self) -> ScrollDirection {
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,
}
}
}