keymap_ui: Add auto-complete for context in keybind editor (#34031)
Closes #ISSUE Implements a very basic completion provider that is attached to the context editor in the keybind editing modal. The context identifiers used for completions are scraped from the default, vim, and base keymaps on demand. Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
parent
66a1c356bf
commit
877ef5e1b1
10 changed files with 163 additions and 20 deletions
120
crates/settings/src/base_keymap_setting.rs
Normal file
120
crates/settings/src/base_keymap_setting.rs
Normal file
|
@ -0,0 +1,120 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use crate::{Settings, SettingsSources, VsCodeSettings};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
|
||||
///
|
||||
/// Default: VSCode
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
|
||||
pub enum BaseKeymap {
|
||||
#[default]
|
||||
VSCode,
|
||||
JetBrains,
|
||||
SublimeText,
|
||||
Atom,
|
||||
TextMate,
|
||||
Emacs,
|
||||
Cursor,
|
||||
None,
|
||||
}
|
||||
|
||||
impl Display for BaseKeymap {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
BaseKeymap::VSCode => write!(f, "VSCode"),
|
||||
BaseKeymap::JetBrains => write!(f, "JetBrains"),
|
||||
BaseKeymap::SublimeText => write!(f, "Sublime Text"),
|
||||
BaseKeymap::Atom => write!(f, "Atom"),
|
||||
BaseKeymap::TextMate => write!(f, "TextMate"),
|
||||
BaseKeymap::Emacs => write!(f, "Emacs (beta)"),
|
||||
BaseKeymap::Cursor => write!(f, "Cursor (beta)"),
|
||||
BaseKeymap::None => write!(f, "None"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BaseKeymap {
|
||||
#[cfg(target_os = "macos")]
|
||||
pub const OPTIONS: [(&'static str, Self); 7] = [
|
||||
("VSCode (Default)", Self::VSCode),
|
||||
("Atom", Self::Atom),
|
||||
("JetBrains", Self::JetBrains),
|
||||
("Sublime Text", Self::SublimeText),
|
||||
("Emacs (beta)", Self::Emacs),
|
||||
("TextMate", Self::TextMate),
|
||||
("Cursor (beta)", Self::Cursor),
|
||||
];
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub const OPTIONS: [(&'static str, Self); 6] = [
|
||||
("VSCode (Default)", Self::VSCode),
|
||||
("Atom", Self::Atom),
|
||||
("JetBrains", Self::JetBrains),
|
||||
("Sublime Text", Self::SublimeText),
|
||||
("Emacs (beta)", Self::Emacs),
|
||||
("Cursor (beta)", Self::Cursor),
|
||||
];
|
||||
|
||||
pub fn asset_path(&self) -> Option<&'static str> {
|
||||
#[cfg(target_os = "macos")]
|
||||
match self {
|
||||
BaseKeymap::JetBrains => Some("keymaps/macos/jetbrains.json"),
|
||||
BaseKeymap::SublimeText => Some("keymaps/macos/sublime_text.json"),
|
||||
BaseKeymap::Atom => Some("keymaps/macos/atom.json"),
|
||||
BaseKeymap::TextMate => Some("keymaps/macos/textmate.json"),
|
||||
BaseKeymap::Emacs => Some("keymaps/macos/emacs.json"),
|
||||
BaseKeymap::Cursor => Some("keymaps/macos/cursor.json"),
|
||||
BaseKeymap::VSCode => None,
|
||||
BaseKeymap::None => None,
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
match self {
|
||||
BaseKeymap::JetBrains => Some("keymaps/linux/jetbrains.json"),
|
||||
BaseKeymap::SublimeText => Some("keymaps/linux/sublime_text.json"),
|
||||
BaseKeymap::Atom => Some("keymaps/linux/atom.json"),
|
||||
BaseKeymap::Emacs => Some("keymaps/linux/emacs.json"),
|
||||
BaseKeymap::Cursor => Some("keymaps/linux/cursor.json"),
|
||||
BaseKeymap::TextMate => None,
|
||||
BaseKeymap::VSCode => None,
|
||||
BaseKeymap::None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn names() -> impl Iterator<Item = &'static str> {
|
||||
Self::OPTIONS.iter().map(|(name, _)| *name)
|
||||
}
|
||||
|
||||
pub fn from_names(option: &str) -> BaseKeymap {
|
||||
Self::OPTIONS
|
||||
.iter()
|
||||
.copied()
|
||||
.find_map(|(name, value)| (name == option).then_some(value))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Settings for BaseKeymap {
|
||||
const KEY: Option<&'static str> = Some("base_keymap");
|
||||
|
||||
type FileContent = Option<Self>;
|
||||
|
||||
fn load(
|
||||
sources: SettingsSources<Self::FileContent>,
|
||||
_: &mut gpui::App,
|
||||
) -> anyhow::Result<Self> {
|
||||
if let Some(Some(user_value)) = sources.user.copied() {
|
||||
return Ok(user_value);
|
||||
}
|
||||
if let Some(Some(server_value)) = sources.server.copied() {
|
||||
return Ok(server_value);
|
||||
}
|
||||
sources.default.ok_or_else(Self::missing_default)
|
||||
}
|
||||
|
||||
fn import_from_vscode(_vscode: &VsCodeSettings, current: &mut Self::FileContent) {
|
||||
*current = Some(BaseKeymap::VSCode);
|
||||
}
|
||||
}
|
|
@ -63,7 +63,7 @@ pub struct KeymapSection {
|
|||
/// current file extension are also supported - see [the
|
||||
/// documentation](https://zed.dev/docs/key-bindings#contexts) for more details.
|
||||
#[serde(default)]
|
||||
context: String,
|
||||
pub context: String,
|
||||
/// This option enables specifying keys based on their position on a QWERTY keyboard, by using
|
||||
/// position-equivalent mappings for some non-QWERTY keyboards. This is currently only supported
|
||||
/// on macOS. See the documentation for more details.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
mod base_keymap_setting;
|
||||
mod editable_setting_control;
|
||||
mod key_equivalents;
|
||||
mod keymap_file;
|
||||
|
@ -11,6 +12,7 @@ use rust_embed::RustEmbed;
|
|||
use std::{borrow::Cow, fmt, str};
|
||||
use util::asset_str;
|
||||
|
||||
pub use base_keymap_setting::*;
|
||||
pub use editable_setting_control::*;
|
||||
pub use key_equivalents::*;
|
||||
pub use keymap_file::{
|
||||
|
@ -71,6 +73,7 @@ pub fn init(cx: &mut App) {
|
|||
.set_default_settings(&default_settings(), cx)
|
||||
.unwrap();
|
||||
cx.set_global(settings);
|
||||
BaseKeymap::register(cx);
|
||||
}
|
||||
|
||||
pub fn default_settings() -> Cow<'static, str> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue