-
Notifications
You must be signed in to change notification settings - Fork 676
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
Don't apply edits on server #4133
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,13 +7,11 @@ import * as vscode from 'vscode'; | |
import { OmniSharpServer } from '../omnisharp/server'; | ||
import AbstractProvider from './abstractProvider'; | ||
import * as protocol from '../omnisharp/protocol'; | ||
import { toRange2 } from '../omnisharp/typeConversion'; | ||
import * as serverUtils from '../omnisharp/utils'; | ||
import { FileModificationType } from '../omnisharp/protocol'; | ||
import { Uri } from 'vscode'; | ||
import CompositeDisposable from '../CompositeDisposable'; | ||
import OptionProvider from '../observers/OptionProvider'; | ||
import { LanguageMiddlewareFeature } from '../omnisharp/LanguageMiddlewareFeature'; | ||
import { buildEditForResponse } from '../omnisharp/fileOperationsResponseEditBuilder'; | ||
|
||
export default class CodeActionProvider extends AbstractProvider implements vscode.CodeActionProvider { | ||
|
||
|
@@ -84,7 +82,8 @@ export default class CodeActionProvider extends AbstractProvider implements vsco | |
Selection: selection, | ||
Identifier: codeAction.Identifier, | ||
WantsTextChanges: true, | ||
WantsAllCodeActionOperations: true | ||
WantsAllCodeActionOperations: true, | ||
ApplyTextChanges: false | ||
}; | ||
|
||
return { | ||
|
@@ -101,80 +100,12 @@ export default class CodeActionProvider extends AbstractProvider implements vsco | |
|
||
private async _runCodeAction(req: protocol.V2.RunCodeActionRequest, token: vscode.CancellationToken): Promise<boolean | string | {}> { | ||
|
||
return serverUtils.runCodeAction(this._server, req).then(async response => { | ||
if (response && Array.isArray(response.Changes)) { | ||
|
||
let edit = new vscode.WorkspaceEdit(); | ||
|
||
let fileToOpen: Uri = null; | ||
let renamedFiles: Uri[] = []; | ||
|
||
for (let change of response.Changes) { | ||
if (change.ModificationType == FileModificationType.Renamed) | ||
{ | ||
// The file was renamed. Omnisharp has already persisted | ||
// the right changes to disk. We don't need to try to | ||
// apply text changes (and will skip this file if we see an edit) | ||
renamedFiles.push(Uri.file(change.FileName)); | ||
} | ||
} | ||
|
||
for (let change of response.Changes) { | ||
if (change.ModificationType == FileModificationType.Opened) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
{ | ||
// The CodeAction requested that we open a file. | ||
// Record that file name and keep processing CodeActions. | ||
// If a CodeAction requests that we open multiple files | ||
// we only open the last one (what would it mean to open multiple files?) | ||
fileToOpen = vscode.Uri.file(change.FileName); | ||
} | ||
|
||
if (change.ModificationType == FileModificationType.Modified) | ||
{ | ||
let uri = vscode.Uri.file(change.FileName); | ||
if (renamedFiles.some(r => r == uri)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic is removed. |
||
{ | ||
// This file got renamed. OmniSharp has already | ||
// persisted the new file with any applicable changes. | ||
continue; | ||
} | ||
|
||
let edits: vscode.TextEdit[] = []; | ||
for (let textChange of change.Changes) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic is unchanged, other than using |
||
edits.push(vscode.TextEdit.replace(toRange2(textChange), textChange.NewText)); | ||
} | ||
|
||
edit.set(uri, edits); | ||
} | ||
} | ||
|
||
// Allow language middlewares to re-map its edits if necessary. | ||
edit = await this._languageMiddlewareFeature.remap("remapWorkspaceEdit", edit, token); | ||
|
||
let applyEditPromise = vscode.workspace.applyEdit(edit); | ||
|
||
// Unfortunately, the textEditor.Close() API has been deprecated | ||
// and replaced with a command that can only close the active editor. | ||
// If files were renamed that weren't the active editor, their tabs will | ||
// be left open and marked as "deleted" by VS Code | ||
let next = applyEditPromise; | ||
if (renamedFiles.some(r => r.fsPath == vscode.window.activeTextEditor.document.uri.fsPath)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic is removed and unneeded, as we now do the rename ourselves. |
||
{ | ||
next = applyEditPromise.then(_ => | ||
{ | ||
return vscode.commands.executeCommand("workbench.action.closeActiveEditor"); | ||
}); | ||
} | ||
|
||
return fileToOpen != null | ||
? next.then(_ => | ||
{ | ||
return vscode.commands.executeCommand("vscode.open", fileToOpen); | ||
}) | ||
: next; | ||
} | ||
}, async (error) => { | ||
return serverUtils.runCodeAction(this._server, req).then(response => { | ||
if (response) { | ||
return buildEditForResponse(response.Changes, this._languageMiddlewareFeature, token); | ||
} | ||
}, async (error) => { | ||
return Promise.reject(`Problem invoking 'RunCodeAction' on OmniSharp server: ${error}`); | ||
}); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import * as vscode from 'vscode'; | ||
import { Uri } from 'vscode'; | ||
import { LanguageMiddlewareFeature } from './LanguageMiddlewareFeature'; | ||
import { FileModificationType, FileOperationResponse, ModifiedFileResponse, RenamedFileResponse } from "./protocol"; | ||
import { toRange2 } from './typeConversion'; | ||
|
||
export async function buildEditForResponse(changes: FileOperationResponse[], languageMiddlewareFeature: LanguageMiddlewareFeature, token: vscode.CancellationToken): Promise<boolean> { | ||
let edit = new vscode.WorkspaceEdit(); | ||
|
||
let fileToOpen: Uri = null; | ||
|
||
if (!changes || !Array.isArray(changes) || !changes.length) { | ||
return true; | ||
} | ||
|
||
for (const change of changes) { | ||
if (change.ModificationType == FileModificationType.Opened) { | ||
// The CodeAction requested that we open a file. | ||
// Record that file name and keep processing CodeActions. | ||
// If a CodeAction requests that we open multiple files | ||
// we only open the last one (what would it mean to open multiple files?) | ||
fileToOpen = vscode.Uri.file(change.FileName); | ||
} | ||
|
||
if (change.ModificationType == FileModificationType.Modified) { | ||
const modifiedChange = <ModifiedFileResponse>change; | ||
const uri = vscode.Uri.file(modifiedChange.FileName); | ||
let edits: vscode.TextEdit[] = []; | ||
for (let textChange of modifiedChange.Changes) { | ||
edits.push(vscode.TextEdit.replace(toRange2(textChange), textChange.NewText)); | ||
} | ||
|
||
edit.set(uri, edits); | ||
} | ||
} | ||
|
||
for (const change of changes) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the actual after change here. |
||
if (change.ModificationType == FileModificationType.Renamed) { | ||
const renamedChange = <RenamedFileResponse>change; | ||
edit.renameFile(vscode.Uri.file(renamedChange.FileName), vscode.Uri.file(renamedChange.NewFileName)); | ||
} | ||
} | ||
|
||
// Allow language middlewares to re-map its edits if necessary. | ||
edit = await languageMiddlewareFeature.remap("remapWorkspaceEdit", edit, token); | ||
|
||
const applyEditPromise = vscode.workspace.applyEdit(edit); | ||
|
||
// Unfortunately, the textEditor.Close() API has been deprecated | ||
// and replaced with a command that can only close the active editor. | ||
// If files were renamed that weren't the active editor, their tabs will | ||
// be left open and marked as "deleted" by VS Code | ||
return fileToOpen != null | ||
? applyEditPromise.then(_ => { | ||
return vscode.commands.executeCommand("vscode.open", fileToOpen); | ||
}) | ||
: applyEditPromise; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The after change replaced this logic.