From f2291d6a760f8a2d15074b5874facb03f5f838bc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 11 Aug 2018 14:44:12 +0300 Subject: doc symbols --- crates/server/src/handlers.rs | 48 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'crates/server/src/handlers.rs') diff --git a/crates/server/src/handlers.rs b/crates/server/src/handlers.rs index 8b7e00c92..51e940ef7 100644 --- a/crates/server/src/handlers.rs +++ b/crates/server/src/handlers.rs @@ -1,5 +1,5 @@ -use url::Url; -use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity}; +use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity, Url, DocumentSymbol, SymbolKind}; +use libsyntax2::SyntaxKind; use libanalysis::World; use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; @@ -34,6 +34,50 @@ pub fn handle_extend_selection( Ok(req::ExtendSelectionResult { selections }) } +pub fn handle_document_symbol( + world: World, + params: req::DocumentSymbolParams, +) -> Result> { + let path = params.text_document.file_path()?; + let file = world.file_syntax(&path)?; + let line_index = world.file_line_index(&path)?; + + let mut res: Vec = Vec::new(); + + for symbol in libeditor::file_symbols(&file) { + let doc_symbol = DocumentSymbol { + name: symbol.name.clone(), + detail: Some(symbol.name), + kind: to_symbol_kind(symbol.kind), + deprecated: None, + range: to_vs_range(&line_index, symbol.node_range), + selection_range: to_vs_range(&line_index, symbol.name_range), + children: None, + }; + if let Some(idx) = symbol.parent { + let children = &mut res[idx].children; + if children.is_none() { + *children = Some(Vec::new()); + } + children.as_mut().unwrap().push(doc_symbol); + } else { + res.push(doc_symbol); + } + } + Ok(Some(req::DocumentSymbolResponse::Nested(res))) +} + +fn to_symbol_kind(kind: SyntaxKind) -> SymbolKind { + match kind { + SyntaxKind::FUNCTION => SymbolKind::Function, + SyntaxKind::STRUCT => SymbolKind::Struct, + SyntaxKind::ENUM => SymbolKind::Enum, + SyntaxKind::TRAIT => SymbolKind::Interface, + SyntaxKind::MODULE => SymbolKind::Module, + _ => SymbolKind::Variable, + } +} + pub fn publish_diagnostics(world: World, uri: Url) -> Result { let path = uri.file_path()?; let file = world.file_syntax(&path)?; -- cgit v1.2.3