My dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
8.7 KiB

  1. (function (factory) {
  2. if (typeof module === "object" && typeof module.exports === "object") {
  3. var v = factory(require, exports);
  4. if (v !== undefined) module.exports = v;
  5. }
  6. else if (typeof define === "function" && define.amd) {
  7. define(["require", "exports", "./main", "./format"], factory);
  8. }
  9. })(function (require, exports) {
  10. /*---------------------------------------------------------------------------------------------
  11. * Copyright (c) Microsoft Corporation. All rights reserved.
  12. * Licensed under the MIT License. See License.txt in the project root for license information.
  13. *--------------------------------------------------------------------------------------------*/
  14. 'use strict';
  15. Object.defineProperty(exports, "__esModule", { value: true });
  16. var main_1 = require("./main");
  17. var format_1 = require("./format");
  18. function removeProperty(text, path, formattingOptions) {
  19. return setProperty(text, path, void 0, formattingOptions);
  20. }
  21. exports.removeProperty = removeProperty;
  22. function setProperty(text, path, value, formattingOptions, getInsertionIndex) {
  23. var errors = [];
  24. var root = main_1.parseTree(text, errors);
  25. var parent = void 0;
  26. var lastSegment = void 0;
  27. while (path.length > 0) {
  28. lastSegment = path.pop();
  29. parent = main_1.findNodeAtLocation(root, path);
  30. if (parent === void 0 && value !== void 0) {
  31. if (typeof lastSegment === 'string') {
  32. value = (_a = {}, _a[lastSegment] = value, _a);
  33. }
  34. else {
  35. value = [value];
  36. }
  37. }
  38. else {
  39. break;
  40. }
  41. }
  42. if (!parent) {
  43. // empty document
  44. if (value === void 0) {
  45. throw new Error('Can not delete in empty document');
  46. }
  47. return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, formattingOptions);
  48. }
  49. else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {
  50. var existing = main_1.findNodeAtLocation(parent, [lastSegment]);
  51. if (existing !== void 0) {
  52. if (value === void 0) {
  53. if (!existing.parent) {
  54. throw new Error('Malformed AST');
  55. }
  56. var propertyIndex = parent.children.indexOf(existing.parent);
  57. var removeBegin = void 0;
  58. var removeEnd = existing.parent.offset + existing.parent.length;
  59. if (propertyIndex > 0) {
  60. // remove the comma of the previous node
  61. var previous = parent.children[propertyIndex - 1];
  62. removeBegin = previous.offset + previous.length;
  63. }
  64. else {
  65. removeBegin = parent.offset + 1;
  66. if (parent.children.length > 1) {
  67. // remove the comma of the next node
  68. var next = parent.children[1];
  69. removeEnd = next.offset;
  70. }
  71. }
  72. return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, formattingOptions);
  73. }
  74. else {
  75. // set value of existing property
  76. return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, formattingOptions);
  77. }
  78. }
  79. else {
  80. if (value === void 0) {
  81. return []; // property does not exist, nothing to do
  82. }
  83. var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value);
  84. var index = getInsertionIndex ? getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length;
  85. var edit = void 0;
  86. if (index > 0) {
  87. var previous = parent.children[index - 1];
  88. edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
  89. }
  90. else if (parent.children.length === 0) {
  91. edit = { offset: parent.offset + 1, length: 0, content: newProperty };
  92. }
  93. else {
  94. edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };
  95. }
  96. return withFormatting(text, edit, formattingOptions);
  97. }
  98. }
  99. else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {
  100. var insertIndex = lastSegment;
  101. if (insertIndex === -1) {
  102. // Insert
  103. var newProperty = "" + JSON.stringify(value);
  104. var edit = void 0;
  105. if (parent.children.length === 0) {
  106. edit = { offset: parent.offset + 1, length: 0, content: newProperty };
  107. }
  108. else {
  109. var previous = parent.children[parent.children.length - 1];
  110. edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
  111. }
  112. return withFormatting(text, edit, formattingOptions);
  113. }
  114. else {
  115. if (value === void 0 && parent.children.length >= 0) {
  116. //Removal
  117. var removalIndex = lastSegment;
  118. var toRemove = parent.children[removalIndex];
  119. var edit = void 0;
  120. if (parent.children.length === 1) {
  121. // only item
  122. edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };
  123. }
  124. else if (parent.children.length - 1 === removalIndex) {
  125. // last item
  126. var previous = parent.children[removalIndex - 1];
  127. var offset = previous.offset + previous.length;
  128. var parentEndOffset = parent.offset + parent.length;
  129. edit = { offset: offset, length: parentEndOffset - 2 - offset, content: '' };
  130. }
  131. else {
  132. edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };
  133. }
  134. return withFormatting(text, edit, formattingOptions);
  135. }
  136. else {
  137. throw new Error('Array modification not supported yet');
  138. }
  139. }
  140. }
  141. else {
  142. throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type);
  143. }
  144. var _a;
  145. }
  146. exports.setProperty = setProperty;
  147. function withFormatting(text, edit, formattingOptions) {
  148. // apply the edit
  149. var newText = applyEdit(text, edit);
  150. // format the new text
  151. var begin = edit.offset;
  152. var end = edit.offset + edit.content.length;
  153. if (edit.length === 0 || edit.content.length === 0) {
  154. while (begin > 0 && !format_1.isEOL(newText, begin - 1)) {
  155. begin--;
  156. }
  157. while (end < newText.length && !format_1.isEOL(newText, end)) {
  158. end++;
  159. }
  160. }
  161. var edits = format_1.format(newText, { offset: begin, length: end - begin }, formattingOptions);
  162. // apply the formatting edits and track the begin and end offsets of the changes
  163. for (var i = edits.length - 1; i >= 0; i--) {
  164. var edit_1 = edits[i];
  165. newText = applyEdit(newText, edit_1);
  166. begin = Math.min(begin, edit_1.offset);
  167. end = Math.max(end, edit_1.offset + edit_1.length);
  168. end += edit_1.content.length - edit_1.length;
  169. }
  170. // create a single edit with all changes
  171. var editLength = text.length - (newText.length - end) - begin;
  172. return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
  173. }
  174. function applyEdit(text, edit) {
  175. return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
  176. }
  177. exports.applyEdit = applyEdit;
  178. function isWS(text, offset) {
  179. return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
  180. }
  181. exports.isWS = isWS;
  182. });
  183. //# sourceMappingURL=edit.js.map