Merge #127
127: Improve folding r=matklad a=aochagavia
I was messing around with adding support for multiline comments in folding and ended up changing a bunch of other things.
First of all, I am not convinced of folding groups of successive items. For instance, I don't see why it is worthwhile to be able to fold something like the following:
```rust
use foo;
use bar;
```
Furthermore, this causes problems if you want to fold a multiline import:
```rust
use foo::{
quux
};
use bar;
```
The problem is that now there are two possible folds at the same position: we could fold the first use or we could fold the import group. IMO, the only place where folding groups makes sense is when folding comments. Therefore I have **removed folding import groups in favor of folding multiline imports**.
Regarding folding comments, I made it a bit more robust by requiring that comments can only be folded if they have the same flavor. So if you have a bunch of `//` comments followed by `//!` comments, you will get two separate fold groups instead of a single one.
Finally, I rewrote the API in such a way that it should be trivial to add new folds. You only need to:
* Create a new FoldKind
* Add it to the `fold_kind` function that converts from `SyntaxKind` to `FoldKind`
Fixes #113
Co-authored-by: Adolfo Ochagavía <github@adolfo.ochagavia.xyz>
This commit is contained in:
@@ -2197,3 +2197,21 @@ impl<'a> WhileExpr<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// Whitespace
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Whitespace<'a> {
|
||||
syntax: SyntaxNodeRef<'a>,
|
||||
}
|
||||
|
||||
impl<'a> AstNode<'a> for Whitespace<'a> {
|
||||
fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
|
||||
match syntax.kind() {
|
||||
WHITESPACE => Some(Whitespace { syntax }),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
|
||||
}
|
||||
|
||||
impl<'a> Whitespace<'a> {}
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ impl<'a> Lifetime<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Comment<'a> {
|
||||
pub fn text(&self) -> SmolStr {
|
||||
self.syntax().leaf_text().unwrap().clone()
|
||||
pub fn text(&self) -> &SmolStr {
|
||||
self.syntax().leaf_text().unwrap()
|
||||
}
|
||||
|
||||
pub fn flavor(&self) -> CommentFlavor {
|
||||
@@ -120,9 +120,17 @@ impl<'a> Comment<'a> {
|
||||
pub fn prefix(&self) -> &'static str {
|
||||
self.flavor().prefix()
|
||||
}
|
||||
|
||||
pub fn count_newlines_lazy(&self) -> impl Iterator<Item = &()> {
|
||||
self.text().chars().filter(|&c| c == '\n').map(|_| &())
|
||||
}
|
||||
|
||||
pub fn has_newlines(&self) -> bool {
|
||||
self.count_newlines_lazy().count() > 0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum CommentFlavor {
|
||||
Line,
|
||||
Doc,
|
||||
@@ -142,6 +150,20 @@ impl CommentFlavor {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Whitespace<'a> {
|
||||
pub fn text(&self) -> &SmolStr {
|
||||
&self.syntax().leaf_text().unwrap()
|
||||
}
|
||||
|
||||
pub fn count_newlines_lazy(&self) -> impl Iterator<Item = &()> {
|
||||
self.text().chars().filter(|&c| c == '\n').map(|_| &())
|
||||
}
|
||||
|
||||
pub fn has_newlines(&self) -> bool {
|
||||
self.count_newlines_lazy().count() > 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Name<'a> {
|
||||
pub fn text(&self) -> SmolStr {
|
||||
let ident = self.syntax().first_child()
|
||||
|
||||
@@ -538,5 +538,6 @@ Grammar(
|
||||
options: [ "NameRef" ]
|
||||
),
|
||||
"Comment": (),
|
||||
"Whitespace": (),
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user