Skip to content

Commit 2ce4f01

Browse files
committed
Add symbols config
1 parent 86585c4 commit 2ce4f01

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

crates/ark/src/lsp/config.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@ use crate::lsp;
66
use crate::lsp::diagnostics::DiagnosticsConfig;
77

88
/// Configuration of the LSP
9-
#[derive(Clone, Debug)]
9+
#[derive(Clone, Default, Debug)]
1010
pub(crate) struct LspConfig {
1111
pub(crate) diagnostics: DiagnosticsConfig,
12+
pub(crate) symbols: SymbolsConfig,
13+
}
14+
15+
#[derive(Serialize, Deserialize, Clone, Debug)]
16+
pub struct SymbolsConfig {
17+
/// Whether to emit assignments in `{` bloks as document symbols.
18+
pub include_assignments_in_blocks: bool,
1219
}
1320

1421
/// Configuration of a document.
@@ -53,17 +60,23 @@ pub(crate) struct VscDiagnosticsConfig {
5360
pub enable: bool,
5461
}
5562

63+
#[derive(Serialize, Deserialize, FieldNamesAsArray, Clone, Debug)]
64+
pub(crate) struct VscSymbolsConfig {
65+
// DEV NOTE: Update `section_from_key()` method after adding a field
66+
pub include_assignments_in_blocks: bool,
67+
}
68+
5669
#[derive(Serialize, Deserialize, Clone, Debug)]
5770
#[serde(untagged)]
5871
pub(crate) enum VscIndentSize {
5972
Alias(String),
6073
Size(usize),
6174
}
6275

63-
impl Default for LspConfig {
76+
impl Default for SymbolsConfig {
6477
fn default() -> Self {
6578
Self {
66-
diagnostics: Default::default(),
79+
include_assignments_in_blocks: false,
6780
}
6881
}
6982
}
@@ -134,6 +147,23 @@ impl From<VscDiagnosticsConfig> for DiagnosticsConfig {
134147
}
135148
}
136149

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+
137167
pub(crate) fn indent_style_from_lsp(insert_spaces: bool) -> IndentStyle {
138168
if insert_spaces {
139169
IndentStyle::Space

crates/ark/src/lsp/handlers.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use crate::lsp::completions::provide_completions;
4848
use crate::lsp::completions::resolve_completion;
4949
use crate::lsp::config::VscDiagnosticsConfig;
5050
use crate::lsp::config::VscDocumentConfig;
51+
use crate::lsp::config::VscSymbolsConfig;
5152
use crate::lsp::definitions::goto_definition;
5253
use crate::lsp::document_context::DocumentContext;
5354
use crate::lsp::encoding::convert_lsp_range_to_tree_sitter_range;
@@ -109,12 +110,17 @@ pub(crate) async fn handle_initialized(
109110
VscDocumentConfig::FIELD_NAMES_AS_ARRAY.to_vec(),
110111
VscDocumentConfig::section_from_key,
111112
);
113+
let mut config_symbols_regs: Vec<Registration> = collect_regs(
114+
VscSymbolsConfig::FIELD_NAMES_AS_ARRAY.to_vec(),
115+
VscSymbolsConfig::section_from_key,
116+
);
112117
let mut config_diagnostics_regs: Vec<Registration> = collect_regs(
113118
VscDiagnosticsConfig::FIELD_NAMES_AS_ARRAY.to_vec(),
114119
VscDiagnosticsConfig::section_from_key,
115120
);
116121

117122
regs.append(&mut config_document_regs);
123+
regs.append(&mut config_symbols_regs);
118124
regs.append(&mut config_diagnostics_regs);
119125
}
120126

crates/ark/src/lsp/state_handlers.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ use crate::lsp;
4343
use crate::lsp::capabilities::Capabilities;
4444
use crate::lsp::config::indent_style_from_lsp;
4545
use crate::lsp::config::DocumentConfig;
46+
use crate::lsp::config::SymbolsConfig;
4647
use crate::lsp::config::VscDiagnosticsConfig;
4748
use crate::lsp::config::VscDocumentConfig;
49+
use crate::lsp::config::VscSymbolsConfig;
4850
use crate::lsp::diagnostics::DiagnosticsConfig;
4951
use crate::lsp::documents::Document;
5052
use crate::lsp::encoding::get_position_encoding_kind;
@@ -244,6 +246,9 @@ pub(crate) async fn did_change_configuration(
244246
// we should just ignore it. Instead we need to pull the settings again for
245247
// all URI of interest.
246248

249+
// Note that the client sends notifications for settings for which we have
250+
// declared interest in. This registration is done in `handle_initialized()`.
251+
247252
update_config(workspace_uris(state), client, state)
248253
.instrument(tracing::info_span!("did_change_configuration"))
249254
.await
@@ -296,6 +301,16 @@ async fn update_config(
296301
.collect();
297302
items.append(&mut diagnostics_items);
298303

304+
let symbols_keys = VscSymbolsConfig::FIELD_NAMES_AS_ARRAY;
305+
let mut symbols_items: Vec<ConfigurationItem> = symbols_keys
306+
.iter()
307+
.map(|key| ConfigurationItem {
308+
scope_uri: None,
309+
section: Some(VscSymbolsConfig::section_from_key(key).into()),
310+
})
311+
.collect();
312+
items.append(&mut symbols_items);
313+
299314
// For document configs we collect all pairs of URIs and config keys of
300315
// interest in a flat vector
301316
let document_keys = VscDocumentConfig::FIELD_NAMES_AS_ARRAY;
@@ -316,7 +331,8 @@ async fn update_config(
316331
// by chunk
317332
let n_document_items = document_keys.len();
318333
let n_diagnostics_items = diagnostics_keys.len();
319-
let n_items = n_diagnostics_items + (n_document_items * uris.len());
334+
let n_symbols_items = symbols_keys.len();
335+
let n_items = n_diagnostics_items + n_symbols_items + (n_document_items * uris.len());
320336

321337
if configs.len() != n_items {
322338
return Err(anyhow!(
@@ -351,6 +367,19 @@ async fn update_config(
351367
lsp::spawn_diagnostics_refresh_all(state.clone());
352368
}
353369

370+
// --- Symbols
371+
let keys = symbols_keys.into_iter();
372+
let items: Vec<Value> = configs.by_ref().take(n_symbols_items).collect();
373+
374+
let mut map = serde_json::Map::new();
375+
std::iter::zip(keys, items).for_each(|(key, item)| {
376+
map.insert(key.into(), item);
377+
});
378+
379+
let config: VscSymbolsConfig = serde_json::from_value(serde_json::Value::Object(map))?;
380+
let config: SymbolsConfig = config.into();
381+
state.config.symbols = config;
382+
354383
// --- Documents
355384
// For each document, deserialise the vector of JSON values into a typed config
356385
for uri in uris.into_iter() {

0 commit comments

Comments
 (0)