Skip to content

Commit 4b35f5d

Browse files
symphorienautozimu
authored andcommitted
accept several settings.json files
1 parent 8bb52ee commit 4b35f5d

File tree

6 files changed

+73
-13
lines changed

6 files changed

+73
-13
lines changed

Cargo.lock

+21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ maplit = "1"
2626
serde = "1"
2727
serde_derive = "1"
2828
serde_json = "1"
29+
json-patch = "0.2"
2930
crossbeam = "0.7.3"
3031
jsonrpc-core = "12"
3132
lsp-types = { version = "0.70.0", features = ["proposed"] }

autoload/LanguageClient.vim

+10
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,16 @@ function! s:GetVar(...) abort
282282
endif
283283
endfunction
284284

285+
" if the argument is a list, return it unchanged, otherwise return the list
286+
" containing the argument.
287+
function! s:ToList(x) abort
288+
if type(a:x) == v:t_list
289+
return a:x
290+
else
291+
return [ a:x ]
292+
endif
293+
endfunction
294+
285295
function! s:ShouldUseFloatWindow() abort
286296
let floatingHoverEnabled = s:GetVar('LanguageClient_useFloatingHover', v:true)
287297
return s:FLOAT_WINDOW_AVAILABLE && floatingHoverEnabled

doc/LanguageClient.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,10 @@ Valid options: "Error" | "Warning" | "Info" | "Log"
202202

203203
2.12 g:LanguageClient_settingsPath *g:LanguageClient_settingsPath*
204204

205-
Path for language server settings. If not an absolute path this is relative
206-
to the workspace directory.
205+
Path for language server settings, or list of such paths. If not an absolute
206+
path this is relative to the workspace directory. If several paths are
207+
provided, then the corresponding settings are merged with precedence going to
208+
the last file.
207209

208210
Example settings file content: >
209211
{

src/language_server_protocol.rs

+35-9
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl LanguageClient {
7979
HashMap<String, Vec<String>>,
8080
Option<String>,
8181
Option<String>,
82-
String,
82+
Vec<String>,
8383
u64,
8484
Option<RootMarkers>,
8585
Option<f64>,
@@ -97,7 +97,7 @@ impl LanguageClient {
9797
"s:GetVar('LanguageClient_serverCommands', {})",
9898
"get(g:, 'LanguageClient_selectionUI', v:null)",
9999
"get(g:, 'LanguageClient_trace', v:null)",
100-
"expand(get(g:, 'LanguageClient_settingsPath', '.vim/settings.json'))",
100+
"map(s:ToList(get(g:, 'LanguageClient_settingsPath', '.vim/settings.json')), 'expand(v:val)')",
101101
"!!get(g:, 'LanguageClient_loadSettings', 1)",
102102
"get(g:, 'LanguageClient_rootMarkers', v:null)",
103103
"get(g:, 'LanguageClient_changeThrottle', v:null)",
@@ -275,13 +275,39 @@ impl LanguageClient {
275275
return Ok(Value::Null);
276276
}
277277

278-
let path = Path::new(root).join(&self.get(|state| state.settingsPath.clone())?);
279-
let buffer = read_to_string(&path).with_context(|err| {
280-
format!("Failed to read file ({}): {}", path.to_string_lossy(), err)
281-
})?;
282-
let value = serde_json::from_str(&buffer)?;
283-
let value = expand_json_path(value);
284-
Ok(value)
278+
let mut res = Value::Null;
279+
let mut last_err = None;
280+
let mut at_least_one_success = false;
281+
for orig_path in self.get(|state| state.settingsPath.clone())? {
282+
let path = Path::new(root).join(orig_path);
283+
let buffer = read_to_string(&path).with_context(|err| {
284+
format!("Failed to read file ({}): {}", path.to_string_lossy(), err)
285+
});
286+
let buffer = match buffer {
287+
Err(e) => {
288+
last_err = Some(e.into());
289+
continue;
290+
}
291+
Ok(x) => x,
292+
};
293+
let value = serde_json::from_str(&buffer);
294+
let value = match value {
295+
Err(e) => {
296+
last_err = Some(e.into());
297+
continue;
298+
}
299+
Ok(x) => x,
300+
};
301+
let value = expand_json_path(value);
302+
json_patch::merge(&mut res, &value);
303+
at_least_one_success = true;
304+
}
305+
306+
match last_err {
307+
// no file was read and an error happened
308+
Some(e) if !at_least_one_success => Err(e),
309+
_ => Ok(res),
310+
}
285311
}
286312

287313
fn define_signs(&self) -> Fallible<()> {

src/types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ pub struct State {
173173
pub diagnostics_max_severity: DiagnosticSeverity,
174174
pub documentHighlightDisplay: HashMap<u64, DocumentHighlightDisplay>,
175175
pub windowLogMessageLevel: MessageType,
176-
pub settingsPath: String,
176+
pub settingsPath: Vec<String>,
177177
pub loadSettings: bool,
178178
pub rootMarkers: Option<RootMarkers>,
179179
pub change_throttle: Option<Duration>,
@@ -252,7 +252,7 @@ impl State {
252252
diagnostics_max_severity: DiagnosticSeverity::Hint,
253253
documentHighlightDisplay: DocumentHighlightDisplay::default(),
254254
windowLogMessageLevel: MessageType::Warning,
255-
settingsPath: format!(".vim{}settings.json", std::path::MAIN_SEPARATOR),
255+
settingsPath: vec![format!(".vim{}settings.json", std::path::MAIN_SEPARATOR)],
256256
loadSettings: false,
257257
rootMarkers: None,
258258
change_throttle: None,

0 commit comments

Comments
 (0)