Skip to content

Commit 54d7cfd

Browse files
committed
Add inPlace formatting option & array mods
1 parent e38baa7 commit 54d7cfd

File tree

3 files changed

+61
-20
lines changed

3 files changed

+61
-20
lines changed

src/impl/edit.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -96,35 +96,41 @@ export function setProperty(text: string, originalPath: JSONPath, value: any, fo
9696
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
9797
}
9898
return withFormatting(text, edit, formattingOptions);
99-
} else {
100-
if (value === void 0 && parent.children.length >= 0) {
101-
//Removal
102-
let removalIndex = lastSegment;
103-
let 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-
let previous = parent.children[removalIndex - 1];
111-
let offset = previous.offset + previous.length;
112-
let 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);
99+
} else if (value === void 0 && parent.children.length >= 0) {
100+
// Removal
101+
let removalIndex = lastSegment;
102+
let 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+
let previous = parent.children[removalIndex - 1];
110+
let offset = previous.offset + previous.length;
111+
let 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);
117+
} else if (value !== void 0 && parent.children.length > lastSegment) {
118+
let modifyIndex = lastSegment;
119+
let toModify = parent.children[modifyIndex];
120+
let newProperty = `${JSON.stringify(value)}`;
121+
return withFormatting(text, { offset: toModify.offset, length: toModify.length, content: newProperty }, formattingOptions);
122+
} else {
123+
throw new Error(`Can not ${value === void 0 ? 'remove' : 'modify'} Array index ${insertIndex} as length is not sufficient`);
121124
}
122125
} else {
123126
throw new Error(`Can not add ${typeof lastSegment !== 'number' ? 'index' : 'property'} to parent of type ${parent.type}`);
124127
}
125128
}
126129

127130
function withFormatting(text: string, edit: Edit, formattingOptions: FormattingOptions): Edit[] {
131+
if (formattingOptions.inPlace) {
132+
return [{ ...edit }]
133+
}
128134
// apply the edit
129135
let newText = applyEdit(text, edit);
130136

src/main.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,11 @@ export interface FormattingOptions {
322322
* The default 'end of line' character. If not set, '\n' is used as default.
323323
*/
324324
eol?: string;
325+
/**
326+
* If true, changes within {@function format} will not be formatted and their original formatting will be preserved.
327+
* Useful for cutting down on computational time for large files.
328+
*/
329+
inPlace?: boolean;
325330
}
326331

327332
/**

src/test/edit.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,27 @@ suite('JSON - edits', () => {
121121
assertEdit(content, edits, '{\n "x": "y"\n}');
122122
});
123123

124+
test('set item', () => {
125+
let content = '{\n "x": [1, 2, 3],\n "y": 0\n}'
126+
127+
let edits = setProperty(content, ['x', 0], 6, formatterOptions);
128+
assertEdit(content, edits, '{\n "x": [6, 2, 3],\n "y": 0\n}');
129+
130+
edits = setProperty(content, ['x', 1], 5, formatterOptions);
131+
assertEdit(content, edits, '{\n "x": [1, 5, 3],\n "y": 0\n}');
132+
133+
edits = setProperty(content, ['x', 2], 4, formatterOptions);
134+
assertEdit(content, edits, '{\n "x": [1, 2, 4],\n "y": 0\n}');
135+
136+
let message = "allowed setProperty to set array item outside of bounds";
137+
try {
138+
setProperty(content, ['x', 3], 3, formatterOptions)
139+
throw new Error(message);
140+
} catch(e) {
141+
assert(e && e.message !== message);
142+
}
143+
});
144+
124145
test('insert item to empty array', () => {
125146
let content = '[\n]';
126147
let edits = setProperty(content, [-1], 'bar', formatterOptions);
@@ -163,4 +184,13 @@ suite('JSON - edits', () => {
163184
assertEdit(content, edits, '// This is a comment\n[\n 1,\n "foo"\n]');
164185
});
165186

187+
test('set property w/ in-place formatting options', () => {
188+
let content = '{\n "x": [1, 2, 3],\n "y": 0\n}'
189+
190+
let edits = setProperty(content, ['x', 0], { a: 1, b: 2 }, formatterOptions);
191+
assertEdit(content, edits, '{\n "x": [{\n "a": 1,\n "b": 2\n }, 2, 3],\n "y": 0\n}');
192+
193+
edits = setProperty(content, ['x', 0], { a: 1, b: 2 }, { ...formatterOptions, inPlace: true });
194+
assertEdit(content, edits, '{\n "x": [{"a":1,"b":2}, 2, 3],\n "y": 0\n}');
195+
});
166196
});

0 commit comments

Comments
 (0)