From 9f1d341ee9bf399fa8fa2a5d2fb5f91e1b319702 Mon Sep 17 00:00:00 2001 From: Luciano Bestia Date: Mon, 18 Jan 2021 19:45:42 +0100 Subject: added region folding --- crates/ide/src/folding_ranges.rs | 76 +++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 8 deletions(-) (limited to 'crates/ide/src') diff --git a/crates/ide/src/folding_ranges.rs b/crates/ide/src/folding_ranges.rs index 45170dd29..99f0c3c99 100644 --- a/crates/ide/src/folding_ranges.rs +++ b/crates/ide/src/folding_ranges.rs @@ -6,9 +6,11 @@ use syntax::{ ast::{self, AstNode, AstToken, VisibilityOwner}, Direction, NodeOrToken, SourceFile, SyntaxKind::{self, *}, - SyntaxNode, TextRange, + SyntaxNode, TextRange, TextSize, }; +use lazy_static::lazy_static; + #[derive(Debug, PartialEq, Eq)] pub enum FoldKind { Comment, @@ -16,6 +18,7 @@ pub enum FoldKind { Mods, Block, ArgList, + Region, } #[derive(Debug)] @@ -29,6 +32,8 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec { let mut visited_comments = FxHashSet::default(); let mut visited_imports = FxHashSet::default(); let mut visited_mods = FxHashSet::default(); + // regions can be nested, here is a LIFO buffer + let mut regions_starts: Vec = vec![]; for element in file.syntax().descendants_with_tokens() { // Fold items that span multiple lines @@ -48,10 +53,32 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec { // Fold groups of comments if let Some(comment) = ast::Comment::cast(token) { if !visited_comments.contains(&comment) { - if let Some(range) = - contiguous_range_for_comment(comment, &mut visited_comments) - { - res.push(Fold { range, kind: FoldKind::Comment }) + // regions are not really comments + use regex::Regex; + lazy_static! { + static ref RE_START: Regex = + Regex::new(r"^\s*//\s*#?region\b").unwrap(); + static ref RE_END: Regex = + Regex::new(r"^\s*//\s*#?endregion\b").unwrap(); + } + if RE_START.is_match(comment.text()) { + regions_starts.push(comment.syntax().text_range().start()); + } else if RE_END.is_match(comment.text()) { + if !regions_starts.is_empty() { + res.push(Fold { + range: TextRange::new( + regions_starts.pop().unwrap(), + comment.syntax().text_range().end(), + ), + kind: FoldKind::Region, + }) + } + } else { + if let Some(range) = + contiguous_range_for_comment(comment, &mut visited_comments) + { + res.push(Fold { range, kind: FoldKind::Comment }) + } } } } @@ -175,9 +202,21 @@ fn contiguous_range_for_comment( } if let Some(c) = ast::Comment::cast(token) { if c.kind() == group_kind { - visited.insert(c.clone()); - last = c; - continue; + // regions are not really comments + use regex::Regex; + lazy_static! { + static ref RE_START: Regex = + Regex::new(r"^\s*//\s*#?region\b").unwrap(); + static ref RE_END: Regex = + Regex::new(r"^\s*//\s*#?endregion\b").unwrap(); + } + if RE_START.is_match(c.text()) || RE_END.is_match(c.text()) { + break; + } else { + visited.insert(c.clone()); + last = c; + continue; + } } } // The comment group ends because either: @@ -224,6 +263,7 @@ mod tests { FoldKind::Mods => "mods", FoldKind::Block => "block", FoldKind::ArgList => "arglist", + FoldKind::Region => "region", }; assert_eq!(kind, &attr.unwrap()); } @@ -418,4 +458,24 @@ fn foo( "#, ) } + + #[test] + fn fold_region() { + log_init_for_test_debug(); + // only error level log is printed on the terminal + log::error!("test fold_region"); + check( + r#" +// 1. some normal comment +// region: test +// 2. some normal comment +calling_function(x,y); +// endregion: test +"#, + ) + } + + fn log_init_for_test_debug() { + let _ = env_logger::builder().is_test(true).try_init(); + } } -- cgit v1.2.3 From 084b21bc36cd624e8db708eb1e12dd6db99a0602 Mon Sep 17 00:00:00 2001 From: Luciano Bestia Date: Fri, 5 Feb 2021 14:32:03 +0100 Subject: simple comparison instead of regex --- crates/ide/src/folding_ranges.rs | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'crates/ide/src') diff --git a/crates/ide/src/folding_ranges.rs b/crates/ide/src/folding_ranges.rs index 99f0c3c99..7ba775a77 100644 --- a/crates/ide/src/folding_ranges.rs +++ b/crates/ide/src/folding_ranges.rs @@ -9,8 +9,6 @@ use syntax::{ SyntaxNode, TextRange, TextSize, }; -use lazy_static::lazy_static; - #[derive(Debug, PartialEq, Eq)] pub enum FoldKind { Comment, @@ -53,17 +51,10 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec { // Fold groups of comments if let Some(comment) = ast::Comment::cast(token) { if !visited_comments.contains(&comment) { - // regions are not really comments - use regex::Regex; - lazy_static! { - static ref RE_START: Regex = - Regex::new(r"^\s*//\s*#?region\b").unwrap(); - static ref RE_END: Regex = - Regex::new(r"^\s*//\s*#?endregion\b").unwrap(); - } - if RE_START.is_match(comment.text()) { + // regions are not real comments + if comment.text().trim().starts_with("// region:") { regions_starts.push(comment.syntax().text_range().start()); - } else if RE_END.is_match(comment.text()) { + } else if comment.text().trim().starts_with("// endregion") { if !regions_starts.is_empty() { res.push(Fold { range: TextRange::new( @@ -202,15 +193,10 @@ fn contiguous_range_for_comment( } if let Some(c) = ast::Comment::cast(token) { if c.kind() == group_kind { - // regions are not really comments - use regex::Regex; - lazy_static! { - static ref RE_START: Regex = - Regex::new(r"^\s*//\s*#?region\b").unwrap(); - static ref RE_END: Regex = - Regex::new(r"^\s*//\s*#?endregion\b").unwrap(); - } - if RE_START.is_match(c.text()) || RE_END.is_match(c.text()) { + // regions are not real comments + if c.text().trim().starts_with("// region:") + || c.text().trim().starts_with("// endregion") + { break; } else { visited.insert(c.clone()); -- cgit v1.2.3 From 75015b6eaaad6cb6ce511cff2f3f1e5e34450106 Mon Sep 17 00:00:00 2001 From: Luciano <31509965+LucianoBestia@users.noreply.github.com> Date: Sat, 13 Feb 2021 17:46:26 +0100 Subject: Update crates/ide/src/folding_ranges.rs Co-authored-by: Lukas Wirth --- crates/ide/src/folding_ranges.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ide/src') diff --git a/crates/ide/src/folding_ranges.rs b/crates/ide/src/folding_ranges.rs index 7ba775a77..531f3c951 100644 --- a/crates/ide/src/folding_ranges.rs +++ b/crates/ide/src/folding_ranges.rs @@ -55,10 +55,10 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec { if comment.text().trim().starts_with("// region:") { regions_starts.push(comment.syntax().text_range().start()); } else if comment.text().trim().starts_with("// endregion") { - if !regions_starts.is_empty() { + if let Some(region) = regions_starts.pop() { res.push(Fold { range: TextRange::new( - regions_starts.pop().unwrap(), + region, comment.syntax().text_range().end(), ), kind: FoldKind::Region, -- cgit v1.2.3 From a28f9545e18918b68b5c07e0231f2af219a15bb7 Mon Sep 17 00:00:00 2001 From: Luciano Bestia Date: Sat, 13 Feb 2021 17:50:52 +0100 Subject: removed logging stuff --- crates/ide/src/folding_ranges.rs | 7 ------- 1 file changed, 7 deletions(-) (limited to 'crates/ide/src') diff --git a/crates/ide/src/folding_ranges.rs b/crates/ide/src/folding_ranges.rs index 531f3c951..4b1b24562 100644 --- a/crates/ide/src/folding_ranges.rs +++ b/crates/ide/src/folding_ranges.rs @@ -447,9 +447,6 @@ fn foo( #[test] fn fold_region() { - log_init_for_test_debug(); - // only error level log is printed on the terminal - log::error!("test fold_region"); check( r#" // 1. some normal comment @@ -460,8 +457,4 @@ calling_function(x,y); "#, ) } - - fn log_init_for_test_debug() { - let _ = env_logger::builder().is_test(true).try_init(); - } } -- cgit v1.2.3