@@ -36,7 +36,7 @@ SourceEdit updateInMap(
36
36
/// removing the element at [key] when re-parsed.
37
37
SourceEdit removeInMap (YamlEditor yamlEdit, YamlMap map, Object ? key) {
38
38
assert (containsKey (map, key));
39
- final keyNode = getKeyNode (map, key);
39
+ final (_, keyNode) = getKeyNode (map, key);
40
40
final valueNode = map.nodes[keyNode]! ;
41
41
42
42
if (map.style == CollectionStyle .FLOW ) {
@@ -83,13 +83,14 @@ SourceEdit _addToBlockMap(
83
83
}
84
84
}
85
85
86
- var valueString = yamlEncodeBlock (newValue, newIndentation, lineEnding);
86
+ final valueString = yamlEncodeBlock (newValue, newIndentation, lineEnding);
87
+
87
88
if (isCollection (newValue) &&
88
89
! isFlowYamlCollectionNode (newValue) &&
89
90
! isEmpty (newValue)) {
90
- formattedValue += '$keyString :$lineEnding $valueString $ lineEnding ' ;
91
+ formattedValue += '$keyString :$lineEnding $valueString ' ;
91
92
} else {
92
- formattedValue += '$keyString : $valueString $ lineEnding ' ;
93
+ formattedValue += '$keyString : $valueString ' ;
93
94
}
94
95
95
96
return SourceEdit (offset, 0 , formattedValue);
@@ -127,12 +128,18 @@ SourceEdit _replaceInBlockMap(
127
128
YamlEditor yamlEdit, YamlMap map, Object ? key, YamlNode newValue) {
128
129
final yaml = yamlEdit.toString ();
129
130
final lineEnding = getLineEnding (yaml);
130
- final newIndentation =
131
- getMapIndentation (yaml, map) + getIndentation (yamlEdit);
131
+ final mapIndentation = getMapIndentation (yaml, map);
132
+ final newIndentation = mapIndentation + getIndentation (yamlEdit);
133
+
134
+ // TODO: Compensate for the indent eaten up
135
+ final (keyIndex, keyNode) = getKeyNode (map, key);
136
+
137
+ var valueAsString = yamlEncodeBlock (
138
+ wrapAsYamlNode (newValue),
139
+ newIndentation,
140
+ lineEnding,
141
+ );
132
142
133
- final keyNode = getKeyNode (map, key);
134
- var valueAsString =
135
- yamlEncodeBlock (wrapAsYamlNode (newValue), newIndentation, lineEnding);
136
143
if (isCollection (newValue) &&
137
144
! isFlowYamlCollectionNode (newValue) &&
138
145
! isEmpty (newValue)) {
@@ -150,9 +157,43 @@ SourceEdit _replaceInBlockMap(
150
157
var end = getContentSensitiveEnd (map.nodes[key]! );
151
158
152
159
/// `package:yaml` parses empty nodes in a way where the start/end of the
153
- /// empty value node is the end of the key node, so we have to adjust for
154
- /// this.
155
- if (end < start) end = start;
160
+ /// empty value node is the end of the key node.
161
+ ///
162
+ /// In our case, we need to ensure that any line-breaks are included in the
163
+ /// edit such that:
164
+ /// 1. We account for `\n` after a key within other keys or at the start
165
+ /// Example..
166
+ /// a:
167
+ /// b: value
168
+ ///
169
+ /// or..
170
+ /// a: value
171
+ /// b:
172
+ /// c: value
173
+ ///
174
+ /// 2. We don't suggest edits that are not within the string bounds because
175
+ /// of the `\n` we need to account for in Rule 1 above. This could be a
176
+ /// key:
177
+ /// * At the index `0` but it's the only key
178
+ /// * At the end in a map with more than one key
179
+ end = start == yaml.length
180
+ ? start
181
+ : end < start
182
+ ? start + 1
183
+ : end;
184
+
185
+ // Aggressively skip all comments
186
+ final (offsetOfLastComment, _) =
187
+ skipAndExtractCommentsInBlock (yaml, end, null , lineEnding);
188
+ end = offsetOfLastComment;
189
+
190
+ valueAsString =
191
+ normalizeEncodedBlock (yaml, lineEnding, end, newValue, valueAsString);
192
+
193
+ /// [skipAndExtractCommentsInBlock] is greedy and eats up any whitespace
194
+ /// it encounters in search of comments. Compensate indent lost in the
195
+ /// current edit
196
+ if (keyIndex != map.length - 1 ) valueAsString += ' ' * mapIndentation;
156
197
157
198
return SourceEdit (start, end - start, valueAsString);
158
199
}
0 commit comments