diff options
Diffstat (limited to 'crates/server/src/handlers.rs')
-rw-r--r-- | crates/server/src/handlers.rs | 48 |
1 files changed, 46 insertions, 2 deletions
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 @@ | |||
1 | use url::Url; | 1 | use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity, Url, DocumentSymbol, SymbolKind}; |
2 | use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity}; | 2 | use libsyntax2::SyntaxKind; |
3 | use libanalysis::World; | 3 | use libanalysis::World; |
4 | use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; | 4 | use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; |
5 | 5 | ||
@@ -34,6 +34,50 @@ pub fn handle_extend_selection( | |||
34 | Ok(req::ExtendSelectionResult { selections }) | 34 | Ok(req::ExtendSelectionResult { selections }) |
35 | } | 35 | } |
36 | 36 | ||
37 | pub fn handle_document_symbol( | ||
38 | world: World, | ||
39 | params: req::DocumentSymbolParams, | ||
40 | ) -> Result<Option<req::DocumentSymbolResponse>> { | ||
41 | let path = params.text_document.file_path()?; | ||
42 | let file = world.file_syntax(&path)?; | ||
43 | let line_index = world.file_line_index(&path)?; | ||
44 | |||
45 | let mut res: Vec<DocumentSymbol> = Vec::new(); | ||
46 | |||
47 | for symbol in libeditor::file_symbols(&file) { | ||
48 | let doc_symbol = DocumentSymbol { | ||
49 | name: symbol.name.clone(), | ||
50 | detail: Some(symbol.name), | ||
51 | kind: to_symbol_kind(symbol.kind), | ||
52 | deprecated: None, | ||
53 | range: to_vs_range(&line_index, symbol.node_range), | ||
54 | selection_range: to_vs_range(&line_index, symbol.name_range), | ||
55 | children: None, | ||
56 | }; | ||
57 | if let Some(idx) = symbol.parent { | ||
58 | let children = &mut res[idx].children; | ||
59 | if children.is_none() { | ||
60 | *children = Some(Vec::new()); | ||
61 | } | ||
62 | children.as_mut().unwrap().push(doc_symbol); | ||
63 | } else { | ||
64 | res.push(doc_symbol); | ||
65 | } | ||
66 | } | ||
67 | Ok(Some(req::DocumentSymbolResponse::Nested(res))) | ||
68 | } | ||
69 | |||
70 | fn to_symbol_kind(kind: SyntaxKind) -> SymbolKind { | ||
71 | match kind { | ||
72 | SyntaxKind::FUNCTION => SymbolKind::Function, | ||
73 | SyntaxKind::STRUCT => SymbolKind::Struct, | ||
74 | SyntaxKind::ENUM => SymbolKind::Enum, | ||
75 | SyntaxKind::TRAIT => SymbolKind::Interface, | ||
76 | SyntaxKind::MODULE => SymbolKind::Module, | ||
77 | _ => SymbolKind::Variable, | ||
78 | } | ||
79 | } | ||
80 | |||
37 | pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> { | 81 | pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> { |
38 | let path = uri.file_path()?; | 82 | let path = uri.file_path()?; |
39 | let file = world.file_syntax(&path)?; | 83 | let file = world.file_syntax(&path)?; |