yerba 0.7.2 → 0.7.4
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/ext/yerba/yerba.c +2 -0
- data/lib/yerba/map.rb +22 -0
- data/lib/yerba/node.rb +8 -2
- data/lib/yerba/sequence.rb +15 -0
- 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 +82 -36
- data/rust/src/document/get.rs +14 -17
- data/rust/src/document/insert.rs +50 -144
- data/rust/src/document/mod.rs +81 -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/ffi.rs +8 -0
- 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: bfa98c0309844cc745efbdea0a559825a797ca9eba6eaf2d63e39b2e5098333c
|
|
4
|
+
data.tar.gz: 270f11efd66edf472dba1a5a524db66bcdc24f1eba081c4e5b267853f275111b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2bf52ab64c03b3eaeafaefe547b4cbe3cf67c21c19025aa21da00afe4e36edbc2d8bf3ae33ce06d744fa8616da37aed189e7e91afab3cc904fec63151aeef667
|
|
7
|
+
data.tar.gz: edc83ce4ee21753401e258deb33e54c7a206c13ab8b909a9d54595295e396caf0a3eaa58a33746205d5a955d8b62d04da0e9473423adcf118bc1a1cd6a955d67
|
data/ext/yerba/yerba.c
CHANGED
|
@@ -986,10 +986,12 @@ static VALUE collection_s_get(VALUE self, VALUE pattern, VALUE path) {
|
|
|
986
986
|
|
|
987
987
|
VALUE line = rb_hash_aref(item, rb_str_new_cstr("line"));
|
|
988
988
|
VALUE kwargs = rb_hash_new();
|
|
989
|
+
VALUE location = rb_hash_aref(item, rb_str_new_cstr("location"));
|
|
989
990
|
|
|
990
991
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("selector")), selector);
|
|
991
992
|
if (!NIL_P(file_path)) rb_hash_aset(kwargs, ID2SYM(rb_intern("file_path")), file_path);
|
|
992
993
|
if (!NIL_P(line)) rb_hash_aset(kwargs, ID2SYM(rb_intern("line")), line);
|
|
994
|
+
if (!NIL_P(location)) rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location);
|
|
993
995
|
|
|
994
996
|
if (strcmp(type_str, "scalar") == 0) {
|
|
995
997
|
VALUE text = rb_hash_aref(item, rb_str_new_cstr("text"));
|
data/lib/yerba/map.rb
CHANGED
|
@@ -123,6 +123,28 @@ module Yerba
|
|
|
123
123
|
end
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
+
# Deletes a key from the map, or deletes the entire map node from the document.
|
|
127
|
+
#
|
|
128
|
+
# When +key+ is given and the map is connected to a document, deletes that key
|
|
129
|
+
# from the map in the YAML document. When no +key+ is given and the map is
|
|
130
|
+
# connected, removes the entire map node at its selector path. When not connected
|
|
131
|
+
# to a document, delegates to the underlying Hash.
|
|
132
|
+
#
|
|
133
|
+
# Returns +self+.
|
|
134
|
+
#
|
|
135
|
+
# # Delete a specific key from a connected map:
|
|
136
|
+
# document = Yerba::Document.parse(<<~YAML)
|
|
137
|
+
# database:
|
|
138
|
+
# host: localhost
|
|
139
|
+
# pool: 10
|
|
140
|
+
# YAML
|
|
141
|
+
#
|
|
142
|
+
# document["database"].delete("pool")
|
|
143
|
+
# document.to_s # => "database:\n host: localhost\n"
|
|
144
|
+
#
|
|
145
|
+
# # Delete the entire map node:
|
|
146
|
+
# document["database"].delete
|
|
147
|
+
# document.to_s # => "{}\n"
|
|
126
148
|
def delete(key = nil)
|
|
127
149
|
if key && connected?
|
|
128
150
|
new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
|
data/lib/yerba/node.rb
CHANGED
|
@@ -36,14 +36,20 @@ module Yerba
|
|
|
36
36
|
instance
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
def from(file_path:, selector:, line: nil, **attributes)
|
|
39
|
+
def from(file_path:, selector:, line: nil, location: nil, **attributes)
|
|
40
40
|
instance = allocate
|
|
41
41
|
|
|
42
|
-
instance.send(:init_node, nil, selector,
|
|
42
|
+
instance.send(:init_node, nil, selector, coerce_location(location), nil, file_path, line)
|
|
43
43
|
instance.send(:init_from, **attributes) if instance.respond_to?(:init_from, true)
|
|
44
44
|
|
|
45
45
|
instance
|
|
46
46
|
end
|
|
47
|
+
|
|
48
|
+
def coerce_location(location)
|
|
49
|
+
return location unless location.is_a?(Hash)
|
|
50
|
+
|
|
51
|
+
Location.new(**location.transform_keys(&:to_sym))
|
|
52
|
+
end
|
|
47
53
|
end
|
|
48
54
|
|
|
49
55
|
def self.included(base)
|
data/lib/yerba/sequence.rb
CHANGED
|
@@ -258,6 +258,21 @@ module Yerba
|
|
|
258
258
|
self
|
|
259
259
|
end
|
|
260
260
|
|
|
261
|
+
# Deletes the entire sequence node from the YAML document.
|
|
262
|
+
#
|
|
263
|
+
# Removes the sequence at its selector path from the parent document.
|
|
264
|
+
# Has no effect if the sequence is not connected to a document.
|
|
265
|
+
#
|
|
266
|
+
# Returns the document, or +nil+ if the sequence is not connected to a document.
|
|
267
|
+
#
|
|
268
|
+
# document = Yerba::Document.parse(<<~YAML)
|
|
269
|
+
# items:
|
|
270
|
+
# - name: Ruby
|
|
271
|
+
# - name: Rust
|
|
272
|
+
# YAML
|
|
273
|
+
#
|
|
274
|
+
# document["items"].delete
|
|
275
|
+
# document.to_s # => "{}\n"
|
|
261
276
|
def delete
|
|
262
277
|
document&.delete(@selector)
|
|
263
278
|
end
|
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
|
@@ -11,12 +11,9 @@ impl Document {
|
|
|
11
11
|
|
|
12
12
|
if source_parent == destination_parent {
|
|
13
13
|
let (parent_path, source_key) = source_path.rsplit_once('.').unwrap_or(("", source_path));
|
|
14
|
-
let parent_node = self.navigate(parent_path)?;
|
|
15
14
|
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
.find_map(BlockMap::cast)
|
|
19
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
15
|
+
let parent_node = self.navigate(parent_path)?;
|
|
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()))?;
|
|
@@ -42,14 +39,12 @@ impl Document {
|
|
|
42
39
|
|
|
43
40
|
match last_segment {
|
|
44
41
|
crate::selector::SelectorSegment::Key(last_key) => {
|
|
45
|
-
let has_wildcard = selector.has_wildcard()
|
|
42
|
+
let has_wildcard = selector.has_wildcard();
|
|
43
|
+
let has_brackets = selector.has_brackets();
|
|
46
44
|
|
|
47
|
-
if parent_path.is_empty() && !has_wildcard {
|
|
45
|
+
if parent_path.is_empty() && (!has_wildcard || !has_brackets) {
|
|
48
46
|
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()))?;
|
|
47
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
53
48
|
|
|
54
49
|
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
55
50
|
|
|
@@ -66,38 +61,30 @@ impl Document {
|
|
|
66
61
|
return Err(YerbaError::SelectorNotFound(dot_path.to_string()));
|
|
67
62
|
}
|
|
68
63
|
|
|
69
|
-
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()))?;
|
|
74
|
-
|
|
64
|
+
if parent_nodes.len() == 1 && (!has_wildcard || !has_brackets) {
|
|
65
|
+
let map = find_block_map(&parent_nodes[0]).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
75
66
|
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
76
67
|
|
|
68
|
+
if map.entries().count() == 1 {
|
|
69
|
+
return self.collapse_to_empty_flow_map(&parent_nodes[0]);
|
|
70
|
+
}
|
|
71
|
+
|
|
77
72
|
return self.remove_map_entry(&entry);
|
|
78
73
|
}
|
|
79
74
|
|
|
80
75
|
let mut ranges: Vec<TextRange> = Vec::new();
|
|
81
76
|
|
|
82
77
|
for parent_node in &parent_nodes {
|
|
83
|
-
if let Some(map) = parent_node
|
|
78
|
+
if let Some(map) = find_block_map(parent_node) {
|
|
84
79
|
if let Some(entry) = find_entry_by_key(&map, last_key) {
|
|
85
80
|
ranges.push(removal_range(entry.syntax()));
|
|
86
81
|
}
|
|
87
82
|
}
|
|
88
83
|
}
|
|
89
84
|
|
|
90
|
-
|
|
91
|
-
return Ok(());
|
|
92
|
-
}
|
|
85
|
+
let edits = ranges.into_iter().map(|range| (range, String::new())).collect();
|
|
93
86
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
for range in ranges {
|
|
97
|
-
self.apply_edit(range, "")?;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
Ok(())
|
|
87
|
+
self.apply_edits(edits)
|
|
101
88
|
}
|
|
102
89
|
|
|
103
90
|
crate::selector::SelectorSegment::Index(index) => self.remove_at(&parent_path, *index),
|
|
@@ -108,10 +95,7 @@ impl Document {
|
|
|
108
95
|
pub fn remove(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {
|
|
109
96
|
let current_node = self.navigate(dot_path)?;
|
|
110
97
|
|
|
111
|
-
let sequence = current_node
|
|
112
|
-
.descendants()
|
|
113
|
-
.find_map(BlockSeq::cast)
|
|
114
|
-
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
98
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
115
99
|
|
|
116
100
|
let target_entry = sequence
|
|
117
101
|
.entries()
|
|
@@ -124,6 +108,10 @@ impl Document {
|
|
|
124
108
|
})
|
|
125
109
|
.ok_or_else(|| YerbaError::SelectorNotFound(format!("{} item '{}'", dot_path, value)))?;
|
|
126
110
|
|
|
111
|
+
if sequence.entries().count() == 1 {
|
|
112
|
+
return self.collapse_to_empty_flow_sequence(¤t_node);
|
|
113
|
+
}
|
|
114
|
+
|
|
127
115
|
self.remove_node(target_entry.syntax())
|
|
128
116
|
}
|
|
129
117
|
|
|
@@ -132,10 +120,7 @@ impl Document {
|
|
|
132
120
|
|
|
133
121
|
let current_node = self.navigate(dot_path)?;
|
|
134
122
|
|
|
135
|
-
let sequence = current_node
|
|
136
|
-
.descendants()
|
|
137
|
-
.find_map(BlockSeq::cast)
|
|
138
|
-
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
123
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
139
124
|
|
|
140
125
|
let entries: Vec<_> = sequence.entries().collect();
|
|
141
126
|
|
|
@@ -143,6 +128,67 @@ impl Document {
|
|
|
143
128
|
return Err(YerbaError::IndexOutOfBounds(index, entries.len()));
|
|
144
129
|
}
|
|
145
130
|
|
|
131
|
+
if entries.len() == 1 {
|
|
132
|
+
return self.collapse_to_empty_flow_sequence(¤t_node);
|
|
133
|
+
}
|
|
134
|
+
|
|
146
135
|
self.remove_node(entries[index].syntax())
|
|
147
136
|
}
|
|
137
|
+
|
|
138
|
+
fn collapse_to_empty_flow_map(&mut self, current_node: &SyntaxNode) -> Result<(), YerbaError> {
|
|
139
|
+
let map_value = current_node
|
|
140
|
+
.descendants()
|
|
141
|
+
.find(|descendant| descendant.kind() == SyntaxKind::BLOCK_MAP_VALUE)
|
|
142
|
+
.ok_or_else(|| YerbaError::SelectorNotFound("Expected a map value".to_string()))?;
|
|
143
|
+
|
|
144
|
+
let mut range = map_value.text_range();
|
|
145
|
+
|
|
146
|
+
if let Some(previous) = map_value.prev_sibling_or_token().and_then(|element| element.into_token()) {
|
|
147
|
+
if previous.kind() == SyntaxKind::WHITESPACE && previous.text().contains('\n') {
|
|
148
|
+
range = TextRange::new(previous.text_range().start(), range.end());
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
self.apply_edit(range, " {}")
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
fn collapse_to_empty_flow_sequence(&mut self, current_node: &SyntaxNode) -> Result<(), YerbaError> {
|
|
156
|
+
if current_node.kind() == SyntaxKind::BLOCK_MAP_VALUE {
|
|
157
|
+
let mut range = current_node.text_range();
|
|
158
|
+
let mut comment_text: Option<String> = None;
|
|
159
|
+
let mut sibling = current_node.prev_sibling_or_token();
|
|
160
|
+
|
|
161
|
+
while let Some(ref element) = sibling {
|
|
162
|
+
match element {
|
|
163
|
+
rowan::NodeOrToken::Token(token) => {
|
|
164
|
+
if token.kind() == SyntaxKind::COMMENT {
|
|
165
|
+
comment_text = Some(token.text().to_string());
|
|
166
|
+
range = TextRange::new(token.text_range().start(), range.end());
|
|
167
|
+
sibling = token.prev_sibling_or_token();
|
|
168
|
+
} else if token.kind() == SyntaxKind::WHITESPACE {
|
|
169
|
+
range = TextRange::new(token.text_range().start(), range.end());
|
|
170
|
+
sibling = token.prev_sibling_or_token();
|
|
171
|
+
} else {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
_ => break,
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
let replacement = match comment_text {
|
|
180
|
+
Some(comment) => format!(" [] {}", comment),
|
|
181
|
+
None => " []".to_string(),
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return self.apply_edit(range, &replacement);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
let sequence = current_node
|
|
188
|
+
.descendants()
|
|
189
|
+
.find_map(BlockSeq::cast)
|
|
190
|
+
.ok_or_else(|| YerbaError::NotASequence("Expected a sequence".to_string()))?;
|
|
191
|
+
|
|
192
|
+
self.apply_edit(removal_range(sequence.syntax()), "[]")
|
|
193
|
+
}
|
|
148
194
|
}
|
data/rust/src/document/get.rs
CHANGED
|
@@ -83,15 +83,17 @@ 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
|
|
90
90
|
.navigate_all_compact(dot_path)
|
|
91
91
|
.iter()
|
|
92
92
|
.map(|node| {
|
|
93
|
-
let
|
|
94
|
-
let
|
|
93
|
+
let range = node.text_range();
|
|
94
|
+
let offset: usize = range.start().into();
|
|
95
|
+
let line = line_at(&source, offset);
|
|
96
|
+
let location = compute_location(&source, offset, range.end().into());
|
|
95
97
|
let selector = node_selector(node);
|
|
96
98
|
let is_scalar = !node
|
|
97
99
|
.descendants()
|
|
@@ -108,13 +110,8 @@ impl Document {
|
|
|
108
110
|
let node_type = if is_scalar {
|
|
109
111
|
"scalar"
|
|
110
112
|
} 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",
|
|
113
|
+
match first_collection(node) {
|
|
114
|
+
Some(FirstCollection::Sequence(_)) => "sequence",
|
|
118
115
|
_ => "map",
|
|
119
116
|
}
|
|
120
117
|
};
|
|
@@ -126,6 +123,7 @@ impl Document {
|
|
|
126
123
|
file_path: file_path.clone(),
|
|
127
124
|
selector,
|
|
128
125
|
line,
|
|
126
|
+
location,
|
|
129
127
|
}
|
|
130
128
|
})
|
|
131
129
|
.collect()
|
|
@@ -142,7 +140,7 @@ impl Document {
|
|
|
142
140
|
|
|
143
141
|
pub fn get_node_info(&self, dot_path: &str) -> NodeInfo {
|
|
144
142
|
let selector = crate::selector::Selector::parse(dot_path);
|
|
145
|
-
let source = self.
|
|
143
|
+
let source = self.source_text();
|
|
146
144
|
|
|
147
145
|
let (location, key_name, key_location) = self.resolve_location(dot_path, &source);
|
|
148
146
|
|
|
@@ -364,7 +362,7 @@ impl Document {
|
|
|
364
362
|
self.navigate(parent_path).ok()?
|
|
365
363
|
};
|
|
366
364
|
|
|
367
|
-
let map = parent_node
|
|
365
|
+
let map = find_block_map(&parent_node)?;
|
|
368
366
|
|
|
369
367
|
find_entry_by_key(&map, last_key).map(|entry| entry.syntax().clone())
|
|
370
368
|
}
|
|
@@ -375,7 +373,7 @@ impl Document {
|
|
|
375
373
|
Err(_) => return Vec::new(),
|
|
376
374
|
};
|
|
377
375
|
|
|
378
|
-
let sequence = match current_node
|
|
376
|
+
let sequence = match find_block_sequence(¤t_node) {
|
|
379
377
|
Some(sequence) => sequence,
|
|
380
378
|
None => return Vec::new(),
|
|
381
379
|
};
|
|
@@ -403,17 +401,16 @@ impl Document {
|
|
|
403
401
|
pub fn get_sequence_indent(&self, dot_path: &str) -> Option<&'static str> {
|
|
404
402
|
let current_node = self.navigate(dot_path).ok()?;
|
|
405
403
|
|
|
406
|
-
let sequence = current_node
|
|
404
|
+
let sequence = find_block_sequence(¤t_node)?;
|
|
407
405
|
let first_entry = sequence.entries().next()?;
|
|
408
406
|
|
|
409
407
|
let entry_indent = preceding_whitespace_indent(first_entry.syntax());
|
|
410
408
|
|
|
411
409
|
let entry_node = current_node.ancestors().find(|ancestor| ancestor.kind() == SyntaxKind::BLOCK_MAP_ENTRY)?;
|
|
412
410
|
|
|
413
|
-
let source = self.
|
|
411
|
+
let source = self.source_text();
|
|
414
412
|
let entry_start: usize = entry_node.text_range().start().into();
|
|
415
|
-
let
|
|
416
|
-
let key_indent = &source[line_start..entry_start];
|
|
413
|
+
let key_indent = &source[line_start_at(&source, entry_start)..entry_start];
|
|
417
414
|
|
|
418
415
|
if entry_indent.len() > key_indent.len() {
|
|
419
416
|
Some("indented")
|