Add keybindings to jump to first / last file in project panel (#11073)

Release Notes:
- vim: Support `g g`/`G` to go to top/bottom of the project panel.

In vim type environments i usually expect to be able to jump to the top
and bottom and i was confused as to why that wasn't possible in the
project panel. So i added it. If anyone using different keymaps also
thinks this might be useful i would be happy to add other defaults. I
think for vim mode it is the most useful though, because you tend to not
use your mouse in vim mode.

This is my first contribution to any rust project, but it seemed like a
good starting point.
The function select_last() is inspired by select_first.
I was also thinking about adding a bigger jump keybinding, that would
jump for example 5 entries up / down, with vim default keybindings "{" /
"}".
FYI: I tested this on linux only and don't have access to any macos
machines.


- N/A
This commit is contained in:
blufony 2024-04-27 00:35:57 +02:00 committed by GitHub
parent 393b16d226
commit adcaa211ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 28 additions and 5 deletions

View file

@ -625,7 +625,9 @@
"t": "project_panel::OpenPermanent",
"v": "project_panel::OpenPermanent",
"p": "project_panel::Open",
"x": "project_panel::RevealInFinder"
"x": "project_panel::RevealInFinder",
"shift-g": "menu::SelectLast",
"g g": "menu::SelectFirst"
}
}
]

View file

@ -16,7 +16,7 @@ use gpui::{
ParentElement, Pixels, Point, PromptLevel, Render, Stateful, Styled, Subscription, Task,
UniformListScrollHandle, View, ViewContext, VisualContext as _, WeakView, WindowContext,
};
use menu::{Confirm, SelectNext, SelectPrev};
use menu::{Confirm, SelectFirst, SelectLast, SelectNext, SelectPrev};
use project::{Entry, EntryKind, Fs, Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId};
use project_panel_settings::{ProjectPanelDockPosition, ProjectPanelSettings};
use serde::{Deserialize, Serialize};
@ -644,7 +644,7 @@ impl ProjectPanel {
self.autoscroll(cx);
cx.notify();
} else {
self.select_first(cx);
self.select_first(&SelectFirst {}, cx);
}
}
@ -989,11 +989,11 @@ impl ProjectPanel {
}
}
} else {
self.select_first(cx);
self.select_first(&SelectFirst {}, cx);
}
}
fn select_first(&mut self, cx: &mut ViewContext<Self>) {
fn select_first(&mut self, _: &SelectFirst, cx: &mut ViewContext<Self>) {
let worktree = self
.visible_entries
.first()
@ -1012,6 +1012,25 @@ impl ProjectPanel {
}
}
fn select_last(&mut self, _: &SelectLast, cx: &mut ViewContext<Self>) {
let worktree = self
.visible_entries
.last()
.and_then(|(worktree_id, _)| self.project.read(cx).worktree_for_id(*worktree_id, cx));
if let Some(worktree) = worktree {
let worktree = worktree.read(cx);
let worktree_id = worktree.id();
if let Some(last_entry) = worktree.entries(true).last() {
self.selection = Some(Selection {
worktree_id,
entry_id: last_entry.id,
});
self.autoscroll(cx);
cx.notify();
}
}
}
fn autoscroll(&mut self, cx: &mut ViewContext<Self>) {
if let Some((_, _, index)) = self.selection.and_then(|s| self.index_for_selection(s)) {
self.scroll_handle.scroll_to_item(index);
@ -1751,6 +1770,8 @@ impl Render for ProjectPanel {
.key_context(self.dispatch_context(cx))
.on_action(cx.listener(Self::select_next))
.on_action(cx.listener(Self::select_prev))
.on_action(cx.listener(Self::select_first))
.on_action(cx.listener(Self::select_last))
.on_action(cx.listener(Self::expand_selected_entry))
.on_action(cx.listener(Self::collapse_selected_entry))
.on_action(cx.listener(Self::collapse_all_entries))