yerba 0.7.2 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/yerba/version.rb +1 -1
- data/rust/Cargo.toml +1 -1
- data/rust/src/document/condition.rs +4 -4
- data/rust/src/document/delete.rs +8 -31
- data/rust/src/document/get.rs +10 -16
- data/rust/src/document/insert.rs +50 -144
- data/rust/src/document/mod.rs +80 -79
- data/rust/src/document/schema.rs +1 -1
- data/rust/src/document/set.rs +42 -38
- data/rust/src/document/sort.rs +150 -310
- data/rust/src/document/style.rs +78 -308
- data/rust/src/document/unique.rs +4 -5
- data/rust/src/selector.rs +3 -3
- data/rust/src/syntax.rs +63 -47
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4305ac41ddb57b2c537679a4924163c87b715418e2e4c9d80ce9f4dc2979ebd4
|
|
4
|
+
data.tar.gz: 425313784c600c32d9b3a054beaaf152550772a804fa40c22f96bd052852ec72
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf1fdc98836e461bd02830a07008ba86df5fd71d22d8ff478e042c5c36e89caad9cb006e5c20ac191a3c24c11fe33add62d12109e1269225464247093d549142
|
|
7
|
+
data.tar.gz: 85fa2fac4eff2cf7662a2549b6b5dac953e4a3646e71b405774ebd39ec2200604429ea8cd11724385ae801248a7250e94c53a4cd41b9c4f126b6d93f6ec8fa71
|
data/lib/yerba/version.rb
CHANGED
data/rust/Cargo.toml
CHANGED
|
@@ -11,7 +11,7 @@ impl Document {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
pub fn filter_with_selectors(&self, dot_path: &str, condition: &str) -> Vec<(yaml_serde::Value, String, usize)> {
|
|
14
|
-
let source = self.
|
|
14
|
+
let source = self.source_text();
|
|
15
15
|
|
|
16
16
|
self
|
|
17
17
|
.navigate_all_compact(dot_path)
|
|
@@ -19,7 +19,7 @@ impl Document {
|
|
|
19
19
|
.filter(|node| self.evaluate_condition_on_node(node, condition))
|
|
20
20
|
.map(|node| {
|
|
21
21
|
let offset: usize = node.text_range().start().into();
|
|
22
|
-
let line = source
|
|
22
|
+
let line = line_at(&source, offset);
|
|
23
23
|
|
|
24
24
|
(node_to_yaml_value(node), super::get::node_selector(node), line)
|
|
25
25
|
})
|
|
@@ -52,7 +52,7 @@ impl Document {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
for node in &target_nodes {
|
|
55
|
-
if let Some(sequence) = node
|
|
55
|
+
if let Some(sequence) = find_block_sequence(node) {
|
|
56
56
|
for entry in sequence.entries() {
|
|
57
57
|
if let Some(text) = entry.flow().and_then(|flow| extract_scalar_text(flow.syntax())) {
|
|
58
58
|
if text == right {
|
|
@@ -67,7 +67,7 @@ impl Document {
|
|
|
67
67
|
}
|
|
68
68
|
"not_contains" => {
|
|
69
69
|
for node in &target_nodes {
|
|
70
|
-
if let Some(sequence) = node
|
|
70
|
+
if let Some(sequence) = find_block_sequence(node) {
|
|
71
71
|
for entry in sequence.entries() {
|
|
72
72
|
if let Some(text) = entry.flow().and_then(|flow| extract_scalar_text(flow.syntax())) {
|
|
73
73
|
if text == right {
|
data/rust/src/document/delete.rs
CHANGED
|
@@ -13,10 +13,7 @@ impl Document {
|
|
|
13
13
|
let (parent_path, source_key) = source_path.rsplit_once('.').unwrap_or(("", source_path));
|
|
14
14
|
let parent_node = self.navigate(parent_path)?;
|
|
15
15
|
|
|
16
|
-
let map = parent_node
|
|
17
|
-
.descendants()
|
|
18
|
-
.find_map(BlockMap::cast)
|
|
19
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
16
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
20
17
|
|
|
21
18
|
let entry = find_entry_by_key(&map, source_key).ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
22
19
|
let key_node = entry.key().ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
@@ -46,10 +43,7 @@ impl Document {
|
|
|
46
43
|
|
|
47
44
|
if parent_path.is_empty() && !has_wildcard {
|
|
48
45
|
let parent_node = self.navigate(&parent_path)?;
|
|
49
|
-
let map = parent_node
|
|
50
|
-
.descendants()
|
|
51
|
-
.find_map(BlockMap::cast)
|
|
52
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
46
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
53
47
|
|
|
54
48
|
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
55
49
|
|
|
@@ -67,10 +61,7 @@ impl Document {
|
|
|
67
61
|
}
|
|
68
62
|
|
|
69
63
|
if parent_nodes.len() == 1 && !has_wildcard {
|
|
70
|
-
let map = parent_nodes[0]
|
|
71
|
-
.descendants()
|
|
72
|
-
.find_map(BlockMap::cast)
|
|
73
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
64
|
+
let map = find_block_map(&parent_nodes[0]).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
74
65
|
|
|
75
66
|
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
76
67
|
|
|
@@ -80,24 +71,16 @@ impl Document {
|
|
|
80
71
|
let mut ranges: Vec<TextRange> = Vec::new();
|
|
81
72
|
|
|
82
73
|
for parent_node in &parent_nodes {
|
|
83
|
-
if let Some(map) = parent_node
|
|
74
|
+
if let Some(map) = find_block_map(parent_node) {
|
|
84
75
|
if let Some(entry) = find_entry_by_key(&map, last_key) {
|
|
85
76
|
ranges.push(removal_range(entry.syntax()));
|
|
86
77
|
}
|
|
87
78
|
}
|
|
88
79
|
}
|
|
89
80
|
|
|
90
|
-
|
|
91
|
-
return Ok(());
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
ranges.reverse();
|
|
95
|
-
|
|
96
|
-
for range in ranges {
|
|
97
|
-
self.apply_edit(range, "")?;
|
|
98
|
-
}
|
|
81
|
+
let edits = ranges.into_iter().map(|range| (range, String::new())).collect();
|
|
99
82
|
|
|
100
|
-
|
|
83
|
+
self.apply_edits(edits)
|
|
101
84
|
}
|
|
102
85
|
|
|
103
86
|
crate::selector::SelectorSegment::Index(index) => self.remove_at(&parent_path, *index),
|
|
@@ -108,10 +91,7 @@ impl Document {
|
|
|
108
91
|
pub fn remove(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {
|
|
109
92
|
let current_node = self.navigate(dot_path)?;
|
|
110
93
|
|
|
111
|
-
let sequence = current_node
|
|
112
|
-
.descendants()
|
|
113
|
-
.find_map(BlockSeq::cast)
|
|
114
|
-
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
94
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
115
95
|
|
|
116
96
|
let target_entry = sequence
|
|
117
97
|
.entries()
|
|
@@ -132,10 +112,7 @@ impl Document {
|
|
|
132
112
|
|
|
133
113
|
let current_node = self.navigate(dot_path)?;
|
|
134
114
|
|
|
135
|
-
let sequence = current_node
|
|
136
|
-
.descendants()
|
|
137
|
-
.find_map(BlockSeq::cast)
|
|
138
|
-
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
115
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
139
116
|
|
|
140
117
|
let entries: Vec<_> = sequence.entries().collect();
|
|
141
118
|
|
data/rust/src/document/get.rs
CHANGED
|
@@ -83,7 +83,7 @@ impl Document {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
pub fn get_all_located(&self, dot_path: &str) -> Vec<LocatedNode> {
|
|
86
|
-
let source = self.
|
|
86
|
+
let source = self.source_text();
|
|
87
87
|
let file_path = self.path.as_ref().map(|p| p.to_string_lossy().to_string());
|
|
88
88
|
|
|
89
89
|
self
|
|
@@ -91,7 +91,7 @@ impl Document {
|
|
|
91
91
|
.iter()
|
|
92
92
|
.map(|node| {
|
|
93
93
|
let offset: usize = node.text_range().start().into();
|
|
94
|
-
let line = source
|
|
94
|
+
let line = line_at(&source, offset);
|
|
95
95
|
let selector = node_selector(node);
|
|
96
96
|
let is_scalar = !node
|
|
97
97
|
.descendants()
|
|
@@ -108,13 +108,8 @@ impl Document {
|
|
|
108
108
|
let node_type = if is_scalar {
|
|
109
109
|
"scalar"
|
|
110
110
|
} else {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
match (map_pos, seq_pos) {
|
|
115
|
-
(Some(m), Some(s)) if s < m => "sequence",
|
|
116
|
-
(Some(_), _) => "map",
|
|
117
|
-
(None, Some(_)) => "sequence",
|
|
111
|
+
match first_collection(node) {
|
|
112
|
+
Some(FirstCollection::Sequence(_)) => "sequence",
|
|
118
113
|
_ => "map",
|
|
119
114
|
}
|
|
120
115
|
};
|
|
@@ -142,7 +137,7 @@ impl Document {
|
|
|
142
137
|
|
|
143
138
|
pub fn get_node_info(&self, dot_path: &str) -> NodeInfo {
|
|
144
139
|
let selector = crate::selector::Selector::parse(dot_path);
|
|
145
|
-
let source = self.
|
|
140
|
+
let source = self.source_text();
|
|
146
141
|
|
|
147
142
|
let (location, key_name, key_location) = self.resolve_location(dot_path, &source);
|
|
148
143
|
|
|
@@ -364,7 +359,7 @@ impl Document {
|
|
|
364
359
|
self.navigate(parent_path).ok()?
|
|
365
360
|
};
|
|
366
361
|
|
|
367
|
-
let map = parent_node
|
|
362
|
+
let map = find_block_map(&parent_node)?;
|
|
368
363
|
|
|
369
364
|
find_entry_by_key(&map, last_key).map(|entry| entry.syntax().clone())
|
|
370
365
|
}
|
|
@@ -375,7 +370,7 @@ impl Document {
|
|
|
375
370
|
Err(_) => return Vec::new(),
|
|
376
371
|
};
|
|
377
372
|
|
|
378
|
-
let sequence = match current_node
|
|
373
|
+
let sequence = match find_block_sequence(¤t_node) {
|
|
379
374
|
Some(sequence) => sequence,
|
|
380
375
|
None => return Vec::new(),
|
|
381
376
|
};
|
|
@@ -403,17 +398,16 @@ impl Document {
|
|
|
403
398
|
pub fn get_sequence_indent(&self, dot_path: &str) -> Option<&'static str> {
|
|
404
399
|
let current_node = self.navigate(dot_path).ok()?;
|
|
405
400
|
|
|
406
|
-
let sequence = current_node
|
|
401
|
+
let sequence = find_block_sequence(¤t_node)?;
|
|
407
402
|
let first_entry = sequence.entries().next()?;
|
|
408
403
|
|
|
409
404
|
let entry_indent = preceding_whitespace_indent(first_entry.syntax());
|
|
410
405
|
|
|
411
406
|
let entry_node = current_node.ancestors().find(|ancestor| ancestor.kind() == SyntaxKind::BLOCK_MAP_ENTRY)?;
|
|
412
407
|
|
|
413
|
-
let source = self.
|
|
408
|
+
let source = self.source_text();
|
|
414
409
|
let entry_start: usize = entry_node.text_range().start().into();
|
|
415
|
-
let
|
|
416
|
-
let key_indent = &source[line_start..entry_start];
|
|
410
|
+
let key_indent = &source[line_start_at(&source, entry_start)..entry_start];
|
|
417
411
|
|
|
418
412
|
if entry_indent.len() > key_indent.len() {
|
|
419
413
|
Some("indented")
|
data/rust/src/document/insert.rs
CHANGED
|
@@ -60,10 +60,7 @@ impl Document {
|
|
|
60
60
|
let quote_style = self.detect_sequence_quote_style(dot_path);
|
|
61
61
|
let current_node = self.navigate(dot_path)?;
|
|
62
62
|
|
|
63
|
-
let sequence = current_node
|
|
64
|
-
.descendants()
|
|
65
|
-
.find_map(BlockSeq::cast)
|
|
66
|
-
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
63
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
67
64
|
|
|
68
65
|
let entries: Vec<_> = sequence.entries().collect();
|
|
69
66
|
|
|
@@ -81,38 +78,7 @@ impl Document {
|
|
|
81
78
|
|
|
82
79
|
for json_value in json_values {
|
|
83
80
|
let yaml_text = crate::yaml_writer::json_to_yaml_text(json_value, "e_style, 0);
|
|
84
|
-
|
|
85
|
-
let new_item = if yaml_text.contains('\n') {
|
|
86
|
-
let item_indent = format!("{} ", indent);
|
|
87
|
-
let lines: Vec<&str> = yaml_text.split('\n').collect();
|
|
88
|
-
|
|
89
|
-
let min_indent = lines
|
|
90
|
-
.iter()
|
|
91
|
-
.skip(1)
|
|
92
|
-
.filter(|line| !line.trim().is_empty())
|
|
93
|
-
.map(|line| line.len() - line.trim_start().len())
|
|
94
|
-
.min()
|
|
95
|
-
.unwrap_or(0);
|
|
96
|
-
|
|
97
|
-
let indented: Vec<String> = lines
|
|
98
|
-
.iter()
|
|
99
|
-
.enumerate()
|
|
100
|
-
.map(|(index, line)| {
|
|
101
|
-
if index == 0 {
|
|
102
|
-
line.to_string()
|
|
103
|
-
} else if line.trim().is_empty() {
|
|
104
|
-
String::new()
|
|
105
|
-
} else {
|
|
106
|
-
let relative = &line[min_indent..];
|
|
107
|
-
format!("{}{}", item_indent, relative)
|
|
108
|
-
}
|
|
109
|
-
})
|
|
110
|
-
.collect();
|
|
111
|
-
|
|
112
|
-
format!("- {}", indented.join("\n"))
|
|
113
|
-
} else {
|
|
114
|
-
format!("- {}", yaml_text)
|
|
115
|
-
};
|
|
81
|
+
let new_item = Self::format_sequence_item(&yaml_text, &indent);
|
|
116
82
|
|
|
117
83
|
new_text.push_str(&format!("\n{}{}", indent, new_item));
|
|
118
84
|
}
|
|
@@ -126,7 +92,7 @@ impl Document {
|
|
|
126
92
|
Self::validate_path(dot_path)?;
|
|
127
93
|
|
|
128
94
|
if let Ok(current_node) = self.navigate(dot_path) {
|
|
129
|
-
if current_node
|
|
95
|
+
if find_block_sequence(¤t_node).is_some()
|
|
130
96
|
|| matches!(self.get_value(dot_path).as_ref(), Some(yaml_serde::Value::Sequence(sequence)) if sequence.is_empty())
|
|
131
97
|
{
|
|
132
98
|
return self.insert_sequence_item(dot_path, value, position);
|
|
@@ -152,7 +118,7 @@ impl Document {
|
|
|
152
118
|
None => continue,
|
|
153
119
|
};
|
|
154
120
|
|
|
155
|
-
let map = match node
|
|
121
|
+
let map = match find_block_map(&node) {
|
|
156
122
|
Some(map) => map,
|
|
157
123
|
None => {
|
|
158
124
|
let has_empty_flow_map = node
|
|
@@ -186,42 +152,13 @@ impl Document {
|
|
|
186
152
|
|
|
187
153
|
let start_col = {
|
|
188
154
|
let offset: usize = first_entry.syntax().text_range().start().into();
|
|
189
|
-
let source = self.
|
|
190
|
-
let before = &source[..offset];
|
|
155
|
+
let source = self.source_text();
|
|
191
156
|
|
|
192
|
-
|
|
157
|
+
column_at(&source, offset)
|
|
193
158
|
};
|
|
194
159
|
|
|
195
160
|
let indent = " ".repeat(start_col);
|
|
196
|
-
|
|
197
|
-
let is_block_value = value.contains('\n') || value.starts_with("- ");
|
|
198
|
-
let new_entry_text = if is_block_value {
|
|
199
|
-
let value_indent = format!("{} ", indent);
|
|
200
|
-
let lines: Vec<&str> = value.lines().collect();
|
|
201
|
-
|
|
202
|
-
let min_indent = lines
|
|
203
|
-
.iter()
|
|
204
|
-
.filter(|line| !line.trim().is_empty())
|
|
205
|
-
.map(|line| line.len() - line.trim_start().len())
|
|
206
|
-
.min()
|
|
207
|
-
.unwrap_or(0);
|
|
208
|
-
|
|
209
|
-
let indented_lines: Vec<String> = lines
|
|
210
|
-
.iter()
|
|
211
|
-
.map(|line| {
|
|
212
|
-
if line.trim().is_empty() {
|
|
213
|
-
String::new()
|
|
214
|
-
} else {
|
|
215
|
-
let relative = &line[min_indent..];
|
|
216
|
-
format!("{}{}", value_indent, relative)
|
|
217
|
-
}
|
|
218
|
-
})
|
|
219
|
-
.collect();
|
|
220
|
-
|
|
221
|
-
format!("{}:\n{}", key, indented_lines.join("\n"))
|
|
222
|
-
} else {
|
|
223
|
-
format!("{}: {}", key, value)
|
|
224
|
-
};
|
|
161
|
+
let new_entry_text = Self::format_map_entry(key, value, &indent);
|
|
225
162
|
|
|
226
163
|
match &position {
|
|
227
164
|
InsertPosition::After(target_key) => {
|
|
@@ -265,7 +202,7 @@ impl Document {
|
|
|
265
202
|
fn insert_sequence_item(&mut self, dot_path: &str, value: &str, position: InsertPosition) -> Result<(), YerbaError> {
|
|
266
203
|
let current_node = self.navigate(dot_path)?;
|
|
267
204
|
|
|
268
|
-
let Some(sequence) = current_node
|
|
205
|
+
let Some(sequence) = find_block_sequence(¤t_node) else {
|
|
269
206
|
if matches!(self.get_value(dot_path).as_ref(), Some(yaml_serde::Value::Sequence(sequence)) if sequence.is_empty()) {
|
|
270
207
|
return self.replace_empty_inline_sequence(dot_path, value);
|
|
271
208
|
}
|
|
@@ -285,37 +222,7 @@ impl Document {
|
|
|
285
222
|
.map(|entry| preceding_whitespace_indent(entry.syntax()))
|
|
286
223
|
.unwrap_or_default();
|
|
287
224
|
|
|
288
|
-
let new_item =
|
|
289
|
-
let item_indent = format!("{} ", indent);
|
|
290
|
-
let lines: Vec<&str> = value.split('\n').collect();
|
|
291
|
-
|
|
292
|
-
let min_indent = lines
|
|
293
|
-
.iter()
|
|
294
|
-
.skip(1)
|
|
295
|
-
.filter(|line| !line.trim().is_empty())
|
|
296
|
-
.map(|line| line.len() - line.trim_start().len())
|
|
297
|
-
.min()
|
|
298
|
-
.unwrap_or(0);
|
|
299
|
-
|
|
300
|
-
let indented: Vec<String> = lines
|
|
301
|
-
.iter()
|
|
302
|
-
.enumerate()
|
|
303
|
-
.map(|(index, line)| {
|
|
304
|
-
if index == 0 {
|
|
305
|
-
line.to_string()
|
|
306
|
-
} else if line.trim().is_empty() {
|
|
307
|
-
String::new()
|
|
308
|
-
} else {
|
|
309
|
-
let relative = &line[min_indent..];
|
|
310
|
-
format!("{}{}", item_indent, relative)
|
|
311
|
-
}
|
|
312
|
-
})
|
|
313
|
-
.collect();
|
|
314
|
-
|
|
315
|
-
format!("- {}", indented.join("\n"))
|
|
316
|
-
} else {
|
|
317
|
-
format!("- {}", value)
|
|
318
|
-
};
|
|
225
|
+
let new_item = Self::format_sequence_item(value, &indent);
|
|
319
226
|
|
|
320
227
|
match position {
|
|
321
228
|
InsertPosition::Last => {
|
|
@@ -413,7 +320,7 @@ impl Document {
|
|
|
413
320
|
fn insert_map_key(&mut self, dot_path: &str, key: &str, value: &str, position: InsertPosition) -> Result<(), YerbaError> {
|
|
414
321
|
let current_node = self.navigate(dot_path)?;
|
|
415
322
|
|
|
416
|
-
let map = match current_node
|
|
323
|
+
let map = match find_block_map(¤t_node) {
|
|
417
324
|
Some(map) => map,
|
|
418
325
|
None => {
|
|
419
326
|
let flow_map = current_node.descendants().find(|descendant| descendant.kind() == SyntaxKind::FLOW_MAP);
|
|
@@ -449,34 +356,7 @@ impl Document {
|
|
|
449
356
|
.map(|entry| preceding_whitespace_indent(entry.syntax()))
|
|
450
357
|
.unwrap_or_default();
|
|
451
358
|
|
|
452
|
-
let
|
|
453
|
-
let new_entry_text = if is_block_value {
|
|
454
|
-
let value_indent = format!("{} ", indent);
|
|
455
|
-
let lines: Vec<&str> = value.lines().collect();
|
|
456
|
-
|
|
457
|
-
let min_indent = lines
|
|
458
|
-
.iter()
|
|
459
|
-
.filter(|line| !line.trim().is_empty())
|
|
460
|
-
.map(|line| line.len() - line.trim_start().len())
|
|
461
|
-
.min()
|
|
462
|
-
.unwrap_or(0);
|
|
463
|
-
|
|
464
|
-
let indented_lines: Vec<String> = lines
|
|
465
|
-
.iter()
|
|
466
|
-
.map(|line| {
|
|
467
|
-
if line.trim().is_empty() {
|
|
468
|
-
String::new()
|
|
469
|
-
} else {
|
|
470
|
-
let relative = &line[min_indent..];
|
|
471
|
-
format!("{}{}", value_indent, relative)
|
|
472
|
-
}
|
|
473
|
-
})
|
|
474
|
-
.collect();
|
|
475
|
-
|
|
476
|
-
format!("{}:\n{}", key, indented_lines.join("\n"))
|
|
477
|
-
} else {
|
|
478
|
-
format!("{}: {}", key, value)
|
|
479
|
-
};
|
|
359
|
+
let new_entry_text = Self::format_map_entry(key, value, &indent);
|
|
480
360
|
|
|
481
361
|
match position {
|
|
482
362
|
InsertPosition::Last => {
|
|
@@ -561,7 +441,7 @@ impl Document {
|
|
|
561
441
|
|
|
562
442
|
let range = flow_map.text_range();
|
|
563
443
|
|
|
564
|
-
let source = self.
|
|
444
|
+
let source = self.source_text();
|
|
565
445
|
let start: usize = range.start().into();
|
|
566
446
|
let before = &source[..start];
|
|
567
447
|
let trimmed_length = before.trim_end_matches([' ', '\n']).len();
|
|
@@ -575,10 +455,7 @@ impl Document {
|
|
|
575
455
|
let (parent_path, map_key) = dot_path.rsplit_once('.').unwrap_or(("", dot_path));
|
|
576
456
|
let parent_node = self.navigate(parent_path)?;
|
|
577
457
|
|
|
578
|
-
let map = parent_node
|
|
579
|
-
.descendants()
|
|
580
|
-
.find_map(BlockMap::cast)
|
|
581
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
458
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
582
459
|
|
|
583
460
|
let entry = find_entry_by_key(&map, map_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
584
461
|
let entry_indent = preceding_whitespace_indent(entry.syntax());
|
|
@@ -601,14 +478,14 @@ impl Document {
|
|
|
601
478
|
fn replace_empty_inline_sequence(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {
|
|
602
479
|
if dot_path.is_empty() {
|
|
603
480
|
let current_node = self.navigate(dot_path)?;
|
|
604
|
-
let
|
|
481
|
+
let flow_sequence = current_node
|
|
605
482
|
.descendants()
|
|
606
483
|
.find(|descendant| descendant.kind() == SyntaxKind::FLOW_SEQ)
|
|
607
484
|
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
608
485
|
|
|
609
486
|
let new_item = Self::format_sequence_item(value, "");
|
|
610
|
-
let range =
|
|
611
|
-
let source = self.
|
|
487
|
+
let range = flow_sequence.text_range();
|
|
488
|
+
let source = self.source_text();
|
|
612
489
|
let start: usize = range.start().into();
|
|
613
490
|
let before = &source[..start];
|
|
614
491
|
|
|
@@ -624,10 +501,7 @@ impl Document {
|
|
|
624
501
|
let (parent_path, key) = dot_path.rsplit_once('.').unwrap_or(("", dot_path));
|
|
625
502
|
let parent_node = self.navigate(parent_path)?;
|
|
626
503
|
|
|
627
|
-
let map = parent_node
|
|
628
|
-
.descendants()
|
|
629
|
-
.find_map(BlockMap::cast)
|
|
630
|
-
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
504
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
631
505
|
|
|
632
506
|
let entry = find_entry_by_key(&map, key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
633
507
|
let item_indent = format!("{} ", preceding_whitespace_indent(entry.syntax()));
|
|
@@ -656,7 +530,7 @@ impl Document {
|
|
|
656
530
|
}
|
|
657
531
|
|
|
658
532
|
fn trailing_inline_comment(&self, node: &SyntaxNode) -> Option<(String, rowan::TextSize)> {
|
|
659
|
-
let source = self.
|
|
533
|
+
let source = self.source_text();
|
|
660
534
|
let start: usize = node.text_range().end().into();
|
|
661
535
|
let rest = &source[start..];
|
|
662
536
|
let line_end = rest.find('\n').unwrap_or(rest.len());
|
|
@@ -670,6 +544,38 @@ impl Document {
|
|
|
670
544
|
Some((trailing[comment_start..].to_string(), rowan::TextSize::from((start + line_end) as u32)))
|
|
671
545
|
}
|
|
672
546
|
|
|
547
|
+
fn format_map_entry(key: &str, value: &str, indent: &str) -> String {
|
|
548
|
+
let is_block_value = value.contains('\n') || value.starts_with("- ");
|
|
549
|
+
|
|
550
|
+
if !is_block_value {
|
|
551
|
+
return format!("{}: {}", key, value);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
let value_indent = format!("{} ", indent);
|
|
555
|
+
let lines: Vec<&str> = value.lines().collect();
|
|
556
|
+
|
|
557
|
+
let min_indent = lines
|
|
558
|
+
.iter()
|
|
559
|
+
.filter(|line| !line.trim().is_empty())
|
|
560
|
+
.map(|line| line.len() - line.trim_start().len())
|
|
561
|
+
.min()
|
|
562
|
+
.unwrap_or(0);
|
|
563
|
+
|
|
564
|
+
let indented_lines: Vec<String> = lines
|
|
565
|
+
.iter()
|
|
566
|
+
.map(|line| {
|
|
567
|
+
if line.trim().is_empty() {
|
|
568
|
+
String::new()
|
|
569
|
+
} else {
|
|
570
|
+
let relative = &line[min_indent..];
|
|
571
|
+
format!("{}{}", value_indent, relative)
|
|
572
|
+
}
|
|
573
|
+
})
|
|
574
|
+
.collect();
|
|
575
|
+
|
|
576
|
+
format!("{}:\n{}", key, indented_lines.join("\n"))
|
|
577
|
+
}
|
|
578
|
+
|
|
673
579
|
fn format_sequence_item(value: &str, indent: &str) -> String {
|
|
674
580
|
if value.contains('\n') {
|
|
675
581
|
let item_indent = format!("{} ", indent);
|