diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 575436960..9a1ddada3 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -3002,11 +3002,15 @@ export class DefaultClient implements Client { const workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); let modifiedDocument: vscode.Uri | undefined; let lastEdit: vscode.TextEdit | undefined; + let numNewlinesFromPreviousEdits: number = 0; for (const file in result.changes) { const uri: vscode.Uri = vscode.Uri.file(file); const edits: vscode.TextEdit[] = []; for (const edit of result.changes[file]) { const range: vscode.Range = makeVscodeRange(edit.range); + if (lastEdit && lastEdit.range.isEqual(range)) { + numNewlinesFromPreviousEdits += (lastEdit.newText.match(/\n/g) || []).length; + } lastEdit = new vscode.TextEdit(range, edit.newText); edits.push(lastEdit); } @@ -3015,8 +3019,40 @@ export class DefaultClient implements Client { }; if (modifiedDocument && lastEdit) { await vscode.workspace.applyEdit(workspaceEdit); - const selectionRange: vscode.Range = lastEdit.range; // TODO: range should be the new range after text edit was applied. + let numNewlines: number = (lastEdit.newText.match(/\n/g) || []).length; + + // Move the cursor to the new code, accounting for \n or \n\n at the start. + let startLine: number = lastEdit.range.start.line; + if (lastEdit.newText.startsWith("\r\n\r\n") || lastEdit.newText.startsWith("\n\n")) { + startLine += 2; + numNewlines -= 2; + } else if (lastEdit.newText.startsWith("\r\n") || lastEdit.newText.startsWith("\n")) { + startLine += 1; + numNewlines -= 1; + } + if (!lastEdit.newText.endsWith("\n")) { + numNewlines++; // Increase the format range. + } + + const selectionPosition: vscode.Position = new vscode.Position(startLine + numNewlinesFromPreviousEdits, 0); + const selectionRange: vscode.Range = new vscode.Range(selectionPosition, selectionPosition); await vscode.window.showTextDocument(modifiedDocument, { selection: selectionRange }); + + // Run formatRange. + const formatEdits: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); + const formatRange: vscode.Range = new vscode.Range(selectionRange.start, new vscode.Position(selectionRange.start.line + numNewlines, 0)); + const settings: OtherSettings = new OtherSettings(vscode.workspace.getWorkspaceFolder(modifiedDocument)?.uri); + const formatOptions: vscode.FormattingOptions = { + insertSpaces: settings.editorInsertSpaces ?? true, + tabSize: settings.editorTabSize ?? 4 + }; + const formatTextEdits: vscode.TextEdit[] | undefined = await vscode.commands.executeCommand("vscode.executeFormatRangeProvider", modifiedDocument, formatRange, formatOptions); + if (formatTextEdits && formatTextEdits.length > 0) { + formatEdits.set(modifiedDocument, formatTextEdits); + } + if (formatEdits.size > 0) { + await vscode.workspace.applyEdit(formatEdits); + } } } }