aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src/ted.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/syntax/src/ted.rs')
-rw-r--r--crates/syntax/src/ted.rs49
1 files changed, 47 insertions, 2 deletions
diff --git a/crates/syntax/src/ted.rs b/crates/syntax/src/ted.rs
index 8d6175ed9..f2166bbd3 100644
--- a/crates/syntax/src/ted.rs
+++ b/crates/syntax/src/ted.rs
@@ -1,8 +1,9 @@
1//! Primitive tree editor, ed for trees 1//! Primitive tree editor, ed for trees
2#![allow(unused)]
3use std::ops::RangeInclusive; 2use std::ops::RangeInclusive;
4 3
5use crate::{SyntaxElement, SyntaxNode}; 4use parser::T;
5
6use crate::{ast::make, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken};
6 7
7#[derive(Debug)] 8#[derive(Debug)]
8pub struct Position { 9pub struct Position {
@@ -42,9 +43,25 @@ impl Position {
42 } 43 }
43} 44}
44 45
46pub fn insert_ws(position: Position, elem: impl Into<SyntaxElement>) {
47 insert_all_ws(position, vec![elem.into()])
48}
45pub fn insert(position: Position, elem: impl Into<SyntaxElement>) { 49pub fn insert(position: Position, elem: impl Into<SyntaxElement>) {
46 insert_all(position, vec![elem.into()]) 50 insert_all(position, vec![elem.into()])
47} 51}
52pub fn insert_all_ws(position: Position, mut elements: Vec<SyntaxElement>) {
53 if let Some(first) = elements.first() {
54 if let Some(ws) = ws_before(&position, first) {
55 elements.insert(0, ws.into())
56 }
57 }
58 if let Some(last) = elements.last() {
59 if let Some(ws) = ws_after(&position, last) {
60 elements.push(ws.into())
61 }
62 }
63 insert_all(position, elements)
64}
48pub fn insert_all(position: Position, elements: Vec<SyntaxElement>) { 65pub fn insert_all(position: Position, elements: Vec<SyntaxElement>) {
49 let (parent, index) = match position.repr { 66 let (parent, index) = match position.repr {
50 PositionRepr::FirstChild(parent) => (parent, 0), 67 PositionRepr::FirstChild(parent) => (parent, 0),
@@ -72,7 +89,35 @@ pub fn replace_all(range: RangeInclusive<SyntaxElement>, new: Vec<SyntaxElement>
72 parent.splice_children(start..end + 1, new) 89 parent.splice_children(start..end + 1, new)
73} 90}
74 91
92pub fn append_child_ws(node: impl Into<SyntaxNode>, child: impl Into<SyntaxElement>) {
93 let position = Position::last_child_of(node);
94 insert_ws(position, child)
95}
75pub fn append_child(node: impl Into<SyntaxNode>, child: impl Into<SyntaxElement>) { 96pub fn append_child(node: impl Into<SyntaxNode>, child: impl Into<SyntaxElement>) {
76 let position = Position::last_child_of(node); 97 let position = Position::last_child_of(node);
77 insert(position, child) 98 insert(position, child)
78} 99}
100
101fn ws_before(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> {
102 let prev = match &position.repr {
103 PositionRepr::FirstChild(_) => return None,
104 PositionRepr::After(it) => it,
105 };
106 ws_between(prev, new)
107}
108fn ws_after(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> {
109 let next = match &position.repr {
110 PositionRepr::FirstChild(parent) => parent.first_child_or_token()?,
111 PositionRepr::After(sibling) => sibling.next_sibling_or_token()?,
112 };
113 ws_between(new, &next)
114}
115fn ws_between(left: &SyntaxElement, right: &SyntaxElement) -> Option<SyntaxToken> {
116 if left.kind() == SyntaxKind::WHITESPACE || right.kind() == SyntaxKind::WHITESPACE {
117 return None;
118 }
119 if right.kind() == T![;] || right.kind() == T![,] {
120 return None;
121 }
122 Some(make::tokens::single_space().into())
123}