My dotfiles
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 

195 linhas
7.6 KiB

  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. 'use strict';
  6. import * as Json from './main';
  7. export function format(documentText, range, options) {
  8. var initialIndentLevel;
  9. var formatText;
  10. var formatTextStart;
  11. var rangeStart;
  12. var rangeEnd;
  13. if (range) {
  14. rangeStart = range.offset;
  15. rangeEnd = rangeStart + range.length;
  16. formatTextStart = rangeStart;
  17. while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
  18. formatTextStart--;
  19. }
  20. var endOffset = rangeEnd;
  21. while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
  22. endOffset++;
  23. }
  24. formatText = documentText.substring(formatTextStart, endOffset);
  25. initialIndentLevel = computeIndentLevel(formatText, 0, options);
  26. }
  27. else {
  28. formatText = documentText;
  29. initialIndentLevel = 0;
  30. formatTextStart = 0;
  31. rangeStart = 0;
  32. rangeEnd = documentText.length;
  33. }
  34. var eol = getEOL(options, documentText);
  35. var lineBreak = false;
  36. var indentLevel = 0;
  37. var indentValue;
  38. if (options.insertSpaces) {
  39. indentValue = repeat(' ', options.tabSize || 4);
  40. }
  41. else {
  42. indentValue = '\t';
  43. }
  44. var scanner = Json.createScanner(formatText, false);
  45. var hasError = false;
  46. function newLineAndIndent() {
  47. return eol + repeat(indentValue, initialIndentLevel + indentLevel);
  48. }
  49. function scanNext() {
  50. var token = scanner.scan();
  51. lineBreak = false;
  52. while (token === Json.SyntaxKind.Trivia || token === Json.SyntaxKind.LineBreakTrivia) {
  53. lineBreak = lineBreak || (token === Json.SyntaxKind.LineBreakTrivia);
  54. token = scanner.scan();
  55. }
  56. hasError = token === Json.SyntaxKind.Unknown || scanner.getTokenError() !== Json.ScanError.None;
  57. return token;
  58. }
  59. var editOperations = [];
  60. function addEdit(text, startOffset, endOffset) {
  61. if (!hasError && startOffset < rangeEnd && endOffset > rangeStart && documentText.substring(startOffset, endOffset) !== text) {
  62. editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
  63. }
  64. }
  65. var firstToken = scanNext();
  66. if (firstToken !== Json.SyntaxKind.EOF) {
  67. var firstTokenStart = scanner.getTokenOffset() + formatTextStart;
  68. var initialIndent = repeat(indentValue, initialIndentLevel);
  69. addEdit(initialIndent, formatTextStart, firstTokenStart);
  70. }
  71. while (firstToken !== Json.SyntaxKind.EOF) {
  72. var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
  73. var secondToken = scanNext();
  74. var replaceContent = '';
  75. while (!lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) {
  76. // comments on the same line: keep them on the same line, but ignore them otherwise
  77. var commentTokenStart = scanner.getTokenOffset() + formatTextStart;
  78. addEdit(' ', firstTokenEnd, commentTokenStart);
  79. firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
  80. replaceContent = secondToken === Json.SyntaxKind.LineCommentTrivia ? newLineAndIndent() : '';
  81. secondToken = scanNext();
  82. }
  83. if (secondToken === Json.SyntaxKind.CloseBraceToken) {
  84. if (firstToken !== Json.SyntaxKind.OpenBraceToken) {
  85. indentLevel--;
  86. replaceContent = newLineAndIndent();
  87. }
  88. }
  89. else if (secondToken === Json.SyntaxKind.CloseBracketToken) {
  90. if (firstToken !== Json.SyntaxKind.OpenBracketToken) {
  91. indentLevel--;
  92. replaceContent = newLineAndIndent();
  93. }
  94. }
  95. else {
  96. switch (firstToken) {
  97. case Json.SyntaxKind.OpenBracketToken:
  98. case Json.SyntaxKind.OpenBraceToken:
  99. indentLevel++;
  100. replaceContent = newLineAndIndent();
  101. break;
  102. case Json.SyntaxKind.CommaToken:
  103. case Json.SyntaxKind.LineCommentTrivia:
  104. replaceContent = newLineAndIndent();
  105. break;
  106. case Json.SyntaxKind.BlockCommentTrivia:
  107. if (lineBreak) {
  108. replaceContent = newLineAndIndent();
  109. }
  110. else {
  111. // symbol following comment on the same line: keep on same line, separate with ' '
  112. replaceContent = ' ';
  113. }
  114. break;
  115. case Json.SyntaxKind.ColonToken:
  116. replaceContent = ' ';
  117. break;
  118. case Json.SyntaxKind.StringLiteral:
  119. if (secondToken === Json.SyntaxKind.ColonToken) {
  120. replaceContent = '';
  121. break;
  122. }
  123. // fall through
  124. case Json.SyntaxKind.NullKeyword:
  125. case Json.SyntaxKind.TrueKeyword:
  126. case Json.SyntaxKind.FalseKeyword:
  127. case Json.SyntaxKind.NumericLiteral:
  128. case Json.SyntaxKind.CloseBraceToken:
  129. case Json.SyntaxKind.CloseBracketToken:
  130. if (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia) {
  131. replaceContent = ' ';
  132. }
  133. else if (secondToken !== Json.SyntaxKind.CommaToken && secondToken !== Json.SyntaxKind.EOF) {
  134. hasError = true;
  135. }
  136. break;
  137. case Json.SyntaxKind.Unknown:
  138. hasError = true;
  139. break;
  140. }
  141. if (lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) {
  142. replaceContent = newLineAndIndent();
  143. }
  144. }
  145. var secondTokenStart = scanner.getTokenOffset() + formatTextStart;
  146. addEdit(replaceContent, firstTokenEnd, secondTokenStart);
  147. firstToken = secondToken;
  148. }
  149. return editOperations;
  150. }
  151. function repeat(s, count) {
  152. var result = '';
  153. for (var i = 0; i < count; i++) {
  154. result += s;
  155. }
  156. return result;
  157. }
  158. function computeIndentLevel(content, offset, options) {
  159. var i = 0;
  160. var nChars = 0;
  161. var tabSize = options.tabSize || 4;
  162. while (i < content.length) {
  163. var ch = content.charAt(i);
  164. if (ch === ' ') {
  165. nChars++;
  166. }
  167. else if (ch === '\t') {
  168. nChars += tabSize;
  169. }
  170. else {
  171. break;
  172. }
  173. i++;
  174. }
  175. return Math.floor(nChars / tabSize);
  176. }
  177. function getEOL(options, text) {
  178. for (var i = 0; i < text.length; i++) {
  179. var ch = text.charAt(i);
  180. if (ch === '\r') {
  181. if (i + 1 < text.length && text.charAt(i + 1) === '\n') {
  182. return '\r\n';
  183. }
  184. return '\r';
  185. }
  186. else if (ch === '\n') {
  187. return '\n';
  188. }
  189. }
  190. return (options && options.eol) || '\n';
  191. }
  192. export function isEOL(text, offset) {
  193. return '\r\n'.indexOf(text.charAt(offset)) !== -1;
  194. }
  195. //# sourceMappingURL=format.js.map