Skip to content

Commit fa2eff9

Browse files
committed
Support inserting at an index in array
1 parent 26ef4cf commit fa2eff9

File tree

2 files changed

+53
-27
lines changed

2 files changed

+53
-27
lines changed

src/vs/base/common/jsonEdit.ts

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -84,40 +84,36 @@ export function setProperty(text: string, originalPath: JSONPath, value: any, fo
8484
return withFormatting(text, edit, formattingOptions);
8585
}
8686
} else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {
87-
const insertIndex = lastSegment;
88-
if (insertIndex === -1) {
87+
if (value !== undefined) {
8988
// Insert
9089
const newProperty = `${JSON.stringify(value)}`;
9190
let edit: Edit;
92-
if (parent.children.length === 0) {
93-
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
91+
if (parent.children.length === 0 || lastSegment === 0) {
92+
edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + ',' };
9493
} else {
95-
const previous = parent.children[parent.children.length - 1];
94+
const index = lastSegment === -1 || lastSegment > parent.children.length ? parent.children.length : lastSegment;
95+
const previous = parent.children[index - 1];
9696
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
9797
}
9898
return withFormatting(text, edit, formattingOptions);
9999
} else {
100-
if (value === undefined && parent.children.length >= 0) {
101-
//Removal
102-
const removalIndex = lastSegment;
103-
const toRemove = parent.children[removalIndex];
104-
let edit: Edit;
105-
if (parent.children.length === 1) {
106-
// only item
107-
edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };
108-
} else if (parent.children.length - 1 === removalIndex) {
109-
// last item
110-
const previous = parent.children[removalIndex - 1];
111-
const offset = previous.offset + previous.length;
112-
const parentEndOffset = parent.offset + parent.length;
113-
edit = { offset, length: parentEndOffset - 2 - offset, content: '' };
114-
} else {
115-
edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };
116-
}
117-
return withFormatting(text, edit, formattingOptions);
100+
//Removal
101+
const removalIndex = lastSegment;
102+
const toRemove = parent.children[removalIndex];
103+
let edit: Edit;
104+
if (parent.children.length === 1) {
105+
// only item
106+
edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };
107+
} else if (parent.children.length - 1 === removalIndex) {
108+
// last item
109+
const previous = parent.children[removalIndex - 1];
110+
const offset = previous.offset + previous.length;
111+
const parentEndOffset = parent.offset + parent.length;
112+
edit = { offset, length: parentEndOffset - 2 - offset, content: '' };
118113
} else {
119-
throw new Error('Array modification not supported yet');
114+
edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };
120115
}
116+
return withFormatting(text, edit, formattingOptions);
121117
}
122118
} else {
123119
throw new Error(`Can not add ${typeof lastSegment !== 'number' ? 'index' : 'property'} to parent of type ${parent.type}`);

src/vs/base/test/common/jsonEdit.test.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,43 @@ suite('JSON - edits', () => {
118118
assertEdit(content, edits, '{\n "x": "y"\n}');
119119
});
120120

121-
test('insert item to empty array', () => {
121+
test('insert item at 0', () => {
122+
let content = '[\n 2,\n 3\n]';
123+
let edits = setProperty(content, [0], 1, formatterOptions);
124+
assertEdit(content, edits, '[\n 1,\n 2,\n 3\n]');
125+
});
126+
127+
test('insert item at 0 in empty array', () => {
128+
let content = '[\n]';
129+
let edits = setProperty(content, [0], 1, formatterOptions);
130+
assertEdit(content, edits, '[\n 1\n]');
131+
});
132+
133+
test('insert item at an index', () => {
134+
let content = '[\n 1,\n 3\n]';
135+
let edits = setProperty(content, [1], 2, formatterOptions);
136+
assertEdit(content, edits, '[\n 1,\n 2,\n 3\n]');
137+
});
138+
139+
test('insert item at an index im empty array', () => {
140+
let content = '[\n]';
141+
let edits = setProperty(content, [1], 1, formatterOptions);
142+
assertEdit(content, edits, '[\n 1\n]');
143+
});
144+
145+
test('insert item at end index', () => {
146+
let content = '[\n 1,\n 2\n]';
147+
let edits = setProperty(content, [2], 3, formatterOptions);
148+
assertEdit(content, edits, '[\n 1,\n 2,\n 3\n]');
149+
});
150+
151+
test('insert item at end to empty array', () => {
122152
let content = '[\n]';
123153
let edits = setProperty(content, [-1], 'bar', formatterOptions);
124154
assertEdit(content, edits, '[\n "bar"\n]');
125155
});
126156

127-
test('insert item', () => {
157+
test('insert item at end', () => {
128158
let content = '[\n 1,\n 2\n]';
129159
let edits = setProperty(content, [-1], 'bar', formatterOptions);
130160
assertEdit(content, edits, '[\n 1,\n 2,\n "bar"\n]');
@@ -160,4 +190,4 @@ suite('JSON - edits', () => {
160190
assertEdit(content, edits, '// This is a comment\n[\n 1,\n "foo"\n]');
161191
});
162192

163-
});
193+
});

0 commit comments

Comments
 (0)