Skip to content

Commit 816b260

Browse files
committed
Simplify LSP settings
1 parent a4f5a00 commit 816b260

File tree

5 files changed

+88
-239
lines changed

5 files changed

+88
-239
lines changed

Cargo.lock

Lines changed: 0 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ark/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ url = "2.4.1"
5353
walkdir = "2"
5454
yaml-rust = "0.4.5"
5555
winsafe = { version = "0.0.19", features = ["kernel"] }
56-
struct-field-names-as-array = "0.3.0"
5756
strum = "0.26.2"
5857
strum_macros = "0.26.2"
5958
futures = "0.3.30"

crates/ark/src/lsp/config.rs

Lines changed: 66 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,75 @@
11
use serde::Deserialize;
22
use serde::Serialize;
3-
use struct_field_names_as_array::FieldNamesAsArray;
3+
use serde_json::Value;
44

5-
use crate::lsp;
65
use crate::lsp::diagnostics::DiagnosticsConfig;
76

7+
pub struct Setting {
8+
pub key: &'static str,
9+
pub set: fn(&mut LspConfig, Value),
10+
}
11+
12+
// List of LSP settings for which clients can send `didChangeConfiguration`
13+
// notifications. We register our interest in watching over these settings in
14+
// our `initialized` handler. The `set` methods convert from a json `Value` to
15+
// the expected type, using a default value if the conversion fails.
16+
pub static SETTINGS: &[Setting] = &[
17+
Setting {
18+
key: "editor.insertSpaces",
19+
set: |cfg, v| {
20+
let default_style = IndentationConfig::default().indent_style;
21+
cfg.document.indent.indent_style = if v
22+
.as_bool()
23+
.unwrap_or_else(|| default_style == IndentStyle::Space)
24+
{
25+
IndentStyle::Space
26+
} else {
27+
IndentStyle::Tab
28+
}
29+
},
30+
},
31+
Setting {
32+
key: "editor.indentSize",
33+
set: |cfg, v| {
34+
cfg.document.indent.indent_size = v
35+
.as_u64()
36+
.map(|n| n as usize)
37+
.unwrap_or_else(|| IndentationConfig::default().indent_size)
38+
},
39+
},
40+
Setting {
41+
key: "editor.tabSize",
42+
set: |cfg, v| {
43+
cfg.document.indent.tab_width = v
44+
.as_u64()
45+
.map(|n| n as usize)
46+
.unwrap_or_else(|| IndentationConfig::default().tab_width)
47+
},
48+
},
49+
Setting {
50+
key: "positron.r.diagnostics.enable",
51+
set: |cfg, v| {
52+
cfg.diagnostics.enable = v
53+
.as_bool()
54+
.unwrap_or_else(|| DiagnosticsConfig::default().enable)
55+
},
56+
},
57+
Setting {
58+
key: "positron.r.symbols.includeAssignmentsInBlocks",
59+
set: |cfg, v| {
60+
cfg.symbols.include_assignments_in_blocks = v
61+
.as_bool()
62+
.unwrap_or_else(|| SymbolsConfig::default().include_assignments_in_blocks)
63+
},
64+
},
65+
];
66+
867
/// Configuration of the LSP
968
#[derive(Clone, Default, Debug)]
1069
pub(crate) struct LspConfig {
1170
pub(crate) diagnostics: DiagnosticsConfig,
1271
pub(crate) symbols: SymbolsConfig,
72+
pub(crate) document: DocumentConfig,
1373
}
1474

1575
#[derive(Serialize, Deserialize, Clone, Debug)]
@@ -39,28 +99,28 @@ pub struct IndentationConfig {
3999
pub tab_width: usize,
40100
}
41101

42-
#[derive(Serialize, Deserialize, Clone, Debug)]
102+
#[derive(PartialEq, Serialize, Deserialize, Clone, Debug)]
43103
pub enum IndentStyle {
44104
Tab,
45105
Space,
46106
}
47107

48108
/// VS Code representation of a document configuration
49-
#[derive(Serialize, Deserialize, FieldNamesAsArray, Clone, Debug)]
109+
#[derive(Serialize, Deserialize, Clone, Debug)]
50110
pub(crate) struct VscDocumentConfig {
51111
// DEV NOTE: Update `section_from_key()` method after adding a field
52112
pub insert_spaces: bool,
53113
pub indent_size: VscIndentSize,
54114
pub tab_size: usize,
55115
}
56116

57-
#[derive(Serialize, Deserialize, FieldNamesAsArray, Clone, Debug)]
117+
#[derive(Serialize, Deserialize, Clone, Debug)]
58118
pub(crate) struct VscDiagnosticsConfig {
59119
// DEV NOTE: Update `section_from_key()` method after adding a field
60120
pub enable: bool,
61121
}
62122

63-
#[derive(Serialize, Deserialize, FieldNamesAsArray, Clone, Debug)]
123+
#[derive(Serialize, Deserialize, Clone, Debug)]
64124
pub(crate) struct VscSymbolsConfig {
65125
// DEV NOTE: Update `section_from_key()` method after adding a field
66126
pub include_assignments_in_blocks: bool,
@@ -91,79 +151,6 @@ impl Default for IndentationConfig {
91151
}
92152
}
93153

94-
impl VscDocumentConfig {
95-
pub(crate) fn section_from_key(key: &str) -> &str {
96-
match key {
97-
"insert_spaces" => "editor.insertSpaces",
98-
"indent_size" => "editor.indentSize",
99-
"tab_size" => "editor.tabSize",
100-
_ => "unknown", // To be caught via downstream errors
101-
}
102-
}
103-
}
104-
105-
/// Convert from VS Code representation of a document config to our own
106-
/// representation. Currently one-to-one.
107-
impl From<VscDocumentConfig> for DocumentConfig {
108-
fn from(x: VscDocumentConfig) -> Self {
109-
let indent_style = indent_style_from_lsp(x.insert_spaces);
110-
111-
let indent_size = match x.indent_size {
112-
VscIndentSize::Size(size) => size,
113-
VscIndentSize::Alias(var) => {
114-
if var == "tabSize" {
115-
x.tab_size
116-
} else {
117-
lsp::log_warn!("Unknown indent alias {var}, using default");
118-
2
119-
}
120-
},
121-
};
122-
123-
Self {
124-
indent: IndentationConfig {
125-
indent_style,
126-
indent_size,
127-
tab_width: x.tab_size,
128-
},
129-
}
130-
}
131-
}
132-
133-
impl VscDiagnosticsConfig {
134-
pub(crate) fn section_from_key(key: &str) -> &str {
135-
match key {
136-
"enable" => "positron.r.diagnostics.enable",
137-
_ => "unknown", // To be caught via downstream errors
138-
}
139-
}
140-
}
141-
142-
impl From<VscDiagnosticsConfig> for DiagnosticsConfig {
143-
fn from(value: VscDiagnosticsConfig) -> Self {
144-
Self {
145-
enable: value.enable,
146-
}
147-
}
148-
}
149-
150-
impl VscSymbolsConfig {
151-
pub(crate) fn section_from_key(key: &str) -> &str {
152-
match key {
153-
"include_assignments_in_blocks" => "positron.r.symbols.includeAssignmentsInBlocks",
154-
_ => "unknown", // To be caught via downstream errors
155-
}
156-
}
157-
}
158-
159-
impl From<VscSymbolsConfig> for SymbolsConfig {
160-
fn from(value: VscSymbolsConfig) -> Self {
161-
Self {
162-
include_assignments_in_blocks: value.include_assignments_in_blocks,
163-
}
164-
}
165-
}
166-
167154
pub(crate) fn indent_style_from_lsp(insert_spaces: bool) -> IndentStyle {
168155
if insert_spaces {
169156
IndentStyle::Space

crates/ark/src/lsp/handlers.rs

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use anyhow::anyhow;
99
use serde_json::Value;
1010
use stdext::unwrap;
1111
use stdext::unwrap::IntoResult;
12-
use struct_field_names_as_array::FieldNamesAsArray;
1312
use tower_lsp::lsp_types::CodeActionParams;
1413
use tower_lsp::lsp_types::CodeActionResponse;
1514
use tower_lsp::lsp_types::CompletionItem;
@@ -46,9 +45,6 @@ use crate::lsp;
4645
use crate::lsp::code_action::code_actions;
4746
use crate::lsp::completions::provide_completions;
4847
use crate::lsp::completions::resolve_completion;
49-
use crate::lsp::config::VscDiagnosticsConfig;
50-
use crate::lsp::config::VscDocumentConfig;
51-
use crate::lsp::config::VscSymbolsConfig;
5248
use crate::lsp::definitions::goto_definition;
5349
use crate::lsp::document_context::DocumentContext;
5450
use crate::lsp::encoding::convert_lsp_range_to_tree_sitter_range;
@@ -106,22 +102,16 @@ pub(crate) async fn handle_initialized(
106102
// Note that some settings, such as editor indentation properties, may be
107103
// changed by extensions or by the user without changing the actual
108104
// underlying setting. Unfortunately we don't receive updates in that case.
109-
let mut config_document_regs = collect_regs(
110-
VscDocumentConfig::FIELD_NAMES_AS_ARRAY.to_vec(),
111-
VscDocumentConfig::section_from_key,
112-
);
113-
let mut config_symbols_regs: Vec<Registration> = collect_regs(
114-
VscSymbolsConfig::FIELD_NAMES_AS_ARRAY.to_vec(),
115-
VscSymbolsConfig::section_from_key,
116-
);
117-
let mut config_diagnostics_regs: Vec<Registration> = collect_regs(
118-
VscDiagnosticsConfig::FIELD_NAMES_AS_ARRAY.to_vec(),
119-
VscDiagnosticsConfig::section_from_key,
120-
);
121-
122-
regs.append(&mut config_document_regs);
123-
regs.append(&mut config_symbols_regs);
124-
regs.append(&mut config_diagnostics_regs);
105+
106+
use crate::lsp::config::SETTINGS;
107+
108+
for setting in SETTINGS {
109+
regs.push(Registration {
110+
id: uuid::Uuid::new_v4().to_string(),
111+
method: String::from("workspace/didChangeConfiguration"),
112+
register_options: Some(serde_json::json!({ "section": setting.key })),
113+
});
114+
}
125115
}
126116

127117
client
@@ -131,17 +121,6 @@ pub(crate) async fn handle_initialized(
131121
Ok(())
132122
}
133123

134-
fn collect_regs(fields: Vec<&str>, into_section: impl Fn(&str) -> &str) -> Vec<Registration> {
135-
fields
136-
.into_iter()
137-
.map(|field| Registration {
138-
id: uuid::Uuid::new_v4().to_string(),
139-
method: String::from("workspace/didChangeConfiguration"),
140-
register_options: Some(serde_json::json!({ "section": into_section(field) })),
141-
})
142-
.collect()
143-
}
144-
145124
#[tracing::instrument(level = "info", skip_all)]
146125
pub(crate) fn handle_symbol(
147126
params: WorkspaceSymbolParams,

0 commit comments

Comments
 (0)