aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/main_loop
diff options
context:
space:
mode:
authorJeremy A. Kolb <[email protected]>2018-09-24 14:52:33 +0100
committerJeremy A. Kolb <[email protected]>2018-09-24 14:52:33 +0100
commitff0a706a30567f297642ba1fa6ee9537ed82c40f (patch)
tree7bb8c79853cf24da27a66c2c891529bcd46d8cdf /crates/ra_lsp_server/src/main_loop
parentbd2b2f1b48f86d59c3b746b72a14192f75419a84 (diff)
Split folding ranges into editor and lsp parts
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs98
1 files changed, 21 insertions, 77 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 36cdeda38..51061543c 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -1,4 +1,4 @@
1use std::collections::{HashMap, HashSet}; 1use std::collections::{HashMap};
2 2
3use languageserver_types::{ 3use languageserver_types::{
4 Diagnostic, DiagnosticSeverity, DocumentSymbol, 4 Diagnostic, DiagnosticSeverity, DocumentSymbol,
@@ -8,11 +8,9 @@ use languageserver_types::{
8 FoldingRange, FoldingRangeParams, FoldingRangeKind 8 FoldingRange, FoldingRangeParams, FoldingRangeKind
9}; 9};
10use serde_json::to_value; 10use serde_json::to_value;
11use ra_analysis::{Query, FileId, RunnableKind, JobToken}; 11use ra_analysis::{Query, FileId, RunnableKind, JobToken, FoldKind};
12use ra_syntax::{ 12use ra_syntax::{
13 algo::{siblings, walk, Direction}, 13 text_utils::contains_offset_nonstrict
14 text_utils::contains_offset_nonstrict,
15 SyntaxKind, SyntaxNodeRef, TextRange
16}; 14};
17 15
18use ::{ 16use ::{
@@ -375,82 +373,28 @@ pub fn handle_folding_range(
375 _token: JobToken, 373 _token: JobToken,
376) -> Result<Option<Vec<FoldingRange>>> { 374) -> Result<Option<Vec<FoldingRange>>> {
377 let file_id = params.text_document.try_conv_with(&world)?; 375 let file_id = params.text_document.try_conv_with(&world)?;
378 let file = world.analysis().file_syntax(file_id);
379 let line_index = world.analysis().file_line_index(file_id); 376 let line_index = world.analysis().file_line_index(file_id);
380 let syntax = file.syntax();
381
382 let mut res = vec![];
383 let mut visited = HashSet::new();
384
385 for node in walk::preorder(syntax) {
386 if visited.contains(&node) {
387 continue;
388 }
389
390 let range_and_kind = match node.kind() {
391 SyntaxKind::COMMENT => (
392 contiguous_range_for(SyntaxKind::COMMENT, node, &mut visited),
393 Some(FoldingRangeKind::Comment),
394 ),
395 SyntaxKind::USE_ITEM => (
396 contiguous_range_for(SyntaxKind::USE_ITEM, node, &mut visited),
397 Some(FoldingRangeKind::Imports),
398 ),
399 _ => (None, None),
400 };
401 377
402 match range_and_kind { 378 let res = Some(world.analysis()
403 (Some(range), Some(kind)) => { 379 .folding_ranges(file_id)
404 let range = range.conv_with(&line_index); 380 .into_iter()
405 res.push(FoldingRange { 381 .map(|fold| {
406 start_line: range.start.line, 382 let kind = match fold.kind {
407 start_character: Some(range.start.character), 383 FoldKind::Comment => FoldingRangeKind::Comment,
408 end_line: range.end.line, 384 FoldKind::Imports => FoldingRangeKind::Imports
409 end_character: Some(range.start.character), 385 };
410 kind: Some(kind), 386 let range = fold.range.conv_with(&line_index);
411 }); 387 FoldingRange {
388 start_line: range.start.line,
389 start_character: Some(range.start.character),
390 end_line: range.end.line,
391 end_character: Some(range.start.character),
392 kind: Some(kind)
412 } 393 }
413 _ => {} 394 })
414 } 395 .collect());
415 }
416
417 if res.is_empty() {
418 Ok(None)
419 } else {
420 Ok(Some(res))
421 }
422}
423 396
424fn contiguous_range_for<'a>( 397 Ok(res)
425 kind: SyntaxKind,
426 node: SyntaxNodeRef<'a>,
427 visited: &mut HashSet<SyntaxNodeRef<'a>>,
428) -> Option<TextRange> {
429 visited.insert(node);
430
431 let left = node;
432 let mut right = node;
433 for node in siblings(node, Direction::Forward) {
434 visited.insert(node);
435 match node.kind() {
436 SyntaxKind::WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
437 k => {
438 if k == kind {
439 right = node
440 } else {
441 break;
442 }
443 }
444 }
445 }
446 if left != right {
447 Some(TextRange::from_to(
448 left.range().start(),
449 right.range().end(),
450 ))
451 } else {
452 None
453 }
454} 398}
455 399
456pub fn handle_code_action( 400pub fn handle_code_action(