mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 18:41:10 +00:00
Start computing workspace configuration more dynamically
This commit is contained in:
parent
ed9927b495
commit
60d3fb48e2
8 changed files with 174 additions and 92 deletions
|
@ -44,7 +44,7 @@ use syntax_map::SyntaxSnapshot;
|
||||||
use theme::{SyntaxTheme, Theme};
|
use theme::{SyntaxTheme, Theme};
|
||||||
use tree_sitter::{self, Query};
|
use tree_sitter::{self, Query};
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
use util::{ResultExt, TryFutureExt as _, UnwrapFuture};
|
use util::{merge_json_value_into, ResultExt, TryFutureExt as _, UnwrapFuture};
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
|
@ -208,6 +208,13 @@ pub trait LspAdapter: 'static + Send + Sync {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn workspace_configuration(
|
||||||
|
&self,
|
||||||
|
_: &mut MutableAppContext,
|
||||||
|
) -> Option<BoxFuture<'static, Value>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
async fn disk_based_diagnostic_sources(&self) -> Vec<String> {
|
async fn disk_based_diagnostic_sources(&self) -> Vec<String> {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
@ -541,6 +548,26 @@ impl LanguageRegistry {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn workspace_configuration(&self, cx: &mut MutableAppContext) -> Task<serde_json::Value> {
|
||||||
|
let mut language_configs = Vec::new();
|
||||||
|
for language in self.available_languages.read().iter() {
|
||||||
|
if let Some(adapter) = language.lsp_adapter.as_ref() {
|
||||||
|
if let Some(language_config) = adapter.workspace_configuration(cx) {
|
||||||
|
language_configs.push(language_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cx.background().spawn(async move {
|
||||||
|
let mut config = serde_json::json!({});
|
||||||
|
let language_configs = futures::future::join_all(language_configs).await;
|
||||||
|
for language_config in language_configs {
|
||||||
|
merge_json_value_into(language_config, &mut config);
|
||||||
|
}
|
||||||
|
config
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add(&self, language: Arc<Language>) {
|
pub fn add(&self, language: Arc<Language>) {
|
||||||
if let Some(theme) = self.theme.read().clone() {
|
if let Some(theme) = self.theme.read().clone() {
|
||||||
language.set_theme(&theme.editor.syntax);
|
language.set_theme(&theme.editor.syntax);
|
||||||
|
|
|
@ -64,7 +64,7 @@ use std::{
|
||||||
};
|
};
|
||||||
use terminals::Terminals;
|
use terminals::Terminals;
|
||||||
|
|
||||||
use util::{debug_panic, defer, post_inc, ResultExt, TryFutureExt as _};
|
use util::{debug_panic, defer, merge_json_value_into, post_inc, ResultExt, TryFutureExt as _};
|
||||||
|
|
||||||
pub use fs::*;
|
pub use fs::*;
|
||||||
pub use worktree::*;
|
pub use worktree::*;
|
||||||
|
@ -125,6 +125,7 @@ pub struct Project {
|
||||||
buffers_being_formatted: HashSet<usize>,
|
buffers_being_formatted: HashSet<usize>,
|
||||||
nonce: u128,
|
nonce: u128,
|
||||||
_maintain_buffer_languages: Task<()>,
|
_maintain_buffer_languages: Task<()>,
|
||||||
|
_maintain_workspace_config: Task<()>,
|
||||||
terminals: Terminals,
|
terminals: Terminals,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,6 +429,7 @@ impl Project {
|
||||||
client_subscriptions: Vec::new(),
|
client_subscriptions: Vec::new(),
|
||||||
_subscriptions: vec![cx.observe_global::<Settings, _>(Self::on_settings_changed)],
|
_subscriptions: vec![cx.observe_global::<Settings, _>(Self::on_settings_changed)],
|
||||||
_maintain_buffer_languages: Self::maintain_buffer_languages(&languages, cx),
|
_maintain_buffer_languages: Self::maintain_buffer_languages(&languages, cx),
|
||||||
|
_maintain_workspace_config: Self::maintain_workspace_config(languages.clone(), cx),
|
||||||
active_entry: None,
|
active_entry: None,
|
||||||
languages,
|
languages,
|
||||||
client,
|
client,
|
||||||
|
@ -486,6 +488,7 @@ impl Project {
|
||||||
active_entry: None,
|
active_entry: None,
|
||||||
collaborators: Default::default(),
|
collaborators: Default::default(),
|
||||||
_maintain_buffer_languages: Self::maintain_buffer_languages(&languages, cx),
|
_maintain_buffer_languages: Self::maintain_buffer_languages(&languages, cx),
|
||||||
|
_maintain_workspace_config: Self::maintain_workspace_config(languages.clone(), cx),
|
||||||
languages,
|
languages,
|
||||||
user_store: user_store.clone(),
|
user_store: user_store.clone(),
|
||||||
fs,
|
fs,
|
||||||
|
@ -1836,6 +1839,46 @@ impl Project {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn maintain_workspace_config(
|
||||||
|
languages: Arc<LanguageRegistry>,
|
||||||
|
cx: &mut ModelContext<Project>,
|
||||||
|
) -> Task<()> {
|
||||||
|
let mut languages_changed = languages.subscribe();
|
||||||
|
let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
|
||||||
|
let settings_observation = cx.observe_global::<Settings, _>(move |_, _| {
|
||||||
|
*settings_changed_tx.borrow_mut() = ();
|
||||||
|
});
|
||||||
|
cx.spawn_weak(|this, mut cx| async move {
|
||||||
|
loop {
|
||||||
|
futures::select_biased! {
|
||||||
|
_ = languages_changed.next().fuse() => {},
|
||||||
|
_ = settings_changed_rx.next().fuse() => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let workspace_config = cx.update(|cx| languages.workspace_configuration(cx)).await;
|
||||||
|
if let Some(this) = this.upgrade(&cx) {
|
||||||
|
this.read_with(&cx, |this, _| {
|
||||||
|
for server_state in this.language_servers.values() {
|
||||||
|
if let LanguageServerState::Running { server, .. } = server_state {
|
||||||
|
server
|
||||||
|
.notify::<lsp::notification::DidChangeConfiguration>(
|
||||||
|
lsp::DidChangeConfigurationParams {
|
||||||
|
settings: workspace_config.clone(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(settings_observation);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn detect_language_for_buffer(
|
fn detect_language_for_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer: &ModelHandle<Buffer>,
|
buffer: &ModelHandle<Buffer>,
|
||||||
|
@ -1875,24 +1918,6 @@ impl Project {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_json_value_into(source: serde_json::Value, target: &mut serde_json::Value) {
|
|
||||||
use serde_json::Value;
|
|
||||||
|
|
||||||
match (source, target) {
|
|
||||||
(Value::Object(source), Value::Object(target)) => {
|
|
||||||
for (key, value) in source {
|
|
||||||
if let Some(target) = target.get_mut(&key) {
|
|
||||||
Self::merge_json_value_into(value, target);
|
|
||||||
} else {
|
|
||||||
target.insert(key.clone(), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(source, target) => *target = source,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_language_server(
|
fn start_language_server(
|
||||||
&mut self,
|
&mut self,
|
||||||
worktree_id: WorktreeId,
|
worktree_id: WorktreeId,
|
||||||
|
@ -1920,17 +1945,16 @@ impl Project {
|
||||||
let override_options = lsp.map(|s| s.initialization_options.clone()).flatten();
|
let override_options = lsp.map(|s| s.initialization_options.clone()).flatten();
|
||||||
match (&mut initialization_options, override_options) {
|
match (&mut initialization_options, override_options) {
|
||||||
(Some(initialization_options), Some(override_options)) => {
|
(Some(initialization_options), Some(override_options)) => {
|
||||||
Self::merge_json_value_into(override_options, initialization_options);
|
merge_json_value_into(override_options, initialization_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
(None, override_options) => initialization_options = override_options,
|
(None, override_options) => initialization_options = override_options,
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.language_server_ids
|
self.language_server_ids
|
||||||
.entry(key.clone())
|
.entry(key.clone())
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
|
let languages = self.languages.clone();
|
||||||
let server_id = post_inc(&mut self.next_language_server_id);
|
let server_id = post_inc(&mut self.next_language_server_id);
|
||||||
let language_server = self.languages.start_language_server(
|
let language_server = self.languages.start_language_server(
|
||||||
server_id,
|
server_id,
|
||||||
|
@ -1977,23 +2001,24 @@ impl Project {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::WorkspaceConfiguration, _, _>({
|
.on_request::<lsp::request::WorkspaceConfiguration, _, _>({
|
||||||
let settings = this.read_with(&cx, |this, _| {
|
move |params, mut cx| {
|
||||||
this.language_server_settings.clone()
|
let languages = languages.clone();
|
||||||
});
|
|
||||||
move |params, _| {
|
|
||||||
let settings = settings.lock().clone();
|
|
||||||
async move {
|
async move {
|
||||||
|
let workspace_config = cx
|
||||||
|
.update(|cx| languages.workspace_configuration(cx))
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(params
|
Ok(params
|
||||||
.items
|
.items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|item| {
|
.map(|item| {
|
||||||
if let Some(section) = &item.section {
|
if let Some(section) = &item.section {
|
||||||
settings
|
workspace_config
|
||||||
.get(section)
|
.get(section)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or(serde_json::Value::Null)
|
.unwrap_or(serde_json::Value::Null)
|
||||||
} else {
|
} else {
|
||||||
settings.clone()
|
workspace_config.clone()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect())
|
.collect())
|
||||||
|
@ -2539,21 +2564,6 @@ impl Project {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_language_server_settings(&mut self, settings: serde_json::Value) {
|
|
||||||
for server_state in self.language_servers.values() {
|
|
||||||
if let LanguageServerState::Running { server, .. } = server_state {
|
|
||||||
server
|
|
||||||
.notify::<lsp::notification::DidChangeConfiguration>(
|
|
||||||
lsp::DidChangeConfigurationParams {
|
|
||||||
settings: settings.clone(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*self.language_server_settings.lock() = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn language_server_statuses(
|
pub fn language_server_statuses(
|
||||||
&self,
|
&self,
|
||||||
) -> impl DoubleEndedIterator<Item = &LanguageServerStatus> {
|
) -> impl DoubleEndedIterator<Item = &LanguageServerStatus> {
|
||||||
|
|
|
@ -9,7 +9,7 @@ path = "src/util.rs"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
test-support = ["serde_json", "tempdir", "git2"]
|
test-support = ["tempdir", "git2"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.38"
|
anyhow = "1.0.38"
|
||||||
|
@ -19,11 +19,10 @@ log = { version = "0.4.16", features = ["kv_unstable_serde"] }
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
tempdir = { version = "0.3.7", optional = true }
|
tempdir = { version = "0.3.7", optional = true }
|
||||||
serde_json = { version = "1.0", features = ["preserve_order"], optional = true }
|
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||||
git2 = { version = "0.15", default-features = false, optional = true }
|
git2 = { version = "0.15", default-features = false, optional = true }
|
||||||
dirs = "3.0"
|
dirs = "3.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempdir = { version = "0.3.7" }
|
tempdir = { version = "0.3.7" }
|
||||||
serde_json = { version = "1.0", features = ["preserve_order"] }
|
|
||||||
git2 = { version = "0.15", default-features = false }
|
git2 = { version = "0.15", default-features = false }
|
||||||
|
|
|
@ -83,6 +83,24 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn merge_json_value_into(source: serde_json::Value, target: &mut serde_json::Value) {
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
match (source, target) {
|
||||||
|
(Value::Object(source), Value::Object(target)) => {
|
||||||
|
for (key, value) in source {
|
||||||
|
if let Some(target) = target.get_mut(&key) {
|
||||||
|
merge_json_value_into(value, target);
|
||||||
|
} else {
|
||||||
|
target.insert(key.clone(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(source, target) => *target = source,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ResultExt {
|
pub trait ResultExt {
|
||||||
type Ok;
|
type Ok;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ use anyhow::Context;
|
||||||
pub use language::*;
|
pub use language::*;
|
||||||
use rust_embed::RustEmbed;
|
use rust_embed::RustEmbed;
|
||||||
use std::{borrow::Cow, str, sync::Arc};
|
use std::{borrow::Cow, str, sync::Arc};
|
||||||
|
use theme::ThemeRegistry;
|
||||||
|
|
||||||
mod c;
|
mod c;
|
||||||
mod elixir;
|
mod elixir;
|
||||||
|
@ -31,7 +32,7 @@ mod yaml;
|
||||||
#[exclude = "*.rs"]
|
#[exclude = "*.rs"]
|
||||||
struct LanguageDir;
|
struct LanguageDir;
|
||||||
|
|
||||||
pub fn init(languages: Arc<LanguageRegistry>) {
|
pub fn init(languages: Arc<LanguageRegistry>, themes: Arc<ThemeRegistry>) {
|
||||||
for (name, grammar, lsp_adapter) in [
|
for (name, grammar, lsp_adapter) in [
|
||||||
(
|
(
|
||||||
"c",
|
"c",
|
||||||
|
@ -61,7 +62,10 @@ pub fn init(languages: Arc<LanguageRegistry>) {
|
||||||
(
|
(
|
||||||
"json",
|
"json",
|
||||||
tree_sitter_json::language(),
|
tree_sitter_json::language(),
|
||||||
Some(Box::new(json::JsonLspAdapter)),
|
Some(Box::new(json::JsonLspAdapter::new(
|
||||||
|
languages.clone(),
|
||||||
|
themes.clone(),
|
||||||
|
))),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"markdown",
|
"markdown",
|
||||||
|
|
|
@ -4,14 +4,32 @@ use async_compression::futures::bufread::GzipDecoder;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use client::http::HttpClient;
|
use client::http::HttpClient;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use futures::{io::BufReader, StreamExt};
|
use futures::{future::BoxFuture, io::BufReader, FutureExt, StreamExt};
|
||||||
use language::{LanguageServerName, LspAdapter};
|
use gpui::MutableAppContext;
|
||||||
|
use language::{LanguageRegistry, LanguageServerName, LspAdapter};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use settings::{keymap_file_json_schema, settings_file_json_schema};
|
||||||
use smol::fs::{self, File};
|
use smol::fs::{self, File};
|
||||||
use std::{any::Any, env::consts, path::PathBuf, sync::Arc};
|
use std::{
|
||||||
use util::ResultExt;
|
any::Any,
|
||||||
|
env::consts,
|
||||||
|
future,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
use theme::ThemeRegistry;
|
||||||
|
use util::{paths, ResultExt, StaffMode};
|
||||||
|
|
||||||
pub struct JsonLspAdapter;
|
pub struct JsonLspAdapter {
|
||||||
|
languages: Arc<LanguageRegistry>,
|
||||||
|
themes: Arc<ThemeRegistry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JsonLspAdapter {
|
||||||
|
pub fn new(languages: Arc<LanguageRegistry>, themes: Arc<ThemeRegistry>) -> Self {
|
||||||
|
Self { languages, themes }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl LspAdapter for JsonLspAdapter {
|
impl LspAdapter for JsonLspAdapter {
|
||||||
|
@ -102,7 +120,45 @@ impl LspAdapter for JsonLspAdapter {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn workspace_configuration(
|
||||||
|
&self,
|
||||||
|
cx: &mut MutableAppContext,
|
||||||
|
) -> Option<BoxFuture<'static, serde_json::Value>> {
|
||||||
|
let action_names = cx.all_action_names().collect::<Vec<_>>();
|
||||||
|
let theme_names = self
|
||||||
|
.themes
|
||||||
|
.list(**cx.default_global::<StaffMode>())
|
||||||
|
.map(|meta| meta.name)
|
||||||
|
.collect();
|
||||||
|
let language_names = self.languages.language_names();
|
||||||
|
Some(
|
||||||
|
future::ready(serde_json::json!({
|
||||||
|
"json": {
|
||||||
|
"format": {
|
||||||
|
"enable": true,
|
||||||
|
},
|
||||||
|
"schemas": [
|
||||||
|
{
|
||||||
|
"fileMatch": [schema_file_match(&paths::SETTINGS)],
|
||||||
|
"schema": settings_file_json_schema(theme_names, &language_names),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fileMatch": [schema_file_match(&paths::KEYMAP)],
|
||||||
|
"schema": keymap_file_json_schema(&action_names),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.boxed(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
async fn language_ids(&self) -> HashMap<String, String> {
|
async fn language_ids(&self) -> HashMap<String, String> {
|
||||||
[("JSON".into(), "jsonc".into())].into_iter().collect()
|
[("JSON".into(), "jsonc".into())].into_iter().collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn schema_file_match(path: &Path) -> &Path {
|
||||||
|
path.strip_prefix(path.parent().unwrap().parent().unwrap())
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ fn main() {
|
||||||
languages.set_executor(cx.background().clone());
|
languages.set_executor(cx.background().clone());
|
||||||
languages.set_language_server_download_dir(paths::LANGUAGES_DIR.clone());
|
languages.set_language_server_download_dir(paths::LANGUAGES_DIR.clone());
|
||||||
let languages = Arc::new(languages);
|
let languages = Arc::new(languages);
|
||||||
languages::init(languages.clone());
|
languages::init(languages.clone(), themes.clone());
|
||||||
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
|
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
|
||||||
|
|
||||||
cx.set_global(client.clone());
|
cx.set_global(client.clone());
|
||||||
|
|
|
@ -29,10 +29,10 @@ use project_panel::ProjectPanel;
|
||||||
use search::{BufferSearchBar, ProjectSearchBar};
|
use search::{BufferSearchBar, ProjectSearchBar};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::to_string_pretty;
|
use serde_json::to_string_pretty;
|
||||||
use settings::{keymap_file_json_schema, settings_file_json_schema, Settings};
|
use settings::Settings;
|
||||||
use std::{borrow::Cow, env, path::Path, str, sync::Arc};
|
use std::{borrow::Cow, env, path::Path, str, sync::Arc};
|
||||||
use terminal_view::terminal_button::{self, TerminalButton};
|
use terminal_view::terminal_button::{self, TerminalButton};
|
||||||
use util::{channel::ReleaseChannel, paths, ResultExt, StaffMode};
|
use util::{channel::ReleaseChannel, paths, ResultExt};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
pub use workspace;
|
pub use workspace;
|
||||||
use workspace::{sidebar::SidebarSide, AppState, Restart, Workspace};
|
use workspace::{sidebar::SidebarSide, AppState, Restart, Workspace};
|
||||||
|
@ -296,34 +296,6 @@ pub fn initialize_workspace(
|
||||||
cx.emit(workspace::Event::PaneAdded(workspace.active_pane().clone()));
|
cx.emit(workspace::Event::PaneAdded(workspace.active_pane().clone()));
|
||||||
cx.emit(workspace::Event::PaneAdded(workspace.dock_pane().clone()));
|
cx.emit(workspace::Event::PaneAdded(workspace.dock_pane().clone()));
|
||||||
|
|
||||||
let theme_names = app_state
|
|
||||||
.themes
|
|
||||||
.list(**cx.default_global::<StaffMode>())
|
|
||||||
.map(|meta| meta.name)
|
|
||||||
.collect();
|
|
||||||
let language_names = app_state.languages.language_names();
|
|
||||||
|
|
||||||
workspace.project().update(cx, |project, cx| {
|
|
||||||
let action_names = cx.all_action_names().collect::<Vec<_>>();
|
|
||||||
project.set_language_server_settings(serde_json::json!({
|
|
||||||
"json": {
|
|
||||||
"format": {
|
|
||||||
"enable": true,
|
|
||||||
},
|
|
||||||
"schemas": [
|
|
||||||
{
|
|
||||||
"fileMatch": [schema_file_match(&paths::SETTINGS)],
|
|
||||||
"schema": settings_file_json_schema(theme_names, &language_names),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fileMatch": [schema_file_match(&paths::KEYMAP)],
|
|
||||||
"schema": keymap_file_json_schema(&action_names),
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
let collab_titlebar_item =
|
let collab_titlebar_item =
|
||||||
cx.add_view(|cx| CollabTitlebarItem::new(&workspace_handle, &app_state.user_store, cx));
|
cx.add_view(|cx| CollabTitlebarItem::new(&workspace_handle, &app_state.user_store, cx));
|
||||||
workspace.set_titlebar_item(collab_titlebar_item, cx);
|
workspace.set_titlebar_item(collab_titlebar_item, cx);
|
||||||
|
@ -676,11 +648,6 @@ fn open_bundled_file(
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schema_file_match(path: &Path) -> &Path {
|
|
||||||
path.strip_prefix(path.parent().unwrap().parent().unwrap())
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -1882,7 +1849,8 @@ mod tests {
|
||||||
let mut languages = LanguageRegistry::new(Task::ready(()));
|
let mut languages = LanguageRegistry::new(Task::ready(()));
|
||||||
languages.set_executor(cx.background().clone());
|
languages.set_executor(cx.background().clone());
|
||||||
let languages = Arc::new(languages);
|
let languages = Arc::new(languages);
|
||||||
languages::init(languages.clone());
|
let themes = ThemeRegistry::new((), cx.font_cache().clone());
|
||||||
|
languages::init(languages.clone(), themes);
|
||||||
for name in languages.language_names() {
|
for name in languages.language_names() {
|
||||||
languages.language_for_name(&name);
|
languages.language_for_name(&name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue