From 3a28f09979bfe4e789cbce1cd9de8a959a94c0fa Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 21 Apr 2022 11:58:18 -0700 Subject: [PATCH 1/7] Allow comments in setting and keymap JSON files --- Cargo.lock | 20 ++++++++++++++++++-- crates/settings/Cargo.toml | 1 + crates/settings/src/keymap_file.rs | 11 ++++++----- crates/settings/src/settings.rs | 10 ++++++++-- crates/vim/src/vim_test_context.rs | 2 +- crates/zed/Cargo.toml | 2 +- crates/zed/src/languages/json/highlights.scm | 2 ++ crates/zed/src/main.rs | 4 ++-- crates/zed/src/settings_file.rs | 11 +++++++---- crates/zed/src/zed.rs | 2 +- 10 files changed, 47 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2dee9d30dc..52c11671a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2572,6 +2572,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json_comments" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ee439ee368ba4a77ac70d04f14015415af8600d6c894dc1f11bd79758c57d5" + [[package]] name = "json_env_logger" version = "0.1.1" @@ -2643,7 +2649,7 @@ dependencies = [ "text", "theme", "tree-sitter", - "tree-sitter-json", + "tree-sitter-json 0.19.0", "tree-sitter-rust", "unindent", "util", @@ -4304,6 +4310,7 @@ dependencies = [ "assets", "collections", "gpui", + "json_comments", "schemars", "serde", "serde_json", @@ -5193,6 +5200,15 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "tree-sitter-json" +version = "0.20.0" +source = "git+https://github.com/tree-sitter/tree-sitter-json?rev=137e1ce6a02698fc246cdb9c6b886ed1de9a1ed8#137e1ce6a02698fc246cdb9c6b886ed1de9a1ed8" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-markdown" version = "0.0.1" @@ -5837,7 +5853,7 @@ dependencies = [ "toml", "tree-sitter", "tree-sitter-c", - "tree-sitter-json", + "tree-sitter-json 0.20.0", "tree-sitter-markdown", "tree-sitter-rust", "tree-sitter-typescript", diff --git a/crates/settings/Cargo.toml b/crates/settings/Cargo.toml index cc37b1bcfd..c26a469b9f 100644 --- a/crates/settings/Cargo.toml +++ b/crates/settings/Cargo.toml @@ -17,6 +17,7 @@ gpui = { path = "../gpui" } theme = { path = "../theme" } util = { path = "../util" } anyhow = "1.0.38" +json_comments = "0.2" schemars = "0.8" serde = { version = "1", features = ["derive", "rc"] } serde_json = { version = "1.0.64", features = ["preserve_order"] } diff --git a/crates/settings/src/keymap_file.rs b/crates/settings/src/keymap_file.rs index d82c7ef8f6..1f6914989b 100644 --- a/crates/settings/src/keymap_file.rs +++ b/crates/settings/src/keymap_file.rs @@ -1,3 +1,4 @@ +use crate::parse_json_with_comments; use anyhow::{Context, Result}; use assets::Assets; use collections::BTreeMap; @@ -7,14 +8,14 @@ use serde_json::value::RawValue; #[derive(Deserialize, Default, Clone)] #[serde(transparent)] -pub struct KeymapFile(BTreeMap); +pub struct KeymapFileContent(BTreeMap); type ActionsByKeystroke = BTreeMap>; #[derive(Deserialize)] -struct ActionWithData<'a>(#[serde(borrow)] &'a str, #[serde(borrow)] &'a RawValue); +struct ActionWithData(Box, Box); -impl KeymapFile { +impl KeymapFileContent { pub fn load_defaults(cx: &mut MutableAppContext) { for path in ["keymaps/default.json", "keymaps/vim.json"] { Self::load(path, cx).unwrap(); @@ -24,7 +25,7 @@ impl KeymapFile { pub fn load(asset_path: &str, cx: &mut MutableAppContext) -> Result<()> { let content = Assets::get(asset_path).unwrap().data; let content_str = std::str::from_utf8(content.as_ref()).unwrap(); - Ok(serde_json::from_str::(content_str)?.add(cx)?) + Ok(parse_json_with_comments::(content_str)?.add(cx)?) } pub fn add(self, cx: &mut MutableAppContext) -> Result<()> { @@ -42,7 +43,7 @@ impl KeymapFile { // string. But `RawValue` currently does not work inside of an untagged enum. let action = if action.starts_with('[') { let ActionWithData(name, data) = serde_json::from_str(action)?; - cx.deserialize_action(name, Some(data.get())) + cx.deserialize_action(&name, Some(data.get())) } else { let name = serde_json::from_str(action)?; cx.deserialize_action(name, None) diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index ccd39baf46..6ddf9021ee 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -9,13 +9,13 @@ use schemars::{ }, JsonSchema, }; -use serde::Deserialize; +use serde::{de::DeserializeOwned, Deserialize}; use serde_json::Value; use std::{collections::HashMap, sync::Arc}; use theme::{Theme, ThemeRegistry}; use util::ResultExt as _; -pub use keymap_file::KeymapFile; +pub use keymap_file::KeymapFileContent; #[derive(Clone)] pub struct Settings { @@ -260,3 +260,9 @@ fn merge_option(target: &mut Option, value: Option) { *target = value; } } + +pub fn parse_json_with_comments(content: &str) -> Result { + Ok(serde_json::from_reader( + json_comments::CommentSettings::c_style().strip_comments(content.as_bytes()), + )?) +} diff --git a/crates/vim/src/vim_test_context.rs b/crates/vim/src/vim_test_context.rs index 1e10b5e206..cceedd7120 100644 --- a/crates/vim/src/vim_test_context.rs +++ b/crates/vim/src/vim_test_context.rs @@ -24,7 +24,7 @@ impl<'a> VimTestContext<'a> { editor::init(cx); crate::init(cx); - settings::KeymapFile::load("keymaps/vim.json", cx).unwrap(); + settings::KeymapFileContent::load("keymaps/vim.json", cx).unwrap(); }); let params = cx.update(WorkspaceParams::test); diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 0d4d43c414..9c27069240 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -86,7 +86,7 @@ tiny_http = "0.8" toml = "0.5" tree-sitter = "0.20.4" tree-sitter-c = "0.20.1" -tree-sitter-json = "0.19.0" +tree-sitter-json = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "137e1ce6a02698fc246cdb9c6b886ed1de9a1ed8" } tree-sitter-rust = "0.20.1" tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" } tree-sitter-typescript = "0.20.1" diff --git a/crates/zed/src/languages/json/highlights.scm b/crates/zed/src/languages/json/highlights.scm index 7788c8aecc..9754465166 100644 --- a/crates/zed/src/languages/json/highlights.scm +++ b/crates/zed/src/languages/json/highlights.scm @@ -1,3 +1,5 @@ +(comment) @comment + (string) @string (pair diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 371cb5a506..2037df84a1 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -17,7 +17,7 @@ use gpui::{App, AssetSource, AsyncAppContext, Task}; use log::LevelFilter; use parking_lot::Mutex; use project::Fs; -use settings::{self, KeymapFile, Settings, SettingsFileContent}; +use settings::{self, KeymapFileContent, Settings, SettingsFileContent}; use smol::process::Command; use std::{env, fs, path::PathBuf, sync::Arc, thread, time::Duration}; use theme::{ThemeRegistry, DEFAULT_THEME_NAME}; @@ -309,7 +309,7 @@ fn load_config_files( fs: Arc, ) -> oneshot::Receiver<( WatchedJsonFile, - WatchedJsonFile, + WatchedJsonFile, )> { let executor = app.background(); let (tx, rx) = oneshot::channel(); diff --git a/crates/zed/src/settings_file.rs b/crates/zed/src/settings_file.rs index d805e7490d..51266a073c 100644 --- a/crates/zed/src/settings_file.rs +++ b/crates/zed/src/settings_file.rs @@ -4,7 +4,7 @@ use postage::sink::Sink as _; use postage::{prelude::Stream, watch}; use project::Fs; use serde::Deserialize; -use settings::{KeymapFile, Settings, SettingsFileContent}; +use settings::{parse_json_with_comments, KeymapFileContent, Settings, SettingsFileContent}; use std::{path::Path, sync::Arc, time::Duration}; use theme::ThemeRegistry; use util::ResultExt; @@ -44,7 +44,7 @@ where fs.load(&path) .await .log_err() - .and_then(|data| serde_json::from_str(&data).log_err()) + .and_then(|data| parse_json_with_comments(&data).log_err()) } else { Some(T::default()) } @@ -76,11 +76,14 @@ pub fn settings_from_files( }) } -pub async fn watch_keymap_file(mut file: WatchedJsonFile, mut cx: AsyncAppContext) { +pub async fn watch_keymap_file( + mut file: WatchedJsonFile, + mut cx: AsyncAppContext, +) { while let Some(content) = file.0.recv().await { cx.update(|cx| { cx.clear_bindings(); - settings::KeymapFile::load_defaults(cx); + settings::KeymapFileContent::load_defaults(cx); content.add(cx).log_err(); }); } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 14816d22b0..07774b86e0 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -138,7 +138,7 @@ pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { workspace::lsp_status::init(cx); - settings::KeymapFile::load_defaults(cx); + settings::KeymapFileContent::load_defaults(cx); } pub fn build_workspace( From f52050a9ecac737788dbd6cbdb8d3784359aaf56 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 21 Apr 2022 12:08:16 -0700 Subject: [PATCH 2/7] Use the 'jsonc' language id for all JSON files This way, comments are allowed by the language server. --- crates/language/src/language.rs | 4 ++++ crates/project/src/project.rs | 21 +++++++++++++++++---- crates/zed/src/languages/json.rs | 8 ++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 37377b6eef..8b7f751593 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -102,6 +102,10 @@ pub trait LspAdapter: 'static + Send + Sync { fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> { None } + + fn id_for_language(&self, _name: &str) -> Option { + None + } } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 5c1064400e..fbbba31d8f 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1132,7 +1132,19 @@ impl Project { if file.is_local() { let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap(); let initial_snapshot = buffer.text_snapshot(); - let language_server = self.language_server_for_buffer(buffer, cx).cloned(); + + let mut language_server = None; + let mut language_id = None; + if let Some(language) = buffer.language() { + let worktree_id = file.worktree_id(cx); + if let Some(adapter) = language.lsp_adapter() { + language_id = adapter.id_for_language(language.name().as_ref()); + language_server = self + .language_servers + .get(&(worktree_id, adapter.name())) + .cloned(); + } + } if let Some(local_worktree) = file.worktree.read(cx).as_local() { if let Some(diagnostics) = local_worktree.diagnostics_for_path(file.path()) { @@ -1147,7 +1159,7 @@ impl Project { lsp::DidOpenTextDocumentParams { text_document: lsp::TextDocumentItem::new( uri, - Default::default(), + language_id.unwrap_or_default(), 0, initial_snapshot.text(), ), @@ -1437,7 +1449,7 @@ impl Project { this.update(&mut cx, |this, cx| { this.language_servers - .insert(key.clone(), (adapter, language_server.clone())); + .insert(key.clone(), (adapter.clone(), language_server.clone())); this.language_server_statuses.insert( server_id, LanguageServerStatus { @@ -1494,12 +1506,13 @@ impl Project { .or_insert_with(|| vec![(0, buffer.text_snapshot())]); let (version, initial_snapshot) = versions.last().unwrap(); let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap(); + let language_id = adapter.id_for_language(language.name().as_ref()); language_server .notify::( lsp::DidOpenTextDocumentParams { text_document: lsp::TextDocumentItem::new( uri, - Default::default(), + language_id.unwrap_or_default(), *version, initial_snapshot.text(), ), diff --git a/crates/zed/src/languages/json.rs b/crates/zed/src/languages/json.rs index 4069413f11..5bbaba8d90 100644 --- a/crates/zed/src/languages/json.rs +++ b/crates/zed/src/languages/json.rs @@ -127,4 +127,12 @@ impl LspAdapter for JsonLspAdapter { "provideFormatter": true })) } + + fn id_for_language(&self, name: &str) -> Option { + if name == "JSON" { + Some("jsonc".into()) + } else { + None + } + } } From 066b4faf6154b9934c522f1ee0c245707ec18219 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 21 Apr 2022 13:33:39 -0700 Subject: [PATCH 3/7] Restructure KeyMap file, make it easy to edit in Zed Add a JSON schema for this file so that autocomplete can be used for the actions. --- assets/keymaps/default.json | 544 ++++++++++++++++------------- assets/keymaps/vim.json | 192 +++++----- crates/gpui/src/app.rs | 4 + crates/settings/src/keymap_file.rs | 73 +++- crates/settings/src/settings.rs | 170 ++++----- crates/zed/src/zed.rs | 93 +++-- 6 files changed, 610 insertions(+), 466 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 506dd362d4..810a95c40c 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -1,264 +1,310 @@ -{ - "*": { - "ctrl-alt-cmd-f": "workspace::FollowNextCollaborator", - "cmd-s": "workspace::Save", - "cmd-alt-i": "zed::DebugElements", - "cmd-k cmd-left": "workspace::ActivatePreviousPane", - "cmd-k cmd-right": "workspace::ActivateNextPane", - "cmd-=": "zed::IncreaseBufferFontSize", - "cmd--": "zed::DecreaseBufferFontSize", - "cmd-,": "zed::OpenSettings" +[ + { + "bindings": { + "ctrl-alt-cmd-f": "workspace::FollowNextCollaborator", + "cmd-s": "workspace::Save", + "cmd-alt-i": "zed::DebugElements", + "cmd-k cmd-left": "workspace::ActivatePreviousPane", + "cmd-k cmd-right": "workspace::ActivateNextPane", + "cmd-=": "zed::IncreaseBufferFontSize", + "cmd--": "zed::DecreaseBufferFontSize", + "cmd-,": "zed::OpenSettings", + "alt-cmd-,": "zed::OpenKeymap" + } }, - "menu": { - "up": "menu::SelectPrev", - "ctrl-p": "menu::SelectPrev", - "down": "menu::SelectNext", - "ctrl-n": "menu::SelectNext", - "cmd-up": "menu::SelectFirst", - "cmd-down": "menu::SelectLast", - "enter": "menu::Confirm", - "escape": "menu::Cancel" + { + "context": "menu", + "bindings": { + "up": "menu::SelectPrev", + "ctrl-p": "menu::SelectPrev", + "down": "menu::SelectNext", + "ctrl-n": "menu::SelectNext", + "cmd-up": "menu::SelectFirst", + "cmd-down": "menu::SelectLast", + "enter": "menu::Confirm", + "escape": "menu::Cancel", + "ctrl-c": "menu::Cancel" + } }, - "Pane": { - "shift-cmd-{": "pane::ActivatePrevItem", - "shift-cmd-}": "pane::ActivateNextItem", - "cmd-w": "pane::CloseActiveItem", - "alt-cmd-w": "pane::CloseInactiveItems", - "ctrl--": "pane::GoBack", - "shift-ctrl-_": "pane::GoForward", - "cmd-k up": [ - "pane::Split", - "Up" - ], - "cmd-k down": [ - "pane::Split", - "Down" - ], - "cmd-k left": [ - "pane::Split", - "Left" - ], - "cmd-k right": [ - "pane::Split", - "Right" - ], - "cmd-shift-F": "project_search::ToggleFocus", - "cmd-f": "project_search::ToggleFocus", - "cmd-g": "search::SelectNextMatch", - "cmd-shift-G": "search::SelectPrevMatch" + { + "context": "Pane", + "bindings": { + "shift-cmd-{": "pane::ActivatePrevItem", + "shift-cmd-}": "pane::ActivateNextItem", + "cmd-w": "pane::CloseActiveItem", + "alt-cmd-w": "pane::CloseInactiveItems", + "ctrl--": "pane::GoBack", + "shift-ctrl-_": "pane::GoForward", + "cmd-k up": [ + "pane::Split", + "Up" + ], + "cmd-k down": [ + "pane::Split", + "Down" + ], + "cmd-k left": [ + "pane::Split", + "Left" + ], + "cmd-k right": [ + "pane::Split", + "Right" + ], + "cmd-shift-F": "project_search::ToggleFocus", + "cmd-f": "project_search::ToggleFocus", + "cmd-g": "search::SelectNextMatch", + "cmd-shift-G": "search::SelectPrevMatch" + } }, - "Workspace": { - "cmd-shift-F": "project_search::Deploy", - "cmd-k cmd-t": "theme_selector::Toggle", - "cmd-k t": "theme_selector::Reload", - "cmd-t": "project_symbols::Toggle", - "cmd-p": "file_finder::Toggle", - "cmd-shift-P": "command_palette::Toggle", - "alt-shift-D": "diagnostics::Deploy", - "ctrl-alt-cmd-j": "journal::NewJournalEntry", - "cmd-1": [ - "workspace::ToggleSidebarItemFocus", - { - "side": "Left", - "item_index": 0 - } - ], - "cmd-shift-!": [ - "workspace::ToggleSidebarItem", - { - "side": "Left", - "item_index": 0 - } - ] + { + "context": "Workspace", + "bindings": { + "cmd-shift-F": "project_search::Deploy", + "cmd-k cmd-t": "theme_selector::Toggle", + "cmd-k t": "theme_selector::Reload", + "cmd-t": "project_symbols::Toggle", + "cmd-p": "file_finder::Toggle", + "cmd-shift-P": "command_palette::Toggle", + "alt-shift-D": "diagnostics::Deploy", + "ctrl-alt-cmd-j": "journal::NewJournalEntry", + "cmd-1": [ + "workspace::ToggleSidebarItemFocus", + { + "side": "Left", + "item_index": 0 + } + ], + "cmd-shift-!": [ + "workspace::ToggleSidebarItem", + { + "side": "Left", + "item_index": 0 + } + ] + } }, - "ProjectSearchBar": { - "enter": "project_search::Search", - "cmd-enter": "project_search::SearchInNew" + { + "context": "ProjectSearchBar", + "bindings": { + "enter": "project_search::Search", + "cmd-enter": "project_search::SearchInNew" + } }, - "BufferSearchBar": { - "escape": "buffer_search::Dismiss", - "cmd-f": "buffer_search::FocusEditor", - "enter": "search::SelectNextMatch", - "shift-enter": "search::SelectPrevMatch" + { + "context": "BufferSearchBar", + "bindings": { + "escape": "buffer_search::Dismiss", + "cmd-f": "buffer_search::FocusEditor", + "enter": "search::SelectNextMatch", + "shift-enter": "search::SelectPrevMatch" + } }, - "Editor": { - "escape": "editor::Cancel", - "backspace": "editor::Backspace", - "ctrl-h": "editor::Backspace", - "delete": "editor::Delete", - "ctrl-d": "editor::Delete", - "tab": "editor::Tab", - "shift-tab": "editor::TabPrev", - "cmd-[": "editor::Outdent", - "cmd-]": "editor::Indent", - "ctrl-shift-K": "editor::DeleteLine", - "alt-backspace": "editor::DeleteToPreviousWordStart", - "alt-h": "editor::DeleteToPreviousWordStart", - "ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart", - "ctrl-alt-h": "editor::DeleteToPreviousSubwordStart", - "alt-delete": "editor::DeleteToNextWordEnd", - "alt-d": "editor::DeleteToNextWordEnd", - "ctrl-alt-delete": "editor::DeleteToNextSubwordEnd", - "ctrl-alt-d": "editor::DeleteToNextSubwordEnd", - "cmd-backspace": "editor::DeleteToBeginningOfLine", - "cmd-delete": "editor::DeleteToEndOfLine", - "ctrl-k": "editor::CutToEndOfLine", - "cmd-shift-D": "editor::DuplicateLine", - "ctrl-cmd-up": "editor::MoveLineUp", - "ctrl-cmd-down": "editor::MoveLineDown", - "cmd-x": "editor::Cut", - "cmd-c": "editor::Copy", - "cmd-v": "editor::Paste", - "cmd-z": "editor::Undo", - "cmd-shift-Z": "editor::Redo", - "up": "editor::MoveUp", - "down": "editor::MoveDown", - "left": "editor::MoveLeft", - "right": "editor::MoveRight", - "ctrl-p": "editor::MoveUp", - "ctrl-n": "editor::MoveDown", - "ctrl-b": "editor::MoveLeft", - "ctrl-f": "editor::MoveRight", - "alt-left": "editor::MoveToPreviousWordStart", - "alt-b": "editor::MoveToPreviousWordStart", - "ctrl-alt-left": "editor::MoveToPreviousSubwordStart", - "ctrl-alt-b": "editor::MoveToPreviousSubwordStart", - "alt-right": "editor::MoveToNextWordEnd", - "alt-f": "editor::MoveToNextWordEnd", - "ctrl-alt-right": "editor::MoveToNextSubwordEnd", - "ctrl-alt-f": "editor::MoveToNextSubwordEnd", - "cmd-left": "editor::MoveToBeginningOfLine", - "ctrl-a": "editor::MoveToBeginningOfLine", - "cmd-right": "editor::MoveToEndOfLine", - "ctrl-e": "editor::MoveToEndOfLine", - "cmd-up": "editor::MoveToBeginning", - "cmd-down": "editor::MoveToEnd", - "shift-up": "editor::SelectUp", - "ctrl-shift-P": "editor::SelectUp", - "shift-down": "editor::SelectDown", - "ctrl-shift-N": "editor::SelectDown", - "shift-left": "editor::SelectLeft", - "ctrl-shift-B": "editor::SelectLeft", - "shift-right": "editor::SelectRight", - "ctrl-shift-F": "editor::SelectRight", - "alt-shift-left": "editor::SelectToPreviousWordStart", - "alt-shift-B": "editor::SelectToPreviousWordStart", - "ctrl-alt-shift-left": "editor::SelectToPreviousSubwordStart", - "ctrl-alt-shift-B": "editor::SelectToPreviousSubwordStart", - "alt-shift-right": "editor::SelectToNextWordEnd", - "alt-shift-F": "editor::SelectToNextWordEnd", - "ctrl-alt-shift-right": "editor::SelectToNextSubwordEnd", - "cmd-shift-up": "editor::SelectToBeginning", - "cmd-shift-down": "editor::SelectToEnd", - "cmd-a": "editor::SelectAll", - "cmd-l": "editor::SelectLine", - "cmd-shift-L": "editor::SplitSelectionIntoLines", - "cmd-alt-up": "editor::AddSelectionAbove", - "cmd-ctrl-p": "editor::AddSelectionAbove", - "cmd-alt-down": "editor::AddSelectionBelow", - "cmd-ctrl-n": "editor::AddSelectionBelow", - "ctrl-alt-shift-F": "editor::SelectToNextSubwordEnd", - "cmd-shift-left": [ - "editor::SelectToBeginningOfLine", - { - "stop_at_soft_wraps": true - } - ], - "ctrl-shift-A": [ - "editor::SelectToBeginningOfLine", - { - "stop_at_soft_wraps": true - } - ], - "cmd-shift-right": [ - "editor::SelectToEndOfLine", - { - "stop_at_soft_wraps": true - } - ], - "ctrl-shift-E": [ - "editor::SelectToEndOfLine", - { - "stop_at_soft_wraps": true - } - ], - "cmd-d": [ - "editor::SelectNext", - { - "replace_newest": false - } - ], - "cmd-k cmd-d": [ - "editor::SelectNext", - { - "replace_newest": true - } - ], - "cmd-/": "editor::ToggleComments", - "alt-up": "editor::SelectLargerSyntaxNode", - "ctrl-w": "editor::SelectLargerSyntaxNode", - "alt-down": "editor::SelectSmallerSyntaxNode", - "ctrl-shift-W": "editor::SelectSmallerSyntaxNode", - "cmd-u": "editor::UndoSelection", - "cmd-shift-U": "editor::RedoSelection", - "f8": "editor::GoToNextDiagnostic", - "shift-f8": "editor::GoToPrevDiagnostic", - "f2": "editor::Rename", - "f12": "editor::GoToDefinition", - "alt-shift-f12": "editor::FindAllReferences", - "ctrl-m": "editor::MoveToEnclosingBracket", - "pageup": "editor::PageUp", - "pagedown": "editor::PageDown", - "alt-cmd-[": "editor::Fold", - "alt-cmd-]": "editor::UnfoldLines", - "alt-cmd-f": "editor::FoldSelectedRanges", - "ctrl-space": "editor::ShowCompletions", - "cmd-.": "editor::ToggleCodeActions", - "alt-enter": "editor::OpenExcerpts", - "cmd-f10": "editor::RestartLanguageServer" + { + "context": "Editor", + "bindings": { + "escape": "editor::Cancel", + "backspace": "editor::Backspace", + "ctrl-h": "editor::Backspace", + "delete": "editor::Delete", + "ctrl-d": "editor::Delete", + "tab": "editor::Tab", + "shift-tab": "editor::TabPrev", + "cmd-[": "editor::Outdent", + "cmd-]": "editor::Indent", + "ctrl-shift-K": "editor::DeleteLine", + "alt-backspace": "editor::DeleteToPreviousWordStart", + "alt-h": "editor::DeleteToPreviousWordStart", + "ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart", + "ctrl-alt-h": "editor::DeleteToPreviousSubwordStart", + "alt-delete": "editor::DeleteToNextWordEnd", + "alt-d": "editor::DeleteToNextWordEnd", + "ctrl-alt-delete": "editor::DeleteToNextSubwordEnd", + "ctrl-alt-d": "editor::DeleteToNextSubwordEnd", + "cmd-backspace": "editor::DeleteToBeginningOfLine", + "cmd-delete": "editor::DeleteToEndOfLine", + "ctrl-k": "editor::CutToEndOfLine", + "cmd-shift-D": "editor::DuplicateLine", + "ctrl-cmd-up": "editor::MoveLineUp", + "ctrl-cmd-down": "editor::MoveLineDown", + "cmd-x": "editor::Cut", + "cmd-c": "editor::Copy", + "cmd-v": "editor::Paste", + "cmd-z": "editor::Undo", + "cmd-shift-Z": "editor::Redo", + "up": "editor::MoveUp", + "down": "editor::MoveDown", + "left": "editor::MoveLeft", + "right": "editor::MoveRight", + "ctrl-p": "editor::MoveUp", + "ctrl-n": "editor::MoveDown", + "ctrl-b": "editor::MoveLeft", + "ctrl-f": "editor::MoveRight", + "alt-left": "editor::MoveToPreviousWordStart", + "alt-b": "editor::MoveToPreviousWordStart", + "ctrl-alt-left": "editor::MoveToPreviousSubwordStart", + "ctrl-alt-b": "editor::MoveToPreviousSubwordStart", + "alt-right": "editor::MoveToNextWordEnd", + "alt-f": "editor::MoveToNextWordEnd", + "ctrl-alt-right": "editor::MoveToNextSubwordEnd", + "ctrl-alt-f": "editor::MoveToNextSubwordEnd", + "cmd-left": "editor::MoveToBeginningOfLine", + "ctrl-a": "editor::MoveToBeginningOfLine", + "cmd-right": "editor::MoveToEndOfLine", + "ctrl-e": "editor::MoveToEndOfLine", + "cmd-up": "editor::MoveToBeginning", + "cmd-down": "editor::MoveToEnd", + "shift-up": "editor::SelectUp", + "ctrl-shift-P": "editor::SelectUp", + "shift-down": "editor::SelectDown", + "ctrl-shift-N": "editor::SelectDown", + "shift-left": "editor::SelectLeft", + "ctrl-shift-B": "editor::SelectLeft", + "shift-right": "editor::SelectRight", + "ctrl-shift-F": "editor::SelectRight", + "alt-shift-left": "editor::SelectToPreviousWordStart", + "alt-shift-B": "editor::SelectToPreviousWordStart", + "ctrl-alt-shift-left": "editor::SelectToPreviousSubwordStart", + "ctrl-alt-shift-B": "editor::SelectToPreviousSubwordStart", + "alt-shift-right": "editor::SelectToNextWordEnd", + "alt-shift-F": "editor::SelectToNextWordEnd", + "ctrl-alt-shift-right": "editor::SelectToNextSubwordEnd", + "cmd-shift-up": "editor::SelectToBeginning", + "cmd-shift-down": "editor::SelectToEnd", + "cmd-a": "editor::SelectAll", + "cmd-l": "editor::SelectLine", + "cmd-shift-L": "editor::SplitSelectionIntoLines", + "cmd-alt-up": "editor::AddSelectionAbove", + "cmd-ctrl-p": "editor::AddSelectionAbove", + "cmd-alt-down": "editor::AddSelectionBelow", + "cmd-ctrl-n": "editor::AddSelectionBelow", + "ctrl-alt-shift-F": "editor::SelectToNextSubwordEnd", + "cmd-shift-left": [ + "editor::SelectToBeginningOfLine", + { + "stop_at_soft_wraps": true + } + ], + "ctrl-shift-A": [ + "editor::SelectToBeginningOfLine", + { + "stop_at_soft_wraps": true + } + ], + "cmd-shift-right": [ + "editor::SelectToEndOfLine", + { + "stop_at_soft_wraps": true + } + ], + "ctrl-shift-E": [ + "editor::SelectToEndOfLine", + { + "stop_at_soft_wraps": true + } + ], + "cmd-d": [ + "editor::SelectNext", + { + "replace_newest": false + } + ], + "cmd-k cmd-d": [ + "editor::SelectNext", + { + "replace_newest": true + } + ], + "cmd-/": "editor::ToggleComments", + "alt-up": "editor::SelectLargerSyntaxNode", + "ctrl-w": "editor::SelectLargerSyntaxNode", + "alt-down": "editor::SelectSmallerSyntaxNode", + "ctrl-shift-W": "editor::SelectSmallerSyntaxNode", + "cmd-u": "editor::UndoSelection", + "cmd-shift-U": "editor::RedoSelection", + "f8": "editor::GoToNextDiagnostic", + "shift-f8": "editor::GoToPrevDiagnostic", + "f2": "editor::Rename", + "f12": "editor::GoToDefinition", + "alt-shift-f12": "editor::FindAllReferences", + "ctrl-m": "editor::MoveToEnclosingBracket", + "pageup": "editor::PageUp", + "pagedown": "editor::PageDown", + "alt-cmd-[": "editor::Fold", + "alt-cmd-]": "editor::UnfoldLines", + "alt-cmd-f": "editor::FoldSelectedRanges", + "ctrl-space": "editor::ShowCompletions", + "cmd-.": "editor::ToggleCodeActions", + "alt-enter": "editor::OpenExcerpts", + "cmd-f10": "editor::RestartLanguageServer" + } }, - "Editor && renaming": { - "enter": "editor::ConfirmRename" + { + "context": "Editor && mode == full", + "bindings": { + "enter": "editor::Newline", + "cmd-f": [ + "buffer_search::Deploy", + { + "focus": true + } + ], + "cmd-e": [ + "buffer_search::Deploy", + { + "focus": false + } + ], + "cmd-shift-O": "outline::Toggle", + "ctrl-g": "go_to_line::Toggle" + } }, - "Editor && showing_completions": { - "enter": "editor::ConfirmCompletion", - "tab": "editor::ConfirmCompletion" + { + "context": "Editor && renaming", + "bindings": { + "enter": "editor::ConfirmRename" + } }, - "Editor && showing_code_actions": { - "enter": "editor::ConfirmCodeAction" + { + "context": "Editor && showing_completions", + "bindings": { + "enter": "editor::ConfirmCompletion", + "tab": "editor::ConfirmCompletion" + } }, - "Editor && mode == full": { - "enter": "editor::Newline", - "cmd-f": [ - "buffer_search::Deploy", - { - "focus": true - } - ], - "cmd-e": [ - "buffer_search::Deploy", - { - "focus": false - } - ], - "cmd-shift-O": "outline::Toggle", - "ctrl-g": "go_to_line::Toggle" + { + "context": "Editor && showing_code_actions", + "bindings": { + "enter": "editor::ConfirmCodeAction" + } }, - "Editor && mode == auto_height": { - "alt-enter": [ - "editor::Input", - "\n" - ] + { + "context": "Editor && mode == auto_height", + "bindings": { + "alt-enter": [ + "editor::Input", + "\n" + ] + } }, - "GoToLine": { - "escape": "go_to_line::Toggle", - "enter": "go_to_line::Confirm" + { + "context": "GoToLine", + "bindings": { + "escape": "go_to_line::Toggle", + "enter": "go_to_line::Confirm" + } }, - "ChatPanel": { - "enter": "chat_panel::Send" + { + "context": "ChatPanel", + "bindings": { + "enter": "chat_panel::Send" + } }, - "ProjectPanel": { - "left": "project_panel::CollapseSelectedEntry", - "right": "project_panel::ExpandSelectedEntry" + { + "context": "ProjectPanel", + "bindings": { + "left": "project_panel::CollapseSelectedEntry", + "right": "project_panel::ExpandSelectedEntry" + } } -} \ No newline at end of file +] \ No newline at end of file diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index 312416f42c..c0745afd99 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -1,93 +1,111 @@ -{ - "Editor && VimControl": { - "i": [ - "vim::SwitchMode", - "Insert" - ], - "g": [ - "vim::PushOperator", - { - "Namespace": "G" - } - ], - "h": "vim::Left", - "j": "vim::Down", - "k": "vim::Up", - "l": "vim::Right", - "0": "vim::StartOfLine", - "shift-$": "vim::EndOfLine", - "shift-G": "vim::EndOfDocument", - "w": "vim::NextWordStart", - "shift-W": [ - "vim::NextWordStart", - { - "ignorePunctuation": true - } - ], - "e": "vim::NextWordEnd", - "shift-E": [ - "vim::NextWordEnd", - { - "ignorePunctuation": true - } - ], - "b": "vim::PreviousWordStart", - "shift-B": [ - "vim::PreviousWordStart", - { - "ignorePunctuation": true - } - ], - "escape": [ - "vim::SwitchMode", - "Normal" - ] +[ + { + "context": "Editor && VimControl", + "bindings": { + "i": [ + "vim::SwitchMode", + "Insert" + ], + "g": [ + "vim::PushOperator", + { + "Namespace": "G" + } + ], + "h": "vim::Left", + "j": "vim::Down", + "k": "vim::Up", + "l": "vim::Right", + "0": "vim::StartOfLine", + "shift-$": "vim::EndOfLine", + "shift-G": "vim::EndOfDocument", + "w": "vim::NextWordStart", + "shift-W": [ + "vim::NextWordStart", + { + "ignorePunctuation": true + } + ], + "e": "vim::NextWordEnd", + "shift-E": [ + "vim::NextWordEnd", + { + "ignorePunctuation": true + } + ], + "b": "vim::PreviousWordStart", + "shift-B": [ + "vim::PreviousWordStart", + { + "ignorePunctuation": true + } + ], + "escape": [ + "vim::SwitchMode", + "Normal" + ] + } }, - "Editor && vim_operator == g": { - "g": "vim::StartOfDocument" + { + "context": "Editor && vim_operator == g", + "bindings": { + "g": "vim::StartOfDocument" + } }, - "Editor && vim_mode == insert": { - "escape": "vim::NormalBefore", - "ctrl-c": "vim::NormalBefore" + { + "context": "Editor && vim_mode == insert", + "bindings": { + "escape": "vim::NormalBefore", + "ctrl-c": "vim::NormalBefore" + } }, - "Editor && vim_mode == normal": { - "c": [ - "vim::PushOperator", - "Change" - ], - "d": [ - "vim::PushOperator", - "Delete" - ] + { + "context": "Editor && vim_mode == normal", + "bindings": { + "c": [ + "vim::PushOperator", + "Change" + ], + "d": [ + "vim::PushOperator", + "Delete" + ] + } }, - "Editor && vim_operator == c": { - "w": [ - "vim::NextWordEnd", - { - "ignorePunctuation": false - } - ], - "shift-W": [ - "vim::NextWordEnd", - { - "ignorePunctuation": true - } - ] + { + "context": "Editor && vim_operator == c", + "bindings": { + "w": [ + "vim::NextWordEnd", + { + "ignorePunctuation": false + } + ], + "shift-W": [ + "vim::NextWordEnd", + { + "ignorePunctuation": true + } + ] + } }, - "Editor && vim_operator == d": { - "w": [ - "vim::NextWordStart", - { - "ignorePunctuation": false, - "stopAtNewline": true - } - ], - "shift-W": [ - "vim::NextWordStart", - { - "ignorePunctuation": true, - "stopAtNewline": true - } - ] + { + "context": "Editor && vim_operator == d", + "bindings": { + "w": [ + "vim::NextWordStart", + { + "ignorePunctuation": false, + "stopAtNewline": true + } + ], + "shift-W": [ + "vim::NextWordStart", + { + "ignorePunctuation": true, + "stopAtNewline": true + } + ] + } } -} \ No newline at end of file +] \ No newline at end of file diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 37cf03a3cc..91497c178f 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1306,6 +1306,10 @@ impl MutableAppContext { } } + pub fn all_action_names<'a>(&'a self) -> impl Iterator + 'a { + self.action_deserializers.keys().copied() + } + pub fn available_actions( &self, window_id: usize, diff --git a/crates/settings/src/keymap_file.rs b/crates/settings/src/keymap_file.rs index 1f6914989b..99cf81c6ba 100644 --- a/crates/settings/src/keymap_file.rs +++ b/crates/settings/src/keymap_file.rs @@ -3,14 +3,38 @@ use anyhow::{Context, Result}; use assets::Assets; use collections::BTreeMap; use gpui::{keymap::Binding, MutableAppContext}; +use schemars::{ + gen::{SchemaGenerator, SchemaSettings}, + schema::{InstanceType, Schema, SchemaObject, SingleOrVec, SubschemaValidation}, + JsonSchema, +}; use serde::Deserialize; -use serde_json::value::RawValue; +use serde_json::{value::RawValue, Value}; + +#[derive(Deserialize, Default, Clone, JsonSchema)] +#[serde(transparent)] +pub struct KeymapFileContent(Vec); + +#[derive(Deserialize, Default, Clone, JsonSchema)] +pub struct KeymapBlock { + #[serde(default)] + context: Option, + bindings: BTreeMap, +} #[derive(Deserialize, Default, Clone)] #[serde(transparent)] -pub struct KeymapFileContent(BTreeMap); +pub struct KeymapAction(Box); -type ActionsByKeystroke = BTreeMap>; +impl JsonSchema for KeymapAction { + fn schema_name() -> String { + "KeymapAction".into() + } + + fn json_schema(_: &mut SchemaGenerator) -> Schema { + Schema::Bool(true) + } +} #[derive(Deserialize)] struct ActionWithData(Box, Box); @@ -29,13 +53,12 @@ impl KeymapFileContent { } pub fn add(self, cx: &mut MutableAppContext) -> Result<()> { - for (context, actions) in self.0 { - let context = if context == "*" { None } else { Some(context) }; + for KeymapBlock { context, bindings } in self.0 { cx.add_bindings( - actions + bindings .into_iter() .map(|(keystroke, action)| { - let action = action.get(); + let action = action.0.get(); // This is a workaround for a limitation in serde: serde-rs/json#497 // We want to deserialize the action data as a `RawValue` so that we can @@ -61,3 +84,39 @@ impl KeymapFileContent { Ok(()) } } + +pub fn keymap_file_json_schema(action_names: &[&'static str]) -> serde_json::Value { + let mut root_schema = SchemaSettings::draft07() + .with(|settings| settings.option_add_null_type = false) + .into_generator() + .into_root_schema_for::(); + + let action_schema = Schema::Object(SchemaObject { + subschemas: Some(Box::new(SubschemaValidation { + one_of: Some(vec![ + Schema::Object(SchemaObject { + instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))), + enum_values: Some( + action_names + .into_iter() + .map(|name| Value::String(name.to_string())) + .collect(), + ), + ..Default::default() + }), + Schema::Object(SchemaObject { + instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Array))), + ..Default::default() + }), + ]), + ..Default::default() + })), + ..Default::default() + }); + + root_schema + .definitions + .insert("KeymapAction".to_owned(), action_schema); + + serde_json::to_value(root_schema).unwrap() +} diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index 6ddf9021ee..02e8388249 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -15,7 +15,7 @@ use std::{collections::HashMap, sync::Arc}; use theme::{Theme, ThemeRegistry}; use util::ResultExt as _; -pub use keymap_file::KeymapFileContent; +pub use keymap_file::{keymap_file_json_schema, KeymapFileContent}; #[derive(Clone)] pub struct Settings { @@ -78,90 +78,6 @@ impl Settings { }) } - pub fn file_json_schema( - theme_names: Vec, - language_names: Vec, - ) -> serde_json::Value { - let settings = SchemaSettings::draft07().with(|settings| { - settings.option_add_null_type = false; - }); - let generator = SchemaGenerator::new(settings); - let mut root_schema = generator.into_root_schema_for::(); - - // Construct theme names reference type - let theme_names = theme_names - .into_iter() - .map(|name| Value::String(name)) - .collect(); - let theme_names_schema = Schema::Object(SchemaObject { - instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))), - enum_values: Some(theme_names), - ..Default::default() - }); - root_schema - .definitions - .insert("ThemeName".to_owned(), theme_names_schema); - - // Construct language overrides reference type - let language_override_schema_reference = Schema::Object(SchemaObject { - reference: Some("#/definitions/LanguageOverride".to_owned()), - ..Default::default() - }); - let language_overrides_properties = language_names - .into_iter() - .map(|name| { - ( - name, - Schema::Object(SchemaObject { - subschemas: Some(Box::new(SubschemaValidation { - all_of: Some(vec![language_override_schema_reference.clone()]), - ..Default::default() - })), - ..Default::default() - }), - ) - }) - .collect(); - let language_overrides_schema = Schema::Object(SchemaObject { - instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))), - object: Some(Box::new(ObjectValidation { - properties: language_overrides_properties, - ..Default::default() - })), - ..Default::default() - }); - root_schema - .definitions - .insert("LanguageOverrides".to_owned(), language_overrides_schema); - - // Modify theme property to use new theme reference type - let settings_file_schema = root_schema.schema.object.as_mut().unwrap(); - let language_overrides_schema_reference = Schema::Object(SchemaObject { - reference: Some("#/definitions/ThemeName".to_owned()), - ..Default::default() - }); - settings_file_schema.properties.insert( - "theme".to_owned(), - Schema::Object(SchemaObject { - subschemas: Some(Box::new(SubschemaValidation { - all_of: Some(vec![language_overrides_schema_reference]), - ..Default::default() - })), - ..Default::default() - }), - ); - - // Modify language_overrides property to use LanguageOverrides reference - settings_file_schema.properties.insert( - "language_overrides".to_owned(), - Schema::Object(SchemaObject { - reference: Some("#/definitions/LanguageOverrides".to_owned()), - ..Default::default() - }), - ); - serde_json::to_value(root_schema).unwrap() - } - pub fn with_overrides( mut self, language_name: impl Into>, @@ -249,6 +165,90 @@ impl Settings { } } +pub fn settings_file_json_schema( + theme_names: Vec, + language_names: Vec, +) -> serde_json::Value { + let settings = SchemaSettings::draft07().with(|settings| { + settings.option_add_null_type = false; + }); + let generator = SchemaGenerator::new(settings); + let mut root_schema = generator.into_root_schema_for::(); + + // Construct theme names reference type + let theme_names = theme_names + .into_iter() + .map(|name| Value::String(name)) + .collect(); + let theme_names_schema = Schema::Object(SchemaObject { + instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))), + enum_values: Some(theme_names), + ..Default::default() + }); + root_schema + .definitions + .insert("ThemeName".to_owned(), theme_names_schema); + + // Construct language overrides reference type + let language_override_schema_reference = Schema::Object(SchemaObject { + reference: Some("#/definitions/LanguageOverride".to_owned()), + ..Default::default() + }); + let language_overrides_properties = language_names + .into_iter() + .map(|name| { + ( + name, + Schema::Object(SchemaObject { + subschemas: Some(Box::new(SubschemaValidation { + all_of: Some(vec![language_override_schema_reference.clone()]), + ..Default::default() + })), + ..Default::default() + }), + ) + }) + .collect(); + let language_overrides_schema = Schema::Object(SchemaObject { + instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))), + object: Some(Box::new(ObjectValidation { + properties: language_overrides_properties, + ..Default::default() + })), + ..Default::default() + }); + root_schema + .definitions + .insert("LanguageOverrides".to_owned(), language_overrides_schema); + + // Modify theme property to use new theme reference type + let settings_file_schema = root_schema.schema.object.as_mut().unwrap(); + let language_overrides_schema_reference = Schema::Object(SchemaObject { + reference: Some("#/definitions/ThemeName".to_owned()), + ..Default::default() + }); + settings_file_schema.properties.insert( + "theme".to_owned(), + Schema::Object(SchemaObject { + subschemas: Some(Box::new(SubschemaValidation { + all_of: Some(vec![language_overrides_schema_reference]), + ..Default::default() + })), + ..Default::default() + }), + ); + + // Modify language_overrides property to use LanguageOverrides reference + settings_file_schema.properties.insert( + "language_overrides".to_owned(), + Schema::Object(SchemaObject { + reference: Some("#/definitions/LanguageOverrides".to_owned()), + ..Default::default() + }), + ); + serde_json::to_value(root_schema).unwrap() +} + fn merge(target: &mut T, value: Option) { if let Some(value) = value { *target = value; diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 07774b86e0..33525400dd 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -25,7 +25,7 @@ pub use project::{self, fs}; use project_panel::ProjectPanel; use search::{BufferSearchBar, ProjectSearchBar}; use serde_json::to_string_pretty; -use settings::Settings; +use settings::{keymap_file_json_schema, settings_file_json_schema, Settings}; use std::{ path::{Path, PathBuf}, sync::Arc, @@ -41,6 +41,7 @@ actions!( Quit, DebugElements, OpenSettings, + OpenKeymap, IncreaseBufferFontSize, DecreaseBufferFontSize, InstallCommandLineInterface, @@ -78,39 +79,13 @@ pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { cx.add_action({ let app_state = app_state.clone(); move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext| { - let app_state = app_state.clone(); - cx.spawn(move |workspace, mut cx| async move { - let fs = &app_state.fs; - if !fs.is_file(&SETTINGS_PATH).await { - fs.create_dir(&ROOT_PATH).await?; - fs.create_file(&SETTINGS_PATH, Default::default()).await?; - } - - workspace - .update(&mut cx, |workspace, cx| { - if workspace.project().read(cx).is_local() { - workspace.open_paths(&[SETTINGS_PATH.clone()], cx) - } else { - let (_, workspace) = - cx.add_window((app_state.build_window_options)(), |cx| { - let project = Project::local( - app_state.client.clone(), - app_state.user_store.clone(), - app_state.languages.clone(), - app_state.fs.clone(), - cx, - ); - (app_state.build_workspace)(project, &app_state, cx) - }); - workspace.update(cx, |workspace, cx| { - workspace.open_paths(&[SETTINGS_PATH.clone()], cx) - }) - } - }) - .await; - Ok::<_, anyhow::Error>(()) - }) - .detach_and_log_err(cx); + open_config_file(&SETTINGS_PATH, app_state.clone(), cx); + } + }); + cx.add_action({ + let app_state = app_state.clone(); + move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext| { + open_config_file(&KEYMAP_PATH, app_state.clone(), cx); } }); cx.add_action( @@ -137,7 +112,6 @@ pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { ); workspace::lsp_status::init(cx); - settings::KeymapFileContent::load_defaults(cx); } @@ -179,13 +153,18 @@ pub fn build_workspace( let theme_names = app_state.themes.list().collect(); let language_names = app_state.languages.language_names(); - project.update(cx, |project, _| { + project.update(cx, |project, cx| { + let action_names = cx.all_action_names().collect::>(); project.set_language_server_settings(serde_json::json!({ "json": { "schemas": [ { - "fileMatch": "**/.zed/settings.json", - "schema": Settings::file_json_schema(theme_names, language_names), + "fileMatch": [".zed/settings.json"], + "schema": settings_file_json_schema(theme_names, language_names), + }, + { + "fileMatch": [".zed/keymap.json"], + "schema": keymap_file_json_schema(&action_names), } ] } @@ -289,6 +268,44 @@ async fn install_cli(cx: &AsyncAppContext) -> Result<()> { } } +fn open_config_file( + path: &'static Path, + app_state: Arc, + cx: &mut ViewContext, +) { + cx.spawn(|workspace, mut cx| async move { + let fs = &app_state.fs; + if !fs.is_file(path).await { + fs.create_dir(&ROOT_PATH).await?; + fs.create_file(path, Default::default()).await?; + } + + workspace + .update(&mut cx, |workspace, cx| { + if workspace.project().read(cx).is_local() { + workspace.open_paths(&[path.to_path_buf()], cx) + } else { + let (_, workspace) = cx.add_window((app_state.build_window_options)(), |cx| { + let project = Project::local( + app_state.client.clone(), + app_state.user_store.clone(), + app_state.languages.clone(), + app_state.fs.clone(), + cx, + ); + (app_state.build_workspace)(project, &app_state, cx) + }); + workspace.update(cx, |workspace, cx| { + workspace.open_paths(&[path.to_path_buf()], cx) + }) + } + }) + .await; + Ok::<_, anyhow::Error>(()) + }) + .detach_and_log_err(cx) +} + #[cfg(test)] mod tests { use super::*; From d43f194342c617f2dc106c8c4740e34587e00399 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 21 Apr 2022 14:07:14 -0700 Subject: [PATCH 4/7] Organize default key bindings into categories --- assets/keymaps/default.json | 361 ++++++++++++++++++++---------------- 1 file changed, 205 insertions(+), 156 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 810a95c40c..eb49ff6d24 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -1,17 +1,5 @@ [ - { - "bindings": { - "ctrl-alt-cmd-f": "workspace::FollowNextCollaborator", - "cmd-s": "workspace::Save", - "cmd-alt-i": "zed::DebugElements", - "cmd-k cmd-left": "workspace::ActivatePreviousPane", - "cmd-k cmd-right": "workspace::ActivateNextPane", - "cmd-=": "zed::IncreaseBufferFontSize", - "cmd--": "zed::DecreaseBufferFontSize", - "cmd-,": "zed::OpenSettings", - "alt-cmd-,": "zed::OpenKeymap" - } - }, + // Standard macOS bindings { "context": "menu", "bindings": { @@ -27,77 +15,15 @@ } }, { - "context": "Pane", "bindings": { "shift-cmd-{": "pane::ActivatePrevItem", "shift-cmd-}": "pane::ActivateNextItem", "cmd-w": "pane::CloseActiveItem", "alt-cmd-w": "pane::CloseInactiveItems", - "ctrl--": "pane::GoBack", - "shift-ctrl-_": "pane::GoForward", - "cmd-k up": [ - "pane::Split", - "Up" - ], - "cmd-k down": [ - "pane::Split", - "Down" - ], - "cmd-k left": [ - "pane::Split", - "Left" - ], - "cmd-k right": [ - "pane::Split", - "Right" - ], - "cmd-shift-F": "project_search::ToggleFocus", - "cmd-f": "project_search::ToggleFocus", - "cmd-g": "search::SelectNextMatch", - "cmd-shift-G": "search::SelectPrevMatch" - } - }, - { - "context": "Workspace", - "bindings": { - "cmd-shift-F": "project_search::Deploy", - "cmd-k cmd-t": "theme_selector::Toggle", - "cmd-k t": "theme_selector::Reload", - "cmd-t": "project_symbols::Toggle", - "cmd-p": "file_finder::Toggle", - "cmd-shift-P": "command_palette::Toggle", - "alt-shift-D": "diagnostics::Deploy", - "ctrl-alt-cmd-j": "journal::NewJournalEntry", - "cmd-1": [ - "workspace::ToggleSidebarItemFocus", - { - "side": "Left", - "item_index": 0 - } - ], - "cmd-shift-!": [ - "workspace::ToggleSidebarItem", - { - "side": "Left", - "item_index": 0 - } - ] - } - }, - { - "context": "ProjectSearchBar", - "bindings": { - "enter": "project_search::Search", - "cmd-enter": "project_search::SearchInNew" - } - }, - { - "context": "BufferSearchBar", - "bindings": { - "escape": "buffer_search::Dismiss", - "cmd-f": "buffer_search::FocusEditor", - "enter": "search::SelectNextMatch", - "shift-enter": "search::SelectPrevMatch" + "cmd-s": "workspace::Save", + "cmd-=": "zed::IncreaseBufferFontSize", + "cmd--": "zed::DecreaseBufferFontSize", + "cmd-,": "zed::OpenSettings" } }, { @@ -110,23 +36,13 @@ "ctrl-d": "editor::Delete", "tab": "editor::Tab", "shift-tab": "editor::TabPrev", - "cmd-[": "editor::Outdent", - "cmd-]": "editor::Indent", - "ctrl-shift-K": "editor::DeleteLine", - "alt-backspace": "editor::DeleteToPreviousWordStart", - "alt-h": "editor::DeleteToPreviousWordStart", - "ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart", - "ctrl-alt-h": "editor::DeleteToPreviousSubwordStart", - "alt-delete": "editor::DeleteToNextWordEnd", - "alt-d": "editor::DeleteToNextWordEnd", - "ctrl-alt-delete": "editor::DeleteToNextSubwordEnd", - "ctrl-alt-d": "editor::DeleteToNextSubwordEnd", + "ctrl-k": "editor::CutToEndOfLine", "cmd-backspace": "editor::DeleteToBeginningOfLine", "cmd-delete": "editor::DeleteToEndOfLine", - "ctrl-k": "editor::CutToEndOfLine", - "cmd-shift-D": "editor::DuplicateLine", - "ctrl-cmd-up": "editor::MoveLineUp", - "ctrl-cmd-down": "editor::MoveLineDown", + "alt-backspace": "editor::DeleteToPreviousWordStart", + "alt-delete": "editor::DeleteToNextWordEnd", + "alt-h": "editor::DeleteToPreviousWordStart", + "alt-d": "editor::DeleteToNextWordEnd", "cmd-x": "editor::Cut", "cmd-c": "editor::Copy", "cmd-v": "editor::Paste", @@ -142,12 +58,8 @@ "ctrl-f": "editor::MoveRight", "alt-left": "editor::MoveToPreviousWordStart", "alt-b": "editor::MoveToPreviousWordStart", - "ctrl-alt-left": "editor::MoveToPreviousSubwordStart", - "ctrl-alt-b": "editor::MoveToPreviousSubwordStart", "alt-right": "editor::MoveToNextWordEnd", "alt-f": "editor::MoveToNextWordEnd", - "ctrl-alt-right": "editor::MoveToNextSubwordEnd", - "ctrl-alt-f": "editor::MoveToNextSubwordEnd", "cmd-left": "editor::MoveToBeginningOfLine", "ctrl-a": "editor::MoveToBeginningOfLine", "cmd-right": "editor::MoveToEndOfLine", @@ -164,21 +76,12 @@ "ctrl-shift-F": "editor::SelectRight", "alt-shift-left": "editor::SelectToPreviousWordStart", "alt-shift-B": "editor::SelectToPreviousWordStart", - "ctrl-alt-shift-left": "editor::SelectToPreviousSubwordStart", - "ctrl-alt-shift-B": "editor::SelectToPreviousSubwordStart", "alt-shift-right": "editor::SelectToNextWordEnd", "alt-shift-F": "editor::SelectToNextWordEnd", - "ctrl-alt-shift-right": "editor::SelectToNextSubwordEnd", "cmd-shift-up": "editor::SelectToBeginning", "cmd-shift-down": "editor::SelectToEnd", "cmd-a": "editor::SelectAll", "cmd-l": "editor::SelectLine", - "cmd-shift-L": "editor::SplitSelectionIntoLines", - "cmd-alt-up": "editor::AddSelectionAbove", - "cmd-ctrl-p": "editor::AddSelectionAbove", - "cmd-alt-down": "editor::AddSelectionBelow", - "cmd-ctrl-n": "editor::AddSelectionBelow", - "ctrl-alt-shift-F": "editor::SelectToNextSubwordEnd", "cmd-shift-left": [ "editor::SelectToBeginningOfLine", { @@ -203,40 +106,8 @@ "stop_at_soft_wraps": true } ], - "cmd-d": [ - "editor::SelectNext", - { - "replace_newest": false - } - ], - "cmd-k cmd-d": [ - "editor::SelectNext", - { - "replace_newest": true - } - ], - "cmd-/": "editor::ToggleComments", - "alt-up": "editor::SelectLargerSyntaxNode", - "ctrl-w": "editor::SelectLargerSyntaxNode", - "alt-down": "editor::SelectSmallerSyntaxNode", - "ctrl-shift-W": "editor::SelectSmallerSyntaxNode", - "cmd-u": "editor::UndoSelection", - "cmd-shift-U": "editor::RedoSelection", - "f8": "editor::GoToNextDiagnostic", - "shift-f8": "editor::GoToPrevDiagnostic", - "f2": "editor::Rename", - "f12": "editor::GoToDefinition", - "alt-shift-f12": "editor::FindAllReferences", - "ctrl-m": "editor::MoveToEnclosingBracket", "pageup": "editor::PageUp", - "pagedown": "editor::PageDown", - "alt-cmd-[": "editor::Fold", - "alt-cmd-]": "editor::UnfoldLines", - "alt-cmd-f": "editor::FoldSelectedRanges", - "ctrl-space": "editor::ShowCompletions", - "cmd-.": "editor::ToggleCodeActions", - "alt-enter": "editor::OpenExcerpts", - "cmd-f10": "editor::RestartLanguageServer" + "pagedown": "editor::PageDown" } }, { @@ -254,11 +125,205 @@ { "focus": false } + ] + } + }, + { + "context": "Editor && mode == auto_height", + "bindings": { + "alt-enter": [ + "editor::Input", + "\n" + ] + } + }, + { + "context": "Pane", + "bindings": { + "cmd-f": "project_search::ToggleFocus", + "cmd-g": "search::SelectNextMatch", + "cmd-shift-G": "search::SelectPrevMatch" + } + }, + { + "context": "BufferSearchBar", + "bindings": { + "escape": "buffer_search::Dismiss", + "cmd-f": "buffer_search::FocusEditor", + "enter": "search::SelectNextMatch", + "shift-enter": "search::SelectPrevMatch" + } + }, + // Bindings from VS Code + { + "context": "Editor", + "bindings": { + "cmd-[": "editor::Outdent", + "cmd-]": "editor::Indent", + "cmd-alt-up": "editor::AddSelectionAbove", + "cmd-ctrl-p": "editor::AddSelectionAbove", + "cmd-alt-down": "editor::AddSelectionBelow", + "cmd-ctrl-n": "editor::AddSelectionBelow", + "cmd-d": [ + "editor::SelectNext", + { + "replace_newest": false + } ], + "cmd-k cmd-d": [ + "editor::SelectNext", + { + "replace_newest": true + } + ], + "cmd-/": "editor::ToggleComments", + "alt-up": "editor::SelectLargerSyntaxNode", + "alt-down": "editor::SelectSmallerSyntaxNode", + "ctrl-shift-W": "editor::SelectSmallerSyntaxNode", + "cmd-u": "editor::UndoSelection", + "cmd-shift-U": "editor::RedoSelection", + "f8": "editor::GoToNextDiagnostic", + "shift-f8": "editor::GoToPrevDiagnostic", + "f2": "editor::Rename", + "f12": "editor::GoToDefinition", + "alt-shift-f12": "editor::FindAllReferences", + "ctrl-m": "editor::MoveToEnclosingBracket", + "alt-cmd-[": "editor::Fold", + "alt-cmd-]": "editor::UnfoldLines", + "ctrl-space": "editor::ShowCompletions", + "cmd-.": "editor::ToggleCodeActions" + } + }, + { + "context": "Editor && mode == full", + "bindings": { "cmd-shift-O": "outline::Toggle", "ctrl-g": "go_to_line::Toggle" } }, + { + "context": "Pane", + "bindings": { + "ctrl--": "pane::GoBack", + "shift-ctrl-_": "pane::GoForward", + "cmd-shift-F": "project_search::ToggleFocus" + } + }, + { + "context": "Workspace", + "bindings": { + "cmd-shift-F": "project_search::Deploy", + "cmd-k cmd-t": "theme_selector::Toggle", + "cmd-k t": "theme_selector::Reload", + "cmd-t": "project_symbols::Toggle", + "cmd-p": "file_finder::Toggle", + "cmd-shift-P": "command_palette::Toggle" + } + }, + // Bindings from Sublime Text + { + "context": "Editor", + "bindings": { + "ctrl-shift-K": "editor::DeleteLine", + "cmd-shift-D": "editor::DuplicateLine", + "cmd-shift-L": "editor::SplitSelectionIntoLines", + "ctrl-cmd-up": "editor::MoveLineUp", + "ctrl-cmd-down": "editor::MoveLineDown", + "ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart", + "ctrl-alt-h": "editor::DeleteToPreviousSubwordStart", + "ctrl-alt-delete": "editor::DeleteToNextSubwordEnd", + "ctrl-alt-d": "editor::DeleteToNextSubwordEnd", + "ctrl-alt-left": "editor::MoveToPreviousSubwordStart", + "ctrl-alt-b": "editor::MoveToPreviousSubwordStart", + "ctrl-alt-right": "editor::MoveToNextSubwordEnd", + "ctrl-alt-f": "editor::MoveToNextSubwordEnd", + "ctrl-alt-shift-left": "editor::SelectToPreviousSubwordStart", + "ctrl-alt-shift-B": "editor::SelectToPreviousSubwordStart", + "ctrl-alt-shift-right": "editor::SelectToNextSubwordEnd", + "ctrl-alt-shift-F": "editor::SelectToNextSubwordEnd" + } + }, + { + "bindings": { + "cmd-k cmd-left": "workspace::ActivatePreviousPane", + "cmd-k cmd-right": "workspace::ActivateNextPane" + } + }, + { + "context": "Pane", + "bindings": { + "cmd-k up": [ + "pane::Split", + "Up" + ], + "cmd-k down": [ + "pane::Split", + "Down" + ], + "cmd-k left": [ + "pane::Split", + "Left" + ], + "cmd-k right": [ + "pane::Split", + "Right" + ] + } + }, + // Custom bindings + { + "bindings": { + "ctrl-alt-cmd-f": "workspace::FollowNextCollaborator", + "cmd-alt-i": "zed::DebugElements", + "alt-cmd-,": "zed::OpenKeymap" + } + }, + { + "context": "Editor", + "bindings": { + "ctrl-w": "editor::SelectLargerSyntaxNode", + "alt-cmd-f": "editor::FoldSelectedRanges", + "alt-enter": "editor::OpenExcerpts", + "cmd-f10": "editor::RestartLanguageServer" + } + }, + { + "context": "Workspace", + "bindings": { + "alt-shift-D": "diagnostics::Deploy", + "ctrl-alt-cmd-j": "journal::NewJournalEntry", + "cmd-1": [ + "workspace::ToggleSidebarItemFocus", + { + "side": "Left", + "item_index": 0 + } + ], + "cmd-shift-!": [ + "workspace::ToggleSidebarItem", + { + "side": "Left", + "item_index": 0 + } + ] + } + }, + { + "context": "ProjectPanel", + "bindings": { + "left": "project_panel::CollapseSelectedEntry", + "right": "project_panel::ExpandSelectedEntry" + } + }, + // Bindings that should be unified with other bindings + // for more general actions + { + "context": "ProjectSearchBar", + "bindings": { + "enter": "project_search::Search", + "cmd-enter": "project_search::SearchInNew" + } + }, { "context": "Editor && renaming", "bindings": { @@ -278,15 +343,6 @@ "enter": "editor::ConfirmCodeAction" } }, - { - "context": "Editor && mode == auto_height", - "bindings": { - "alt-enter": [ - "editor::Input", - "\n" - ] - } - }, { "context": "GoToLine", "bindings": { @@ -299,12 +355,5 @@ "bindings": { "enter": "chat_panel::Send" } - }, - { - "context": "ProjectPanel", - "bindings": { - "left": "project_panel::CollapseSelectedEntry", - "right": "project_panel::ExpandSelectedEntry" - } } ] \ No newline at end of file From 915ba9188862a53cade07bc8b30a37cc91c5eff2 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 21 Apr 2022 14:12:17 -0700 Subject: [PATCH 5/7] Allow toggling line comments in JSON --- crates/zed/src/languages/json/config.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/zed/src/languages/json/config.toml b/crates/zed/src/languages/json/config.toml index ad87dcf633..cb36279358 100644 --- a/crates/zed/src/languages/json/config.toml +++ b/crates/zed/src/languages/json/config.toml @@ -1,5 +1,6 @@ name = "JSON" path_suffixes = ["json"] +line_comment = "// " autoclose_before = ",]}" brackets = [ { start = "{", end = "}", close = true, newline = true }, From 490b65b55f7691f1e19755bdd8e8a76e05835378 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 21 Apr 2022 15:24:05 -0700 Subject: [PATCH 6/7] Reuse Confirm action in chat panel, go-to-line, and project search --- assets/keymaps/default.json | 33 ++++++----------------------- crates/chat_panel/src/chat_panel.rs | 5 +++-- crates/go_to_line/src/go_to_line.rs | 12 +++++++++-- crates/search/src/project_search.rs | 8 ++++--- 4 files changed, 25 insertions(+), 33 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index eb49ff6d24..6eaff19f89 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -1,7 +1,6 @@ [ // Standard macOS bindings { - "context": "menu", "bindings": { "up": "menu::SelectPrev", "ctrl-p": "menu::SelectPrev", @@ -11,11 +10,7 @@ "cmd-down": "menu::SelectLast", "enter": "menu::Confirm", "escape": "menu::Cancel", - "ctrl-c": "menu::Cancel" - } - }, - { - "bindings": { + "ctrl-c": "menu::Cancel", "shift-cmd-{": "pane::ActivatePrevItem", "shift-cmd-}": "pane::ActivateNextItem", "cmd-w": "pane::CloseActiveItem", @@ -287,6 +282,12 @@ "cmd-f10": "editor::RestartLanguageServer" } }, + { + "context": "ProjectSearchBar", + "bindings": { + "cmd-enter": "project_search::SearchInNew" + } + }, { "context": "Workspace", "bindings": { @@ -317,13 +318,6 @@ }, // Bindings that should be unified with other bindings // for more general actions - { - "context": "ProjectSearchBar", - "bindings": { - "enter": "project_search::Search", - "cmd-enter": "project_search::SearchInNew" - } - }, { "context": "Editor && renaming", "bindings": { @@ -342,18 +336,5 @@ "bindings": { "enter": "editor::ConfirmCodeAction" } - }, - { - "context": "GoToLine", - "bindings": { - "escape": "go_to_line::Toggle", - "enter": "go_to_line::Confirm" - } - }, - { - "context": "ChatPanel", - "bindings": { - "enter": "chat_panel::Send" - } } ] \ No newline at end of file diff --git a/crates/chat_panel/src/chat_panel.rs b/crates/chat_panel/src/chat_panel.rs index 187c0139db..415ff6187e 100644 --- a/crates/chat_panel/src/chat_panel.rs +++ b/crates/chat_panel/src/chat_panel.rs @@ -16,6 +16,7 @@ use settings::{Settings, SoftWrap}; use std::sync::Arc; use time::{OffsetDateTime, UtcOffset}; use util::{ResultExt, TryFutureExt}; +use workspace::menu::Confirm; const MESSAGE_LOADING_THRESHOLD: usize = 50; @@ -32,7 +33,7 @@ pub struct ChatPanel { pub enum Event {} -actions!(chat_panel, [Send, LoadMoreMessages]); +actions!(chat_panel, [LoadMoreMessages]); pub fn init(cx: &mut MutableAppContext) { cx.add_action(ChatPanel::send); @@ -345,7 +346,7 @@ impl ChatPanel { .boxed() } - fn send(&mut self, _: &Send, cx: &mut ViewContext) { + fn send(&mut self, _: &Confirm, cx: &mut ViewContext) { if let Some((channel, _)) = self.active_channel.as_ref() { let body = self.input_editor.update(cx, |editor, cx| { let body = editor.text(cx); diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 16b633ad72..7fa68a7675 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -5,13 +5,17 @@ use gpui::{ }; use settings::Settings; use text::{Bias, Point}; -use workspace::Workspace; +use workspace::{ + menu::{Cancel, Confirm}, + Workspace, +}; -actions!(go_to_line, [Toggle, Confirm]); +actions!(go_to_line, [Toggle]); pub fn init(cx: &mut MutableAppContext) { cx.add_action(GoToLine::toggle); cx.add_action(GoToLine::confirm); + cx.add_action(GoToLine::cancel); } pub struct GoToLine { @@ -66,6 +70,10 @@ impl GoToLine { } } + fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext) { + cx.emit(Event::Dismissed); + } + fn confirm(&mut self, _: &Confirm, cx: &mut ViewContext) { self.prev_scroll_position.take(); self.active_editor.update(cx, |active_editor, cx| { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 1028d7f77e..bb35b2ebdc 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -17,9 +17,11 @@ use std::{ path::PathBuf, }; use util::ResultExt as _; -use workspace::{Item, ItemNavHistory, Pane, ToolbarItemLocation, ToolbarItemView, Workspace}; +use workspace::{ + menu::Confirm, Item, ItemNavHistory, Pane, ToolbarItemLocation, ToolbarItemView, Workspace, +}; -actions!(project_search, [Deploy, Search, SearchInNew, ToggleFocus]); +actions!(project_search, [Deploy, SearchInNew, ToggleFocus]); const MAX_TAB_TITLE_LEN: usize = 24; @@ -530,7 +532,7 @@ impl ProjectSearchBar { } } - fn search(&mut self, _: &Search, cx: &mut ViewContext) { + fn search(&mut self, _: &Confirm, cx: &mut ViewContext) { if let Some(search_view) = self.active_project_search.as_ref() { search_view.update(cx, |search_view, cx| search_view.search(cx)); } From 14cf51638c904501513778d53440417ce5d16332 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 21 Apr 2022 15:28:15 -0700 Subject: [PATCH 7/7] :art: Tweak order of default key bindings --- assets/keymaps/default.json | 43 ++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 6eaff19f89..43c1f84e2a 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -174,7 +174,6 @@ "cmd-/": "editor::ToggleComments", "alt-up": "editor::SelectLargerSyntaxNode", "alt-down": "editor::SelectSmallerSyntaxNode", - "ctrl-shift-W": "editor::SelectSmallerSyntaxNode", "cmd-u": "editor::UndoSelection", "cmd-shift-U": "editor::RedoSelection", "f8": "editor::GoToNextDiagnostic", @@ -265,6 +264,26 @@ ] } }, + // Bindings that should be unified with bindings for more general actions + { + "context": "Editor && renaming", + "bindings": { + "enter": "editor::ConfirmRename" + } + }, + { + "context": "Editor && showing_completions", + "bindings": { + "enter": "editor::ConfirmCompletion", + "tab": "editor::ConfirmCompletion" + } + }, + { + "context": "Editor && showing_code_actions", + "bindings": { + "enter": "editor::ConfirmCodeAction" + } + }, // Custom bindings { "bindings": { @@ -277,6 +296,7 @@ "context": "Editor", "bindings": { "ctrl-w": "editor::SelectLargerSyntaxNode", + "ctrl-shift-W": "editor::SelectSmallerSyntaxNode", "alt-cmd-f": "editor::FoldSelectedRanges", "alt-enter": "editor::OpenExcerpts", "cmd-f10": "editor::RestartLanguageServer" @@ -315,26 +335,5 @@ "left": "project_panel::CollapseSelectedEntry", "right": "project_panel::ExpandSelectedEntry" } - }, - // Bindings that should be unified with other bindings - // for more general actions - { - "context": "Editor && renaming", - "bindings": { - "enter": "editor::ConfirmRename" - } - }, - { - "context": "Editor && showing_completions", - "bindings": { - "enter": "editor::ConfirmCompletion", - "tab": "editor::ConfirmCompletion" - } - }, - { - "context": "Editor && showing_code_actions", - "bindings": { - "enter": "editor::ConfirmCodeAction" - } } ] \ No newline at end of file