@@ -13,73 +13,47 @@ import OptionProvider from '../observers/OptionProvider';
13
13
import { LanguageMiddlewareFeature } from '../omnisharp/LanguageMiddlewareFeature' ;
14
14
import { buildEditForResponse } from '../omnisharp/fileOperationsResponseEditBuilder' ;
15
15
16
- export default class CodeActionProvider extends AbstractProvider implements vscode . CodeActionProvider {
17
-
16
+ export default class CodeActionProvider extends AbstractProvider implements vscode . CodeActionProvider < vscode . CodeAction > {
18
17
private _commandId : string ;
19
18
20
19
constructor ( server : OmniSharpServer , private optionProvider : OptionProvider , languageMiddlewareFeature : LanguageMiddlewareFeature ) {
21
20
super ( server , languageMiddlewareFeature ) ;
22
21
this . _commandId = 'omnisharp.runCodeAction' ;
23
- let registerCommandDisposable = vscode . commands . registerCommand ( this . _commandId , this . _runCodeAction , this ) ;
22
+ const registerCommandDisposable = vscode . commands . registerCommand ( this . _commandId , this . _runCodeAction , this ) ;
24
23
this . addDisposables ( new CompositeDisposable ( registerCommandDisposable ) ) ;
25
24
}
26
25
27
- public async provideCodeActions ( document : vscode . TextDocument , range : vscode . Range , context : vscode . CodeActionContext , token : vscode . CancellationToken ) : Promise < vscode . Command [ ] > {
28
- let options = this . optionProvider . GetLatestOptions ( ) ;
26
+ public async provideCodeActions ( document : vscode . TextDocument , range : vscode . Range | vscode . Selection , context : vscode . CodeActionContext , token : vscode . CancellationToken ) : Promise < vscode . CodeAction [ ] > {
27
+ const options = this . optionProvider . GetLatestOptions ( ) ;
29
28
if ( options . disableCodeActions ) {
30
29
return ;
31
30
}
32
31
33
- let line : number ;
34
- let column : number ;
35
- let selection : protocol . V2 . Range ;
36
-
37
- // VS Code will pass the range of the word at the editor caret, even if there isn't a selection.
38
- // To ensure that we don't suggest selection-based refactorings when there isn't a selection, we first
39
- // find the text editor for this document and verify that there is a selection.
40
- let editor = vscode . window . visibleTextEditors . find ( e => e . document === document ) ;
41
- if ( editor ) {
42
- if ( editor . selection . isEmpty ) {
43
- // The editor does not have a selection. Use the active position of the selection (i.e. the caret).
44
- let active = editor . selection . active ;
32
+ const line = range . start . line ;
33
+ const column = range . start . character ;
45
34
46
- line = active . line ;
47
- column = active . character ;
48
- }
49
- else {
50
- // The editor has a selection. Use it.
51
- let start = editor . selection . start ;
52
- let end = editor . selection . end ;
35
+ const request : protocol . V2 . GetCodeActionsRequest = {
36
+ FileName : document . fileName ,
37
+ Line : line ,
38
+ Column : column ,
39
+ } ;
53
40
54
- selection = {
55
- Start : { Line : start . line , Column : start . character } ,
56
- End : { Line : end . line , Column : end . character }
57
- } ;
58
- }
59
- }
60
- else {
61
- // We couldn't find the editor, so just use the range we were provided.
62
- selection = {
41
+ // Only suggest selection-based refactorings when a selection exists.
42
+ // If there is no selection and the editor isn't focused,
43
+ // VS Code will pass us an empty Selection rather than a Range,
44
+ // hence the extra range.isEmpty check.
45
+ if ( range instanceof vscode . Selection && ! range . isEmpty ) {
46
+ request . Selection = {
63
47
Start : { Line : range . start . line , Column : range . start . character } ,
64
48
End : { Line : range . end . line , Column : range . end . character }
65
49
} ;
66
50
}
67
51
68
- let request : protocol . V2 . GetCodeActionsRequest = {
69
- FileName : document . fileName ,
70
- Line : line ,
71
- Column : column ,
72
- Selection : selection
73
- } ;
74
-
75
52
try {
76
- let response = await serverUtils . getCodeActions ( this . _server , request , token ) ;
53
+ const response = await serverUtils . getCodeActions ( this . _server , request , token ) ;
77
54
return response . CodeActions . map ( codeAction => {
78
- let runRequest : protocol . V2 . RunCodeActionRequest = {
79
- FileName : document . fileName ,
80
- Line : line ,
81
- Column : column ,
82
- Selection : selection ,
55
+ const runRequest : protocol . V2 . RunCodeActionRequest = {
56
+ ...request ,
83
57
Identifier : codeAction . Identifier ,
84
58
WantsTextChanges : true ,
85
59
WantsAllCodeActionOperations : true ,
@@ -88,24 +62,26 @@ export default class CodeActionProvider extends AbstractProvider implements vsco
88
62
89
63
return {
90
64
title : codeAction . Name ,
91
- command : this . _commandId ,
92
- arguments : [ runRequest , token ]
65
+ command : {
66
+ title : codeAction . Name ,
67
+ command : this . _commandId ,
68
+ arguments : [ runRequest , token ]
69
+ } ,
93
70
} ;
94
71
} ) ;
95
- }
96
- catch ( error ) {
72
+ } catch ( error ) {
97
73
return Promise . reject ( `Problem invoking 'GetCodeActions' on OmniSharp server: ${ error } ` ) ;
98
74
}
99
75
}
100
76
101
77
private async _runCodeAction ( req : protocol . V2 . RunCodeActionRequest , token : vscode . CancellationToken ) : Promise < boolean | string | { } > {
102
-
103
- return serverUtils . runCodeAction ( this . _server , req ) . then ( async response => {
78
+ try {
79
+ const response = await serverUtils . runCodeAction ( this . _server , req ) ;
104
80
if ( response ) {
105
81
return buildEditForResponse ( response . Changes , this . _languageMiddlewareFeature , token ) ;
106
82
}
107
- } , async ( error ) => {
83
+ } catch ( error ) {
108
84
return Promise . reject ( `Problem invoking 'RunCodeAction' on OmniSharp server: ${ error } ` ) ;
109
- } ) ;
85
+ }
110
86
}
111
87
}
0 commit comments