Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An additional parameter keepLines has been added into the formatting options which allows to keep the original line formatting #66

Merged
merged 9 commits into from
Jul 11, 2022
13 changes: 13 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
aiday-mar marked this conversation as resolved.
Show resolved Hide resolved
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp

// List of extensions which should be recommended for users of this workspace.
"recommendations": [

],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [

]
}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
3.1.0 2022-07-07
==================
* Added the possibility to have multi-line formatting
aiday-mar marked this conversation as resolved.
Show resolved Hide resolved

3.0.0 2020-11-13
==================
* fixed API spec for `parseTree`. Can return `undefine` for empty input.
Expand Down
135 changes: 110 additions & 25 deletions src/impl/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export function format(documentText: string, range: Range | undefined, options:
}
let eol = getEOL(options, documentText);

let numberLineBreaks = 0;
let lineBreak = false;
aiday-mar marked this conversation as resolved.
Show resolved Hide resolved
let indentLevel = 0;
let indentValue: string;
Expand All @@ -48,14 +49,23 @@ export function format(documentText: string, range: Range | undefined, options:
let scanner = createScanner(formatText, false);
let hasError = false;

function newLineAndIndent(): string {
return eol + repeat(indentValue, initialIndentLevel + indentLevel);
function newLinesAndIndent(): string {
if (numberLineBreaks > 0) {
return repeat(eol, numberLineBreaks) + repeat(indentValue, initialIndentLevel + indentLevel);
} else {
return eol + repeat(indentValue, initialIndentLevel + indentLevel);
}
}

function scanNext(): SyntaxKind {
let token = scanner.scan();
numberLineBreaks = 0;
lineBreak = false;
while (token === SyntaxKind.Trivia || token === SyntaxKind.LineBreakTrivia) {
lineBreak = lineBreak || (token === SyntaxKind.LineBreakTrivia);
if (token === SyntaxKind.LineBreakTrivia && options.keepLines) {
numberLineBreaks += 1;
}
token = scanner.scan();
}
hasError = token === SyntaxKind.Unknown || scanner.getTokenError() !== ScanError.None;
Expand Down Expand Up @@ -88,76 +98,151 @@ export function format(documentText: string, range: Range | undefined, options:
addEdit(' ', firstTokenEnd, commentTokenStart);
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
needsLineBreak = secondToken === SyntaxKind.LineCommentTrivia;
replaceContent = needsLineBreak ? newLineAndIndent() : '';
replaceContent = needsLineBreak ? newLinesAndIndent() : '';
secondToken = scanNext();
}

if (secondToken === SyntaxKind.CloseBraceToken) {
if (firstToken !== SyntaxKind.OpenBraceToken) {
if (options.keepLines) {
if (firstToken !== SyntaxKind.OpenBraceToken) { indentLevel--; };
aiday-mar marked this conversation as resolved.
Show resolved Hide resolved
if (lineBreak) {
replaceContent = newLinesAndIndent();
} else {
replaceContent = ' ';
}
} else if (!options.keepLines && firstToken !== SyntaxKind.OpenBraceToken){
indentLevel--;
replaceContent = newLineAndIndent();
replaceContent = newLinesAndIndent();
}
} else if (secondToken === SyntaxKind.CloseBracketToken) {
if (firstToken !== SyntaxKind.OpenBracketToken) {
if (options.keepLines) {
if(firstToken !== SyntaxKind.OpenBracketToken) {indentLevel--;};
if (lineBreak) {
replaceContent = newLinesAndIndent();
} else {
replaceContent = ' ';
}
}
else if (firstToken !== SyntaxKind.OpenBracketToken) {
indentLevel--;
replaceContent = newLineAndIndent();
replaceContent = newLinesAndIndent();
}
} else {

switch (firstToken) {
case SyntaxKind.OpenBracketToken:
case SyntaxKind.OpenBraceToken:
indentLevel++;
replaceContent = newLineAndIndent();
if (options.keepLines) {
if (lineBreak) {
replaceContent = newLinesAndIndent();
} else {
replaceContent = " ";
}
} else {
replaceContent = newLinesAndIndent();
}
break;
case SyntaxKind.CommaToken:
if(options.keepLines) {
if (lineBreak) {
replaceContent = newLinesAndIndent();
} else {
replaceContent = " ";
}
} else {
replaceContent = newLinesAndIndent();
}
break;
case SyntaxKind.LineCommentTrivia:
replaceContent = newLineAndIndent();
replaceContent = newLinesAndIndent();
break;
case SyntaxKind.BlockCommentTrivia:
if (lineBreak) {
replaceContent = newLineAndIndent();
replaceContent = newLinesAndIndent();
} else if (!needsLineBreak) {
// symbol following comment on the same line: keep on same line, separate with ' '
replaceContent = ' ';
}
break;
case SyntaxKind.ColonToken:
if (!needsLineBreak) {
replaceContent = ' ';
if (options.keepLines) {
aiday-mar marked this conversation as resolved.
Show resolved Hide resolved
if (lineBreak) {
replaceContent = newLinesAndIndent();
} else if (!needsLineBreak) {
replaceContent = ' ';
}
} else {
if (!needsLineBreak) {
replaceContent = ' ';
}
}
break;
case SyntaxKind.StringLiteral:
if (secondToken === SyntaxKind.ColonToken) {
if (!needsLineBreak) {
replaceContent = '';
if (options.keepLines) {
if (lineBreak) {
replaceContent = newLinesAndIndent();
} else {
if (secondToken === SyntaxKind.ColonToken) {
if (!needsLineBreak) {
replaceContent = '';
}
}
}
} else {
if (secondToken === SyntaxKind.ColonToken) {
if (!needsLineBreak) {
replaceContent = '';
}
}
break;
}
// fall through
break;
case SyntaxKind.NullKeyword:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.NumericLiteral:
case SyntaxKind.CloseBraceToken:
case SyntaxKind.CloseBracketToken:
if (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia) {
if (!needsLineBreak) {
replaceContent = ' ';
if (options.keepLines) {
if (lineBreak) {
replaceContent = newLinesAndIndent();
} else {
if (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia) {
if (!needsLineBreak) {
replaceContent = ' ';
}
} else if (secondToken !== SyntaxKind.CommaToken && secondToken !== SyntaxKind.EOF) {
hasError = true;
}
}
} else {
if (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia) {
if (!needsLineBreak) {
replaceContent = ' ';
}
} else if (secondToken !== SyntaxKind.CommaToken && secondToken !== SyntaxKind.EOF) {
hasError = true;
}
} else if (secondToken !== SyntaxKind.CommaToken && secondToken !== SyntaxKind.EOF) {
hasError = true;
}
break;
case SyntaxKind.Unknown:
hasError = true;
break;
}

if (lineBreak && (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia)) {
replaceContent = newLineAndIndent();
replaceContent = newLinesAndIndent();
}
}
if (secondToken === SyntaxKind.EOF) {
replaceContent = options.insertFinalNewline ? eol : '';
if (options.keepLines) {
if (lineBreak) {
replaceContent = newLinesAndIndent();
} else {
replaceContent = options.insertFinalNewline ? eol : '';
}
} else {
replaceContent = options.insertFinalNewline ? eol : '';
}
}
let secondTokenStart = scanner.getTokenOffset() + formatTextStart;
addEdit(replaceContent, firstTokenEnd, secondTokenStart);
Expand Down
4 changes: 4 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,10 @@ export interface FormattingOptions {
* If set, will add a new line at the end of the document.
*/
insertFinalNewline?: boolean;
/**
* If true, will keep line positions as is in the formatting
*/
keepLines?: boolean;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/test/edit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ suite('JSON - edits', () => {
let formattingOptions: FormattingOptions = {
insertSpaces: true,
tabSize: 2,
eol: '\n'
eol: '\n',
keepLines: false
};

let options: ModificationOptions = {
Expand Down
Loading