Skip to content

Commit 8d23c90

Browse files
IvoWingelaarautozimu
authored andcommitted
Fix parsing of documentSymbol request
1 parent b4de079 commit 8d23c90

File tree

2 files changed

+126
-17
lines changed

2 files changed

+126
-17
lines changed

src/language_server_protocol.rs

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,34 +1223,87 @@ impl LanguageClient {
12231223
return Ok(result);
12241224
}
12251225

1226-
let symbols: Vec<SymbolInformation> = serde_json::from_value(result.clone())?;
1226+
let syms: <lsp::request::DocumentSymbolRequest as lsp::request::Request>::Result =
1227+
serde_json::from_value(result.clone())?;
1228+
12271229
let title = format!("[LC]: symbols for {}", filename);
12281230

12291231
let selectionUI = self.get(|state| state.selectionUI)?;
12301232
let selectionUI_autoOpen = self.get(|state| state.selectionUI_autoOpen)?;
12311233
match selectionUI {
12321234
SelectionUI::FZF => {
1233-
let source: Vec<_> = symbols
1234-
.iter()
1235-
.map(|sym| {
1236-
let start = sym.location.range.start;
1237-
format!(
1238-
"{}:{}:\t{}\t\t{:?}",
1239-
start.line + 1,
1240-
start.character + 1,
1241-
sym.name,
1242-
sym.kind
1243-
)
1244-
})
1245-
.collect();
1235+
let symbols = match syms {
1236+
Some(lsp::DocumentSymbolResponse::Flat(flat)) => flat
1237+
.iter()
1238+
.map(|sym| {
1239+
let start = sym.location.range.start;
1240+
format!(
1241+
"{}:{}:\t{}\t\t{:?}",
1242+
start.line + 1,
1243+
start.character + 1,
1244+
sym.name,
1245+
sym.kind
1246+
)
1247+
})
1248+
.collect(),
1249+
Some(lsp::DocumentSymbolResponse::Nested(nested)) => {
1250+
let mut symbols = Vec::new();
1251+
1252+
fn walk_document_symbol(
1253+
buffer: &mut Vec<String>,
1254+
parent: Option<&str>,
1255+
ds: &lsp::DocumentSymbol,
1256+
) {
1257+
let start = ds.selection_range.start;
1258+
1259+
let name = if let Some(parent) = parent {
1260+
format!("{}::{}", parent, ds.name)
1261+
} else {
1262+
ds.name.clone()
1263+
};
1264+
1265+
let n = format!(
1266+
"{}:{}:\t{}\t\t{:?}",
1267+
start.line + 1,
1268+
start.character + 1,
1269+
name,
1270+
ds.kind
1271+
);
1272+
1273+
buffer.push(n);
1274+
1275+
if let Some(children) = &ds.children {
1276+
for child in children {
1277+
walk_document_symbol(buffer, Some(&ds.name), child);
1278+
}
1279+
}
1280+
}
1281+
1282+
for ds in &nested {
1283+
walk_document_symbol(&mut symbols, None, ds);
1284+
}
1285+
1286+
symbols
1287+
}
1288+
_ => Vec::new(),
1289+
};
12461290

12471291
self.vim()?.rpcclient.notify(
12481292
"s:FZF",
1249-
json!([source, format!("s:{}", NOTIFICATION__FZFSinkLocation)]),
1293+
json!([symbols, format!("s:{}", NOTIFICATION__FZFSinkLocation)]),
12501294
)?;
12511295
}
12521296
SelectionUI::Quickfix => {
1253-
let list: Fallible<Vec<_>> = symbols.iter().map(QuickfixEntry::from_lsp).collect();
1297+
let list = match syms {
1298+
Some(lsp::DocumentSymbolResponse::Flat(flat)) => {
1299+
flat.iter().map(QuickfixEntry::from_lsp).collect()
1300+
}
1301+
Some(lsp::DocumentSymbolResponse::Nested(nested)) => {
1302+
<(Vec<QuickfixEntry>)>::from_lsp(&nested)
1303+
}
1304+
_ => Ok(Vec::new()),
1305+
};
1306+
12541307
let list = list?;
12551308
self.vim()?.setqflist(&list, " ", &title)?;
12561309
if selectionUI_autoOpen {
@@ -1260,7 +1313,16 @@ impl LanguageClient {
12601313
.echo("Document symbols populated to quickfix list.")?;
12611314
}
12621315
SelectionUI::LocationList => {
1263-
let list: Fallible<Vec<_>> = symbols.iter().map(QuickfixEntry::from_lsp).collect();
1316+
let list = match syms {
1317+
Some(lsp::DocumentSymbolResponse::Flat(flat)) => {
1318+
flat.iter().map(QuickfixEntry::from_lsp).collect()
1319+
}
1320+
Some(lsp::DocumentSymbolResponse::Nested(nested)) => {
1321+
<(Vec<QuickfixEntry>)>::from_lsp(&nested)
1322+
}
1323+
_ => Ok(Vec::new()),
1324+
};
1325+
12641326
let list = list?;
12651327
self.vim()?.setloclist(&list, " ", &title)?;
12661328
if selectionUI_autoOpen {

src/types.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,53 @@ impl FromLSP<SymbolInformation> for QuickfixEntry {
10451045
}
10461046
}
10471047

1048+
impl FromLSP<Vec<lsp::SymbolInformation>> for Vec<QuickfixEntry> {
1049+
fn from_lsp(symbols: &Vec<lsp::SymbolInformation>) -> Fallible<Self> {
1050+
symbols.iter().map(QuickfixEntry::from_lsp).collect()
1051+
}
1052+
}
1053+
1054+
impl FromLSP<Vec<lsp::DocumentSymbol>> for Vec<QuickfixEntry> {
1055+
fn from_lsp(document_symbols: &Vec<lsp::DocumentSymbol>) -> Fallible<Self> {
1056+
let mut symbols = Vec::new();
1057+
1058+
fn walk_document_symbol(
1059+
buffer: &mut Vec<QuickfixEntry>,
1060+
parent: Option<&str>,
1061+
ds: &lsp::DocumentSymbol,
1062+
) {
1063+
let start = ds.selection_range.start;
1064+
1065+
let name = if let Some(parent) = parent {
1066+
format!("{}::{}", parent, ds.name)
1067+
} else {
1068+
ds.name.clone()
1069+
};
1070+
1071+
buffer.push(QuickfixEntry {
1072+
filename: "".to_string(),
1073+
lnum: start.line + 1,
1074+
col: Some(start.character + 1),
1075+
text: Some(name),
1076+
nr: None,
1077+
typ: None,
1078+
});
1079+
1080+
if let Some(children) = &ds.children {
1081+
for child in children {
1082+
walk_document_symbol(buffer, Some(&ds.name), child);
1083+
}
1084+
}
1085+
}
1086+
1087+
for ds in document_symbols {
1088+
walk_document_symbol(&mut symbols, None, ds);
1089+
}
1090+
1091+
Ok(symbols)
1092+
}
1093+
}
1094+
10481095
#[derive(Debug, Serialize, Deserialize)]
10491096
#[serde(untagged)]
10501097
pub enum RawMessage {

0 commit comments

Comments
 (0)