-
Notifications
You must be signed in to change notification settings - Fork 46
Unify initialization process for all editors #680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
use std::time::Duration; | ||
|
||
use log::info; | ||
use serde_json::Value; | ||
|
||
use crate::{context::ServerContextSnapshot, util::time_cancel_token}; | ||
use emmylua_code_analysis::file_path_to_uri; | ||
|
||
use super::ClientConfig; | ||
|
||
pub async fn get_client_config_default( | ||
context: &ServerContextSnapshot, | ||
config: &mut ClientConfig, | ||
scopes: Option<&[&str]>, | ||
) -> Option<()> { | ||
let workspace_folders = context | ||
.workspace_manager | ||
.read() | ||
.await | ||
.workspace_folders | ||
.clone(); | ||
let main_workspace_folder = workspace_folders.get(0); | ||
let client = &context.client; | ||
let scope_uri = main_workspace_folder.map(|p| file_path_to_uri(p).unwrap()); | ||
|
||
let mut configs = Vec::new(); | ||
let mut used_scope = None; | ||
for scope in scopes.unwrap_or(&["emmylua"]) { | ||
let params = lsp_types::ConfigurationParams { | ||
items: vec![lsp_types::ConfigurationItem { | ||
scope_uri: scope_uri.clone(), | ||
section: Some(scope.to_string()), | ||
}], | ||
}; | ||
let cancel_token = time_cancel_token(Duration::from_secs(5)); | ||
let fetched_configs: Vec<_> = client | ||
.get_configuration::<Value>(params, cancel_token) | ||
.await? | ||
.into_iter() | ||
.filter(|config| !config.is_null()) | ||
.collect(); | ||
if !fetched_configs.is_empty() { | ||
info!("found client config in scope {scope:?}"); | ||
configs = fetched_configs; | ||
used_scope = Some(scope.to_string()); | ||
} | ||
} | ||
|
||
if let Some(used_scope) = used_scope { | ||
info!( | ||
"using client config from scope {used_scope:?}: {}", | ||
serde_json::to_string_pretty(&configs) | ||
.as_deref() | ||
.unwrap_or("<failed to serialize json>") | ||
); | ||
} else { | ||
info!("no client config found"); | ||
} | ||
|
||
for config in &mut configs { | ||
// VSCode always sends default values for all options, even those that weren't | ||
// explicitly configured by user. This results in `null`s being sent for | ||
// every option. Naturally, serde chokes on these nulls when applying partial | ||
// configuration. | ||
// | ||
// Because of this, we have to ignore them here. | ||
skip_nulls(config); | ||
} | ||
|
||
config.partial_emmyrcs = Some(configs); | ||
|
||
Some(()) | ||
} | ||
|
||
fn skip_nulls(v: &mut Value) { | ||
if let Value::Object(obj) = v { | ||
obj.retain(|_, v| !v.is_null()); | ||
for (_, v) in obj { | ||
skip_nulls(v); | ||
} | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
use std::{collections::HashMap, time::Duration}; | ||
|
||
use serde::{Deserialize, Serialize}; | ||
|
||
use crate::{context::ServerContextSnapshot, util::time_cancel_token}; | ||
|
||
use super::ClientConfig; | ||
use crate::handlers::initialized::client_config::default_config::get_client_config_default; | ||
use crate::{context::ServerContextSnapshot, util::time_cancel_token}; | ||
use serde::{Deserialize, Serialize}; | ||
use std::{collections::HashMap, time::Duration}; | ||
|
||
#[derive(Debug, Deserialize, Serialize)] | ||
struct VscodeFilesConfig { | ||
|
@@ -17,6 +15,8 @@ pub async fn get_client_config_vscode( | |
context: &ServerContextSnapshot, | ||
config: &mut ClientConfig, | ||
) -> Option<()> { | ||
get_client_config_default(context, config, None).await; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why request configuration? The existing configuration in EmmyLua is unrelated to the language server itself; it’s mainly for color settings. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to provide a way to change non-project-related settings (like which inlay hints to display, whether to render markdown in comments or not, etc.) from VSCode interface. This approach repeats what rust-analyzer and several other LSPs do. Current WIP on VSCode settings: ![]() Plus, I want to provide a standard way for all editors to change EmmyLua's config. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Manual maintenance is very difficult. LuaLS generates its package.json, so if this is to be implemented, I hope it can be generated automatically. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With schema export already present, this shouldn't be hard to implement. I'll add it when sending PR to the VSCode extension. |
||
|
||
let client = &context.client; | ||
let params = lsp_types::ConfigurationParams { | ||
items: vec![lsp_types::ConfigurationItem { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this rolls back a change made in previous commit. This is because NeoVim doesn't require workspace root to run EmmyLua. In this case,
workspace_folders
will be empty, but we should still request configs from the client.Let me know if I've missed something and I shouldn't change this.