Skip to content

Commit

Permalink
feat(formatGenerator): added support for format using generators
Browse files Browse the repository at this point in the history
  • Loading branch information
H4ad committed Jan 22, 2024
1 parent b6b34ba commit d37ab29
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 12 deletions.
34 changes: 22 additions & 12 deletions src/impl/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import { createScanner } from './scanner';
import { cachedSpaces, cachedBreakLinesWithSpaces, supportedEols, SupportedEOL } from './string-intern';

export function format(documentText: string, range: Range | undefined, options: FormattingOptions): Edit[] {
const operations: Edit[] = [];

for (const edit of formatGenerator(documentText, range, options)) {
operations.push(edit);
}

return operations;
}

export function* formatGenerator(documentText: string, range: Range | undefined, options: FormattingOptions): Generator<Edit, void, void> {
let initialIndentLevel: number;
let formatText: string;
let formatTextStart: number;
Expand Down Expand Up @@ -85,24 +95,22 @@ export function format(documentText: string, range: Range | undefined, options:
hasError = token === SyntaxKind.Unknown || scanner.getTokenError() !== ScanError.None;
return token;
}
const editOperations: Edit[] = [];
function addEdit(text: string, startOffset: number, endOffset: number) {
if (!hasError && (!range || (startOffset < rangeEnd && endOffset > rangeStart)) && documentText.substring(startOffset, endOffset) !== text) {
editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
}
}

const shouldAddEdit = (text: string, startOffset: number, endOffset: number) => !hasError && (!range || (startOffset < rangeEnd && endOffset > rangeStart)) && documentText.substring(startOffset, endOffset) !== text
// { offset: startOffset, length: endOffset - startOffset, content: text }
let firstToken = scanNext();
if (options.keepLines && numberLineBreaks > 0) {
addEdit(repeat(eol, numberLineBreaks), 0, 0);
const text = repeat(eol, numberLineBreaks);
if (shouldAddEdit(text, 0, 0))
yield { offset: 0, length: 0, content: text };
}

if (firstToken !== SyntaxKind.EOF) {
let firstTokenStart = scanner.getTokenOffset() + formatTextStart;
let initialIndent = (indentValue.length * initialIndentLevel < 20) && options.insertSpaces
? cachedSpaces[indentValue.length * initialIndentLevel]
: repeat(indentValue, initialIndentLevel);
addEdit(initialIndent, formatTextStart, firstTokenStart);
if (shouldAddEdit(initialIndent, formatTextStart, firstTokenStart))
yield { offset: formatTextStart, length: firstTokenStart - formatTextStart, content: initialIndent };
}

while (firstToken !== SyntaxKind.EOF) {
Expand All @@ -114,7 +122,9 @@ export function format(documentText: string, range: Range | undefined, options:

while (numberLineBreaks === 0 && (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia)) {
let commentTokenStart = scanner.getTokenOffset() + formatTextStart;
addEdit(cachedSpaces[1], firstTokenEnd, commentTokenStart);
if (shouldAddEdit(cachedSpaces[1], firstTokenEnd, commentTokenStart))
yield { offset: firstTokenEnd, length: commentTokenStart - firstTokenEnd, content: cachedSpaces[1] };

firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
needsLineBreak = secondToken === SyntaxKind.LineCommentTrivia;
replaceContent = needsLineBreak ? newLinesAndIndent() : '';
Expand Down Expand Up @@ -211,10 +221,10 @@ export function format(documentText: string, range: Range | undefined, options:
}
}
const secondTokenStart = scanner.getTokenOffset() + formatTextStart;
addEdit(replaceContent, firstTokenEnd, secondTokenStart);
if (shouldAddEdit(replaceContent, firstTokenEnd, secondTokenStart))
yield { offset: firstTokenEnd, length: secondTokenStart - firstTokenEnd, content: replaceContent };
firstToken = secondToken;
}
return editOperations;
}

function repeat(s: string, count: number): string {
Expand Down
18 changes: 18 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@ export interface JSONVisitor {
*/
export type EditResult = Edit[];

/**
* See more {@link EditResult}
*/
export type EditGeneratorResult = Generator<Edit, void, void>;

/**
* Represents a text modification
*/
Expand Down Expand Up @@ -376,6 +381,19 @@ export function format(documentText: string, range: Range | undefined, options:
return formatter.format(documentText, range, options);
}

/**
* Computes the edit operations needed to format a JSON document.
*
* @param documentText The input text
* @param range The range to format or `undefined` to format the full content
* @param options The formatting options
* @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}.
* To apply the edit operations to the input, use {@linkcode applyEdits}.
*/
export function formatGenerator(documentText: string, range: Range | undefined, options: FormattingOptions): EditGeneratorResult {
return formatter.formatGenerator(documentText, range, options);
}

/**
* Options used by {@linkcode modify} when computing the modification edit operations
*/
Expand Down

0 comments on commit d37ab29

Please sign in to comment.