55
66'use strict' ;
77
8- import { CodeActionProvider , CodeActionContext , Command , CancellationToken , TextDocument , WorkspaceEdit , TextEdit , Range , Uri , workspace , commands } from 'vscode' ;
9- import { OmniSharpServer } from '../omnisharp/server' ;
8+ import * as vscode from 'vscode' ;
9+ import { OmniSharpServer } from '../omnisharp/server' ;
1010import AbstractProvider from './abstractProvider' ;
1111import * as protocol from '../omnisharp/protocol' ;
12- import { toRange2 } from '../omnisharp/typeConvertion' ;
12+ import { toRange2 } from '../omnisharp/typeConvertion' ;
1313import * as serverUtils from '../omnisharp/utils' ;
1414
15- export default class OmnisharpCodeActionProvider extends AbstractProvider implements CodeActionProvider {
15+ export default class CodeActionProvider extends AbstractProvider implements vscode . CodeActionProvider {
1616
1717 private _disabled : boolean ;
1818 private _commandId : string ;
@@ -21,38 +21,80 @@ export default class OmnisharpCodeActionProvider extends AbstractProvider implem
2121 super ( server ) ;
2222 this . _commandId = 'omnisharp.runCodeAction' ;
2323
24- this . _updateEnablement ( ) ;
25- let d1 = workspace . onDidChangeConfiguration ( this . _updateEnablement , this ) ;
26- let d2 = commands . registerCommand ( this . _commandId , this . _runCodeAction , this ) ;
24+ this . _checkOption ( ) ;
25+
26+ let d1 = vscode . workspace . onDidChangeConfiguration ( this . _checkOption , this ) ;
27+ let d2 = vscode . commands . registerCommand ( this . _commandId , this . _runCodeAction , this ) ;
2728 this . _disposables . push ( d1 , d2 ) ;
2829 }
2930
30- private _updateEnablement ( ) : void {
31- let value = workspace . getConfiguration ( ) . get ( 'csharp.disableCodeActions' , false ) ;
31+ private _checkOption ( ) : void {
32+ let value = vscode . workspace . getConfiguration ( ) . get ( 'csharp.disableCodeActions' , false ) ;
3233 this . _disabled = value ;
3334 }
3435
35- public provideCodeActions ( document : TextDocument , range : Range , context : CodeActionContext , token : CancellationToken ) : Promise < Command [ ] > {
36+ public provideCodeActions ( document : vscode . TextDocument , range : vscode . Range , context : vscode . CodeActionContext , token : vscode . CancellationToken ) : Promise < vscode . Command [ ] > {
3637 if ( this . _disabled ) {
3738 return ;
3839 }
3940
40- let req : protocol . V2 . GetCodeActionsRequest = {
41+ let line : number ;
42+ let column : number ;
43+ let selection : protocol . V2 . Range ;
44+
45+ // VS Code will pass the range of the word at the editor caret, even if there isn't a selection.
46+ // To ensure that we don't suggest selection-based refactorings when there isn't a selection, we first
47+ // find the text editor for this document and verify that there is a selection.
48+ let editor = vscode . window . visibleTextEditors . find ( e => e . document === document ) ;
49+ if ( editor ) {
50+ if ( editor . selection . isEmpty ) {
51+ // The editor does not have a selection. Use the active position of the selection (i.e. the caret).
52+ let active = editor . selection . active ;
53+
54+ line = active . line + 1 ;
55+ column = active . character + 1 ;
56+ }
57+ else {
58+ // The editor has a selection. Use it.
59+ let start = editor . selection . start ;
60+ let end = editor . selection . end ;
61+
62+ selection = {
63+ Start : { Line : start . line + 1 , Column : start . character + 1 } ,
64+ End : { Line : end . line + 1 , Column : end . character + 1 }
65+ } ;
66+ }
67+ }
68+ else {
69+ // We couldn't find the editor, so just use the range we were provided.
70+ selection = {
71+ Start : { Line : range . start . line + 1 , Column : range . start . character + 1 } ,
72+ End : { Line : range . end . line + 1 , Column : range . end . character + 1 }
73+ } ;
74+ }
75+
76+ let request : protocol . V2 . GetCodeActionsRequest = {
4177 FileName : document . fileName ,
42- Selection : OmnisharpCodeActionProvider . _asRange ( range )
78+ Line : line ,
79+ Column : column ,
80+ Selection : selection
4381 } ;
4482
45- return serverUtils . getCodeActions ( this . _server , req , token ) . then ( response => {
83+ return serverUtils . getCodeActions ( this . _server , request , token ) . then ( response => {
4684 return response . CodeActions . map ( codeAction => {
85+ let runRequest : protocol . V2 . RunCodeActionRequest = {
86+ FileName : document . fileName ,
87+ Line : line ,
88+ Column : column ,
89+ Selection : selection ,
90+ Identifier : codeAction . Identifier ,
91+ WantsTextChanges : true
92+ } ;
93+
4794 return {
4895 title : codeAction . Name ,
4996 command : this . _commandId ,
50- arguments : [ < protocol . V2 . RunCodeActionRequest > {
51- FileName : document . fileName ,
52- Selection : OmnisharpCodeActionProvider . _asRange ( range ) ,
53- Identifier : codeAction . Identifier ,
54- WantsTextChanges : true
55- } ]
97+ arguments : [ runRequest ]
5698 } ;
5799 } ) ;
58100 } , ( error ) => {
@@ -66,31 +108,23 @@ export default class OmnisharpCodeActionProvider extends AbstractProvider implem
66108
67109 if ( response && Array . isArray ( response . Changes ) ) {
68110
69- let edit = new WorkspaceEdit ( ) ;
111+ let edit = new vscode . WorkspaceEdit ( ) ;
70112
71113 for ( let change of response . Changes ) {
72- let uri = Uri . file ( change . FileName ) ;
73- let edits : TextEdit [ ] = [ ] ;
114+ let uri = vscode . Uri . file ( change . FileName ) ;
115+ let edits : vscode . TextEdit [ ] = [ ] ;
74116 for ( let textChange of change . Changes ) {
75- edits . push ( TextEdit . replace ( toRange2 ( textChange ) , textChange . NewText ) ) ;
117+ edits . push ( vscode . TextEdit . replace ( toRange2 ( textChange ) , textChange . NewText ) ) ;
76118 }
77119
78120 edit . set ( uri , edits ) ;
79121 }
80122
81- return workspace . applyEdit ( edit ) ;
123+ return vscode . workspace . applyEdit ( edit ) ;
82124 }
83125
84126 } , ( error ) => {
85- return Promise . reject ( ' Problem invoking \ 'RunCodeAction\ ' on OmniSharp server: ' + error ) ;
127+ return Promise . reject ( ` Problem invoking 'RunCodeAction' on OmniSharp server: ${ error } ` ) ;
86128 } ) ;
87129 }
88-
89- private static _asRange ( range : Range ) : protocol . V2 . Range {
90- let { start, end} = range ;
91- return {
92- Start : { Line : start . line + 1 , Column : start . character + 1 } ,
93- End : { Line : end . line + 1 , Column : end . character + 1 }
94- } ;
95- }
96- }
130+ }
0 commit comments