|
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- 'use strict';
- import * as Json from './main';
- export function format(documentText, range, options) {
- var initialIndentLevel;
- var formatText;
- var formatTextStart;
- var rangeStart;
- var rangeEnd;
- if (range) {
- rangeStart = range.offset;
- rangeEnd = rangeStart + range.length;
- formatTextStart = rangeStart;
- while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
- formatTextStart--;
- }
- var endOffset = rangeEnd;
- while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
- endOffset++;
- }
- formatText = documentText.substring(formatTextStart, endOffset);
- initialIndentLevel = computeIndentLevel(formatText, 0, options);
- }
- else {
- formatText = documentText;
- initialIndentLevel = 0;
- formatTextStart = 0;
- rangeStart = 0;
- rangeEnd = documentText.length;
- }
- var eol = getEOL(options, documentText);
- var lineBreak = false;
- var indentLevel = 0;
- var indentValue;
- if (options.insertSpaces) {
- indentValue = repeat(' ', options.tabSize || 4);
- }
- else {
- indentValue = '\t';
- }
- var scanner = Json.createScanner(formatText, false);
- var hasError = false;
- function newLineAndIndent() {
- return eol + repeat(indentValue, initialIndentLevel + indentLevel);
- }
- function scanNext() {
- var token = scanner.scan();
- lineBreak = false;
- while (token === Json.SyntaxKind.Trivia || token === Json.SyntaxKind.LineBreakTrivia) {
- lineBreak = lineBreak || (token === Json.SyntaxKind.LineBreakTrivia);
- token = scanner.scan();
- }
- hasError = token === Json.SyntaxKind.Unknown || scanner.getTokenError() !== Json.ScanError.None;
- return token;
- }
- var editOperations = [];
- function addEdit(text, startOffset, endOffset) {
- if (!hasError && startOffset < rangeEnd && endOffset > rangeStart && documentText.substring(startOffset, endOffset) !== text) {
- editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
- }
- }
- var firstToken = scanNext();
- if (firstToken !== Json.SyntaxKind.EOF) {
- var firstTokenStart = scanner.getTokenOffset() + formatTextStart;
- var initialIndent = repeat(indentValue, initialIndentLevel);
- addEdit(initialIndent, formatTextStart, firstTokenStart);
- }
- while (firstToken !== Json.SyntaxKind.EOF) {
- var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
- var secondToken = scanNext();
- var replaceContent = '';
- while (!lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) {
- // comments on the same line: keep them on the same line, but ignore them otherwise
- var commentTokenStart = scanner.getTokenOffset() + formatTextStart;
- addEdit(' ', firstTokenEnd, commentTokenStart);
- firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
- replaceContent = secondToken === Json.SyntaxKind.LineCommentTrivia ? newLineAndIndent() : '';
- secondToken = scanNext();
- }
- if (secondToken === Json.SyntaxKind.CloseBraceToken) {
- if (firstToken !== Json.SyntaxKind.OpenBraceToken) {
- indentLevel--;
- replaceContent = newLineAndIndent();
- }
- }
- else if (secondToken === Json.SyntaxKind.CloseBracketToken) {
- if (firstToken !== Json.SyntaxKind.OpenBracketToken) {
- indentLevel--;
- replaceContent = newLineAndIndent();
- }
- }
- else {
- switch (firstToken) {
- case Json.SyntaxKind.OpenBracketToken:
- case Json.SyntaxKind.OpenBraceToken:
- indentLevel++;
- replaceContent = newLineAndIndent();
- break;
- case Json.SyntaxKind.CommaToken:
- case Json.SyntaxKind.LineCommentTrivia:
- replaceContent = newLineAndIndent();
- break;
- case Json.SyntaxKind.BlockCommentTrivia:
- if (lineBreak) {
- replaceContent = newLineAndIndent();
- }
- else {
- // symbol following comment on the same line: keep on same line, separate with ' '
- replaceContent = ' ';
- }
- break;
- case Json.SyntaxKind.ColonToken:
- replaceContent = ' ';
- break;
- case Json.SyntaxKind.StringLiteral:
- if (secondToken === Json.SyntaxKind.ColonToken) {
- replaceContent = '';
- break;
- }
- // fall through
- case Json.SyntaxKind.NullKeyword:
- case Json.SyntaxKind.TrueKeyword:
- case Json.SyntaxKind.FalseKeyword:
- case Json.SyntaxKind.NumericLiteral:
- case Json.SyntaxKind.CloseBraceToken:
- case Json.SyntaxKind.CloseBracketToken:
- if (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia) {
- replaceContent = ' ';
- }
- else if (secondToken !== Json.SyntaxKind.CommaToken && secondToken !== Json.SyntaxKind.EOF) {
- hasError = true;
- }
- break;
- case Json.SyntaxKind.Unknown:
- hasError = true;
- break;
- }
- if (lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) {
- replaceContent = newLineAndIndent();
- }
- }
- var secondTokenStart = scanner.getTokenOffset() + formatTextStart;
- addEdit(replaceContent, firstTokenEnd, secondTokenStart);
- firstToken = secondToken;
- }
- return editOperations;
- }
- function repeat(s, count) {
- var result = '';
- for (var i = 0; i < count; i++) {
- result += s;
- }
- return result;
- }
- function computeIndentLevel(content, offset, options) {
- var i = 0;
- var nChars = 0;
- var tabSize = options.tabSize || 4;
- while (i < content.length) {
- var ch = content.charAt(i);
- if (ch === ' ') {
- nChars++;
- }
- else if (ch === '\t') {
- nChars += tabSize;
- }
- else {
- break;
- }
- i++;
- }
- return Math.floor(nChars / tabSize);
- }
- function getEOL(options, text) {
- for (var i = 0; i < text.length; i++) {
- var ch = text.charAt(i);
- if (ch === '\r') {
- if (i + 1 < text.length && text.charAt(i + 1) === '\n') {
- return '\r\n';
- }
- return '\r';
- }
- else if (ch === '\n') {
- return '\n';
- }
- }
- return (options && options.eol) || '\n';
- }
- export function isEOL(text, offset) {
- return '\r\n'.indexOf(text.charAt(offset)) !== -1;
- }
- //# sourceMappingURL=format.js.map
|