|
3 | 3 | import * as path from 'path'; |
4 | 4 | import * as os from 'os'; |
5 | 5 | import * as fs from 'fs'; |
6 | | -import { workspace, extensions, ExtensionContext, window, StatusBarAlignment, commands, ViewColumn, Uri, CancellationToken, TextDocumentContentProvider, TextEditor, WorkspaceConfiguration, languages, IndentAction, ProgressLocation, Progress, Position, Range, InputBoxOptions } from 'vscode'; |
| 6 | +import { workspace, extensions, ExtensionContext, window, StatusBarAlignment, commands, ViewColumn, Uri, CancellationToken, TextDocumentContentProvider, TextEditor, WorkspaceConfiguration, languages, IndentAction, ProgressLocation, InputBoxOptions, Selection, Position } from 'vscode'; |
7 | 7 | import { ExecuteCommandParams, ExecuteCommandRequest, LanguageClient, LanguageClientOptions, RevealOutputChannelOn, ServerOptions, Position as LSPosition, Location as LSLocation } from 'vscode-languageclient'; |
8 | 8 | import { collectionJavaExtensions } from './plugin'; |
9 | 9 | import { prepareExecutable, awaitServerConnection } from './javaServerStarter'; |
@@ -177,7 +177,7 @@ export function activate(context: ExtensionContext) { |
177 | 177 | commands.registerCommand(Commands.PROJECT_CONFIGURATION_STATUS, (uri, status) => setProjectConfigurationUpdate(languageClient, uri, status)); |
178 | 178 |
|
179 | 179 | commands.registerCommand(Commands.APPLY_WORKSPACE_EDIT, (obj) => { |
180 | | - applyWorkspaceEdit(obj); |
| 180 | + applyWorkspaceEdit(obj, languageClient); |
181 | 181 | }); |
182 | 182 |
|
183 | 183 | commands.registerCommand(Commands.EDIT_ORGANIZE_IMPORTS, async () => { |
@@ -247,15 +247,7 @@ export function activate(context: ExtensionContext) { |
247 | 247 | context.subscriptions.push(disposable); |
248 | 248 | context.subscriptions.push(onConfigurationChange()); |
249 | 249 | toggleItem(window.activeTextEditor, item); |
250 | | - |
251 | | - function applyWorkspaceEdit(obj) { |
252 | | - let edit = languageClient.protocol2CodeConverter.asWorkspaceEdit(obj); |
253 | | - if (edit) { |
254 | | - workspace.applyEdit(edit); |
255 | | - } |
256 | | - } |
257 | 250 | }); |
258 | | - |
259 | 251 | }); |
260 | 252 | }); |
261 | 253 | } |
@@ -554,5 +546,44 @@ async function addFormatter(extensionPath, formatterUrl, defaultFormatter, relat |
554 | 546 | }); |
555 | 547 | } |
556 | 548 |
|
| 549 | +async function applyWorkspaceEdit(obj, languageClient) { |
| 550 | + let edit = languageClient.protocol2CodeConverter.asWorkspaceEdit(obj); |
| 551 | + if (edit) { |
| 552 | + await workspace.applyEdit(edit); |
| 553 | + // By executing the range formatting command to correct the indention according to the VS Code editor settings. |
| 554 | + // More details, see: https://github.com/redhat-developer/vscode-java/issues/557 |
| 555 | + try { |
| 556 | + let currentEditor = window.activeTextEditor; |
| 557 | + // If the Uri path of the edit change is not equal to that of the active editor, we will skip the range formatting |
| 558 | + if (currentEditor.document.uri.fsPath !== edit.entries()[0][0].fsPath) { |
| 559 | + return; |
| 560 | + } |
| 561 | + let cursorPostion = currentEditor.selection.active; |
| 562 | + // Get the array of all the changes |
| 563 | + let changes = edit.entries()[0][1]; |
| 564 | + // Get the position information of the first change |
| 565 | + let startPosition = new Position(changes[0].range.start.line, changes[0].range.start.character); |
| 566 | + let lineOffsets = changes[0].newText.split(/\r?\n/).length - 1; |
| 567 | + for (let i = 1; i < changes.length; i++) { |
| 568 | + // When it comes to a discontinuous range, execute the range formatting and record the new start position |
| 569 | + if (changes[i].range.start.line !== startPosition.line) { |
| 570 | + await executeRangeFormat(currentEditor, startPosition, lineOffsets); |
| 571 | + startPosition = new Position(changes[i].range.start.line, changes[i].range.start.character); |
| 572 | + lineOffsets = 0; |
| 573 | + } |
| 574 | + lineOffsets += changes[i].newText.split(/\r?\n/).length - 1; |
| 575 | + } |
| 576 | + await executeRangeFormat(currentEditor, startPosition, lineOffsets); |
| 577 | + // Recover the cursor's original position |
| 578 | + currentEditor.selection = new Selection(cursorPostion, cursorPostion); |
| 579 | + } catch (error) { |
| 580 | + languageClient.error(error); |
| 581 | + } |
| 582 | + } |
| 583 | +} |
557 | 584 |
|
558 | | - |
| 585 | +async function executeRangeFormat(editor, startPosition, lineOffset) { |
| 586 | + let endPosition = editor.document.positionAt(editor.document.offsetAt(new Position(startPosition.line + lineOffset + 1, 0)) - 1); |
| 587 | + editor.selection = new Selection(startPosition, endPosition); |
| 588 | + await commands.executeCommand('editor.action.formatSelection'); |
| 589 | +} |
0 commit comments