Add KeyBindings to CommandPalette
This commit is contained in:
parent
b918c27cf9
commit
25bc898807
7 changed files with 116 additions and 273 deletions
|
@ -11,7 +11,7 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
use ui::{v_stack, HighlightedLabel, StyledExt};
|
use ui::{h_stack, v_stack, HighlightedLabel, KeyBinding, StyledExt};
|
||||||
use util::{
|
use util::{
|
||||||
channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL},
|
channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL},
|
||||||
ResultExt,
|
ResultExt,
|
||||||
|
@ -318,66 +318,16 @@ impl PickerDelegate for CommandPaletteDelegate {
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
.when(selected, |this| this.bg(colors.ghost_element_selected))
|
.when(selected, |this| this.bg(colors.ghost_element_selected))
|
||||||
.hover(|this| this.bg(colors.ghost_element_hover))
|
.hover(|this| this.bg(colors.ghost_element_hover))
|
||||||
.child(HighlightedLabel::new(
|
.child(
|
||||||
command.name.clone(),
|
h_stack()
|
||||||
r#match.positions.clone(),
|
.justify_between()
|
||||||
))
|
.child(HighlightedLabel::new(
|
||||||
|
command.name.clone(),
|
||||||
|
r#match.positions.clone(),
|
||||||
|
))
|
||||||
|
.children(KeyBinding::for_action(&*command.action, cx)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn render_match(
|
|
||||||
// &self,
|
|
||||||
// ix: usize,
|
|
||||||
// mouse_state: &mut MouseState,
|
|
||||||
// selected: bool,
|
|
||||||
// cx: &gpui::AppContext,
|
|
||||||
// ) -> AnyElement<Picker<Self>> {
|
|
||||||
// let mat = &self.matches[ix];
|
|
||||||
// let command = &self.actions[mat.candidate_id];
|
|
||||||
// let theme = theme::current(cx);
|
|
||||||
// let style = theme.picker.item.in_state(selected).style_for(mouse_state);
|
|
||||||
// let key_style = &theme.command_palette.key.in_state(selected);
|
|
||||||
// let keystroke_spacing = theme.command_palette.keystroke_spacing;
|
|
||||||
|
|
||||||
// Flex::row()
|
|
||||||
// .with_child(
|
|
||||||
// Label::new(mat.string.clone(), style.label.clone())
|
|
||||||
// .with_highlights(mat.positions.clone()),
|
|
||||||
// )
|
|
||||||
// .with_children(command.keystrokes.iter().map(|keystroke| {
|
|
||||||
// Flex::row()
|
|
||||||
// .with_children(
|
|
||||||
// [
|
|
||||||
// (keystroke.ctrl, "^"),
|
|
||||||
// (keystroke.alt, "⌥"),
|
|
||||||
// (keystroke.cmd, "⌘"),
|
|
||||||
// (keystroke.shift, "⇧"),
|
|
||||||
// ]
|
|
||||||
// .into_iter()
|
|
||||||
// .filter_map(|(modifier, label)| {
|
|
||||||
// if modifier {
|
|
||||||
// Some(
|
|
||||||
// Label::new(label, key_style.label.clone())
|
|
||||||
// .contained()
|
|
||||||
// .with_style(key_style.container),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// }
|
|
||||||
// }),
|
|
||||||
// )
|
|
||||||
// .with_child(
|
|
||||||
// Label::new(keystroke.key.clone(), key_style.label.clone())
|
|
||||||
// .contained()
|
|
||||||
// .with_style(key_style.container),
|
|
||||||
// )
|
|
||||||
// .contained()
|
|
||||||
// .with_margin_left(keystroke_spacing)
|
|
||||||
// .flex_float()
|
|
||||||
// }))
|
|
||||||
// .contained()
|
|
||||||
// .with_style(style.container)
|
|
||||||
// .into_any()
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn humanize_action_name(name: &str) -> String {
|
fn humanize_action_name(name: &str) -> String {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
build_action_from_type, Action, Bounds, DispatchPhase, Element, FocusEvent, FocusHandle,
|
build_action_from_type, Action, Bounds, DispatchPhase, Element, FocusEvent, FocusHandle,
|
||||||
FocusId, KeyContext, KeyMatch, Keymap, Keystroke, KeystrokeMatcher, MouseDownEvent, Pixels,
|
FocusId, KeyBinding, KeyContext, KeyMatch, Keymap, Keystroke, KeystrokeMatcher, MouseDownEvent,
|
||||||
Style, StyleRefinement, ViewContext, WindowContext,
|
Pixels, Style, StyleRefinement, ViewContext, WindowContext,
|
||||||
};
|
};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
@ -145,6 +145,15 @@ impl DispatchTree {
|
||||||
actions
|
actions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
|
||||||
|
self.keymap
|
||||||
|
.lock()
|
||||||
|
.bindings_for_action(action.type_id())
|
||||||
|
.filter(|candidate| candidate.action.partial_eq(action))
|
||||||
|
.cloned()
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dispatch_key(
|
pub fn dispatch_key(
|
||||||
&mut self,
|
&mut self,
|
||||||
keystroke: &Keystroke,
|
keystroke: &Keystroke,
|
||||||
|
|
|
@ -3,9 +3,19 @@ use anyhow::Result;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
pub struct KeyBinding {
|
pub struct KeyBinding {
|
||||||
action: Box<dyn Action>,
|
pub(crate) action: Box<dyn Action>,
|
||||||
pub(super) keystrokes: SmallVec<[Keystroke; 2]>,
|
pub(crate) keystrokes: SmallVec<[Keystroke; 2]>,
|
||||||
pub(super) context_predicate: Option<KeyBindingContextPredicate>,
|
pub(crate) context_predicate: Option<KeyBindingContextPredicate>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for KeyBinding {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
KeyBinding {
|
||||||
|
action: self.action.boxed_clone(),
|
||||||
|
keystrokes: self.keystrokes.clone(),
|
||||||
|
context_predicate: self.context_predicate.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyBinding {
|
impl KeyBinding {
|
||||||
|
|
|
@ -3,13 +3,13 @@ use crate::{
|
||||||
AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
|
AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
|
||||||
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
|
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
|
||||||
EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla, ImageData,
|
EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla, ImageData,
|
||||||
InputEvent, IsZero, KeyContext, KeyDownEvent, LayoutId, Model, ModelContext, Modifiers,
|
InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, LayoutId, Model, ModelContext,
|
||||||
MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels,
|
Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path,
|
||||||
PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite,
|
Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
|
||||||
PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels,
|
PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
|
||||||
SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet, Subscription,
|
RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet,
|
||||||
TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, WeakView,
|
Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext,
|
||||||
WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
|
WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
@ -1377,6 +1377,13 @@ impl<'a> WindowContext<'a> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
|
||||||
|
self.window
|
||||||
|
.current_frame
|
||||||
|
.dispatch_tree
|
||||||
|
.bindings_for_action(action)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context for WindowContext<'_> {
|
impl Context for WindowContext<'_> {
|
||||||
|
|
|
@ -1,50 +1,42 @@
|
||||||
use std::collections::HashSet;
|
use gpui::Action;
|
||||||
|
use strum::EnumIter;
|
||||||
use strum::{EnumIter, IntoEnumIterator};
|
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Keybinding {
|
pub struct KeyBinding {
|
||||||
/// A keybinding consists of a key and a set of modifier keys.
|
/// A keybinding consists of a key and a set of modifier keys.
|
||||||
/// More then one keybinding produces a chord.
|
/// More then one keybinding produces a chord.
|
||||||
///
|
///
|
||||||
/// This should always contain at least one element.
|
/// This should always contain at least one element.
|
||||||
keybinding: Vec<(String, ModifierKeys)>,
|
key_binding: gpui::KeyBinding,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Keybinding {
|
impl KeyBinding {
|
||||||
pub fn new(key: String, modifiers: ModifierKeys) -> Self {
|
pub fn for_action(action: &dyn Action, cx: &mut WindowContext) -> Option<Self> {
|
||||||
Self {
|
// todo! this last is arbitrary, we want to prefer users key bindings over defaults,
|
||||||
keybinding: vec![(key, modifiers)],
|
// and vim over normal (in vim mode), etc.
|
||||||
}
|
let key_binding = cx.bindings_for_action(action).last().cloned()?;
|
||||||
|
Some(Self::new(key_binding))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_chord(
|
pub fn new(key_binding: gpui::KeyBinding) -> Self {
|
||||||
first_note: (String, ModifierKeys),
|
Self { key_binding }
|
||||||
second_note: (String, ModifierKeys),
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
keybinding: vec![first_note, second_note],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||||
div()
|
div()
|
||||||
.flex()
|
.flex()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.children(self.keybinding.iter().map(|(key, modifiers)| {
|
.children(self.key_binding.keystrokes().iter().map(|keystroke| {
|
||||||
div()
|
div()
|
||||||
.flex()
|
.flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.children(ModifierKey::iter().filter_map(|modifier| {
|
.when(keystroke.modifiers.control, |el| el.child(Key::new("^")))
|
||||||
if modifiers.0.contains(&modifier) {
|
.when(keystroke.modifiers.alt, |el| el.child(Key::new("⌥")))
|
||||||
Some(Key::new(modifier.glyph().to_string()))
|
.when(keystroke.modifiers.command, |el| el.child(Key::new("⌘")))
|
||||||
} else {
|
.when(keystroke.modifiers.shift, |el| el.child(Key::new("⇧")))
|
||||||
None
|
.child(Key::new(keystroke.key.clone()))
|
||||||
}
|
|
||||||
}))
|
|
||||||
.child(Key::new(key.clone()))
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,76 +73,6 @@ pub enum ModifierKey {
|
||||||
Shift,
|
Shift,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModifierKey {
|
|
||||||
/// Returns the glyph for the [`ModifierKey`].
|
|
||||||
pub fn glyph(&self) -> char {
|
|
||||||
match self {
|
|
||||||
Self::Control => '^',
|
|
||||||
Self::Alt => '⌥',
|
|
||||||
Self::Command => '⌘',
|
|
||||||
Self::Shift => '⇧',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ModifierKeys(HashSet<ModifierKey>);
|
|
||||||
|
|
||||||
impl ModifierKeys {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self(HashSet::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn all() -> Self {
|
|
||||||
Self(HashSet::from_iter(ModifierKey::iter()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(mut self, modifier: ModifierKey) -> Self {
|
|
||||||
self.0.insert(modifier);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn control(mut self, control: bool) -> Self {
|
|
||||||
if control {
|
|
||||||
self.0.insert(ModifierKey::Control);
|
|
||||||
} else {
|
|
||||||
self.0.remove(&ModifierKey::Control);
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alt(mut self, alt: bool) -> Self {
|
|
||||||
if alt {
|
|
||||||
self.0.insert(ModifierKey::Alt);
|
|
||||||
} else {
|
|
||||||
self.0.remove(&ModifierKey::Alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn command(mut self, command: bool) -> Self {
|
|
||||||
if command {
|
|
||||||
self.0.insert(ModifierKey::Command);
|
|
||||||
} else {
|
|
||||||
self.0.remove(&ModifierKey::Command);
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shift(mut self, shift: bool) -> Self {
|
|
||||||
if shift {
|
|
||||||
self.0.insert(ModifierKey::Shift);
|
|
||||||
} else {
|
|
||||||
self.0.remove(&ModifierKey::Shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "stories")]
|
#[cfg(feature = "stories")]
|
||||||
pub use stories::*;
|
pub use stories::*;
|
||||||
|
|
||||||
|
@ -158,29 +80,38 @@ pub use stories::*;
|
||||||
mod stories {
|
mod stories {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::Story;
|
use crate::Story;
|
||||||
use gpui::{Div, Render};
|
use gpui::{action, Div, Render};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
pub struct KeybindingStory;
|
pub struct KeybindingStory;
|
||||||
|
|
||||||
|
#[action]
|
||||||
|
struct NoAction {}
|
||||||
|
|
||||||
|
pub fn binding(key: &str) -> gpui::KeyBinding {
|
||||||
|
gpui::KeyBinding::new(key, NoAction {}, None)
|
||||||
|
}
|
||||||
|
|
||||||
impl Render for KeybindingStory {
|
impl Render for KeybindingStory {
|
||||||
type Element = Div<Self>;
|
type Element = Div<Self>;
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
let all_modifier_permutations = ModifierKey::iter().permutations(2);
|
let all_modifier_permutations =
|
||||||
|
["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
|
||||||
|
|
||||||
Story::container(cx)
|
Story::container(cx)
|
||||||
.child(Story::title_for::<_, Keybinding>(cx))
|
.child(Story::title_for::<_, KeyBinding>(cx))
|
||||||
.child(Story::label(cx, "Single Key"))
|
.child(Story::label(cx, "Single Key"))
|
||||||
.child(Keybinding::new("Z".to_string(), ModifierKeys::new()))
|
.child(KeyBinding::new(binding("Z")))
|
||||||
.child(Story::label(cx, "Single Key with Modifier"))
|
.child(Story::label(cx, "Single Key with Modifier"))
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex()
|
.flex()
|
||||||
.gap_3()
|
.gap_3()
|
||||||
.children(ModifierKey::iter().map(|modifier| {
|
.child(KeyBinding::new(binding("ctrl-c")))
|
||||||
Keybinding::new("C".to_string(), ModifierKeys::new().add(modifier))
|
.child(KeyBinding::new(binding("alt-c")))
|
||||||
})),
|
.child(KeyBinding::new(binding("cmd-c")))
|
||||||
|
.child(KeyBinding::new(binding("shift-c"))),
|
||||||
)
|
)
|
||||||
.child(Story::label(cx, "Single Key with Modifier (Permuted)"))
|
.child(Story::label(cx, "Single Key with Modifier (Permuted)"))
|
||||||
.child(
|
.child(
|
||||||
|
@ -194,29 +125,17 @@ mod stories {
|
||||||
.gap_4()
|
.gap_4()
|
||||||
.py_3()
|
.py_3()
|
||||||
.children(chunk.map(|permutation| {
|
.children(chunk.map(|permutation| {
|
||||||
let mut modifiers = ModifierKeys::new();
|
KeyBinding::new(binding(&*(permutation.join("-") + "-x")))
|
||||||
|
|
||||||
for modifier in permutation {
|
|
||||||
modifiers = modifiers.add(modifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
Keybinding::new("X".to_string(), modifiers)
|
|
||||||
}))
|
}))
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(Story::label(cx, "Single Key with All Modifiers"))
|
.child(Story::label(cx, "Single Key with All Modifiers"))
|
||||||
.child(Keybinding::new("Z".to_string(), ModifierKeys::all()))
|
.child(KeyBinding::new(binding("ctrl-alt-cmd-shift-z")))
|
||||||
.child(Story::label(cx, "Chord"))
|
.child(Story::label(cx, "Chord"))
|
||||||
.child(Keybinding::new_chord(
|
.child(KeyBinding::new(binding("a z")))
|
||||||
("A".to_string(), ModifierKeys::new()),
|
|
||||||
("Z".to_string(), ModifierKeys::new()),
|
|
||||||
))
|
|
||||||
.child(Story::label(cx, "Chord with Modifier"))
|
.child(Story::label(cx, "Chord with Modifier"))
|
||||||
.child(Keybinding::new_chord(
|
.child(KeyBinding::new(binding("ctrl-a shift-z")))
|
||||||
("A".to_string(), ModifierKeys::new().control(true)),
|
|
||||||
("Z".to_string(), ModifierKeys::new().shift(true)),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{h_stack, v_stack, Keybinding, Label, LabelColor};
|
use crate::{h_stack, v_stack, KeyBinding, Label, LabelColor};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Palette {
|
pub struct Palette {
|
||||||
|
@ -108,7 +108,7 @@ impl Palette {
|
||||||
pub struct PaletteItem {
|
pub struct PaletteItem {
|
||||||
pub label: SharedString,
|
pub label: SharedString,
|
||||||
pub sublabel: Option<SharedString>,
|
pub sublabel: Option<SharedString>,
|
||||||
pub keybinding: Option<Keybinding>,
|
pub keybinding: Option<KeyBinding>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaletteItem {
|
impl PaletteItem {
|
||||||
|
@ -132,7 +132,7 @@ impl PaletteItem {
|
||||||
|
|
||||||
pub fn keybinding<K>(mut self, keybinding: K) -> Self
|
pub fn keybinding<K>(mut self, keybinding: K) -> Self
|
||||||
where
|
where
|
||||||
K: Into<Option<Keybinding>>,
|
K: Into<Option<KeyBinding>>,
|
||||||
{
|
{
|
||||||
self.keybinding = keybinding.into();
|
self.keybinding = keybinding.into();
|
||||||
self
|
self
|
||||||
|
@ -161,7 +161,7 @@ pub use stories::*;
|
||||||
mod stories {
|
mod stories {
|
||||||
use gpui::{Div, Render};
|
use gpui::{Div, Render};
|
||||||
|
|
||||||
use crate::{ModifierKeys, Story};
|
use crate::{binding, Story};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -181,46 +181,24 @@ mod stories {
|
||||||
Palette::new("palette-2")
|
Palette::new("palette-2")
|
||||||
.placeholder("Execute a command...")
|
.placeholder("Execute a command...")
|
||||||
.items(vec![
|
.items(vec![
|
||||||
PaletteItem::new("theme selector: toggle").keybinding(
|
PaletteItem::new("theme selector: toggle")
|
||||||
Keybinding::new_chord(
|
.keybinding(KeyBinding::new(binding("cmd-k cmd-t"))),
|
||||||
("k".to_string(), ModifierKeys::new().command(true)),
|
PaletteItem::new("assistant: inline assist")
|
||||||
("t".to_string(), ModifierKeys::new().command(true)),
|
.keybinding(KeyBinding::new(binding("cmd-enter"))),
|
||||||
),
|
PaletteItem::new("assistant: quote selection")
|
||||||
),
|
.keybinding(KeyBinding::new(binding("cmd-<"))),
|
||||||
PaletteItem::new("assistant: inline assist").keybinding(
|
PaletteItem::new("assistant: toggle focus")
|
||||||
Keybinding::new(
|
.keybinding(KeyBinding::new(binding("cmd-?"))),
|
||||||
"enter".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PaletteItem::new("assistant: quote selection").keybinding(
|
|
||||||
Keybinding::new(
|
|
||||||
">".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PaletteItem::new("assistant: toggle focus").keybinding(
|
|
||||||
Keybinding::new(
|
|
||||||
"?".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PaletteItem::new("auto update: check"),
|
PaletteItem::new("auto update: check"),
|
||||||
PaletteItem::new("auto update: view release notes"),
|
PaletteItem::new("auto update: view release notes"),
|
||||||
PaletteItem::new("branches: open recent").keybinding(
|
PaletteItem::new("branches: open recent")
|
||||||
Keybinding::new(
|
.keybinding(KeyBinding::new(binding("cmd-alt-b"))),
|
||||||
"b".to_string(),
|
|
||||||
ModifierKeys::new().command(true).alt(true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PaletteItem::new("chat panel: toggle focus"),
|
PaletteItem::new("chat panel: toggle focus"),
|
||||||
PaletteItem::new("cli: install"),
|
PaletteItem::new("cli: install"),
|
||||||
PaletteItem::new("client: sign in"),
|
PaletteItem::new("client: sign in"),
|
||||||
PaletteItem::new("client: sign out"),
|
PaletteItem::new("client: sign out"),
|
||||||
PaletteItem::new("editor: cancel").keybinding(Keybinding::new(
|
PaletteItem::new("editor: cancel")
|
||||||
"escape".to_string(),
|
.keybinding(KeyBinding::new(binding("escape"))),
|
||||||
ModifierKeys::new(),
|
|
||||||
)),
|
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,12 @@ use gpui::{AppContext, ViewContext};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use theme2::ActiveTheme;
|
use theme2::ActiveTheme;
|
||||||
|
|
||||||
use crate::HighlightedText;
|
use crate::{binding, HighlightedText};
|
||||||
use crate::{
|
use crate::{
|
||||||
Buffer, BufferRow, BufferRows, Button, EditorPane, FileSystemStatus, GitStatus,
|
Buffer, BufferRow, BufferRows, Button, EditorPane, FileSystemStatus, GitStatus,
|
||||||
HighlightedLine, Icon, Keybinding, Label, LabelColor, ListEntry, ListEntrySize, Livestream,
|
HighlightedLine, Icon, KeyBinding, Label, LabelColor, ListEntry, ListEntrySize, Livestream,
|
||||||
MicStatus, ModifierKeys, Notification, PaletteItem, Player, PlayerCallStatus,
|
MicStatus, Notification, PaletteItem, Player, PlayerCallStatus, PlayerWithCallStatus,
|
||||||
PlayerWithCallStatus, PublicPlayer, ScreenShareStatus, Symbol, Tab, Toggle, VideoStatus,
|
PublicPlayer, ScreenShareStatus, Symbol, Tab, Toggle, VideoStatus,
|
||||||
};
|
};
|
||||||
use crate::{ListItem, NotificationAction};
|
use crate::{ListItem, NotificationAction};
|
||||||
|
|
||||||
|
@ -701,46 +701,16 @@ pub fn static_collab_panel_channels() -> Vec<ListItem> {
|
||||||
|
|
||||||
pub fn example_editor_actions() -> Vec<PaletteItem> {
|
pub fn example_editor_actions() -> Vec<PaletteItem> {
|
||||||
vec![
|
vec![
|
||||||
PaletteItem::new("New File").keybinding(Keybinding::new(
|
PaletteItem::new("New File").keybinding(KeyBinding::new(binding("cmd-n"))),
|
||||||
"N".to_string(),
|
PaletteItem::new("Open File").keybinding(KeyBinding::new(binding("cmd-o"))),
|
||||||
ModifierKeys::new().command(true),
|
PaletteItem::new("Save File").keybinding(KeyBinding::new(binding("cmd-s"))),
|
||||||
)),
|
PaletteItem::new("Cut").keybinding(KeyBinding::new(binding("cmd-x"))),
|
||||||
PaletteItem::new("Open File").keybinding(Keybinding::new(
|
PaletteItem::new("Copy").keybinding(KeyBinding::new(binding("cmd-c"))),
|
||||||
"O".to_string(),
|
PaletteItem::new("Paste").keybinding(KeyBinding::new(binding("cmd-v"))),
|
||||||
ModifierKeys::new().command(true),
|
PaletteItem::new("Undo").keybinding(KeyBinding::new(binding("cmd-z"))),
|
||||||
)),
|
PaletteItem::new("Redo").keybinding(KeyBinding::new(binding("cmd-shift-z"))),
|
||||||
PaletteItem::new("Save File").keybinding(Keybinding::new(
|
PaletteItem::new("Find").keybinding(KeyBinding::new(binding("cmd-f"))),
|
||||||
"S".to_string(),
|
PaletteItem::new("Replace").keybinding(KeyBinding::new(binding("cmd-r"))),
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("Cut").keybinding(Keybinding::new(
|
|
||||||
"X".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("Copy").keybinding(Keybinding::new(
|
|
||||||
"C".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("Paste").keybinding(Keybinding::new(
|
|
||||||
"V".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("Undo").keybinding(Keybinding::new(
|
|
||||||
"Z".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("Redo").keybinding(Keybinding::new(
|
|
||||||
"Z".to_string(),
|
|
||||||
ModifierKeys::new().command(true).shift(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("Find").keybinding(Keybinding::new(
|
|
||||||
"F".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("Replace").keybinding(Keybinding::new(
|
|
||||||
"R".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("Jump to Line"),
|
PaletteItem::new("Jump to Line"),
|
||||||
PaletteItem::new("Select All"),
|
PaletteItem::new("Select All"),
|
||||||
PaletteItem::new("Deselect All"),
|
PaletteItem::new("Deselect All"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue