1717 lines
74 KiB
Rust
1717 lines
74 KiB
Rust
mod action;
|
|
mod active_session;
|
|
pub(crate) mod auto_handoff;
|
|
pub mod bonus_grant_notification_model;
|
|
#[cfg(target_os = "macos")]
|
|
pub(crate) mod cli_install;
|
|
mod close_session_confirmation_dialog;
|
|
pub(crate) mod cross_window_tab_drag;
|
|
pub mod delete_conversation_confirmation_dialog;
|
|
mod global_actions;
|
|
pub mod header_toolbar_editor;
|
|
pub mod header_toolbar_item;
|
|
pub mod hoa_onboarding;
|
|
mod home;
|
|
mod lightbox_view;
|
|
mod native_modal;
|
|
mod one_time_modal_model;
|
|
mod registry;
|
|
pub mod rewind_confirmation_dialog;
|
|
pub mod sync_inputs;
|
|
pub mod tab_group;
|
|
pub mod tab_settings;
|
|
mod toast_stack;
|
|
pub mod util;
|
|
pub mod view;
|
|
|
|
pub use action::{
|
|
AutoCloudHandoffTrigger, CommandSearchOptions, InitContent, RestoreConversationLayout,
|
|
TabContextMenuAnchor, VerticalTabsPaneContextMenuTarget, WorkspaceAction,
|
|
};
|
|
pub use active_session::ActiveSession;
|
|
use galaxy_core::context_flag::ContextFlag;
|
|
pub(crate) use global_actions::save_app_urgently;
|
|
pub use global_actions::{
|
|
ForkAIConversationParams, ForkFromExchange, ForkedConversationDestination,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
pub use util::{active_terminal_in_window, PaneViewLocator, TabMovement};
|
|
pub use view::{
|
|
Workspace, NEW_SESSION_MENU_BUTTON_POSITION_ID, NEW_TAB_BUTTON_POSITION_ID,
|
|
PANEL_HEADER_HEIGHT, TAB_BAR_HEIGHT, TOTAL_TAB_BAR_HEIGHT, WORKSPACE_PADDING,
|
|
};
|
|
use warpui::accessibility::AccessibilityVerbosity;
|
|
use warpui::elements::DropTargetData;
|
|
use warpui::keymap::macros::id;
|
|
use warpui::keymap::{BindingDescription, EditableBinding, FixedBinding};
|
|
use warpui::AppContext;
|
|
|
|
use crate::ai::blocklist::NEW_AGENT_PANE_LABEL;
|
|
use crate::channel::{Channel, ChannelState};
|
|
use crate::features::FeatureFlag;
|
|
use crate::palette::PaletteMode;
|
|
use crate::server::telemetry::{AgentModeEntrypoint, PaletteSource};
|
|
use crate::settings_view::{self, flags, SettingsSection};
|
|
use crate::tab::{uses_vertical_tabs, NewSessionMenuItem};
|
|
use crate::util::bindings::{self, cmd_or_ctrl_shift, is_binding_pty_compliant, CustomAction};
|
|
use crate::{code, modal, notebooks, tab_configs};
|
|
|
|
// Helper function to access panel header corner radius from other modules
|
|
pub fn panel_header_corner_radius() -> galaxyui::elements::CornerRadius {
|
|
galaxyui::elements::CornerRadius::with_top(galaxyui::elements::Radius::Pixels(8.))
|
|
}
|
|
|
|
pub use one_time_modal_model::OneTimeModalModel;
|
|
pub use registry::WorkspaceRegistry;
|
|
pub use toast_stack::ToastStack;
|
|
|
|
use crate::workspace::view::{
|
|
LEFT_PANEL_AGENT_CONVERSATIONS_BINDING_NAME, LEFT_PANEL_GLOBAL_SEARCH_BINDING_NAME,
|
|
LEFT_PANEL_PROJECT_EXPLORER_BINDING_NAME, LEFT_PANEL_WARP_DRIVE_BINDING_NAME,
|
|
NEW_AGENT_TAB_BINDING_NAME, NEW_AMBIENT_AGENT_TAB_BINDING_NAME, NEW_FILE_BINDING_NAME,
|
|
NEW_TAB_BINDING_NAME, NEW_TERMINAL_TAB_BINDING_NAME, OPEN_GLOBAL_SEARCH_BINDING_NAME,
|
|
TOGGLE_CONVERSATION_LIST_VIEW_BINDING_NAME, TOGGLE_NOTIFICATION_MAILBOX_BINDING_NAME,
|
|
TOGGLE_PROJECT_EXPLORER_BINDING_NAME, TOGGLE_RIGHT_PANEL_BINDING_NAME,
|
|
TOGGLE_TAB_CONFIGS_MENU_BINDING_NAME, TOGGLE_VERTICAL_TABS_PANEL_BINDING_NAME,
|
|
TOGGLE_WARP_DRIVE_BINDING_NAME,
|
|
};
|
|
|
|
pub fn init(app: &mut AppContext) {
|
|
app.add_singleton_model(|_| WorkspaceRegistry::new());
|
|
app.add_singleton_model(|_| cross_window_tab_drag::CrossWindowTabDrag::new());
|
|
app.add_singleton_model(|_| global_actions::SessionSaveCoordinator::new());
|
|
use galaxyui::keymap::macros::*;
|
|
app.register_binding_validator::<Workspace>(is_binding_pty_compliant);
|
|
|
|
modal::init(app);
|
|
native_modal::init(app);
|
|
lightbox_view::init(app);
|
|
rewind_confirmation_dialog::init(app);
|
|
delete_conversation_confirmation_dialog::init(app);
|
|
crate::tab_configs::remove_confirmation_dialog::init(app);
|
|
hoa_onboarding::init(app);
|
|
tab_configs::session_config_modal::init(app);
|
|
view::launch_modal::oz_launch::init(app);
|
|
view::openwarp_launch_modal::init(app);
|
|
view::orchestration_launch_modal::init(app);
|
|
view::auto_handoff_sleep_modal::init(app);
|
|
view::cloud_agent_capacity_modal::init(app);
|
|
view::codex_modal::init(app);
|
|
view::free_ai_removal_modal::init(app);
|
|
view::free_tier_limit_hit_modal::init(app);
|
|
view::global_search::view::GlobalSearchView::init(app);
|
|
view::right_panel::RightPanelView::init(app);
|
|
header_toolbar_editor::init(app);
|
|
view::conversation_list::view::register_conversation_list_view_bindings(app);
|
|
|
|
settings_view::init_actions_from_parent_view(app, &id!("Workspace"), |settings_action| {
|
|
WorkspaceAction::DispatchToSettingsTab(settings_action)
|
|
});
|
|
global_actions::init_global_actions(app);
|
|
notebooks::init(app);
|
|
code::init(app);
|
|
sync_inputs::init(app);
|
|
lsp::init(app);
|
|
|
|
app.register_fixed_bindings([FixedBinding::empty(
|
|
"Dump debug info",
|
|
WorkspaceAction::DumpDebugInfo,
|
|
id!("Workspace"),
|
|
)]);
|
|
app.register_fixed_bindings([
|
|
FixedBinding::new(
|
|
"escape",
|
|
WorkspaceAction::DismissSessionConfigTabConfigChip,
|
|
id!("Workspace") & id!(flags::SESSION_CONFIG_TAB_CONFIG_CHIP_OPEN),
|
|
),
|
|
FixedBinding::new(
|
|
"enter",
|
|
WorkspaceAction::DismissSessionConfigTabConfigChip,
|
|
id!("Workspace") & id!(flags::SESSION_CONFIG_TAB_CONFIG_CHIP_OPEN),
|
|
),
|
|
]);
|
|
|
|
if ChannelState::enable_debug_features() {
|
|
let crash_description = "Crash the app (for testing)";
|
|
app.register_editable_bindings([
|
|
EditableBinding::new("workspace:crash", crash_description, WorkspaceAction::Crash)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:log_review_comment_send_status_for_active_tab",
|
|
"[Debug] Log review comment send status for active tab",
|
|
WorkspaceAction::LogReviewCommentSendStatusForActiveTab,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:panic",
|
|
"Trigger a panic (for testing)",
|
|
WorkspaceAction::Panic,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:open_view_tree_debug_view",
|
|
"Open view tree debugger",
|
|
WorkspaceAction::OpenViewTreeDebugWindow,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
]);
|
|
app.register_fixed_bindings([FixedBinding::empty(
|
|
"[Debug] View first-time user experience",
|
|
WorkspaceAction::AddGetStartedTab,
|
|
id!("Workspace"),
|
|
)]);
|
|
#[cfg(debug_assertions)]
|
|
{
|
|
// Debug actions for build plan migration modal (command palette only)
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:open_build_plan_migration_modal",
|
|
"[Debug] Open Build Plan Migration Modal",
|
|
WorkspaceAction::OpenBuildPlanMigrationModal,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:reset_build_plan_migration_modal_state",
|
|
"[Debug] Reset Build Plan Migration Modal State",
|
|
WorkspaceAction::ResetBuildPlanMigrationModalState,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:debug_reset_bedrock_login_banner_dismissed",
|
|
"[Debug] Un-dismiss AWS login banner",
|
|
WorkspaceAction::DebugResetBedrockLoginBannerDismissed,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:open_oz_launch_modal",
|
|
"[Debug] Open Oz Launch Modal",
|
|
WorkspaceAction::OpenOzLaunchModal,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:reset_oz_launch_modal_state",
|
|
"[Debug] Reset Oz Launch Modal State",
|
|
WorkspaceAction::ResetOzLaunchModalState,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:open_openwarp_launch_modal",
|
|
"[Debug] Open OpenGalaxy Launch Modal",
|
|
WorkspaceAction::OpenOpenWarpLaunchModal,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:reset_openwarp_launch_modal_state",
|
|
"[Debug] Reset OpenGalaxy Launch Modal State",
|
|
WorkspaceAction::ResetOpenWarpLaunchModalState,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:open_orchestration_launch_modal",
|
|
"[Debug] Open Orchestration Launch Modal",
|
|
WorkspaceAction::OpenOrchestrationLaunchModal,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:reset_orchestration_launch_modal_state",
|
|
"[Debug] Reset Orchestration Launch Modal State",
|
|
WorkspaceAction::ResetOrchestrationLaunchModalState,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:open_auto_handoff_sleep_modal",
|
|
"[Debug] Open Auto-Handoff Sleep Modal",
|
|
WorkspaceAction::OpenAutoHandoffSleepModal,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:reset_auto_handoff_sleep_modal_state",
|
|
"[Debug] Reset Auto-Handoff Sleep Modal State",
|
|
WorkspaceAction::ResetAutoHandoffSleepModalState,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:trigger_auto_handoff_to_cloud",
|
|
"[Debug] Trigger Auto-Handoff to Cloud",
|
|
WorkspaceAction::TriggerAutoHandoffToCloud,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:open_free_ai_removal_modal",
|
|
"[Debug] Open Free AI Removal Modal",
|
|
WorkspaceAction::OpenFreeAiRemovalModal,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:reset_free_ai_removal_modal_state",
|
|
"[Debug] Reset Free AI Removal Modal State",
|
|
WorkspaceAction::ResetFreeAiRemovalModalState,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:install_opencode_warp_plugin",
|
|
"[Debug] Install OpenCode Galaxy plugin",
|
|
WorkspaceAction::InstallOpenCodeWarpPlugin,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:use_local_opencode_warp_plugin",
|
|
"[Debug] Use local OpenCode Galaxy plugin (testing only)",
|
|
WorkspaceAction::UseLocalOpenCodeWarpPlugin,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:open_session_config_modal",
|
|
"[Debug] Open Session Config Modal",
|
|
WorkspaceAction::ShowSessionConfigModal,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_hoa_onboarding_flow",
|
|
"[Debug] Start HOA Onboarding Flow",
|
|
WorkspaceAction::ShowHoaOnboardingFlow,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
]);
|
|
}
|
|
}
|
|
|
|
#[cfg(target_os = "macos")]
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:sample_process",
|
|
"Sample Process",
|
|
WorkspaceAction::SampleProcess,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))]);
|
|
|
|
#[cfg(feature = "dhat_heap_profiling")]
|
|
{
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:dump_heap_profile",
|
|
"Dump heap profile (can only be done once)",
|
|
WorkspaceAction::DumpHeapProfile,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))]);
|
|
}
|
|
|
|
app.register_fixed_bindings([
|
|
FixedBinding::custom(
|
|
CustomAction::CycleNextSession,
|
|
WorkspaceAction::CycleNextSession,
|
|
"Switch to next tab",
|
|
id!("Workspace") & id!("Workspace_MultipleTabs"),
|
|
),
|
|
FixedBinding::custom(
|
|
CustomAction::CyclePrevSession,
|
|
WorkspaceAction::CyclePrevSession,
|
|
"Switch to previous tab",
|
|
id!("Workspace") & id!("Workspace_MultipleTabs"),
|
|
),
|
|
FixedBinding::custom(
|
|
CustomAction::AddWindow,
|
|
WorkspaceAction::AddWindow,
|
|
"Create New Window",
|
|
id!("Workspace"),
|
|
)
|
|
.with_enabled(|| ContextFlag::CreateNewSession.is_enabled()),
|
|
]);
|
|
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
NEW_FILE_BINDING_NAME,
|
|
BindingDescription::new("New File"),
|
|
WorkspaceAction::NewCodeFile,
|
|
)
|
|
.with_custom_action(CustomAction::NewFile)
|
|
.with_context_predicate(id!("Workspace") & !id!("Workspace_ViewOnlySharedSession"))]);
|
|
|
|
if FeatureFlag::UIZoom.is_enabled() {
|
|
app.register_fixed_bindings([
|
|
FixedBinding::custom(
|
|
CustomAction::IncreaseZoom,
|
|
WorkspaceAction::IncreaseZoom,
|
|
"Zoom In",
|
|
id!("Workspace"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str()),
|
|
FixedBinding::custom(
|
|
CustomAction::DecreaseZoom,
|
|
WorkspaceAction::DecreaseZoom,
|
|
"Zoom Out",
|
|
id!("Workspace"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str()),
|
|
FixedBinding::custom(
|
|
CustomAction::ResetZoom,
|
|
WorkspaceAction::ResetZoom,
|
|
"Reset Zoom",
|
|
id!("Workspace"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str()),
|
|
]);
|
|
} else {
|
|
app.register_fixed_bindings([
|
|
FixedBinding::custom(
|
|
CustomAction::IncreaseFontSize,
|
|
WorkspaceAction::IncreaseFontSize,
|
|
"Increase font size",
|
|
id!("Workspace"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str()),
|
|
FixedBinding::custom(
|
|
CustomAction::DecreaseFontSize,
|
|
WorkspaceAction::DecreaseFontSize,
|
|
"Decrease font size",
|
|
id!("Workspace"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str()),
|
|
]);
|
|
}
|
|
|
|
if ContextFlag::LaunchConfigurations.is_enabled() {
|
|
app.register_fixed_bindings([FixedBinding::custom(
|
|
CustomAction::SaveCurrentConfig,
|
|
WorkspaceAction::OpenLaunchConfigSaveModal,
|
|
"Save new launch configuration",
|
|
id!("Workspace"),
|
|
)]);
|
|
}
|
|
|
|
if ChannelState::channel() == Channel::Integration {
|
|
// Hack: Add explicit bindings for the tests, since the tests' injected
|
|
// keypresses won't trigger Mac menu items. Unfortunately we can't use
|
|
// cfg[test] because we are a separate process!
|
|
app.register_fixed_bindings([
|
|
FixedBinding::new(
|
|
cmd_or_ctrl_shift("t"),
|
|
WorkspaceAction::AddDefaultTab,
|
|
id!("Workspace"),
|
|
),
|
|
FixedBinding::new(
|
|
cmd_or_ctrl_shift("p"),
|
|
WorkspaceAction::TogglePalette {
|
|
mode: PaletteMode::Command,
|
|
source: PaletteSource::IntegrationTest,
|
|
},
|
|
id!("Workspace"),
|
|
),
|
|
FixedBinding::new(
|
|
"cmdorctrl-,",
|
|
WorkspaceAction::ShowSettings,
|
|
id!("Workspace"),
|
|
),
|
|
]);
|
|
}
|
|
|
|
if FeatureFlag::UIZoom.is_enabled() {
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:increase_zoom",
|
|
"Increase zoom level",
|
|
WorkspaceAction::IncreaseZoom,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_key_binding("cmdorctrl-="),
|
|
EditableBinding::new(
|
|
"workspace:decrease_zoom",
|
|
"Decrease zoom level",
|
|
WorkspaceAction::DecreaseZoom,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_key_binding("cmdorctrl--"),
|
|
EditableBinding::new(
|
|
"workspace:reset_zoom",
|
|
"Reset zoom level to default",
|
|
WorkspaceAction::ResetZoom,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:increase_font_size",
|
|
"Increase font size",
|
|
WorkspaceAction::IncreaseFontSize,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_key_binding("alt-shift->"),
|
|
EditableBinding::new(
|
|
"workspace:decrease_font_size",
|
|
"Decrease font size",
|
|
WorkspaceAction::DecreaseFontSize,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_key_binding("alt-shift-<"),
|
|
EditableBinding::new(
|
|
"workspace:reset_font_size",
|
|
"Reset font size to default",
|
|
WorkspaceAction::ResetFontSize,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
]);
|
|
} else {
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:increase_font_size",
|
|
"Increase font size",
|
|
WorkspaceAction::IncreaseFontSize,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_key_binding("cmdorctrl-="),
|
|
EditableBinding::new(
|
|
"workspace:decrease_font_size",
|
|
"Decrease font size",
|
|
WorkspaceAction::DecreaseFontSize,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_key_binding("cmdorctrl--"),
|
|
EditableBinding::new(
|
|
"workspace:reset_font_size",
|
|
"Reset font size to default",
|
|
WorkspaceAction::ResetFontSize,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_key_binding("cmdorctrl-0")
|
|
.with_custom_action(CustomAction::ResetFontSize),
|
|
]);
|
|
}
|
|
|
|
app.register_fixed_bindings([
|
|
// Menu dispatch for the "Open File Picker" custom action.
|
|
FixedBinding::custom(
|
|
CustomAction::ToggleProjectExplorer,
|
|
WorkspaceAction::ToggleProjectExplorer,
|
|
BindingDescription::new("Toggle project explorer")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Project Explorer"),
|
|
id!("Workspace") & id!(flags::SHOW_PROJECT_EXPLORER),
|
|
),
|
|
]);
|
|
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:show_theme_chooser",
|
|
"Open theme picker",
|
|
WorkspaceAction::ShowThemeChooserForActiveTheme,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str()),
|
|
EditableBinding::new(
|
|
TOGGLE_TAB_CONFIGS_MENU_BINDING_NAME,
|
|
"Open tab configs menu",
|
|
WorkspaceAction::ToggleTabConfigsMenu,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_mac_key_binding("cmd-ctrl-t")
|
|
.with_linux_or_windows_key_binding("ctrl-alt-shift-T"),
|
|
EditableBinding::new(
|
|
"workspace:activate_first_tab",
|
|
"Switch to 1st tab",
|
|
WorkspaceAction::ActivateTabByNumber(1),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-1"),
|
|
EditableBinding::new(
|
|
"workspace:activate_second_tab",
|
|
"Switch to 2nd tab",
|
|
WorkspaceAction::ActivateTabByNumber(2),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-2"),
|
|
EditableBinding::new(
|
|
"workspace:activate_third_tab",
|
|
"Switch to 3rd tab",
|
|
WorkspaceAction::ActivateTabByNumber(3),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-3"),
|
|
EditableBinding::new(
|
|
"workspace:activate_fourth_tab",
|
|
"Switch to 4th tab",
|
|
WorkspaceAction::ActivateTabByNumber(4),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-4"),
|
|
EditableBinding::new(
|
|
"workspace:activate_fifth_tab",
|
|
"Switch to 5th tab",
|
|
WorkspaceAction::ActivateTabByNumber(5),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-5"),
|
|
EditableBinding::new(
|
|
"workspace:activate_sixth_tab",
|
|
"Switch to 6th tab",
|
|
WorkspaceAction::ActivateTabByNumber(6),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-6"),
|
|
EditableBinding::new(
|
|
"workspace:activate_seventh_tab",
|
|
"Switch to 7th tab",
|
|
WorkspaceAction::ActivateTabByNumber(7),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-7"),
|
|
EditableBinding::new(
|
|
"workspace:activate_eighth_tab",
|
|
"Switch to 8th tab",
|
|
WorkspaceAction::ActivateTabByNumber(8),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-8"),
|
|
EditableBinding::new(
|
|
"workspace:activate_last_tab",
|
|
"Switch to last tab",
|
|
WorkspaceAction::ActivateLastTab,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_key_binding("cmdorctrl-9"),
|
|
EditableBinding::new(
|
|
"workspace:activate_prev_tab",
|
|
"Activate previous tab",
|
|
WorkspaceAction::ActivatePrevTab,
|
|
)
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!("Workspace_MultipleTabs") & !id!("Workspace_PaneDragging"),
|
|
)
|
|
.with_mac_key_binding("shift-cmd-{")
|
|
.with_linux_or_windows_key_binding("ctrl-pageup"),
|
|
EditableBinding::new(
|
|
"workspace:activate_next_tab",
|
|
"Activate next tab",
|
|
WorkspaceAction::ActivateNextTab,
|
|
)
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!("Workspace_MultipleTabs") & !id!("Workspace_PaneDragging"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_mac_key_binding("shift-cmd-}")
|
|
.with_linux_or_windows_key_binding("ctrl-pagedown"),
|
|
EditableBinding::new(
|
|
"pane_group:navigate_prev",
|
|
"Activate previous pane",
|
|
WorkspaceAction::NavigatePrevPaneOrPanel,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_custom_action(CustomAction::ActivatePreviousPane),
|
|
EditableBinding::new(
|
|
"pane_group:navigate_next",
|
|
"Activate next pane",
|
|
WorkspaceAction::NavigateNextPaneOrPanel,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_custom_action(CustomAction::ActivateNextPane),
|
|
EditableBinding::new(
|
|
"workspace:create_team_notebook",
|
|
BindingDescription::new("Create a new team notebook")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "New Team Notebook"),
|
|
WorkspaceAction::CreateTeamNotebook,
|
|
)
|
|
.with_custom_action(CustomAction::NewTeamNotebook)
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!(flags::ENABLE_WARP_DRIVE)
|
|
& id!("WarpDrive_BelongsToTeam")
|
|
& id!("IsOnline"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Notebooks.as_str()),
|
|
EditableBinding::new(
|
|
"workspace:create_personal_notebook",
|
|
BindingDescription::new("Create a new personal notebook")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "New Personal Notebook"),
|
|
WorkspaceAction::CreatePersonalNotebook,
|
|
)
|
|
.with_group(bindings::BindingGroup::Notebooks.as_str())
|
|
.with_custom_action(CustomAction::NewPersonalNotebook)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE)),
|
|
EditableBinding::new(
|
|
"workspace:create_team_workflow",
|
|
BindingDescription::new("Create a new team workflow")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "New Team Workflow"),
|
|
WorkspaceAction::CreateTeamWorkflow,
|
|
)
|
|
.with_custom_action(CustomAction::NewTeamWorkflow)
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!(flags::ENABLE_WARP_DRIVE)
|
|
& id!("IsOnline")
|
|
& id!("WarpDrive_BelongsToTeam"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Workflow.as_str()),
|
|
EditableBinding::new(
|
|
"workspace:create_personal_workflow",
|
|
BindingDescription::new("Create a new personal workflow")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "New Personal Workflow"),
|
|
WorkspaceAction::CreatePersonalWorkflow,
|
|
)
|
|
.with_group(bindings::BindingGroup::Workflow.as_str())
|
|
.with_custom_action(CustomAction::NewPersonalWorkflow)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE)),
|
|
EditableBinding::new(
|
|
"workspace:create_team_folder",
|
|
BindingDescription::new("Create a new team folder")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "New Team Folder"),
|
|
WorkspaceAction::CreateTeamFolder,
|
|
)
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!(flags::ENABLE_WARP_DRIVE)
|
|
& id!("IsOnline")
|
|
& id!("WarpDrive_BelongsToTeam"),
|
|
)
|
|
.with_group(bindings::BindingGroup::Folders.as_str()),
|
|
EditableBinding::new(
|
|
"workspace:create_personal_folder",
|
|
BindingDescription::new("Create a new personal folder")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "New Personal Folder"),
|
|
WorkspaceAction::CreatePersonalFolder,
|
|
)
|
|
.with_group(bindings::BindingGroup::Folders.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE) & id!("IsOnline")),
|
|
EditableBinding::new(
|
|
NEW_TAB_BINDING_NAME,
|
|
BindingDescription::new("Create new tab"),
|
|
WorkspaceAction::AddDefaultTab,
|
|
)
|
|
.with_context_predicate(id!("Workspace") & !id!("Workspace_PaneDragging"))
|
|
.with_custom_action(CustomAction::NewTab)
|
|
.with_enabled(|| ContextFlag::CreateNewSession.is_enabled()),
|
|
EditableBinding::new(
|
|
NEW_TERMINAL_TAB_BINDING_NAME,
|
|
BindingDescription::new("New Terminal Tab"),
|
|
WorkspaceAction::AddTerminalTab {
|
|
hide_homepage: false,
|
|
},
|
|
)
|
|
.with_context_predicate(id!("Workspace") & !id!("Workspace_PaneDragging"))
|
|
.with_custom_action(CustomAction::NewTerminalTab)
|
|
.with_enabled(|| ContextFlag::CreateNewSession.is_enabled()),
|
|
EditableBinding::new(
|
|
NEW_AGENT_TAB_BINDING_NAME,
|
|
BindingDescription::new("New Agent Tab"),
|
|
WorkspaceAction::AddAgentTab,
|
|
)
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())
|
|
.with_custom_action(CustomAction::NewAgentTab)
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!(flags::IS_ANY_AI_ENABLED) & !id!("Workspace_PaneDragging"),
|
|
),
|
|
EditableBinding::new(
|
|
NEW_AMBIENT_AGENT_TAB_BINDING_NAME,
|
|
BindingDescription::new("New Cloud Agent Tab"),
|
|
WorkspaceAction::AddAmbientAgentTab,
|
|
)
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!(flags::IS_ANY_AI_ENABLED) & !id!("Workspace_PaneDragging"),
|
|
)
|
|
.with_enabled(|| {
|
|
FeatureFlag::AgentView.is_enabled() && FeatureFlag::CloudMode.is_enabled()
|
|
}),
|
|
EditableBinding::new(
|
|
"workspace:toggle_left_panel",
|
|
BindingDescription::new("Open Left Panel"),
|
|
WorkspaceAction::ToggleLeftPanel,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::ToggleGalaxyDrive),
|
|
EditableBinding::new(
|
|
TOGGLE_RIGHT_PANEL_BINDING_NAME,
|
|
BindingDescription::new("Toggle code review")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Toggle Code Review"),
|
|
WorkspaceAction::ToggleRightPanel,
|
|
)
|
|
.with_enabled(|| cfg!(feature = "local_fs"))
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_mac_key_binding("cmd-shift-+")
|
|
.with_linux_or_windows_key_binding("ctrl-shift-+"),
|
|
EditableBinding::new(
|
|
TOGGLE_VERTICAL_TABS_PANEL_BINDING_NAME,
|
|
BindingDescription::new("Toggle vertical tabs panel")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Toggle Vertical Tabs Panel"),
|
|
WorkspaceAction::ToggleVerticalTabsPanel,
|
|
)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::USE_VERTICAL_TABS_FLAG))
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_enabled(|| FeatureFlag::VerticalTabs.is_enabled())
|
|
.with_key_binding(cmd_or_ctrl_shift("b")),
|
|
EditableBinding::new(
|
|
LEFT_PANEL_PROJECT_EXPLORER_BINDING_NAME,
|
|
BindingDescription::new("Left Panel: Project explorer"),
|
|
WorkspaceAction::ToggleProjectExplorer,
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::SHOW_PROJECT_EXPLORER))
|
|
.with_custom_action(CustomAction::ToggleProjectExplorer),
|
|
EditableBinding::new(
|
|
LEFT_PANEL_AGENT_CONVERSATIONS_BINDING_NAME,
|
|
BindingDescription::new("Left Panel: Agent conversations"),
|
|
WorkspaceAction::ToggleConversationListView,
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::SHOW_CONVERSATION_HISTORY))
|
|
.with_enabled(|| FeatureFlag::AgentViewConversationListView.is_enabled())
|
|
.with_custom_action(CustomAction::ToggleConversationListView),
|
|
EditableBinding::new(
|
|
LEFT_PANEL_GLOBAL_SEARCH_BINDING_NAME,
|
|
BindingDescription::new("Left Panel: Global search"),
|
|
WorkspaceAction::ToggleGlobalSearch,
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::SHOW_GLOBAL_SEARCH))
|
|
.with_enabled(|| FeatureFlag::GlobalSearch.is_enabled())
|
|
.with_custom_action(CustomAction::ToggleGlobalSearch),
|
|
EditableBinding::new(
|
|
"file_tree:toggle_hidden_files",
|
|
BindingDescription::new("Toggle hidden files in Project Explorer"),
|
|
WorkspaceAction::ToggleHiddenFiles,
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::SHOW_PROJECT_EXPLORER))
|
|
.with_mac_key_binding("cmd-shift->")
|
|
.with_linux_or_windows_key_binding("ctrl-shift->"),
|
|
EditableBinding::new(
|
|
LEFT_PANEL_WARP_DRIVE_BINDING_NAME,
|
|
BindingDescription::new("Left Panel: Galaxy Drive"),
|
|
WorkspaceAction::ToggleGalaxyDrive,
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE))
|
|
.with_mac_key_binding("ctrl-4")
|
|
.with_linux_or_windows_key_binding("alt-4"),
|
|
EditableBinding::new(
|
|
TOGGLE_PROJECT_EXPLORER_BINDING_NAME,
|
|
BindingDescription::new("Toggle project explorer")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Project Explorer"),
|
|
WorkspaceAction::ToggleProjectExplorer,
|
|
)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::SHOW_PROJECT_EXPLORER)),
|
|
EditableBinding::new(
|
|
OPEN_GLOBAL_SEARCH_BINDING_NAME,
|
|
BindingDescription::new("Open global search")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Global Search"),
|
|
WorkspaceAction::OpenGlobalSearch,
|
|
)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::SHOW_GLOBAL_SEARCH))
|
|
.with_mac_key_binding("cmd-shift-F")
|
|
// we use alt because we use ctrl-shift-f for find because ctrl-f needs to be reserved for the shell
|
|
.with_linux_or_windows_key_binding("alt-shift-F"),
|
|
EditableBinding::new(
|
|
TOGGLE_WARP_DRIVE_BINDING_NAME,
|
|
BindingDescription::new("Toggle Galaxy Drive")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Galaxy Drive"),
|
|
WorkspaceAction::ToggleGalaxyDrive,
|
|
)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE)),
|
|
EditableBinding::new(
|
|
TOGGLE_CONVERSATION_LIST_VIEW_BINDING_NAME,
|
|
BindingDescription::new("Toggle Agent conversation list view").with_custom_description(
|
|
bindings::MAC_MENUS_CONTEXT,
|
|
"Agent conversation list view",
|
|
),
|
|
WorkspaceAction::ToggleConversationListView,
|
|
)
|
|
.with_enabled(|| FeatureFlag::AgentViewConversationListView.is_enabled())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::SHOW_CONVERSATION_HISTORY))
|
|
.with_mac_key_binding("cmd-shift-A")
|
|
.with_linux_or_windows_key_binding("ctrl-shift-A")
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str()),
|
|
EditableBinding::new(
|
|
"workspace:close_panel",
|
|
BindingDescription::new("Close focused panel")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Close focused panel"),
|
|
WorkspaceAction::ClosePanel,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::CloseCurrentSession),
|
|
EditableBinding::new(
|
|
"workspace:toggle_command_palette",
|
|
BindingDescription::new("Toggle command palette")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Command Palette"),
|
|
WorkspaceAction::TogglePalette {
|
|
mode: PaletteMode::Command,
|
|
source: PaletteSource::Keybinding,
|
|
},
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace") & !id!("Workspace_CloudConversationWebViewer"))
|
|
.with_custom_action(CustomAction::CommandPalette),
|
|
EditableBinding::new(
|
|
"workspace:move_tab_left",
|
|
BindingDescription::new("Move tab left")
|
|
.with_dynamic_override(|ctx| uses_vertical_tabs(ctx).then(|| "move tab up".into())),
|
|
WorkspaceAction::MoveActiveTabLeft,
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!("Workspace_MultipleTabs")
|
|
& !id!("Workspace_LeftmostTabActive")
|
|
& !id!("Workspace_PaneDragging"),
|
|
)
|
|
.with_custom_action(CustomAction::MoveTabLeft),
|
|
EditableBinding::new(
|
|
"workspace:move_tab_right",
|
|
BindingDescription::new("Move tab right").with_dynamic_override(|ctx| {
|
|
uses_vertical_tabs(ctx).then(|| "move tab down".into())
|
|
}),
|
|
WorkspaceAction::MoveActiveTabRight,
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!("Workspace_MultipleTabs")
|
|
& !id!("Workspace_RightmostTabActive")
|
|
& !id!("Workspace_PaneDragging"),
|
|
)
|
|
.with_custom_action(CustomAction::MoveTabRight),
|
|
EditableBinding::new(
|
|
"workspace:toggle_keybindings_page",
|
|
"Toggle keyboard shortcuts",
|
|
WorkspaceAction::ToggleKeybindingsPage,
|
|
)
|
|
.with_group(bindings::BindingGroup::KeyboardShortcuts.as_str())
|
|
.with_context_predicate(id!("Workspace") & !id!("Workspace_TextOpen"))
|
|
.with_custom_action(CustomAction::ToggleKeybindingsPage),
|
|
EditableBinding::new(
|
|
"workspace:show_keybinding_settings",
|
|
"Open keybindings editor",
|
|
WorkspaceAction::ConfigureKeybindingSettings {
|
|
keybinding_name: None,
|
|
},
|
|
)
|
|
.with_group(bindings::BindingGroup::KeyboardShortcuts.as_str())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_mac_key_binding("cmd-ctrl-k"),
|
|
EditableBinding::new(
|
|
"workspace:toggle_block_snackbar",
|
|
"Toggle sticky command header",
|
|
WorkspaceAction::ToggleBlockSnackbar,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
]);
|
|
|
|
// TODO(PLAT-113): Support a11y on non-MacOS platforms
|
|
if cfg!(target_os = "macos") {
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:set_a11y_concise_verbosity_level",
|
|
"[a11y] Set concise accessibility announcements",
|
|
WorkspaceAction::SetA11yVerbosityLevel(AccessibilityVerbosity::Concise),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_key_binding("cmdorctrl-alt-c"),
|
|
EditableBinding::new(
|
|
"workspace:set_a11y_verbose_verbosity_level",
|
|
"[a11y] Set verbose accessibility announcements",
|
|
WorkspaceAction::SetA11yVerbosityLevel(AccessibilityVerbosity::Verbose),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_key_binding("cmdorctrl-alt-v"),
|
|
]);
|
|
}
|
|
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:rename_active_tab",
|
|
"Rename the current tab",
|
|
WorkspaceAction::RenameActiveTab,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_custom_action(CustomAction::RenameTab)
|
|
.with_context_predicate(id!("Workspace"))]);
|
|
|
|
// Pane rename — same shape as RenameActiveTab but acts on the focused pane
|
|
// in the active tab. Ships with no default keybinding so it surfaces in
|
|
// Settings → Keyboard shortcuts as remappable; resolves issue #9351, where
|
|
// the action existed only in the right-click context menu and was not
|
|
// reachable via the binding registry.
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:rename_active_pane",
|
|
"Rename the current pane",
|
|
WorkspaceAction::RenameActivePane,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace"))]);
|
|
|
|
// Tab grouping bindings (keyless by default; gated on `GroupedTabs`).
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:new_tab_group",
|
|
"Create new tab group",
|
|
// Reuse the new-session dropdown's action, not a dedicated variant.
|
|
WorkspaceAction::SelectNewSessionMenuItem(NewSessionMenuItem::CreateNewTabGroup),
|
|
)
|
|
.with_enabled(|| FeatureFlag::GroupedTabs.is_enabled())
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace") & !id!("Workspace_PaneDragging")),
|
|
EditableBinding::new(
|
|
"workspace:new_tab_group_from_active_or_selected_tabs",
|
|
"Create tab group from active or selected tab(s)",
|
|
WorkspaceAction::NewTabGroupFromActiveOrSelectedTabs,
|
|
)
|
|
.with_enabled(|| FeatureFlag::GroupedTabs.is_enabled())
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace") & !id!("Workspace_PaneDragging")),
|
|
// Gated on `Workspace_ActiveOrSelectedTabsInGroup`: offered only when
|
|
// there's an unambiguous group to leave — a single-group multi-selection,
|
|
// or (with no selection) a grouped active tab. Mixed selections aren't
|
|
// offered, matching the multi-tab right-click menu.
|
|
EditableBinding::new(
|
|
"workspace:remove_active_or_selected_tabs_from_group",
|
|
"Remove active or selected tab(s) from group",
|
|
WorkspaceAction::RemoveActiveOrSelectedTabsFromGroup,
|
|
)
|
|
.with_enabled(|| FeatureFlag::GroupedTabs.is_enabled())
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!("Workspace_ActiveOrSelectedTabsInGroup")
|
|
& !id!("Workspace_PaneDragging"),
|
|
),
|
|
]);
|
|
|
|
// Tab/group pinning bindings (keyless by default; gated on `PinnedTabs`).
|
|
// Pin/unpin are split into separate entries so the palette label tracks
|
|
// the active tab/group's current state.
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:pin_active_tab",
|
|
"Pin current tab",
|
|
WorkspaceAction::PinActiveTab,
|
|
)
|
|
.with_enabled(|| FeatureFlag::PinnedTabs.is_enabled())
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace") & !id!("Workspace_ActiveTabPinned") & !id!("Workspace_PaneDragging"),
|
|
),
|
|
EditableBinding::new(
|
|
"workspace:unpin_active_tab",
|
|
"Unpin current tab",
|
|
WorkspaceAction::UnpinActiveTab,
|
|
)
|
|
.with_enabled(|| FeatureFlag::PinnedTabs.is_enabled())
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!("Workspace_ActiveTabPinned") & !id!("Workspace_PaneDragging"),
|
|
),
|
|
EditableBinding::new(
|
|
"workspace:pin_active_tab_group",
|
|
"Pin current tab group",
|
|
WorkspaceAction::PinActiveTabGroup,
|
|
)
|
|
.with_enabled(|| {
|
|
FeatureFlag::PinnedTabs.is_enabled() && FeatureFlag::GroupedTabs.is_enabled()
|
|
})
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!("Workspace_ActiveTabInGroup")
|
|
& !id!("Workspace_ActiveTabGroupPinned")
|
|
& !id!("Workspace_PaneDragging"),
|
|
),
|
|
EditableBinding::new(
|
|
"workspace:unpin_active_tab_group",
|
|
"Unpin current tab group",
|
|
WorkspaceAction::UnpinActiveTabGroup,
|
|
)
|
|
.with_enabled(|| {
|
|
FeatureFlag::PinnedTabs.is_enabled() && FeatureFlag::GroupedTabs.is_enabled()
|
|
})
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!("Workspace_ActiveTabInGroup")
|
|
& id!("Workspace_ActiveTabGroupPinned")
|
|
& !id!("Workspace_PaneDragging"),
|
|
),
|
|
]);
|
|
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:terminate_app",
|
|
"Quit Galaxy",
|
|
WorkspaceAction::TerminateApp,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Close.as_str())
|
|
.with_enabled(|| ContextFlag::CloseWindow.is_enabled()),
|
|
EditableBinding::new(
|
|
"workspace:close_window",
|
|
BindingDescription::new("Close Window")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Close Window"),
|
|
WorkspaceAction::CloseWindow,
|
|
)
|
|
.with_mac_key_binding("cmd-shift-W")
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Close.as_str())
|
|
.with_custom_action(CustomAction::CloseWindow)
|
|
.with_enabled(|| ContextFlag::CloseWindow.is_enabled()),
|
|
EditableBinding::new(
|
|
"workspace:close_active_tab",
|
|
"Close the current tab",
|
|
WorkspaceAction::CloseActiveTab,
|
|
)
|
|
.with_custom_action(CustomAction::CloseTab)
|
|
.with_group(bindings::BindingGroup::Close.as_str())
|
|
.with_context_predicate(
|
|
id!("Workspace") & (id!("Workspace_CloseWindow") | id!("Workspace_MultipleTabs")),
|
|
),
|
|
EditableBinding::new(
|
|
"workspace:close_other_tabs",
|
|
"Close other tabs",
|
|
WorkspaceAction::CloseNonActiveTabs,
|
|
)
|
|
.with_custom_action(CustomAction::CloseOtherTabs)
|
|
.with_group(bindings::BindingGroup::Close.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:close_tabs_right_active_tab",
|
|
BindingDescription::new("Close tabs to the right").with_dynamic_override(|ctx| {
|
|
uses_vertical_tabs(ctx).then(|| "close tabs below".into())
|
|
}),
|
|
WorkspaceAction::CloseTabsRightActiveTab,
|
|
)
|
|
.with_group(bindings::BindingGroup::Close.as_str())
|
|
.with_custom_action(CustomAction::CloseTabsRight)
|
|
.with_context_predicate(id!("Workspace")),
|
|
// We have two actions depending on the current state
|
|
// (i.e. whether notifications are already on or off).
|
|
EditableBinding::new(
|
|
"workspace:toggle_notifications_on",
|
|
"Turn notifications on",
|
|
WorkspaceAction::ToggleNotifications,
|
|
)
|
|
.with_group(bindings::BindingGroup::Notifications.as_str())
|
|
.with_context_predicate(id!("Workspace") & !id!("Notifications_Enabled")),
|
|
EditableBinding::new(
|
|
"workspace:toggle_notifications_off",
|
|
"Turn notifications off",
|
|
WorkspaceAction::ToggleNotifications,
|
|
)
|
|
.with_group(bindings::BindingGroup::Notifications.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!("Notifications_Enabled")),
|
|
EditableBinding::new(
|
|
"workspace:toggle_navigation_palette",
|
|
BindingDescription::new("Toggle navigation palette")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Navigation Palette"),
|
|
WorkspaceAction::TogglePalette {
|
|
mode: PaletteMode::Navigation,
|
|
source: PaletteSource::Keybinding,
|
|
},
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::NavigationPalette),
|
|
EditableBinding::new(
|
|
"workspace:toggle_launch_config_palette",
|
|
"Launch configuration palette",
|
|
WorkspaceAction::TogglePalette {
|
|
mode: PaletteMode::LaunchConfig,
|
|
source: PaletteSource::Keybinding,
|
|
},
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::LaunchConfigPalette)
|
|
.with_enabled(|| ContextFlag::LaunchConfigurations.is_enabled()),
|
|
EditableBinding::new(
|
|
"workspace:toggle_files_palette",
|
|
"Toggle Files Palette",
|
|
WorkspaceAction::TogglePalette {
|
|
mode: PaletteMode::Files,
|
|
source: PaletteSource::Keybinding,
|
|
},
|
|
)
|
|
.with_context_predicate(id!("Workspace") & !id!("Workspace_ViewOnlySharedSession"))
|
|
.with_custom_action(CustomAction::FilesPalette),
|
|
EditableBinding::new(
|
|
"workspace:open_launch_config_save_modal",
|
|
"Save new launch configuration",
|
|
WorkspaceAction::OpenLaunchConfigSaveModal,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::SaveCurrentConfig)
|
|
.with_enabled(|| ContextFlag::LaunchConfigurations.is_enabled()),
|
|
EditableBinding::new(
|
|
// If you rename this name, please update the name in command_palette/action/data_source.rs
|
|
"workspace:search_drive",
|
|
"Search Galaxy Drive",
|
|
WorkspaceAction::OpenPalette {
|
|
mode: PaletteMode::WarpDrive,
|
|
source: PaletteSource::Keybinding,
|
|
query: None,
|
|
},
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::SearchDrive),
|
|
]);
|
|
|
|
if FeatureFlag::Autoupdate.is_enabled() {
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:update_and_relaunch",
|
|
"Install update and relaunch",
|
|
// TODO(vorporeal): I wonder if we should change wording here?
|
|
WorkspaceAction::ApplyUpdate,
|
|
)
|
|
.with_group(bindings::BindingGroup::AutoUpdate.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!("AutoupdateState_UpdateReady"))
|
|
.with_enabled(|| ContextFlag::PromptForVersionUpdates.is_enabled()),
|
|
EditableBinding::new(
|
|
"workspace:check_for_updates",
|
|
"Check for updates",
|
|
WorkspaceAction::CheckForUpdate,
|
|
)
|
|
.with_group(bindings::BindingGroup::AutoUpdate.as_str())
|
|
.with_context_predicate(id!("Workspace") & !id!("AutoupdateState_UpdateReady"))
|
|
.with_enabled(|| ContextFlag::PromptForVersionUpdates.is_enabled()),
|
|
]);
|
|
}
|
|
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:log_out",
|
|
"Log out",
|
|
WorkspaceAction::LogOut,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace") & !id!("IsAnonymousUser"))]);
|
|
|
|
if FeatureFlag::GalaxyControlCli.is_enabled() {
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:enable_galaxy_control",
|
|
"Enable Galaxy Control",
|
|
WorkspaceAction::EnableGalaxyControl,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace") & !id!(flags::GALAXY_CONTROL_ENABLED)),
|
|
EditableBinding::new(
|
|
"workspace:disable_galaxy_control",
|
|
"Disable Galaxy Control",
|
|
WorkspaceAction::DisableGalaxyControl,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::GALAXY_CONTROL_ENABLED)),
|
|
]);
|
|
}
|
|
|
|
if !FeatureFlag::AvatarInTabBar.is_enabled() {
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:toggle_resource_center",
|
|
"Toggle resource center",
|
|
WorkspaceAction::ToggleResourceCenter,
|
|
)
|
|
.with_group(bindings::BindingGroup::Navigation.as_str())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::ToggleResourceCenter)]);
|
|
}
|
|
|
|
if cfg!(not(target_family = "wasm")) {
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:export_all_warp_drive_objects",
|
|
"Export all Galaxy Drive objects",
|
|
WorkspaceAction::ExportAllWarpDriveObjects,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE))]);
|
|
}
|
|
|
|
// Oz and Galaxy Control CLI install/uninstall actions (macOS only)
|
|
#[cfg(target_os = "macos")]
|
|
{
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:install_cli",
|
|
"Install Oz CLI globally for use outside of Warp",
|
|
WorkspaceAction::InstallOz,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:uninstall_cli",
|
|
"Undo global Oz CLI installation (oz will still work within Warp)",
|
|
WorkspaceAction::UninstallOz,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
]);
|
|
if FeatureFlag::GalaxyControlCli.is_enabled() {
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:install_galaxyctrl",
|
|
"Install Galaxy Control CLI globally",
|
|
WorkspaceAction::InstallGalaxyctrl,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:uninstall_galaxyctrl",
|
|
"Remove global Galaxy Control CLI installation",
|
|
WorkspaceAction::UninstallGalaxyctrl,
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
]);
|
|
}
|
|
}
|
|
|
|
if FeatureFlag::Changelog.is_enabled() {
|
|
app.register_editable_bindings([
|
|
// Always show the "View latest changelog" action in the command palette,
|
|
// but without a keybinding when the update toast is not visible.
|
|
EditableBinding::new(
|
|
"workspace:view_changelog",
|
|
"View latest changelog",
|
|
WorkspaceAction::ViewLatestChangelog,
|
|
)
|
|
.with_context_predicate(id!("Workspace") & !id!("UpdateToastVisible"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
// Note that while the changelog resides in WarpEssentials, we should gate access to
|
|
// the changelog based on whether WarpEssentials is an available view.
|
|
.with_enabled(|| ContextFlag::WarpEssentials.is_enabled()),
|
|
// When the update toast is visible, register the keybinding as well.
|
|
EditableBinding::new(
|
|
"workspace:view_changelog",
|
|
"View latest changelog",
|
|
WorkspaceAction::ViewLatestChangelog,
|
|
)
|
|
.with_context_predicate(id!("Workspace") & id!("UpdateToastVisible"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_custom_action(CustomAction::ViewChangelog)
|
|
.with_linux_or_windows_key_binding(format!("alt-{}", cmd_or_ctrl_shift("o")))
|
|
.with_enabled(|| ContextFlag::WarpEssentials.is_enabled()),
|
|
]);
|
|
}
|
|
|
|
// We use the same binding name for the AI Assistant and block list AI to preserve custom
|
|
// keybindings between them.
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:toggle_ai_assistant",
|
|
*NEW_AGENT_PANE_LABEL,
|
|
WorkspaceAction::NewPaneInAgentMode {
|
|
entrypoint: AgentModeEntrypoint::NewPaneBinding,
|
|
zero_state_prompt_suggestion_type: None,
|
|
},
|
|
)
|
|
.with_enabled(|| FeatureFlag::AgentMode.is_enabled())
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!(flags::IS_ANY_AI_ENABLED) & !id!("CodeEditorView"),
|
|
)
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())
|
|
.with_custom_action(CustomAction::NewAgentModePane),
|
|
EditableBinding::new(
|
|
"workspace:toggle_ai_assistant",
|
|
"Toggle Galaxy AI",
|
|
WorkspaceAction::ToggleAIAssistant,
|
|
)
|
|
.with_enabled(|| !FeatureFlag::AgentMode.is_enabled())
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!(flags::IS_ANY_AI_ENABLED) & !id!("CodeEditorView"),
|
|
)
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())
|
|
// We use the same custom action as AM so that we don't have
|
|
// two mac menu items for AM vs Warp AI since they are mutually exclusive.
|
|
.with_custom_action(CustomAction::NewAgentModePane),
|
|
]);
|
|
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:create_team_env_vars",
|
|
BindingDescription::new("Create new team environment variables")
|
|
.with_custom_description(
|
|
bindings::MAC_MENUS_CONTEXT,
|
|
"New Team Environment Variables",
|
|
),
|
|
WorkspaceAction::CreateTeamEnvVarCollection,
|
|
)
|
|
.with_custom_action(CustomAction::NewTeamEnvVars)
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!(flags::ENABLE_WARP_DRIVE)
|
|
& id!("WarpDrive_BelongsToTeam")
|
|
& id!("IsOnline"),
|
|
)
|
|
.with_group(bindings::BindingGroup::EnvVarCollection.as_str()),
|
|
EditableBinding::new(
|
|
"workspace:create_personal_env_vars",
|
|
BindingDescription::new("Create new personal environment variables")
|
|
.with_custom_description(
|
|
bindings::MAC_MENUS_CONTEXT,
|
|
"New Personal Environment Variables",
|
|
),
|
|
WorkspaceAction::CreatePersonalEnvVarCollection,
|
|
)
|
|
.with_group(bindings::BindingGroup::EnvVarCollection.as_str())
|
|
.with_custom_action(CustomAction::NewPersonalEnvVars)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE)),
|
|
EditableBinding::new(
|
|
"workspace:create_personal_ai_prompt",
|
|
BindingDescription::new("Create a new personal prompt")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "New Personal Prompt"),
|
|
WorkspaceAction::CreatePersonalAIPrompt,
|
|
)
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())
|
|
.with_custom_action(CustomAction::NewPersonalAIPrompt)
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE) & id!(flags::IS_ANY_AI_ENABLED),
|
|
),
|
|
EditableBinding::new(
|
|
"workspace:create_team_ai_prompt",
|
|
BindingDescription::new("Create a new team prompt")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "New Team Prompt"),
|
|
WorkspaceAction::CreateTeamAIPrompt,
|
|
)
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())
|
|
.with_custom_action(CustomAction::NewTeamAIPrompt)
|
|
.with_context_predicate(
|
|
id!("Workspace")
|
|
& id!(flags::ENABLE_WARP_DRIVE)
|
|
& id!("WarpDrive_BelongsToTeam")
|
|
& id!("IsOnline")
|
|
& id!(flags::IS_ANY_AI_ENABLED),
|
|
),
|
|
]);
|
|
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:shift_focus_left",
|
|
"Switch Focus to Left Panel",
|
|
WorkspaceAction::FocusLeftPanel,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_key_binding("cmdorctrl-shift-("),
|
|
EditableBinding::new(
|
|
"workspace:shift_focus_right",
|
|
"Switch Focus to Right Panel",
|
|
WorkspaceAction::FocusRightPanel,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_key_binding("cmdorctrl-shift-)"),
|
|
]);
|
|
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:import_to_personal_drive",
|
|
"Import To Personal Drive",
|
|
WorkspaceAction::ImportToPersonalDrive,
|
|
)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE)),
|
|
EditableBinding::new(
|
|
"workspace:import_to_team_drive",
|
|
"Import To Team Drive",
|
|
WorkspaceAction::ImportToTeamDrive,
|
|
)
|
|
.with_context_predicate(
|
|
id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE) & id!("WarpDrive_BelongsToTeam"),
|
|
),
|
|
]);
|
|
|
|
// Register a debug-only action for writing the user's access token to the system clipboard
|
|
// to aid debugging and development.
|
|
#[cfg(not(feature = "skip_login"))]
|
|
if ChannelState::enable_debug_features() {
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:copy_access_token_to_clipboard",
|
|
"Copy access token to clipboard",
|
|
WorkspaceAction::CopyAccessTokenToClipboard,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))]);
|
|
}
|
|
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:open_repository",
|
|
BindingDescription::new("Open repository")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Open Repository"),
|
|
WorkspaceAction::OpenRepository { path: None },
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::OpenRepository)
|
|
.with_group(bindings::BindingGroup::Folders.as_str()),
|
|
EditableBinding::new(
|
|
"workspace:open_ai_fact_collection",
|
|
BindingDescription::new("Open AI Rules")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Open AI Rules"),
|
|
WorkspaceAction::OpenAIFactCollection,
|
|
)
|
|
.with_enabled(|| FeatureFlag::AIRules.is_enabled())
|
|
.with_custom_action(CustomAction::OpenAIFactCollection)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::IS_ANY_AI_ENABLED))
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str()),
|
|
]);
|
|
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:open_mcp_servers",
|
|
BindingDescription::new("Open MCP Servers")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Open MCP Servers"),
|
|
WorkspaceAction::OpenMCPServerCollection,
|
|
)
|
|
.with_enabled(|| {
|
|
FeatureFlag::McpServer.is_enabled() && ContextFlag::ShowMCPServers.is_enabled()
|
|
})
|
|
.with_custom_action(CustomAction::OpenMCPServerCollection)
|
|
.with_context_predicate(id!("Workspace") & id!(flags::IS_ANY_AI_ENABLED))
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())]);
|
|
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:jump_to_latest_toast",
|
|
"Jump to latest agent task",
|
|
WorkspaceAction::JumpToLatestToast,
|
|
)
|
|
.with_enabled(|| FeatureFlag::AgentMode.is_enabled())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::IS_ANY_AI_ENABLED))
|
|
.with_mac_key_binding("cmd-shift-G")
|
|
.with_linux_or_windows_key_binding("ctrl-shift-G")
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())]);
|
|
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
TOGGLE_NOTIFICATION_MAILBOX_BINDING_NAME,
|
|
"Toggle notification mailbox",
|
|
WorkspaceAction::ToggleNotificationMailbox { select_first: true },
|
|
)
|
|
.with_enabled(|| FeatureFlag::HOANotifications.is_enabled())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_mac_key_binding("cmd-shift-U")
|
|
.with_linux_or_windows_key_binding("ctrl-shift-U")
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())]);
|
|
|
|
add_open_setting_pages_as_editable_binding(app);
|
|
add_overflow_menu_items_as_editable_binding(app);
|
|
|
|
app.register_editable_bindings([EditableBinding::new(
|
|
"workspace:toggle_agent_management_view",
|
|
"Toggle the agent management view",
|
|
WorkspaceAction::ToggleAgentManagementView,
|
|
)
|
|
.with_enabled(|| FeatureFlag::AgentManagementView.is_enabled())
|
|
.with_context_predicate(id!("Workspace") & id!(flags::IS_ANY_AI_ENABLED))
|
|
.with_mac_key_binding("cmd-shift-M")
|
|
.with_linux_or_windows_key_binding("ctrl-shift-M")
|
|
.with_group(bindings::BindingGroup::WarpAi.as_str())]);
|
|
}
|
|
|
|
fn add_open_setting_pages_as_editable_binding(app: &mut AppContext) {
|
|
// Add the ability to open setting modals to the command palette.
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:show_settings",
|
|
BindingDescription::new("Open Settings")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Settings"),
|
|
WorkspaceAction::ShowSettings,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_custom_action(CustomAction::ShowSettings),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_account_page",
|
|
"Open Settings: Account",
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::About),
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_custom_action(CustomAction::ShowAccount),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_appearance_page",
|
|
BindingDescription::new("Open Settings: Appearance")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Appearance..."),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::Appearance),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::ShowAppearance),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_features_page",
|
|
"Open Settings: Features",
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::Features),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_shared_blocks_page",
|
|
BindingDescription::new("Open Settings: Shared Blocks")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "View Shared Blocks..."),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::About),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::ViewSharedBlocks),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_keyboard_shortcuts_page",
|
|
BindingDescription::new("Open Settings: Keyboard Shortcuts").with_custom_description(
|
|
bindings::MAC_MENUS_CONTEXT,
|
|
"Configure Keyboard Shortcuts...",
|
|
),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::Keybindings),
|
|
)
|
|
.with_group(bindings::BindingGroup::KeyboardShortcuts.as_str())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::ConfigureKeybindings),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_about_page",
|
|
BindingDescription::new("Open Settings: About")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "About Galaxy"),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::About),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::ShowAboutGalaxy),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_teams_page",
|
|
BindingDescription::new("Open Settings: Teams")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Open Team Settings"),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::Teams),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_custom_action(CustomAction::OpenTeamSettings)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_privacy_page",
|
|
BindingDescription::new("Open Settings: Privacy"),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::Privacy),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_wormhole_page",
|
|
BindingDescription::new("Open Settings: Wormhole")
|
|
.with_custom_description(bindings::MAC_MENUS_CONTEXT, "Configure Wormhole..."),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::Wormhole),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_ai_settings_page",
|
|
BindingDescription::new("Open Settings: AI"),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::WarpAgent),
|
|
)
|
|
.with_enabled(|| FeatureFlag::AgentMode.is_enabled())
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_code_page",
|
|
BindingDescription::new("Open Settings: Code"),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::CodeIndexing),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_referrals_page",
|
|
BindingDescription::new("Open Settings: Referrals"),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::About),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_settings_environments_page",
|
|
BindingDescription::new("Open Settings: Environments"),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::About),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:show_mcp_servers_settings_page",
|
|
BindingDescription::new("Open Settings: MCP Servers"),
|
|
WorkspaceAction::ShowSettingsPage(SettingsSection::MCPServers),
|
|
)
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:open_settings_file",
|
|
"Open settings file",
|
|
WorkspaceAction::OpenSettingsFile,
|
|
)
|
|
.with_enabled(|| FeatureFlag::SettingsFile.is_enabled() && cfg!(feature = "local_fs"))
|
|
.with_group(bindings::BindingGroup::Settings.as_str())
|
|
.with_context_predicate(id!("Workspace")),
|
|
]);
|
|
}
|
|
|
|
fn add_overflow_menu_items_as_editable_binding(app: &mut AppContext) {
|
|
// Add the ability to open all overflow menu items to the command palette.
|
|
app.register_editable_bindings([
|
|
EditableBinding::new(
|
|
"workspace:show_invite_modal",
|
|
"Invite People...",
|
|
WorkspaceAction::ShowReferralSettingsPage,
|
|
)
|
|
.with_context_predicate(id!("Workspace"))
|
|
.with_custom_action(CustomAction::ReferAFriend),
|
|
EditableBinding::new(
|
|
"workspace:link_to_slack",
|
|
"Join our Slack community (opens external link)",
|
|
WorkspaceAction::JoinSlack,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:link_to_user_docs",
|
|
"View user docs (opens external link)",
|
|
WorkspaceAction::ViewUserDocs,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:send_feedback",
|
|
BindingDescription::new("Send feedback (opens external link)"),
|
|
WorkspaceAction::SendFeedback,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
#[cfg(not(target_family = "wasm"))]
|
|
EditableBinding::new(
|
|
"workspace:view_logs",
|
|
"View Galaxy logs",
|
|
WorkspaceAction::ViewLogs,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
EditableBinding::new(
|
|
"workspace:link_to_privacy_policy",
|
|
"View privacy policy (opens external link)",
|
|
WorkspaceAction::ViewPrivacyPolicy,
|
|
)
|
|
.with_context_predicate(id!("Workspace")),
|
|
]);
|
|
}
|
|
|
|
#[derive(PartialEq, Copy, Clone, Debug)]
|
|
pub struct TabBarDropTargetData {
|
|
pub tab_bar_location: TabBarLocation,
|
|
}
|
|
|
|
#[derive(PartialEq, Copy, Clone, Debug)]
|
|
pub struct VerticalTabsPaneDropTargetData {
|
|
pub tab_bar_location: TabBarLocation,
|
|
}
|
|
|
|
#[derive(PartialEq, Copy, Clone, Debug, Serialize, Deserialize)]
|
|
pub enum TabBarLocation {
|
|
TabIndex(usize),
|
|
AfterTabIndex(usize), // Indicates any area after the tabs in the tab bar, includes the total tab count
|
|
}
|
|
|
|
impl DropTargetData for TabBarDropTargetData {
|
|
fn as_any(&self) -> &dyn std::any::Any {
|
|
self
|
|
}
|
|
}
|
|
|
|
impl DropTargetData for VerticalTabsPaneDropTargetData {
|
|
fn as_any(&self) -> &dyn std::any::Any {
|
|
self
|
|
}
|
|
}
|