vim: Add scroll keybindings for the OutlinePanel (#42438)
Closes #ISSUE
```json
{
"context": "OutlinePanel && not_editing",
"bindings": {
"enter": "editor::ToggleFocus",
"/": "menu::Cancel",
"ctrl-u": "outline_panel::ScrollUp",
"ctrl-d": "outline_panel::ScrollDown",
"z t": "outline_panel::ScrollCursorTop",
"z z": "outline_panel::ScrollCursorCenter",
"z b": "outline_panel::ScrollCursorBottom"
}
},
{
"context": "OutlinePanel && editing",
"bindings": {
"enter": "menu::Cancel"
}
},
```
Release Notes:
- Added scroll keybindings for the OutlinePanel
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
This commit is contained in:
1 parent
3ae473f072
commit
1b93e20e8b
5 files changed
+115
-2
No files matched your search
Generated
+1
@@ -18138,6 +18138,7 @@ dependencies = [
|
||||
"menu",
|
||||
"multi_buffer",
|
||||
"nvim-rs",
|
||||
"outline_panel",
|
||||
"parking_lot",
|
||||
"perf",
|
||||
"picker",
|
||||
|
||||
+30
-2
@@ -970,10 +970,38 @@
|
||||
{
|
||||
"context": "OutlinePanel && not_editing",
|
||||
"bindings": {
|
||||
"j": "menu::SelectNext",
|
||||
"k": "menu::SelectPrevious",
|
||||
"h": "outline_panel::CollapseSelectedEntry",
|
||||
"j": "vim::MenuSelectNext",
|
||||
"k": "vim::MenuSelectPrevious",
|
||||
"down": "vim::MenuSelectNext",
|
||||
"up": "vim::MenuSelectPrevious",
|
||||
"l": "outline_panel::ExpandSelectedEntry",
|
||||
"shift-g": "menu::SelectLast",
|
||||
"g g": "menu::SelectFirst",
|
||||
"-": "outline_panel::SelectParent",
|
||||
"enter": "editor::ToggleFocus",
|
||||
"/": "menu::Cancel",
|
||||
"ctrl-u": "outline_panel::ScrollUp",
|
||||
"ctrl-d": "outline_panel::ScrollDown",
|
||||
"z t": "outline_panel::ScrollCursorTop",
|
||||
"z z": "outline_panel::ScrollCursorCenter",
|
||||
"z b": "outline_panel::ScrollCursorBottom",
|
||||
"0": ["vim::Number", 0],
|
||||
"1": ["vim::Number", 1],
|
||||
"2": ["vim::Number", 2],
|
||||
"3": ["vim::Number", 3],
|
||||
"4": ["vim::Number", 4],
|
||||
"5": ["vim::Number", 5],
|
||||
"6": ["vim::Number", 6],
|
||||
"7": ["vim::Number", 7],
|
||||
"8": ["vim::Number", 8],
|
||||
"9": ["vim::Number", 9],
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "OutlinePanel && editing",
|
||||
"bindings": {
|
||||
"enter": "menu::Cancel",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -75,6 +75,16 @@ actions!(
|
||||
OpenSelectedEntry,
|
||||
/// Reveals the selected item in the system file manager.
|
||||
RevealInFileManager,
|
||||
/// Scroll half a page upwards
|
||||
ScrollUp,
|
||||
/// Scroll half a page downwards
|
||||
ScrollDown,
|
||||
/// Scroll until the cursor displays at the center
|
||||
ScrollCursorCenter,
|
||||
/// Scroll until the cursor displays at the top
|
||||
ScrollCursorTop,
|
||||
/// Scroll until the cursor displays at the bottom
|
||||
ScrollCursorBottom,
|
||||
/// Selects the parent of the current entry.
|
||||
SelectParent,
|
||||
/// Toggles the pin status of the active editor.
|
||||
@@ -100,6 +110,7 @@ pub struct OutlinePanel {
|
||||
active: bool,
|
||||
pinned: bool,
|
||||
scroll_handle: UniformListScrollHandle,
|
||||
rendered_entries_len: usize,
|
||||
context_menu: Option<(Entity<ContextMenu>, Point<Pixels>, Subscription)>,
|
||||
focus_handle: FocusHandle,
|
||||
pending_serialization: Task<Option<()>>,
|
||||
@@ -839,6 +850,7 @@ impl OutlinePanel {
|
||||
fs: workspace.app_state().fs.clone(),
|
||||
max_width_item_index: None,
|
||||
scroll_handle,
|
||||
rendered_entries_len: 0,
|
||||
focus_handle,
|
||||
filter_editor,
|
||||
fs_entries: Vec::new(),
|
||||
@@ -1149,6 +1161,70 @@ impl OutlinePanel {
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_up(&mut self, _: &ScrollUp, window: &mut Window, cx: &mut Context<Self>) {
|
||||
for _ in 0..self.rendered_entries_len / 2 {
|
||||
window.dispatch_action(SelectPrevious.boxed_clone(), cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_down(&mut self, _: &ScrollDown, window: &mut Window, cx: &mut Context<Self>) {
|
||||
for _ in 0..self.rendered_entries_len / 2 {
|
||||
window.dispatch_action(SelectNext.boxed_clone(), cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_cursor_center(
|
||||
&mut self,
|
||||
_: &ScrollCursorCenter,
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some(selected_entry) = self.selected_entry() {
|
||||
let index = self
|
||||
.cached_entries
|
||||
.iter()
|
||||
.position(|cached_entry| &cached_entry.entry == selected_entry);
|
||||
if let Some(index) = index {
|
||||
self.scroll_handle
|
||||
.scroll_to_item_strict(index, ScrollStrategy::Center);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_cursor_top(&mut self, _: &ScrollCursorTop, _: &mut Window, cx: &mut Context<Self>) {
|
||||
if let Some(selected_entry) = self.selected_entry() {
|
||||
let index = self
|
||||
.cached_entries
|
||||
.iter()
|
||||
.position(|cached_entry| &cached_entry.entry == selected_entry);
|
||||
if let Some(index) = index {
|
||||
self.scroll_handle
|
||||
.scroll_to_item_strict(index, ScrollStrategy::Top);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_cursor_bottom(
|
||||
&mut self,
|
||||
_: &ScrollCursorBottom,
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some(selected_entry) = self.selected_entry() {
|
||||
let index = self
|
||||
.cached_entries
|
||||
.iter()
|
||||
.position(|cached_entry| &cached_entry.entry == selected_entry);
|
||||
if let Some(index) = index {
|
||||
self.scroll_handle
|
||||
.scroll_to_item_strict(index, ScrollStrategy::Bottom);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn select_next(&mut self, _: &SelectNext, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if let Some(entry_to_select) = self.selected_entry().and_then(|selected_entry| {
|
||||
self.cached_entries
|
||||
@@ -4578,6 +4654,7 @@ impl OutlinePanel {
|
||||
"entries",
|
||||
items_len,
|
||||
cx.processor(move |outline_panel, range: Range<usize>, window, cx| {
|
||||
outline_panel.rendered_entries_len = range.end - range.start;
|
||||
let entries = outline_panel.cached_entries.get(range);
|
||||
entries
|
||||
.map(|entries| entries.to_vec())
|
||||
@@ -4970,7 +5047,12 @@ impl Render for OutlinePanel {
|
||||
.key_context(self.dispatch_context(window, cx))
|
||||
.on_action(cx.listener(Self::open_selected_entry))
|
||||
.on_action(cx.listener(Self::cancel))
|
||||
.on_action(cx.listener(Self::scroll_up))
|
||||
.on_action(cx.listener(Self::scroll_down))
|
||||
.on_action(cx.listener(Self::select_next))
|
||||
.on_action(cx.listener(Self::scroll_cursor_center))
|
||||
.on_action(cx.listener(Self::scroll_cursor_top))
|
||||
.on_action(cx.listener(Self::scroll_cursor_bottom))
|
||||
.on_action(cx.listener(Self::select_previous))
|
||||
.on_action(cx.listener(Self::select_first))
|
||||
.on_action(cx.listener(Self::select_last))
|
||||
|
||||
@@ -66,6 +66,7 @@ lsp = { workspace = true, features = ["test-support"] }
|
||||
markdown_preview.workspace = true
|
||||
parking_lot.workspace = true
|
||||
project_panel.workspace = true
|
||||
outline_panel.workspace = true
|
||||
release_channel.workspace = true
|
||||
semver.workspace = true
|
||||
settings_ui.workspace = true
|
||||
|
||||
@@ -23,6 +23,7 @@ impl VimTestContext {
|
||||
release_channel::init(Version::new(0, 0, 0), cx);
|
||||
command_palette::init(cx);
|
||||
project_panel::init(cx);
|
||||
outline_panel::init(cx);
|
||||
git_ui::init(cx);
|
||||
crate::init(cx);
|
||||
search::init(cx);
|
||||
|
||||
Reference in new issue
Block a user