305: Fold curly blocks r=matklad a=matklad
307: ⬆️ 1.31.1 r=matklad a=matklad
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
f1fafeee02
@ -9,7 +9,7 @@ env:
|
||||
|
||||
build: &rust_build
|
||||
language: rust
|
||||
rust: 1.31.0
|
||||
rust: 1.31.1
|
||||
script:
|
||||
- cargo gen-tests --verify
|
||||
- cargo gen-syntax --verify
|
||||
|
@ -10,6 +10,7 @@ use ra_syntax::{
|
||||
pub enum FoldKind {
|
||||
Comment,
|
||||
Imports,
|
||||
Block,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -62,6 +63,8 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
|
||||
match kind {
|
||||
COMMENT => Some(FoldKind::Comment),
|
||||
USE_ITEM => Some(FoldKind::Imports),
|
||||
NAMED_FIELD_DEF_LIST | FIELD_PAT_LIST | ITEM_LIST | EXTERN_ITEM_LIST | USE_TREE_LIST
|
||||
| BLOCK | ENUM_VARIANT_LIST => Some(FoldKind::Block),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -170,7 +173,7 @@ mod tests {
|
||||
use test_utils::extract_ranges;
|
||||
|
||||
fn do_check(text: &str, fold_kinds: &[FoldKind]) {
|
||||
let (ranges, text) = extract_ranges(text);
|
||||
let (ranges, text) = extract_ranges(text, "fold");
|
||||
let file = SourceFileNode::parse(&text);
|
||||
let folds = folding_ranges(&file);
|
||||
|
||||
@ -198,26 +201,27 @@ mod tests {
|
||||
#[test]
|
||||
fn test_fold_comments() {
|
||||
let text = r#"
|
||||
<|>// Hello
|
||||
<fold>// Hello
|
||||
// this is a multiline
|
||||
// comment
|
||||
//<|>
|
||||
//</fold>
|
||||
|
||||
// But this is not
|
||||
|
||||
fn main() {
|
||||
<|>// We should
|
||||
fn main() <fold>{
|
||||
<fold>// We should
|
||||
// also
|
||||
// fold
|
||||
// this one.<|>
|
||||
<|>//! But this one is different
|
||||
//! because it has another flavor<|>
|
||||
<|>/* As does this
|
||||
multiline comment */<|>
|
||||
}"#;
|
||||
// this one.</fold>
|
||||
<fold>//! But this one is different
|
||||
//! because it has another flavor</fold>
|
||||
<fold>/* As does this
|
||||
multiline comment */</fold>
|
||||
}</fold>"#;
|
||||
|
||||
let fold_kinds = &[
|
||||
FoldKind::Comment,
|
||||
FoldKind::Block,
|
||||
FoldKind::Comment,
|
||||
FoldKind::Comment,
|
||||
FoldKind::Comment,
|
||||
@ -228,60 +232,66 @@ fn main() {
|
||||
#[test]
|
||||
fn test_fold_imports() {
|
||||
let text = r#"
|
||||
<|>use std::{
|
||||
<fold>use std::<fold>{
|
||||
str,
|
||||
vec,
|
||||
io as iop
|
||||
};<|>
|
||||
}</fold>;</fold>
|
||||
|
||||
fn main() {
|
||||
}"#;
|
||||
fn main() <fold>{
|
||||
}</fold>"#;
|
||||
|
||||
let folds = &[FoldKind::Imports];
|
||||
let folds = &[FoldKind::Imports, FoldKind::Block, FoldKind::Block];
|
||||
do_check(text, folds);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_import_groups() {
|
||||
let text = r#"
|
||||
<|>use std::str;
|
||||
<fold>use std::str;
|
||||
use std::vec;
|
||||
use std::io as iop;<|>
|
||||
use std::io as iop;</fold>
|
||||
|
||||
<|>use std::mem;
|
||||
use std::f64;<|>
|
||||
<fold>use std::mem;
|
||||
use std::f64;</fold>
|
||||
|
||||
use std::collections::HashMap;
|
||||
// Some random comment
|
||||
use std::collections::VecDeque;
|
||||
|
||||
fn main() {
|
||||
}"#;
|
||||
fn main() <fold>{
|
||||
}</fold>"#;
|
||||
|
||||
let folds = &[FoldKind::Imports, FoldKind::Imports];
|
||||
let folds = &[FoldKind::Imports, FoldKind::Imports, FoldKind::Block];
|
||||
do_check(text, folds);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_import_and_groups() {
|
||||
let text = r#"
|
||||
<|>use std::str;
|
||||
<fold>use std::str;
|
||||
use std::vec;
|
||||
use std::io as iop;<|>
|
||||
use std::io as iop;</fold>
|
||||
|
||||
<|>use std::mem;
|
||||
use std::f64;<|>
|
||||
<fold>use std::mem;
|
||||
use std::f64;</fold>
|
||||
|
||||
<|>use std::collections::{
|
||||
<fold>use std::collections::<fold>{
|
||||
HashMap,
|
||||
VecDeque,
|
||||
};<|>
|
||||
}</fold>;</fold>
|
||||
// Some random comment
|
||||
|
||||
fn main() {
|
||||
}"#;
|
||||
fn main() <fold>{
|
||||
}</fold>"#;
|
||||
|
||||
let folds = &[FoldKind::Imports, FoldKind::Imports, FoldKind::Imports];
|
||||
let folds = &[
|
||||
FoldKind::Imports,
|
||||
FoldKind::Imports,
|
||||
FoldKind::Imports,
|
||||
FoldKind::Block,
|
||||
FoldKind::Block,
|
||||
];
|
||||
do_check(text, folds);
|
||||
}
|
||||
|
||||
|
@ -446,8 +446,9 @@ pub fn handle_folding_range(
|
||||
.into_iter()
|
||||
.map(|fold| {
|
||||
let kind = match fold.kind {
|
||||
FoldKind::Comment => FoldingRangeKind::Comment,
|
||||
FoldKind::Imports => FoldingRangeKind::Imports,
|
||||
FoldKind::Comment => Some(FoldingRangeKind::Comment),
|
||||
FoldKind::Imports => Some(FoldingRangeKind::Imports),
|
||||
FoldKind::Block => None,
|
||||
};
|
||||
let range = fold.range.conv_with(&line_index);
|
||||
FoldingRange {
|
||||
@ -455,7 +456,7 @@ pub fn handle_folding_range(
|
||||
start_character: Some(range.start.character),
|
||||
end_line: range.end.line,
|
||||
end_character: Some(range.start.character),
|
||||
kind: Some(kind),
|
||||
kind,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
|
@ -66,15 +66,40 @@ pub fn try_extract_range(text: &str) -> Option<(TextRange, String)> {
|
||||
Some((TextRange::from_to(start, end), text))
|
||||
}
|
||||
|
||||
pub fn extract_ranges(text: &str) -> (Vec<TextRange>, String) {
|
||||
/// Extracts ranges, marked with `<tag> </tag>` paris from the `text`
|
||||
pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
|
||||
let open = format!("<{}>", tag);
|
||||
let close = format!("</{}>", tag);
|
||||
let mut ranges = Vec::new();
|
||||
let mut text = String::from(text);
|
||||
while let Some((range, new_text)) = try_extract_range(&text) {
|
||||
text = new_text;
|
||||
ranges.push(range);
|
||||
let mut res = String::new();
|
||||
let mut stack = Vec::new();
|
||||
loop {
|
||||
match text.find('<') {
|
||||
None => {
|
||||
res.push_str(text);
|
||||
break;
|
||||
}
|
||||
Some(i) => {
|
||||
res.push_str(&text[..i]);
|
||||
text = &text[i..];
|
||||
if text.starts_with(&open) {
|
||||
text = &text[open.len()..];
|
||||
let from = TextUnit::of_str(&res);
|
||||
stack.push(from);
|
||||
} else if text.starts_with(&close) {
|
||||
text = &text[close.len()..];
|
||||
let from = stack
|
||||
.pop()
|
||||
.unwrap_or_else(|| panic!("unmatched </{}>", tag));
|
||||
let to = TextUnit::of_str(&res);
|
||||
ranges.push(TextRange::from_to(from, to));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(ranges, text)
|
||||
assert!(stack.is_empty(), "unmatched <{}>", tag);
|
||||
ranges.sort_by_key(|r| (r.start(), r.end()));
|
||||
(ranges, res)
|
||||
}
|
||||
|
||||
pub fn add_cursor(text: &str, offset: TextUnit) -> String {
|
||||
|
@ -15,7 +15,7 @@ pub type Result<T> = std::result::Result<T, failure::Error>;
|
||||
pub const GRAMMAR: &str = "crates/ra_syntax/src/grammar.ron";
|
||||
pub const SYNTAX_KINDS: &str = "crates/ra_syntax/src/syntax_kinds/generated.rs.tera";
|
||||
pub const AST: &str = "crates/ra_syntax/src/ast/generated.rs.tera";
|
||||
const TOOLCHAIN: &str = "1.31.0";
|
||||
const TOOLCHAIN: &str = "1.31.1";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Test {
|
||||
|
Loading…
x
Reference in New Issue
Block a user