keymap_ui: Create language for Zed keybind context (#34558)
Closes #ISSUE Creates a new language in the languages crate for the DSL used in Zed keybinding context. Previously, keybind context was highlighted as Rust in the keymap UI due to the expression syntax of Rust matching that of the context DSL, however, this had the side effect of highlighting upper case contexts (e.g. `Editor`) however Rust types would be highlighted based on the theme. By extracting only the necessary pieces of the Rust language `highlights.scm`, `brackets.scm`, and `config.toml`, and continuing to use the Rust grammar, we get a better result across different themes Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
parent
313f5968eb
commit
58807f0dd2
6 changed files with 65 additions and 13 deletions
|
@ -212,6 +212,10 @@ pub fn init(languages: Arc<LanguageRegistry>, node: NodeRuntime, cx: &mut App) {
|
||||||
name: "gitcommit",
|
name: "gitcommit",
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
LanguageInfo {
|
||||||
|
name: "zed-keybind-context",
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
for registration in built_in_languages {
|
for registration in built_in_languages {
|
||||||
|
|
1
crates/languages/src/zed-keybind-context/brackets.scm
Normal file
1
crates/languages/src/zed-keybind-context/brackets.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
("(" @open ")" @close)
|
6
crates/languages/src/zed-keybind-context/config.toml
Normal file
6
crates/languages/src/zed-keybind-context/config.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
name = "Zed Keybind Context"
|
||||||
|
grammar = "rust"
|
||||||
|
autoclose_before = ")"
|
||||||
|
brackets = [
|
||||||
|
{ start = "(", end = ")", close = true, newline = false },
|
||||||
|
]
|
23
crates/languages/src/zed-keybind-context/highlights.scm
Normal file
23
crates/languages/src/zed-keybind-context/highlights.scm
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
(identifier) @variable
|
||||||
|
|
||||||
|
[
|
||||||
|
"("
|
||||||
|
")"
|
||||||
|
] @punctuation.bracket
|
||||||
|
|
||||||
|
[
|
||||||
|
(integer_literal)
|
||||||
|
(float_literal)
|
||||||
|
] @number
|
||||||
|
|
||||||
|
(boolean_literal) @boolean
|
||||||
|
|
||||||
|
[
|
||||||
|
"!="
|
||||||
|
"=="
|
||||||
|
"=>"
|
||||||
|
">"
|
||||||
|
"&&"
|
||||||
|
"||"
|
||||||
|
"!"
|
||||||
|
] @operator
|
|
@ -505,7 +505,7 @@ impl KeymapEditor {
|
||||||
|
|
||||||
fn process_bindings(
|
fn process_bindings(
|
||||||
json_language: Arc<Language>,
|
json_language: Arc<Language>,
|
||||||
rust_language: Arc<Language>,
|
zed_keybind_context_language: Arc<Language>,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> (Vec<ProcessedKeybinding>, Vec<StringMatchCandidate>) {
|
) -> (Vec<ProcessedKeybinding>, Vec<StringMatchCandidate>) {
|
||||||
let key_bindings_ptr = cx.key_bindings();
|
let key_bindings_ptr = cx.key_bindings();
|
||||||
|
@ -536,7 +536,10 @@ impl KeymapEditor {
|
||||||
let context = key_binding
|
let context = key_binding
|
||||||
.predicate()
|
.predicate()
|
||||||
.map(|predicate| {
|
.map(|predicate| {
|
||||||
KeybindContextString::Local(predicate.to_string().into(), rust_language.clone())
|
KeybindContextString::Local(
|
||||||
|
predicate.to_string().into(),
|
||||||
|
zed_keybind_context_language.clone(),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.unwrap_or(KeybindContextString::Global);
|
.unwrap_or(KeybindContextString::Global);
|
||||||
|
|
||||||
|
@ -588,11 +591,12 @@ impl KeymapEditor {
|
||||||
let workspace = self.workspace.clone();
|
let workspace = self.workspace.clone();
|
||||||
cx.spawn(async move |this, cx| {
|
cx.spawn(async move |this, cx| {
|
||||||
let json_language = load_json_language(workspace.clone(), cx).await;
|
let json_language = load_json_language(workspace.clone(), cx).await;
|
||||||
let rust_language = load_rust_language(workspace.clone(), cx).await;
|
let zed_keybind_context_language =
|
||||||
|
load_keybind_context_language(workspace.clone(), cx).await;
|
||||||
|
|
||||||
let (action_query, keystroke_query) = this.update(cx, |this, cx| {
|
let (action_query, keystroke_query) = this.update(cx, |this, cx| {
|
||||||
let (key_bindings, string_match_candidates) =
|
let (key_bindings, string_match_candidates) =
|
||||||
Self::process_bindings(json_language, rust_language, cx);
|
Self::process_bindings(json_language, zed_keybind_context_language, cx);
|
||||||
|
|
||||||
this.keybinding_conflict_state = ConflictState::new(&key_bindings);
|
this.keybinding_conflict_state = ConflictState::new(&key_bindings);
|
||||||
|
|
||||||
|
@ -1590,13 +1594,20 @@ impl KeybindingEditorModal {
|
||||||
}
|
}
|
||||||
|
|
||||||
let editor_entity = input.editor().clone();
|
let editor_entity = input.editor().clone();
|
||||||
|
let workspace = workspace.clone();
|
||||||
cx.spawn(async move |_input_handle, cx| {
|
cx.spawn(async move |_input_handle, cx| {
|
||||||
let contexts = cx
|
let contexts = cx
|
||||||
.background_spawn(async { collect_contexts_from_assets() })
|
.background_spawn(async { collect_contexts_from_assets() })
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
let language = load_keybind_context_language(workspace, cx).await;
|
||||||
editor_entity
|
editor_entity
|
||||||
.update(cx, |editor, _cx| {
|
.update(cx, |editor, cx| {
|
||||||
|
if let Some(buffer) = editor.buffer().read(cx).as_singleton() {
|
||||||
|
buffer.update(cx, |buffer, cx| {
|
||||||
|
buffer.set_language(Some(language), cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
editor.set_completion_provider(Some(std::rc::Rc::new(
|
editor.set_completion_provider(Some(std::rc::Rc::new(
|
||||||
KeyContextCompletionProvider { contexts },
|
KeyContextCompletionProvider { contexts },
|
||||||
)));
|
)));
|
||||||
|
@ -2131,25 +2142,31 @@ async fn load_json_language(workspace: WeakEntity<Workspace>, cx: &mut AsyncApp)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn load_rust_language(workspace: WeakEntity<Workspace>, cx: &mut AsyncApp) -> Arc<Language> {
|
async fn load_keybind_context_language(
|
||||||
let rust_language_task = workspace
|
workspace: WeakEntity<Workspace>,
|
||||||
|
cx: &mut AsyncApp,
|
||||||
|
) -> Arc<Language> {
|
||||||
|
let language_task = workspace
|
||||||
.read_with(cx, |workspace, cx| {
|
.read_with(cx, |workspace, cx| {
|
||||||
workspace
|
workspace
|
||||||
.project()
|
.project()
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.languages()
|
.languages()
|
||||||
.language_for_name("Rust")
|
.language_for_name("Zed Keybind Context")
|
||||||
})
|
})
|
||||||
.context("Failed to load Rust language")
|
.context("Failed to load Zed Keybind Context language")
|
||||||
.log_err();
|
.log_err();
|
||||||
let rust_language = match rust_language_task {
|
let language = match language_task {
|
||||||
Some(task) => task.await.context("Failed to load Rust language").log_err(),
|
Some(task) => task
|
||||||
|
.await
|
||||||
|
.context("Failed to load Zed Keybind Context language")
|
||||||
|
.log_err(),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
return rust_language.unwrap_or_else(|| {
|
return language.unwrap_or_else(|| {
|
||||||
Arc::new(Language::new(
|
Arc::new(Language::new(
|
||||||
LanguageConfig {
|
LanguageConfig {
|
||||||
name: "Rust".into(),
|
name: "Zed Keybind Context".into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Some(tree_sitter_rust::LANGUAGE.into()),
|
Some(tree_sitter_rust::LANGUAGE.into()),
|
||||||
|
|
|
@ -135,6 +135,7 @@ impl Render for SingleLineInput {
|
||||||
let editor_style = EditorStyle {
|
let editor_style = EditorStyle {
|
||||||
background: theme_color.ghost_element_background,
|
background: theme_color.ghost_element_background,
|
||||||
local_player: cx.theme().players().local(),
|
local_player: cx.theme().players().local(),
|
||||||
|
syntax: cx.theme().syntax().clone(),
|
||||||
text: text_style,
|
text: text_style,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue