Skip to content

Commit 8c54407

Browse files
committed
Unify initialization process for all editors
Right now, our LSP only requests settings when client is VSCode or NeoVim. To make matters worse, it requests *different* settings for these clients: - for VSCode, it requests VSCode-specific about files and extensions, - for NeoVim, it requests settings in scope `"Lua"`, and uses them as overrides for `.emmyrc`. This PR aims to unify this behavior and make it easier for users to override settings without having to create `.emmyrc.json`. This is especially handy when you want to override a setting for a single project, but don't want to change project's `.emmyrc.json`. For example, switching documentation highlighting on per-project basis will become easier (see discussion in #665). # Changes - When client is VSCode, LSP will request settings under `"emmylua"` scope, as well as VSCode-specific settings mentioned above. I'll add relevant settings to the plugin settings page in a separate PR when this is merged; until then, these changes will not affect user experience. - When client is NeoVim, LSP will request settings under `"emmylua"` scope. If there's no such scope, it will fall back to using the `"Lua"` scope. Currently, both LuaLs and EmmyLua use the same scope `"Lua"`. It works in NeoVim because options for every LSP server are independent. In VSCode, however, they all share the same namespace, meaning that we can't reuse `"Lua"`. I'd like to keep things consistent, hence this rename. I'll send a PR to update nvim-lspconfig's documentation for EmmyLua when this is merged. - For any other client, LSP will request settings under `"emmylua"` scope. Currently, there are no clients that provide this scope (EmmyLua2 for Intellij doesn't provide any config scopes), so it shouldn't break anything, but it will provide future client implementations with a better way to override LSP configuration. # Tests Tested this with VSCode and NeoVim.
1 parent 9464063 commit 8c54407

File tree

4 files changed

+75
-57
lines changed

4 files changed

+75
-57
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::time::Duration;
2+
3+
use log::info;
4+
use serde_json::Value;
5+
6+
use crate::{context::ServerContextSnapshot, util::time_cancel_token};
7+
use emmylua_code_analysis::file_path_to_uri;
8+
9+
use super::ClientConfig;
10+
11+
pub async fn get_client_config_default(
12+
context: &ServerContextSnapshot,
13+
config: &mut ClientConfig,
14+
scopes: Option<&[&str]>,
15+
) -> Option<()> {
16+
let workspace_folders = context
17+
.workspace_manager
18+
.read()
19+
.await
20+
.workspace_folders
21+
.clone();
22+
let main_workspace_folder = workspace_folders.get(0);
23+
let client = &context.client;
24+
let scope_uri = main_workspace_folder.map(|p| file_path_to_uri(p).unwrap());
25+
26+
let mut configs = Vec::new();
27+
let mut used_scope = None;
28+
for scope in scopes.unwrap_or(&["emmylua"]) {
29+
let params = lsp_types::ConfigurationParams {
30+
items: vec![lsp_types::ConfigurationItem {
31+
scope_uri: scope_uri.clone(),
32+
section: Some(scope.to_string()),
33+
}],
34+
};
35+
let cancel_token = time_cancel_token(Duration::from_secs(5));
36+
let fetched_configs: Vec<_> = client
37+
.get_configuration::<Value>(params, cancel_token)
38+
.await?
39+
.into_iter()
40+
.filter(|config| !config.is_null())
41+
.collect();
42+
if !fetched_configs.is_empty() {
43+
info!("found client config in scope {scope:?}");
44+
configs = fetched_configs;
45+
used_scope = Some(scope.to_string());
46+
}
47+
}
48+
49+
if let Some(used_scope) = used_scope {
50+
info!(
51+
"using client config from scope {used_scope:?}: {}",
52+
serde_json::to_string_pretty(&configs)
53+
.as_deref()
54+
.unwrap_or("<failed to serialize json>")
55+
);
56+
} else {
57+
info!("no client config found");
58+
}
59+
60+
config.partial_emmyrcs = Some(configs);
61+
62+
Some(())
63+
}

crates/emmylua_ls/src/handlers/initialized/client_config/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
mod neovim_config;
1+
mod default_config;
22
mod vscode_config;
33

4-
use neovim_config::get_client_config_neovim;
4+
use default_config::get_client_config_default;
55
use serde_json::Value;
66
use vscode_config::get_client_config_vscode;
77

@@ -30,8 +30,10 @@ pub async fn get_client_config(
3030
};
3131
match client_id {
3232
ClientId::VSCode => get_client_config_vscode(context, &mut config).await,
33-
ClientId::Neovim => get_client_config_neovim(context, &mut config).await,
34-
_ => Some(()),
33+
ClientId::Neovim => {
34+
get_client_config_default(context, &mut config, Some(&["Lua", "emmylua"])).await
35+
}
36+
_ => get_client_config_default(context, &mut config, None).await,
3537
};
3638

3739
config

crates/emmylua_ls/src/handlers/initialized/client_config/neovim_config.rs

Lines changed: 0 additions & 47 deletions
This file was deleted.

crates/emmylua_ls/src/handlers/initialized/client_config/vscode_config.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
use std::{collections::HashMap, time::Duration};
2-
3-
use serde::{Deserialize, Serialize};
4-
5-
use crate::{context::ServerContextSnapshot, util::time_cancel_token};
6-
71
use super::ClientConfig;
2+
use crate::handlers::initialized::client_config::default_config::get_client_config_default;
3+
use crate::{context::ServerContextSnapshot, util::time_cancel_token};
4+
use serde::{Deserialize, Serialize};
5+
use std::{collections::HashMap, time::Duration};
86

97
#[derive(Debug, Deserialize, Serialize)]
108
struct VscodeFilesConfig {
@@ -17,6 +15,8 @@ pub async fn get_client_config_vscode(
1715
context: &ServerContextSnapshot,
1816
config: &mut ClientConfig,
1917
) -> Option<()> {
18+
get_client_config_default(context, config, None).await;
19+
2020
let client = &context.client;
2121
let params = lsp_types::ConfigurationParams {
2222
items: vec![lsp_types::ConfigurationItem {

0 commit comments

Comments
 (0)