mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 07:04:49 +00:00
Split folding ranges into editor and lsp parts
This commit is contained in:
parent
bd2b2f1b48
commit
ff0a706a30
4 changed files with 114 additions and 77 deletions
86
crates/ra_editor/src/folding_ranges.rs
Normal file
86
crates/ra_editor/src/folding_ranges.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use ra_syntax::{
|
||||
File, TextRange, SyntaxNodeRef,
|
||||
SyntaxKind,
|
||||
algo::{walk, Direction, siblings},
|
||||
};
|
||||
|
||||
pub enum FoldKind {
|
||||
Comment,
|
||||
Imports,
|
||||
}
|
||||
|
||||
pub struct Fold {
|
||||
pub range: TextRange,
|
||||
pub kind: FoldKind,
|
||||
}
|
||||
|
||||
pub fn folding_ranges(file: &File) -> Vec<Fold> {
|
||||
let syntax = file.syntax();
|
||||
|
||||
let mut res = vec![];
|
||||
let mut visited = HashSet::new();
|
||||
|
||||
for node in walk::preorder(syntax) {
|
||||
if visited.contains(&node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let range_and_kind = match node.kind() {
|
||||
SyntaxKind::COMMENT => (
|
||||
contiguous_range_for(SyntaxKind::COMMENT, node, &mut visited),
|
||||
Some(FoldKind::Comment),
|
||||
),
|
||||
SyntaxKind::USE_ITEM => (
|
||||
contiguous_range_for(SyntaxKind::USE_ITEM, node, &mut visited),
|
||||
Some(FoldKind::Imports),
|
||||
),
|
||||
_ => (None, None),
|
||||
};
|
||||
|
||||
match range_and_kind {
|
||||
(Some(range), Some(kind)) => {
|
||||
res.push(Fold {
|
||||
range: range,
|
||||
kind: kind
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn contiguous_range_for<'a>(
|
||||
kind: SyntaxKind,
|
||||
node: SyntaxNodeRef<'a>,
|
||||
visited: &mut HashSet<SyntaxNodeRef<'a>>,
|
||||
) -> Option<TextRange> {
|
||||
visited.insert(node);
|
||||
|
||||
let left = node;
|
||||
let mut right = node;
|
||||
for node in siblings(node, Direction::Forward) {
|
||||
visited.insert(node);
|
||||
match node.kind() {
|
||||
SyntaxKind::WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
|
||||
k => {
|
||||
if k == kind {
|
||||
right = node
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if left != right {
|
||||
Some(TextRange::from_to(
|
||||
left.range().start(),
|
||||
right.range().end(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ mod extend_selection;
|
|||
mod symbols;
|
||||
mod line_index;
|
||||
mod edit;
|
||||
mod folding_ranges;
|
||||
mod code_actions;
|
||||
mod typing;
|
||||
mod completion;
|
||||
|
@ -36,6 +37,7 @@ pub use self::{
|
|||
},
|
||||
typing::{join_lines, on_eq_typed},
|
||||
completion::{scope_completion, CompletionItem},
|
||||
folding_ranges::{Fold, FoldKind, folding_ranges}
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue