mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 10:29:35 +03:00
Adjust pane, tab, panel management bindings to match VS Code
This commit is contained in:
parent
806da0e9ba
commit
581c9af395
@ -210,6 +210,43 @@
|
||||
{
|
||||
"context": "Pane",
|
||||
"bindings": {
|
||||
"ctrl-1": [
|
||||
"pane::ActivateItem",
|
||||
0
|
||||
],
|
||||
"ctrl-2": [
|
||||
"pane::ActivateItem",
|
||||
1
|
||||
],
|
||||
"ctrl-3": [
|
||||
"pane::ActivateItem",
|
||||
2
|
||||
],
|
||||
"ctrl-4": [
|
||||
"pane::ActivateItem",
|
||||
3
|
||||
],
|
||||
"ctrl-5": [
|
||||
"pane::ActivateItem",
|
||||
4
|
||||
],
|
||||
"ctrl-6": [
|
||||
"pane::ActivateItem",
|
||||
5
|
||||
],
|
||||
"ctrl-7": [
|
||||
"pane::ActivateItem",
|
||||
6
|
||||
],
|
||||
"ctrl-8": [
|
||||
"pane::ActivateItem",
|
||||
7
|
||||
],
|
||||
"ctrl-9": [
|
||||
"pane::ActivateItem",
|
||||
8
|
||||
],
|
||||
"ctrl-0": "pane::ActivateLastItem",
|
||||
"ctrl--": "pane::GoBack",
|
||||
"shift-ctrl-_": "pane::GoForward",
|
||||
"cmd-shift-T": "pane::ReopenClosedItem",
|
||||
@ -219,6 +256,43 @@
|
||||
{
|
||||
"context": "Workspace",
|
||||
"bindings": {
|
||||
"cmd-1": [
|
||||
"workspace::ActivatePane",
|
||||
0
|
||||
],
|
||||
"cmd-2": [
|
||||
"workspace::ActivatePane",
|
||||
1
|
||||
],
|
||||
"cmd-3": [
|
||||
"workspace::ActivatePane",
|
||||
2
|
||||
],
|
||||
"cmd-4": [
|
||||
"workspace::ActivatePane",
|
||||
3
|
||||
],
|
||||
"cmd-5": [
|
||||
"workspace::ActivatePane",
|
||||
4
|
||||
],
|
||||
"cmd-6": [
|
||||
"workspace::ActivatePane",
|
||||
5
|
||||
],
|
||||
"cmd-7": [
|
||||
"workspace::ActivatePane",
|
||||
6
|
||||
],
|
||||
"cmd-8": [
|
||||
"workspace::ActivatePane",
|
||||
7
|
||||
],
|
||||
"cmd-9": [
|
||||
"workspace::ActivatePane",
|
||||
8
|
||||
],
|
||||
"cmd-b": "workspace::ToggleLeftSidebar",
|
||||
"cmd-shift-F": "project_search::Deploy",
|
||||
"cmd-k cmd-t": "theme_selector::Toggle",
|
||||
"cmd-k cmd-s": "zed::OpenKeymap",
|
||||
@ -226,6 +300,7 @@
|
||||
"cmd-p": "file_finder::Toggle",
|
||||
"cmd-shift-P": "command_palette::Toggle",
|
||||
"cmd-shift-M": "diagnostics::Deploy",
|
||||
"cmd-shift-E": "project_panel::Toggle",
|
||||
"cmd-alt-s": "workspace::SaveAll"
|
||||
}
|
||||
},
|
||||
@ -310,34 +385,8 @@
|
||||
{
|
||||
"context": "Workspace",
|
||||
"bindings": {
|
||||
"cmd-1": [
|
||||
"workspace::ToggleSidebarItemFocus",
|
||||
{
|
||||
"side": "Left",
|
||||
"item_index": 0
|
||||
}
|
||||
],
|
||||
"cmd-shift-!": [
|
||||
"workspace::ToggleSidebarItem",
|
||||
{
|
||||
"side": "Left",
|
||||
"item_index": 0
|
||||
}
|
||||
],
|
||||
"cmd-9": [
|
||||
"workspace::ToggleSidebarItemFocus",
|
||||
{
|
||||
"side": "Right",
|
||||
"item_index": 0
|
||||
}
|
||||
],
|
||||
"cmd-shift-(": [
|
||||
"workspace::ToggleSidebarItem",
|
||||
{
|
||||
"side": "Right",
|
||||
"item_index": 0
|
||||
}
|
||||
]
|
||||
"cmd-shift-C": "contacts_panel::Toggle",
|
||||
"cmd-shift-B": "workspace::ToggleRightSidebar"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -8,6 +8,7 @@ use contact_notification::ContactNotification;
|
||||
use editor::{Cancel, Editor};
|
||||
use fuzzy::{match_strings, StringMatchCandidate};
|
||||
use gpui::{
|
||||
actions,
|
||||
elements::*,
|
||||
geometry::{rect::RectF, vector::vec2f},
|
||||
impl_actions, impl_internal_actions,
|
||||
@ -24,6 +25,8 @@ use std::{ops::DerefMut, sync::Arc};
|
||||
use theme::IconButton;
|
||||
use workspace::{sidebar::SidebarItem, JoinProject, ToggleProjectOnline, Workspace};
|
||||
|
||||
actions!(contacts_panel, [Toggle]);
|
||||
|
||||
impl_actions!(
|
||||
contacts_panel,
|
||||
[RequestContact, RemoveContact, RespondToContactRequest]
|
||||
|
@ -108,7 +108,8 @@ actions!(
|
||||
Cut,
|
||||
Paste,
|
||||
Delete,
|
||||
Rename
|
||||
Rename,
|
||||
Toggle
|
||||
]
|
||||
);
|
||||
impl_internal_actions!(project_panel, [Open, ToggleExpanded, DeployContextMenu]);
|
||||
|
@ -18,11 +18,15 @@ use settings::Settings;
|
||||
use std::{any::Any, cell::RefCell, mem, path::Path, rc::Rc};
|
||||
use util::ResultExt;
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
pub struct ActivateItem(pub usize);
|
||||
|
||||
actions!(
|
||||
pane,
|
||||
[
|
||||
ActivatePrevItem,
|
||||
ActivateNextItem,
|
||||
ActivateLastItem,
|
||||
CloseActiveItem,
|
||||
CloseInactiveItems,
|
||||
ReopenClosedItem,
|
||||
@ -39,9 +43,6 @@ pub struct CloseItem {
|
||||
pub pane: WeakViewHandle<Pane>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
pub struct ActivateItem(pub usize);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
pub struct GoBack {
|
||||
#[serde(skip_deserializing)]
|
||||
@ -54,8 +55,8 @@ pub struct GoForward {
|
||||
pub pane: Option<WeakViewHandle<Pane>>,
|
||||
}
|
||||
|
||||
impl_actions!(pane, [GoBack, GoForward]);
|
||||
impl_internal_actions!(pane, [CloseItem, ActivateItem]);
|
||||
impl_actions!(pane, [GoBack, GoForward, ActivateItem]);
|
||||
impl_internal_actions!(pane, [CloseItem]);
|
||||
|
||||
const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
|
||||
|
||||
@ -63,6 +64,9 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||
cx.add_action(|pane: &mut Pane, action: &ActivateItem, cx| {
|
||||
pane.activate_item(action.0, true, true, cx);
|
||||
});
|
||||
cx.add_action(|pane: &mut Pane, _: &ActivateLastItem, cx| {
|
||||
pane.activate_item(pane.items.len() - 1, true, true, cx);
|
||||
});
|
||||
cx.add_action(|pane: &mut Pane, _: &ActivatePrevItem, cx| {
|
||||
pane.activate_prev_item(cx);
|
||||
});
|
||||
|
@ -55,7 +55,8 @@ impl Into<AnyViewHandle> for &dyn SidebarItemHandle {
|
||||
pub struct Sidebar {
|
||||
side: Side,
|
||||
items: Vec<Item>,
|
||||
active_item_ix: Option<usize>,
|
||||
is_open: bool,
|
||||
active_item_ix: usize,
|
||||
actual_width: Rc<RefCell<f32>>,
|
||||
custom_width: Rc<RefCell<f32>>,
|
||||
}
|
||||
@ -83,25 +84,41 @@ pub struct ToggleSidebarItem {
|
||||
pub item_index: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||
pub struct ToggleSidebarItemFocus {
|
||||
pub side: Side,
|
||||
pub item_index: usize,
|
||||
}
|
||||
|
||||
impl_actions!(workspace, [ToggleSidebarItem, ToggleSidebarItemFocus]);
|
||||
impl_actions!(workspace, [ToggleSidebarItem]);
|
||||
|
||||
impl Sidebar {
|
||||
pub fn new(side: Side) -> Self {
|
||||
Self {
|
||||
side,
|
||||
items: Default::default(),
|
||||
active_item_ix: None,
|
||||
active_item_ix: 0,
|
||||
is_open: false,
|
||||
actual_width: Rc::new(RefCell::new(260.)),
|
||||
custom_width: Rc::new(RefCell::new(260.)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_open(&self) -> bool {
|
||||
self.is_open
|
||||
}
|
||||
|
||||
pub fn active_item_ix(&self) -> usize {
|
||||
self.active_item_ix
|
||||
}
|
||||
|
||||
pub fn set_open(&mut self, open: bool, cx: &mut ViewContext<Self>) {
|
||||
if open != self.is_open {
|
||||
self.is_open = open;
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_open(&mut self, cx: &mut ViewContext<Self>) {
|
||||
if self.is_open {}
|
||||
self.is_open = !self.is_open;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn add_item<T: SidebarItem>(
|
||||
&mut self,
|
||||
icon_path: &'static str,
|
||||
@ -133,23 +150,25 @@ impl Sidebar {
|
||||
}
|
||||
|
||||
pub fn activate_item(&mut self, item_ix: usize, cx: &mut ViewContext<Self>) {
|
||||
self.active_item_ix = Some(item_ix);
|
||||
self.active_item_ix = item_ix;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn toggle_item(&mut self, item_ix: usize, cx: &mut ViewContext<Self>) {
|
||||
if self.active_item_ix == Some(item_ix) {
|
||||
self.active_item_ix = None;
|
||||
if self.active_item_ix == item_ix {
|
||||
self.is_open = false;
|
||||
} else {
|
||||
self.active_item_ix = Some(item_ix);
|
||||
self.active_item_ix = item_ix;
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn active_item(&self) -> Option<&Rc<dyn SidebarItemHandle>> {
|
||||
self.active_item_ix
|
||||
.and_then(|ix| self.items.get(ix))
|
||||
.map(|item| &item.view)
|
||||
if self.is_open {
|
||||
self.items.get(self.active_item_ix).map(|item| &item.view)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn render_resize_handle(&self, theme: &Theme, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
@ -249,6 +268,7 @@ impl View for SidebarButtons {
|
||||
let item_style = theme.item;
|
||||
let badge_style = theme.badge;
|
||||
let active_ix = sidebar.active_item_ix;
|
||||
let is_open = sidebar.is_open;
|
||||
let side = sidebar.side;
|
||||
let group_style = match side {
|
||||
Side::Left => theme.group_left,
|
||||
@ -267,7 +287,7 @@ impl View for SidebarButtons {
|
||||
item_index: ix,
|
||||
};
|
||||
MouseEventHandler::new::<Self, _, _>(ix, cx, move |state, cx| {
|
||||
let is_active = Some(ix) == active_ix;
|
||||
let is_active = is_open && ix == active_ix;
|
||||
let style = item_style.style_for(state, is_active);
|
||||
Stack::new()
|
||||
.with_child(Svg::new(icon_path).with_color(style.icon_color).boxed())
|
||||
|
@ -1,7 +1,4 @@
|
||||
use crate::{
|
||||
sidebar::{Side, ToggleSidebarItem},
|
||||
AppState, ToggleFollow, Workspace,
|
||||
};
|
||||
use crate::{sidebar::Side, AppState, ToggleFollow, Workspace};
|
||||
use anyhow::Result;
|
||||
use client::{proto, Client, Contact};
|
||||
use gpui::{
|
||||
@ -104,13 +101,7 @@ impl WaitingRoom {
|
||||
&app_state,
|
||||
cx,
|
||||
);
|
||||
workspace.toggle_sidebar_item(
|
||||
&ToggleSidebarItem {
|
||||
side: Side::Left,
|
||||
item_index: 0,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
workspace.toggle_sidebar(Side::Left, cx);
|
||||
if let Some((host_peer_id, _)) =
|
||||
workspace.project.read(cx).collaborators().iter().find(
|
||||
|(_, collaborator)| collaborator.replica_id == 0,
|
||||
|
@ -31,7 +31,7 @@ use postage::prelude::Stream;
|
||||
use project::{fs, Fs, Project, ProjectEntryId, ProjectPath, ProjectStore, Worktree, WorktreeId};
|
||||
use serde::Deserialize;
|
||||
use settings::Settings;
|
||||
use sidebar::{Side, Sidebar, SidebarButtons, ToggleSidebarItem, ToggleSidebarItemFocus};
|
||||
use sidebar::{Side, Sidebar, SidebarButtons, ToggleSidebarItem};
|
||||
use smallvec::SmallVec;
|
||||
use status_bar::StatusBar;
|
||||
pub use status_bar::StatusItemView;
|
||||
@ -90,6 +90,8 @@ actions!(
|
||||
ActivatePreviousPane,
|
||||
ActivateNextPane,
|
||||
FollowNextCollaborator,
|
||||
ToggleLeftSidebar,
|
||||
ToggleRightSidebar,
|
||||
]
|
||||
);
|
||||
|
||||
@ -104,6 +106,9 @@ pub struct ToggleProjectOnline {
|
||||
pub project: Option<ModelHandle<Project>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
pub struct ActivatePane(pub usize);
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct ToggleFollow(pub PeerId);
|
||||
|
||||
@ -122,7 +127,7 @@ impl_internal_actions!(
|
||||
RemoveWorktreeFromProject
|
||||
]
|
||||
);
|
||||
impl_actions!(workspace, [ToggleProjectOnline]);
|
||||
impl_actions!(workspace, [ToggleProjectOnline, ActivatePane]);
|
||||
|
||||
pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
|
||||
pane::init(cx);
|
||||
@ -185,7 +190,6 @@ pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
|
||||
},
|
||||
);
|
||||
cx.add_action(Workspace::toggle_sidebar_item);
|
||||
cx.add_action(Workspace::toggle_sidebar_item_focus);
|
||||
cx.add_action(Workspace::focus_center);
|
||||
cx.add_action(|workspace: &mut Workspace, _: &ActivatePreviousPane, cx| {
|
||||
workspace.activate_previous_pane(cx)
|
||||
@ -193,6 +197,13 @@ pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
|
||||
cx.add_action(|workspace: &mut Workspace, _: &ActivateNextPane, cx| {
|
||||
workspace.activate_next_pane(cx)
|
||||
});
|
||||
cx.add_action(|workspace: &mut Workspace, _: &ToggleLeftSidebar, cx| {
|
||||
workspace.toggle_sidebar(Side::Left, cx);
|
||||
});
|
||||
cx.add_action(|workspace: &mut Workspace, _: &ToggleRightSidebar, cx| {
|
||||
workspace.toggle_sidebar(Side::Right, cx);
|
||||
});
|
||||
cx.add_action(Workspace::activate_pane_at_index);
|
||||
|
||||
let client = &app_state.client;
|
||||
client.add_view_request_handler(Workspace::handle_follow);
|
||||
@ -1248,17 +1259,39 @@ impl Workspace {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_sidebar(&mut self, side: Side, cx: &mut ViewContext<Self>) {
|
||||
let sidebar = match side {
|
||||
Side::Left => &mut self.left_sidebar,
|
||||
Side::Right => &mut self.right_sidebar,
|
||||
};
|
||||
sidebar.update(cx, |sidebar, cx| {
|
||||
sidebar.set_open(!sidebar.is_open(), cx);
|
||||
});
|
||||
cx.focus_self();
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn toggle_sidebar_item(&mut self, action: &ToggleSidebarItem, cx: &mut ViewContext<Self>) {
|
||||
let sidebar = match action.side {
|
||||
Side::Left => &mut self.left_sidebar,
|
||||
Side::Right => &mut self.right_sidebar,
|
||||
};
|
||||
let active_item = sidebar.update(cx, |sidebar, cx| {
|
||||
sidebar.toggle_item(action.item_index, cx);
|
||||
sidebar.active_item().map(|item| item.to_any())
|
||||
if sidebar.is_open() && sidebar.active_item_ix() == action.item_index {
|
||||
sidebar.set_open(false, cx);
|
||||
None
|
||||
} else {
|
||||
sidebar.set_open(true, cx);
|
||||
sidebar.activate_item(action.item_index, cx);
|
||||
sidebar.active_item().cloned()
|
||||
}
|
||||
});
|
||||
if let Some(active_item) = active_item {
|
||||
cx.focus(active_item);
|
||||
if active_item.is_focused(cx) {
|
||||
cx.focus_self();
|
||||
} else {
|
||||
cx.focus(active_item.to_any());
|
||||
}
|
||||
} else {
|
||||
cx.focus_self();
|
||||
}
|
||||
@ -1267,15 +1300,17 @@ impl Workspace {
|
||||
|
||||
pub fn toggle_sidebar_item_focus(
|
||||
&mut self,
|
||||
action: &ToggleSidebarItemFocus,
|
||||
side: Side,
|
||||
item_index: usize,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let sidebar = match action.side {
|
||||
let sidebar = match side {
|
||||
Side::Left => &mut self.left_sidebar,
|
||||
Side::Right => &mut self.right_sidebar,
|
||||
};
|
||||
let active_item = sidebar.update(cx, |sidebar, cx| {
|
||||
sidebar.activate_item(action.item_index, cx);
|
||||
sidebar.set_open(true, cx);
|
||||
sidebar.activate_item(item_index, cx);
|
||||
sidebar.active_item().cloned()
|
||||
});
|
||||
if let Some(active_item) = active_item {
|
||||
@ -1405,6 +1440,15 @@ impl Workspace {
|
||||
}
|
||||
}
|
||||
|
||||
fn activate_pane_at_index(&mut self, action: &ActivatePane, cx: &mut ViewContext<Self>) {
|
||||
let panes = self.center.panes();
|
||||
if let Some(pane) = panes.get(action.0).map(|p| (*p).clone()) {
|
||||
self.activate_pane(pane, cx);
|
||||
} else {
|
||||
self.split_pane(self.active_pane.clone(), SplitDirection::Right, cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn activate_next_pane(&mut self, cx: &mut ViewContext<Self>) {
|
||||
let next_pane = {
|
||||
let panes = self.center.panes();
|
||||
@ -2481,13 +2525,7 @@ pub fn open_paths(
|
||||
let mut workspace = Workspace::new(project, cx);
|
||||
(app_state.initialize_workspace)(&mut workspace, &app_state, cx);
|
||||
if contains_directory {
|
||||
workspace.toggle_sidebar_item(
|
||||
&ToggleSidebarItem {
|
||||
side: Side::Left,
|
||||
item_index: 0,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
workspace.toggle_sidebar(Side::Left, cx);
|
||||
}
|
||||
workspace
|
||||
})
|
||||
|
@ -187,11 +187,21 @@ pub fn menus() -> Vec<Menu<'static>> {
|
||||
},
|
||||
MenuItem::Separator,
|
||||
MenuItem::Action {
|
||||
name: "Project Browser",
|
||||
action: Box::new(workspace::sidebar::ToggleSidebarItemFocus {
|
||||
side: workspace::sidebar::Side::Left,
|
||||
item_index: 0,
|
||||
}),
|
||||
name: "Toggle Left Sidebar",
|
||||
action: Box::new(workspace::ToggleLeftSidebar),
|
||||
},
|
||||
MenuItem::Action {
|
||||
name: "Toggle Right Sidebar",
|
||||
action: Box::new(workspace::ToggleRightSidebar),
|
||||
},
|
||||
MenuItem::Separator,
|
||||
MenuItem::Action {
|
||||
name: "Project Panel",
|
||||
action: Box::new(project_panel::Toggle),
|
||||
},
|
||||
MenuItem::Action {
|
||||
name: "Contacts Panel",
|
||||
action: Box::new(contacts_panel::Toggle),
|
||||
},
|
||||
MenuItem::Action {
|
||||
name: "Command Palette",
|
||||
|
@ -34,7 +34,7 @@ use std::{
|
||||
};
|
||||
use util::ResultExt;
|
||||
pub use workspace;
|
||||
use workspace::{AppState, Workspace};
|
||||
use workspace::{sidebar::Side, AppState, Workspace};
|
||||
|
||||
#[derive(Deserialize, Clone, PartialEq)]
|
||||
struct OpenBrowser {
|
||||
@ -128,6 +128,16 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
|
||||
}
|
||||
},
|
||||
);
|
||||
cx.add_action(
|
||||
|workspace: &mut Workspace, _: &project_panel::Toggle, cx: &mut ViewContext<Workspace>| {
|
||||
workspace.toggle_sidebar_item_focus(Side::Left, 0, cx);
|
||||
},
|
||||
);
|
||||
cx.add_action(
|
||||
|workspace: &mut Workspace, _: &contacts_panel::Toggle, cx: &mut ViewContext<Workspace>| {
|
||||
workspace.toggle_sidebar_item_focus(Side::Right, 0, cx);
|
||||
},
|
||||
);
|
||||
|
||||
lsp_status::init(cx);
|
||||
settings::KeymapFileContent::load_defaults(cx);
|
||||
@ -429,7 +439,7 @@ mod tests {
|
||||
let workspace_1 = cx.root_view::<Workspace>(cx.window_ids()[0]).unwrap();
|
||||
workspace_1.update(cx, |workspace, cx| {
|
||||
assert_eq!(workspace.worktrees(cx).count(), 2);
|
||||
assert!(workspace.left_sidebar().read(cx).active_item().is_some());
|
||||
assert!(workspace.left_sidebar().read(cx).is_open());
|
||||
assert!(workspace.active_pane().is_focused(cx));
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user