gpui: Add keybind metadata API (#33316)
Closes #ISSUE Adds a very simple API to track metadata about keybindings in GPUI, namely the source of the binding. The motivation for this is displaying the source of keybindings in the [keymap UI](https://github.com/zed-industries/zed/pull/32436). The API is designed to be as simple and flexible as possible, storing only a `Option<u32>` on the bindings themselves to keep the struct small. It is intended to be used as an index or key into a table/map created and managed by the consumer of the API to map from indices to arbitrary meta-data. I.e. the consumer is responsible for both generating these indices and giving them meaning. The current usage in Zed is stateless, just a mapping between constants and User, Default, Base, and Vim keymap sources, however, this can be extended in the future to also track _which_ base keymap is being used. Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
parent
13f134448d
commit
deb2564b31
6 changed files with 119 additions and 13 deletions
|
@ -3,7 +3,7 @@ use collections::{BTreeMap, HashMap, IndexMap};
|
|||
use fs::Fs;
|
||||
use gpui::{
|
||||
Action, ActionBuildError, App, InvalidKeystrokeError, KEYSTROKE_PARSE_EXPECTED_MESSAGE,
|
||||
KeyBinding, KeyBindingContextPredicate, NoAction,
|
||||
KeyBinding, KeyBindingContextPredicate, KeyBindingMetaIndex, NoAction,
|
||||
};
|
||||
use schemars::{
|
||||
JsonSchema,
|
||||
|
@ -151,9 +151,21 @@ impl KeymapFile {
|
|||
parse_json_with_comments::<Self>(content)
|
||||
}
|
||||
|
||||
pub fn load_asset(asset_path: &str, cx: &App) -> anyhow::Result<Vec<KeyBinding>> {
|
||||
pub fn load_asset(
|
||||
asset_path: &str,
|
||||
source: Option<KeybindSource>,
|
||||
cx: &App,
|
||||
) -> anyhow::Result<Vec<KeyBinding>> {
|
||||
match Self::load(asset_str::<SettingsAssets>(asset_path).as_ref(), cx) {
|
||||
KeymapFileLoadResult::Success { key_bindings } => Ok(key_bindings),
|
||||
KeymapFileLoadResult::Success { mut key_bindings } => match source {
|
||||
Some(source) => Ok({
|
||||
for key_binding in &mut key_bindings {
|
||||
key_binding.set_meta(source.meta());
|
||||
}
|
||||
key_bindings
|
||||
}),
|
||||
None => Ok(key_bindings),
|
||||
},
|
||||
KeymapFileLoadResult::SomeFailedToLoad { error_message, .. } => {
|
||||
anyhow::bail!("Error loading built-in keymap \"{asset_path}\": {error_message}",)
|
||||
}
|
||||
|
@ -619,6 +631,61 @@ impl KeymapFile {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum KeybindSource {
|
||||
User,
|
||||
Default,
|
||||
Base,
|
||||
Vim,
|
||||
}
|
||||
|
||||
impl KeybindSource {
|
||||
const BASE: KeyBindingMetaIndex = KeyBindingMetaIndex(0);
|
||||
const DEFAULT: KeyBindingMetaIndex = KeyBindingMetaIndex(1);
|
||||
const VIM: KeyBindingMetaIndex = KeyBindingMetaIndex(2);
|
||||
const USER: KeyBindingMetaIndex = KeyBindingMetaIndex(3);
|
||||
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
KeybindSource::User => "User",
|
||||
KeybindSource::Default => "Default",
|
||||
KeybindSource::Base => "Base",
|
||||
KeybindSource::Vim => "Vim",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta(&self) -> KeyBindingMetaIndex {
|
||||
match self {
|
||||
KeybindSource::User => Self::USER,
|
||||
KeybindSource::Default => Self::DEFAULT,
|
||||
KeybindSource::Base => Self::BASE,
|
||||
KeybindSource::Vim => Self::VIM,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_meta(index: KeyBindingMetaIndex) -> Self {
|
||||
match index {
|
||||
_ if index == Self::USER => KeybindSource::User,
|
||||
_ if index == Self::USER => KeybindSource::Base,
|
||||
_ if index == Self::DEFAULT => KeybindSource::Default,
|
||||
_ if index == Self::VIM => KeybindSource::Vim,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeyBindingMetaIndex> for KeybindSource {
|
||||
fn from(index: KeyBindingMetaIndex) -> Self {
|
||||
Self::from_meta(index)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeybindSource> for KeyBindingMetaIndex {
|
||||
fn from(source: KeybindSource) -> Self {
|
||||
return source.meta();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::KeymapFile;
|
||||
|
|
|
@ -15,7 +15,8 @@ pub use editable_setting_control::*;
|
|||
pub use json_schema::*;
|
||||
pub use key_equivalents::*;
|
||||
pub use keymap_file::{
|
||||
KeyBindingValidator, KeyBindingValidatorRegistration, KeymapFile, KeymapFileLoadResult,
|
||||
KeyBindingValidator, KeyBindingValidatorRegistration, KeybindSource, KeymapFile,
|
||||
KeymapFileLoadResult,
|
||||
};
|
||||
pub use settings_file::*;
|
||||
pub use settings_store::{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue