mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 06:03:58 +00:00
Make siblings an inherent method
This commit is contained in:
parent
d323c81d5c
commit
1a2a8dec14
6 changed files with 30 additions and 34 deletions
|
@ -1,12 +1,11 @@
|
||||||
use join_to_string::join;
|
use join_to_string::join;
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
File, TextUnit, TextRange,
|
File, TextUnit, TextRange, Direction,
|
||||||
ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner},
|
ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner},
|
||||||
SyntaxKind::{COMMA, WHITESPACE},
|
SyntaxKind::{COMMA, WHITESPACE},
|
||||||
SyntaxNodeRef,
|
SyntaxNodeRef,
|
||||||
algo::{
|
algo::{
|
||||||
Direction, siblings,
|
|
||||||
find_leaf_at_offset,
|
find_leaf_at_offset,
|
||||||
find_covering_node,
|
find_covering_node,
|
||||||
},
|
},
|
||||||
|
@ -24,12 +23,12 @@ pub fn flip_comma<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce()
|
||||||
let syntax = file.syntax();
|
let syntax = file.syntax();
|
||||||
|
|
||||||
let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?;
|
let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?;
|
||||||
let left = non_trivia_sibling(comma, Direction::Backward)?;
|
let prev = non_trivia_sibling(comma, Direction::Prev)?;
|
||||||
let right = non_trivia_sibling(comma, Direction::Forward)?;
|
let next = non_trivia_sibling(comma, Direction::Next)?;
|
||||||
Some(move || {
|
Some(move || {
|
||||||
let mut edit = EditBuilder::new();
|
let mut edit = EditBuilder::new();
|
||||||
edit.replace(left.range(), right.text().to_string());
|
edit.replace(prev.range(), next.text().to_string());
|
||||||
edit.replace(right.range(), left.text().to_string());
|
edit.replace(next.range(), prev.text().to_string());
|
||||||
LocalEdit {
|
LocalEdit {
|
||||||
edit: edit.finish(),
|
edit: edit.finish(),
|
||||||
cursor_position: None,
|
cursor_position: None,
|
||||||
|
@ -129,7 +128,7 @@ pub fn introduce_variable<'a>(file: &'a File, range: TextRange) -> Option<impl F
|
||||||
}
|
}
|
||||||
|
|
||||||
fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> {
|
fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> {
|
||||||
siblings(node, direction)
|
node.siblings(direction)
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.find(|node| !node.kind().is_trivia())
|
.find(|node| !node.kind().is_trivia())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
File, TextRange, SyntaxNodeRef, TextUnit,
|
File, TextRange, SyntaxNodeRef, TextUnit, Direction,
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node, Direction, siblings},
|
algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> {
|
pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> {
|
||||||
|
@ -71,12 +71,12 @@ fn pick_best<'a>(l: SyntaxNodeRef<'a>, r: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> {
|
fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> {
|
||||||
let left = adj_comments(node, Direction::Backward);
|
let prev = adj_comments(node, Direction::Prev);
|
||||||
let right = adj_comments(node, Direction::Forward);
|
let next = adj_comments(node, Direction::Next);
|
||||||
if left != right {
|
if prev != next {
|
||||||
Some(TextRange::from_to(
|
Some(TextRange::from_to(
|
||||||
left.range().start(),
|
prev.range().start(),
|
||||||
right.range().end(),
|
next.range().end(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -85,7 +85,7 @@ fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> {
|
||||||
|
|
||||||
fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef {
|
fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef {
|
||||||
let mut res = node;
|
let mut res = node;
|
||||||
for node in siblings(node, dir) {
|
for node in node.siblings(dir) {
|
||||||
match node.kind() {
|
match node.kind() {
|
||||||
COMMENT => res = node,
|
COMMENT => res = node,
|
||||||
WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
|
WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::collections::HashSet;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
File, TextRange, SyntaxNodeRef,
|
File, TextRange, SyntaxNodeRef,
|
||||||
SyntaxKind,
|
SyntaxKind,
|
||||||
algo::{Direction, siblings},
|
Direction,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
@ -62,7 +62,7 @@ fn contiguous_range_for<'a>(
|
||||||
|
|
||||||
let left = node;
|
let left = node;
|
||||||
let mut right = node;
|
let mut right = node;
|
||||||
for node in siblings(node, Direction::Forward) {
|
for node in node.siblings(Direction::Next) {
|
||||||
visited.insert(node);
|
visited.insert(node);
|
||||||
match node.kind() {
|
match node.kind() {
|
||||||
SyntaxKind::WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
|
SyntaxKind::WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
|
||||||
|
|
|
@ -94,22 +94,6 @@ pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRe
|
||||||
common_ancestor(left, right)
|
common_ancestor(left, right)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Direction {
|
|
||||||
Forward,
|
|
||||||
Backward,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn siblings<'a>(
|
|
||||||
node: SyntaxNodeRef<'a>,
|
|
||||||
direction: Direction
|
|
||||||
) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
|
|
||||||
generate(Some(node), move |&node| match direction {
|
|
||||||
Direction::Forward => node.next_sibling(),
|
|
||||||
Direction::Backward => node.prev_sibling(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> {
|
fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> {
|
||||||
for p in n1.ancestors() {
|
for p in n1.ancestors() {
|
||||||
if n2.ancestors().any(|a| a == p) {
|
if n2.ancestors().any(|a| a == p) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ pub use {
|
||||||
ast::AstNode,
|
ast::AstNode,
|
||||||
lexer::{tokenize, Token},
|
lexer::{tokenize, Token},
|
||||||
syntax_kinds::SyntaxKind,
|
syntax_kinds::SyntaxKind,
|
||||||
yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError},
|
yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError, Direction},
|
||||||
reparsing::AtomEdit,
|
reparsing::AtomEdit,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,13 @@ impl SyntaxNode {
|
||||||
SyntaxNode(::rowan::SyntaxNode::new(green, errors))
|
SyntaxNode(::rowan::SyntaxNode::new(green, errors))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum Direction {
|
||||||
|
Next,
|
||||||
|
Prev,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> SyntaxNodeRef<'a> {
|
impl<'a> SyntaxNodeRef<'a> {
|
||||||
pub fn leaf_text(self) -> Option<&'a SmolStr> {
|
pub fn leaf_text(self) -> Option<&'a SmolStr> {
|
||||||
self.0.leaf_text()
|
self.0.leaf_text()
|
||||||
|
@ -71,6 +78,12 @@ impl<'a> SyntaxNodeRef<'a> {
|
||||||
::algo::walk::WalkEvent::Exit(_) => None,
|
::algo::walk::WalkEvent::Exit(_) => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
pub fn siblings(self, direction: Direction) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
|
||||||
|
::algo::generate(Some(self), move |&node| match direction {
|
||||||
|
Direction::Next => node.next_sibling(),
|
||||||
|
Direction::Prev => node.prev_sibling(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: TreeRoot<RaTypes>> SyntaxNode<R> {
|
impl<R: TreeRoot<RaTypes>> SyntaxNode<R> {
|
||||||
|
|
Loading…
Reference in a new issue