Allow comments in setting and keymap JSON files
This commit is contained in:
parent
066e572767
commit
3a28f09979
10 changed files with 47 additions and 18 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -2572,6 +2572,12 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "json_comments"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41ee439ee368ba4a77ac70d04f14015415af8600d6c894dc1f11bd79758c57d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "json_env_logger"
|
name = "json_env_logger"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -2643,7 +2649,7 @@ dependencies = [
|
||||||
"text",
|
"text",
|
||||||
"theme",
|
"theme",
|
||||||
"tree-sitter",
|
"tree-sitter",
|
||||||
"tree-sitter-json",
|
"tree-sitter-json 0.19.0",
|
||||||
"tree-sitter-rust",
|
"tree-sitter-rust",
|
||||||
"unindent",
|
"unindent",
|
||||||
"util",
|
"util",
|
||||||
|
@ -4304,6 +4310,7 @@ dependencies = [
|
||||||
"assets",
|
"assets",
|
||||||
"collections",
|
"collections",
|
||||||
"gpui",
|
"gpui",
|
||||||
|
"json_comments",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -5193,6 +5200,15 @@ dependencies = [
|
||||||
"tree-sitter",
|
"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]]
|
[[package]]
|
||||||
name = "tree-sitter-markdown"
|
name = "tree-sitter-markdown"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
@ -5837,7 +5853,7 @@ dependencies = [
|
||||||
"toml",
|
"toml",
|
||||||
"tree-sitter",
|
"tree-sitter",
|
||||||
"tree-sitter-c",
|
"tree-sitter-c",
|
||||||
"tree-sitter-json",
|
"tree-sitter-json 0.20.0",
|
||||||
"tree-sitter-markdown",
|
"tree-sitter-markdown",
|
||||||
"tree-sitter-rust",
|
"tree-sitter-rust",
|
||||||
"tree-sitter-typescript",
|
"tree-sitter-typescript",
|
||||||
|
|
|
@ -17,6 +17,7 @@ gpui = { path = "../gpui" }
|
||||||
theme = { path = "../theme" }
|
theme = { path = "../theme" }
|
||||||
util = { path = "../util" }
|
util = { path = "../util" }
|
||||||
anyhow = "1.0.38"
|
anyhow = "1.0.38"
|
||||||
|
json_comments = "0.2"
|
||||||
schemars = "0.8"
|
schemars = "0.8"
|
||||||
serde = { version = "1", features = ["derive", "rc"] }
|
serde = { version = "1", features = ["derive", "rc"] }
|
||||||
serde_json = { version = "1.0.64", features = ["preserve_order"] }
|
serde_json = { version = "1.0.64", features = ["preserve_order"] }
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::parse_json_with_comments;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use assets::Assets;
|
use assets::Assets;
|
||||||
use collections::BTreeMap;
|
use collections::BTreeMap;
|
||||||
|
@ -7,14 +8,14 @@ use serde_json::value::RawValue;
|
||||||
|
|
||||||
#[derive(Deserialize, Default, Clone)]
|
#[derive(Deserialize, Default, Clone)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct KeymapFile(BTreeMap<String, ActionsByKeystroke>);
|
pub struct KeymapFileContent(BTreeMap<String, ActionsByKeystroke>);
|
||||||
|
|
||||||
type ActionsByKeystroke = BTreeMap<String, Box<RawValue>>;
|
type ActionsByKeystroke = BTreeMap<String, Box<RawValue>>;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct ActionWithData<'a>(#[serde(borrow)] &'a str, #[serde(borrow)] &'a RawValue);
|
struct ActionWithData(Box<str>, Box<RawValue>);
|
||||||
|
|
||||||
impl KeymapFile {
|
impl KeymapFileContent {
|
||||||
pub fn load_defaults(cx: &mut MutableAppContext) {
|
pub fn load_defaults(cx: &mut MutableAppContext) {
|
||||||
for path in ["keymaps/default.json", "keymaps/vim.json"] {
|
for path in ["keymaps/default.json", "keymaps/vim.json"] {
|
||||||
Self::load(path, cx).unwrap();
|
Self::load(path, cx).unwrap();
|
||||||
|
@ -24,7 +25,7 @@ impl KeymapFile {
|
||||||
pub fn load(asset_path: &str, cx: &mut MutableAppContext) -> Result<()> {
|
pub fn load(asset_path: &str, cx: &mut MutableAppContext) -> Result<()> {
|
||||||
let content = Assets::get(asset_path).unwrap().data;
|
let content = Assets::get(asset_path).unwrap().data;
|
||||||
let content_str = std::str::from_utf8(content.as_ref()).unwrap();
|
let content_str = std::str::from_utf8(content.as_ref()).unwrap();
|
||||||
Ok(serde_json::from_str::<Self>(content_str)?.add(cx)?)
|
Ok(parse_json_with_comments::<Self>(content_str)?.add(cx)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(self, cx: &mut MutableAppContext) -> Result<()> {
|
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.
|
// string. But `RawValue` currently does not work inside of an untagged enum.
|
||||||
let action = if action.starts_with('[') {
|
let action = if action.starts_with('[') {
|
||||||
let ActionWithData(name, data) = serde_json::from_str(action)?;
|
let ActionWithData(name, data) = serde_json::from_str(action)?;
|
||||||
cx.deserialize_action(name, Some(data.get()))
|
cx.deserialize_action(&name, Some(data.get()))
|
||||||
} else {
|
} else {
|
||||||
let name = serde_json::from_str(action)?;
|
let name = serde_json::from_str(action)?;
|
||||||
cx.deserialize_action(name, None)
|
cx.deserialize_action(name, None)
|
||||||
|
|
|
@ -9,13 +9,13 @@ use schemars::{
|
||||||
},
|
},
|
||||||
JsonSchema,
|
JsonSchema,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::{de::DeserializeOwned, Deserialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
use theme::{Theme, ThemeRegistry};
|
use theme::{Theme, ThemeRegistry};
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
|
|
||||||
pub use keymap_file::KeymapFile;
|
pub use keymap_file::KeymapFileContent;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
@ -260,3 +260,9 @@ fn merge_option<T: Copy>(target: &mut Option<T>, value: Option<T>) {
|
||||||
*target = value;
|
*target = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_json_with_comments<T: DeserializeOwned>(content: &str) -> Result<T> {
|
||||||
|
Ok(serde_json::from_reader(
|
||||||
|
json_comments::CommentSettings::c_style().strip_comments(content.as_bytes()),
|
||||||
|
)?)
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl<'a> VimTestContext<'a> {
|
||||||
editor::init(cx);
|
editor::init(cx);
|
||||||
crate::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);
|
let params = cx.update(WorkspaceParams::test);
|
||||||
|
|
|
@ -86,7 +86,7 @@ tiny_http = "0.8"
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
tree-sitter = "0.20.4"
|
tree-sitter = "0.20.4"
|
||||||
tree-sitter-c = "0.20.1"
|
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-rust = "0.20.1"
|
||||||
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
|
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
|
||||||
tree-sitter-typescript = "0.20.1"
|
tree-sitter-typescript = "0.20.1"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
(comment) @comment
|
||||||
|
|
||||||
(string) @string
|
(string) @string
|
||||||
|
|
||||||
(pair
|
(pair
|
||||||
|
|
|
@ -17,7 +17,7 @@ use gpui::{App, AssetSource, AsyncAppContext, Task};
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use project::Fs;
|
use project::Fs;
|
||||||
use settings::{self, KeymapFile, Settings, SettingsFileContent};
|
use settings::{self, KeymapFileContent, Settings, SettingsFileContent};
|
||||||
use smol::process::Command;
|
use smol::process::Command;
|
||||||
use std::{env, fs, path::PathBuf, sync::Arc, thread, time::Duration};
|
use std::{env, fs, path::PathBuf, sync::Arc, thread, time::Duration};
|
||||||
use theme::{ThemeRegistry, DEFAULT_THEME_NAME};
|
use theme::{ThemeRegistry, DEFAULT_THEME_NAME};
|
||||||
|
@ -309,7 +309,7 @@ fn load_config_files(
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
) -> oneshot::Receiver<(
|
) -> oneshot::Receiver<(
|
||||||
WatchedJsonFile<SettingsFileContent>,
|
WatchedJsonFile<SettingsFileContent>,
|
||||||
WatchedJsonFile<KeymapFile>,
|
WatchedJsonFile<KeymapFileContent>,
|
||||||
)> {
|
)> {
|
||||||
let executor = app.background();
|
let executor = app.background();
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
|
|
|
@ -4,7 +4,7 @@ use postage::sink::Sink as _;
|
||||||
use postage::{prelude::Stream, watch};
|
use postage::{prelude::Stream, watch};
|
||||||
use project::Fs;
|
use project::Fs;
|
||||||
use serde::Deserialize;
|
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 std::{path::Path, sync::Arc, time::Duration};
|
||||||
use theme::ThemeRegistry;
|
use theme::ThemeRegistry;
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
@ -44,7 +44,7 @@ where
|
||||||
fs.load(&path)
|
fs.load(&path)
|
||||||
.await
|
.await
|
||||||
.log_err()
|
.log_err()
|
||||||
.and_then(|data| serde_json::from_str(&data).log_err())
|
.and_then(|data| parse_json_with_comments(&data).log_err())
|
||||||
} else {
|
} else {
|
||||||
Some(T::default())
|
Some(T::default())
|
||||||
}
|
}
|
||||||
|
@ -76,11 +76,14 @@ pub fn settings_from_files(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn watch_keymap_file(mut file: WatchedJsonFile<KeymapFile>, mut cx: AsyncAppContext) {
|
pub async fn watch_keymap_file(
|
||||||
|
mut file: WatchedJsonFile<KeymapFileContent>,
|
||||||
|
mut cx: AsyncAppContext,
|
||||||
|
) {
|
||||||
while let Some(content) = file.0.recv().await {
|
while let Some(content) = file.0.recv().await {
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
cx.clear_bindings();
|
cx.clear_bindings();
|
||||||
settings::KeymapFile::load_defaults(cx);
|
settings::KeymapFileContent::load_defaults(cx);
|
||||||
content.add(cx).log_err();
|
content.add(cx).log_err();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
|
||||||
|
|
||||||
workspace::lsp_status::init(cx);
|
workspace::lsp_status::init(cx);
|
||||||
|
|
||||||
settings::KeymapFile::load_defaults(cx);
|
settings::KeymapFileContent::load_defaults(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_workspace(
|
pub fn build_workspace(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue