Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit 816017b

Browse files
authored
Merge pull request #1150 from alexheretic/initialize-options-settings
Support InitializationOptions.settings
2 parents c76d29b + 292cb5b commit 816017b

File tree

9 files changed

+137
-79
lines changed

9 files changed

+137
-79
lines changed

src/actions/hover.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,8 +1186,7 @@ pub mod test {
11861186
true,
11871187
);
11881188

1189-
let init_options = InitializationOptions::default();
1190-
ctx.init(&init_options, output);
1189+
ctx.init(InitializationOptions::default(), output);
11911190
ctx.build(&project_dir, BuildPriority::Immediate, output);
11921191

11931192
TooltipTestHarness {

src/actions/mod.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl ActionContext {
8989
pub fn init<O: Output>(
9090
&mut self,
9191
current_project: PathBuf,
92-
init_options: &InitializationOptions,
92+
init_options: InitializationOptions,
9393
client_capabilities: lsp_data::ClientCapabilities,
9494
out: &O,
9595
) -> Result<(), ()> {
@@ -306,20 +306,32 @@ impl InitActionContext {
306306
}
307307
}
308308

309-
fn init<O: Output>(&self, init_options: &InitializationOptions, out: &O) {
309+
fn init<O: Output>(&self, init_options: InitializationOptions, out: &O) {
310310
let current_project = self.current_project.clone();
311-
let config = self.config.clone();
312-
// Spawn another thread since we're shelling out to Cargo and this can
313-
// cause a non-trivial amount of time due to disk access
314-
thread::spawn(move || {
315-
let mut config = config.lock().unwrap();
316-
if let Err(e) = config.infer_defaults(&current_project) {
317-
debug!(
318-
"Encountered an error while trying to infer config defaults: {:?}",
319-
e
320-
);
311+
312+
let needs_inference = {
313+
let mut config = self.config.lock().unwrap();
314+
315+
if let Some(init_config) = init_options.settings.map(|s| s.rust) {
316+
config.update(init_config);
321317
}
322-
});
318+
config.needs_inference()
319+
};
320+
321+
if needs_inference {
322+
let config = Arc::clone(&self.config);
323+
// Spawn another thread since we're shelling out to Cargo and this can
324+
// cause a non-trivial amount of time due to disk access
325+
thread::spawn(move || {
326+
let mut config = config.lock().unwrap();
327+
if let Err(e) = config.infer_defaults(&current_project) {
328+
debug!(
329+
"Encountered an error while trying to infer config defaults: {:?}",
330+
e
331+
);
332+
}
333+
});
334+
}
323335

324336
if !init_options.omit_init_build {
325337
self.build_current_project(BuildPriority::Cargo, out);

src/actions/notifications.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
//! One-way notifications that the RLS receives from the client.
1212
1313
use crate::actions::{FileWatch, InitActionContext, VersionOrdering};
14-
use crate::config::Config;
1514
use crate::Span;
1615
use log::{debug, trace, warn};
1716
use rls_vfs::{Change, VfsSpan};
18-
use serde::de::Error;
1917
use serde::Deserialize;
2018
use serde_json;
2119
use std::sync::atomic::Ordering;
@@ -158,16 +156,12 @@ impl BlockingNotificationAction for DidChangeConfiguration {
158156
out: O,
159157
) -> Result<(), ()> {
160158
trace!("config change: {:?}", params.settings);
161-
let config = params
162-
.settings
163-
.get("rust")
164-
.ok_or_else(|| serde_json::Error::missing_field("rust"))
165-
.and_then(Config::deserialize);
159+
let settings = ChangeConfigSettings::deserialize(&params.settings);
166160

167-
let new_config = match config {
161+
let new_config = match settings {
168162
Ok(mut value) => {
169-
value.normalise();
170-
value
163+
value.rust.normalise();
164+
value.rust
171165
}
172166
Err(err) => {
173167
warn!(

src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<T> AsRef<T> for Inferrable<T> {
114114
}
115115

116116
/// RLS configuration options.
117-
#[derive(Clone, Debug, Deserialize, Serialize)]
117+
#[derive(Clone, Debug, Deserialize)]
118118
#[allow(missing_docs)]
119119
#[serde(default)]
120120
pub struct Config {

src/lsp_data.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rls_span as span;
2121
use serde_derive::{Deserialize, Serialize};
2222
use url::Url;
2323

24+
use crate::config;
2425
use crate::actions::hover;
2526

2627
pub use languageserver_types::notification::Notification as LSPNotification;
@@ -256,23 +257,32 @@ impl RangeExt for Range {
256257
}
257258
}
258259

260+
/// `DidChangeConfigurationParams.settings` payload reading the { rust: {...} } bit.
261+
#[derive(Debug, Deserialize)]
262+
pub struct ChangeConfigSettings {
263+
pub rust: config::Config,
264+
}
265+
259266
/* ----------------- JSON-RPC protocol types ----------------- */
260267

261268
/// Supported initialization options that can be passed in the `initialize`
262269
/// request, under `initialization_options` key. These are specific to the RLS.
263-
#[derive(Debug, PartialEq, Deserialize, Serialize)]
270+
#[derive(Debug, Deserialize)]
264271
#[serde(default, rename_all = "camelCase")]
265272
pub struct InitializationOptions {
266273
/// Should the build not be triggered immediately after receiving `initialize`
267274
pub omit_init_build: bool,
268275
pub cmd_run: bool,
276+
/// `DidChangeConfigurationParams.settings` payload for upfront configuration.
277+
pub settings: Option<ChangeConfigSettings>,
269278
}
270279

271280
impl Default for InitializationOptions {
272281
fn default() -> Self {
273282
InitializationOptions {
274283
omit_init_build: false,
275284
cmd_run: false,
285+
settings: None,
276286
}
277287
}
278288
}

src/server/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,16 @@ impl BlockingRequestAction for InitializeRequest {
9898
let init_options: InitializationOptions = params
9999
.initialization_options
100100
.as_ref()
101-
.and_then(|options| serde_json::from_value(options.to_owned()).ok())
101+
.and_then(|options| {
102+
let de = serde_json::from_value(options.to_owned());
103+
if let Err(ref e) = de {
104+
warn!("initialization_options: {}", e);
105+
}
106+
de.ok()
107+
})
102108
.unwrap_or_default();
103109

104-
trace!("init: {:?}", init_options);
110+
trace!("init: {:?} -> {:?}", params.initialization_options, init_options);
105111

106112
if ctx.inited().is_ok() {
107113
return Err(ResponseError::Message(
@@ -120,7 +126,7 @@ impl BlockingRequestAction for InitializeRequest {
120126
result.send(id, &out);
121127

122128
let capabilities = lsp_data::ClientCapabilities::new(&params);
123-
ctx.init(get_root_path(&params), &init_options, capabilities, &out)
129+
ctx.init(get_root_path(&params), init_options, capabilities, &out)
124130
.unwrap();
125131

126132
Ok(NoResponse)

src/test/harness.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,17 @@ impl Environment {
9595
crate fn mock_server(
9696
&mut self,
9797
messages: Vec<String>,
98-
) -> (ls_server::LsService<RecordOutput>, LsResultList) {
98+
) -> (ls_server::LsService<RecordOutput>, LsResultList, Arc<Mutex<Config>>) {
9999
let analysis = Arc::new(AnalysisHost::new(Target::Debug));
100100
let vfs = Arc::new(Vfs::new());
101101
let config = Arc::new(Mutex::new(self.config.take().unwrap()));
102102
let reader = Box::new(MockMsgReader::new(messages));
103103
let output = RecordOutput::new();
104104
let results = output.output.clone();
105105
(
106-
ls_server::LsService::new(analysis, vfs, config, reader, output),
106+
ls_server::LsService::new(analysis, vfs, Arc::clone(&config), reader, output),
107107
results,
108+
config,
108109
)
109110
}
110111
}

src/test/lens.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use url::Url;
66

77
use crate::{
88
actions::requests,
9-
lsp_data::InitializationOptions,
109
server as ls_server,
1110
test::{
1211
harness::{compare_json, expect_message, expect_series, Environment, ExpectedMessage},
@@ -16,6 +15,8 @@ use crate::{
1615

1716
#[test]
1817
fn test_lens_run() {
18+
use serde_json::json;
19+
1920
let mut env = Environment::new("lens_run");
2021

2122
let source_file_path = Path::new("src").join("main.rs");
@@ -29,10 +30,7 @@ fn test_lens_run() {
2930
initialize_with_opts(
3031
0,
3132
root_path,
32-
Some(InitializationOptions {
33-
omit_init_build: false,
34-
cmd_run: true,
35-
}),
33+
Some(json!({ "cmdRun": true })),
3634
).to_string(),
3735
request::<requests::CodeLensRequest>(
3836
100,
@@ -42,7 +40,7 @@ fn test_lens_run() {
4240
).to_string(),
4341
];
4442

45-
let (mut server, results) = env.mock_server(messages);
43+
let (mut server, results, ..) = env.mock_server(messages);
4644
// Initialize and build.
4745
assert_eq!(
4846
ls_server::LsService::handle_message(&mut server),

0 commit comments

Comments
 (0)