project_panel: Add action to open file in split pane (#36973)
Closes #18605 Related: - https://github.com/zed-industries/zed/discussions/16901 - https://github.com/zed-industries/zed/issues/10549 Adds an action to open file in split pane. Also updates vim keybindings for better compatibility with netrw: [“v”](https://github.com/vim/vim/blob/bc461f952d854ffbde83eb74044efc3b329ea10e/runtime/pack/dist/opt/netrw/doc/netrw.txt#L1091) and [“o”](https://github.com/vim/vim/blob/bc461f952d854ffbde83eb74044efc3b329ea10e/runtime/pack/dist/opt/netrw/doc/netrw.txt#L1075) keys should open file in splits. <table> <tr> <td><video src="https://github.com/user-attachments/assets/e24c6fd4-4eb0-407a-bdd1-5300908ea2a1"> <td><video src="https://github.com/user-attachments/assets/fa0b8105-41a9-4421-a3cc-89244a90d67a"> </table> Release Notes: - Added `project_panel::OpenSplitVertical` and `project_panel::OpenSplitHorizontal` actions for opening file in a splits.
This commit is contained in:
@@ -860,11 +860,11 @@
|
||||
"j": "menu::SelectNext",
|
||||
"k": "menu::SelectPrevious",
|
||||
"l": "project_panel::ExpandSelectedEntry",
|
||||
"o": "project_panel::OpenPermanent",
|
||||
"shift-d": "project_panel::Delete",
|
||||
"shift-r": "project_panel::Rename",
|
||||
"t": "project_panel::OpenPermanent",
|
||||
"v": "project_panel::OpenPermanent",
|
||||
"v": "project_panel::OpenSplitVertical",
|
||||
"o": "project_panel::OpenSplitHorizontal",
|
||||
"p": "project_panel::Open",
|
||||
"x": "project_panel::RevealInFileManager",
|
||||
"s": "workspace::OpenWithSystem",
|
||||
|
||||
@@ -64,7 +64,7 @@ use ui::{
|
||||
use util::{ResultExt, TakeUntilExt, TryFutureExt, maybe, paths::compare_paths};
|
||||
use workspace::{
|
||||
DraggedSelection, OpenInTerminal, OpenOptions, OpenVisible, PreviewTabsSettings, SelectedEntry,
|
||||
Workspace,
|
||||
SplitDirection, Workspace,
|
||||
dock::{DockPosition, Panel, PanelEvent},
|
||||
notifications::{DetachAndPromptErr, NotifyTaskExt},
|
||||
};
|
||||
@@ -266,6 +266,10 @@ actions!(
|
||||
Open,
|
||||
/// Opens the selected file in a permanent tab.
|
||||
OpenPermanent,
|
||||
/// Opens the selected file in a vertical split.
|
||||
OpenSplitVertical,
|
||||
/// Opens the selected file in a horizontal split.
|
||||
OpenSplitHorizontal,
|
||||
/// Toggles focus on the project panel.
|
||||
ToggleFocus,
|
||||
/// Toggles visibility of git-ignored files.
|
||||
@@ -371,6 +375,8 @@ pub enum Event {
|
||||
},
|
||||
SplitEntry {
|
||||
entry_id: ProjectEntryId,
|
||||
allow_preview: bool,
|
||||
split_direction: Option<SplitDirection>,
|
||||
},
|
||||
Focus,
|
||||
}
|
||||
@@ -700,15 +706,21 @@ impl ProjectPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
&Event::SplitEntry { entry_id } => {
|
||||
&Event::SplitEntry {
|
||||
entry_id,
|
||||
allow_preview,
|
||||
split_direction,
|
||||
} => {
|
||||
if let Some(worktree) = project.read(cx).worktree_for_entry(entry_id, cx)
|
||||
&& let Some(entry) = worktree.read(cx).entry_for_id(entry_id) {
|
||||
workspace
|
||||
.split_path(
|
||||
.split_path_preview(
|
||||
ProjectPath {
|
||||
worktree_id: worktree.read(cx).id(),
|
||||
path: entry.path.clone(),
|
||||
},
|
||||
allow_preview,
|
||||
split_direction,
|
||||
window, cx,
|
||||
)
|
||||
.detach_and_log_err(cx);
|
||||
@@ -1300,23 +1312,52 @@ impl ProjectPanel {
|
||||
|
||||
fn open(&mut self, _: &Open, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let preview_tabs_enabled = PreviewTabsSettings::get_global(cx).enabled;
|
||||
self.open_internal(true, !preview_tabs_enabled, window, cx);
|
||||
self.open_internal(true, !preview_tabs_enabled, None, window, cx);
|
||||
}
|
||||
|
||||
fn open_permanent(&mut self, _: &OpenPermanent, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.open_internal(false, true, window, cx);
|
||||
self.open_internal(false, true, None, window, cx);
|
||||
}
|
||||
|
||||
fn open_split_vertical(
|
||||
&mut self,
|
||||
_: &OpenSplitVertical,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.open_internal(false, true, Some(SplitDirection::vertical(cx)), window, cx);
|
||||
}
|
||||
|
||||
fn open_split_horizontal(
|
||||
&mut self,
|
||||
_: &OpenSplitHorizontal,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.open_internal(
|
||||
false,
|
||||
true,
|
||||
Some(SplitDirection::horizontal(cx)),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
fn open_internal(
|
||||
&mut self,
|
||||
allow_preview: bool,
|
||||
focus_opened_item: bool,
|
||||
split_direction: Option<SplitDirection>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some((_, entry)) = self.selected_entry(cx) {
|
||||
if entry.is_file() {
|
||||
self.open_entry(entry.id, focus_opened_item, allow_preview, cx);
|
||||
if split_direction.is_some() {
|
||||
self.split_entry(entry.id, allow_preview, split_direction, cx);
|
||||
} else {
|
||||
self.open_entry(entry.id, focus_opened_item, allow_preview, cx);
|
||||
}
|
||||
cx.notify();
|
||||
} else {
|
||||
self.toggle_expanded(entry.id, window, cx);
|
||||
@@ -1554,8 +1595,19 @@ impl ProjectPanel {
|
||||
});
|
||||
}
|
||||
|
||||
fn split_entry(&mut self, entry_id: ProjectEntryId, cx: &mut Context<Self>) {
|
||||
cx.emit(Event::SplitEntry { entry_id });
|
||||
fn split_entry(
|
||||
&mut self,
|
||||
entry_id: ProjectEntryId,
|
||||
allow_preview: bool,
|
||||
split_direction: Option<SplitDirection>,
|
||||
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
cx.emit(Event::SplitEntry {
|
||||
entry_id,
|
||||
allow_preview,
|
||||
split_direction,
|
||||
});
|
||||
}
|
||||
|
||||
fn new_file(&mut self, _: &NewFile, window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -4282,7 +4334,7 @@ impl ProjectPanel {
|
||||
}
|
||||
} else if event.modifiers().secondary() {
|
||||
if event.click_count() > 1 {
|
||||
project_panel.split_entry(entry_id, cx);
|
||||
project_panel.split_entry(entry_id, false, None, cx);
|
||||
} else {
|
||||
project_panel.selection = Some(selection);
|
||||
if let Some(position) = project_panel.marked_entries.iter().position(|e| *e == selection) {
|
||||
@@ -5254,6 +5306,8 @@ impl Render for ProjectPanel {
|
||||
.on_action(cx.listener(Self::collapse_all_entries))
|
||||
.on_action(cx.listener(Self::open))
|
||||
.on_action(cx.listener(Self::open_permanent))
|
||||
.on_action(cx.listener(Self::open_split_vertical))
|
||||
.on_action(cx.listener(Self::open_split_horizontal))
|
||||
.on_action(cx.listener(Self::confirm))
|
||||
.on_action(cx.listener(Self::cancel))
|
||||
.on_action(cx.listener(Self::copy_path))
|
||||
|
||||
Reference in New Issue
Block a user