@@ -7,6 +7,7 @@ import * as vscode from 'vscode';
7
7
import * as nls from 'vscode-nls' ;
8
8
import { Command , CommandManager } from '../commands/commandManager' ;
9
9
import type * as Proto from '../protocol' ;
10
+ import { OrganizeImportsMode } from '../protocol.const' ;
10
11
import { ClientCapability , ITypeScriptServiceClient } from '../typescriptService' ;
11
12
import API from '../utils/api' ;
12
13
import { nulToken } from '../utils/cancellation' ;
@@ -19,17 +20,16 @@ import FileConfigurationManager from './fileConfigurationManager';
19
20
const localize = nls . loadMessageBundle ( ) ;
20
21
21
22
22
- class OrganizeImportsCommand implements Command {
23
- public static readonly Id = '_typescript.organizeImports' ;
24
-
25
- public readonly id = OrganizeImportsCommand . Id ;
23
+ abstract class BaseOrganizeImportsCommand implements Command {
24
+ protected abstract readonly mode : OrganizeImportsMode ;
26
25
27
26
constructor (
27
+ public id : string ,
28
28
private readonly client : ITypeScriptServiceClient ,
29
29
private readonly telemetryReporter : TelemetryReporter ,
30
30
) { }
31
31
32
- public async execute ( file : string , sortOnly = false ) : Promise < any > {
32
+ public async execute ( file ? : string ) : Promise < any > {
33
33
/* __GDPR__
34
34
"organizeImports.execute" : {
35
35
"owner": "mjbvz",
@@ -39,6 +39,23 @@ class OrganizeImportsCommand implements Command {
39
39
}
40
40
*/
41
41
this . telemetryReporter . logTelemetry ( 'organizeImports.execute' , { } ) ;
42
+ if ( ! file ) {
43
+ const activeEditor = vscode . window . activeTextEditor ;
44
+ if ( ! activeEditor ) {
45
+ vscode . window . showErrorMessage ( localize ( 'error.organizeImports.noResource' , "Organize Imports failed. No resource provided." ) ) ;
46
+ return ;
47
+ }
48
+
49
+ const resource = activeEditor . document . uri ;
50
+ const document = await vscode . workspace . openTextDocument ( resource ) ;
51
+ const openedFiledPath = this . client . toOpenedFilePath ( document ) ;
52
+ if ( ! openedFiledPath ) {
53
+ vscode . window . showErrorMessage ( localize ( 'error.organizeImports.unknownFile' , "Organize Imports failed. Unknown file type." ) ) ;
54
+ return ;
55
+ }
56
+
57
+ file = openedFiledPath ;
58
+ }
42
59
43
60
const args : Proto . OrganizeImportsRequestArgs = {
44
61
scope : {
@@ -47,7 +64,9 @@ class OrganizeImportsCommand implements Command {
47
64
file
48
65
}
49
66
} ,
50
- skipDestructiveCodeActions : sortOnly ,
67
+ // Deprecated in 4.9; `mode` takes priority
68
+ skipDestructiveCodeActions : this . mode === OrganizeImportsMode . SortAndCombine ,
69
+ mode : typeConverters . OrganizeImportsMode . toProtocolOrganizeImportsMode ( this . mode ) ,
51
70
} ;
52
71
const response = await this . client . interruptGetErr ( ( ) => this . client . execute ( 'organizeImports' , args , nulToken ) ) ;
53
72
if ( response . type !== 'response' || ! response . body ) {
@@ -61,24 +80,53 @@ class OrganizeImportsCommand implements Command {
61
80
}
62
81
}
63
82
83
+ class OrganizeImportsCommand extends BaseOrganizeImportsCommand {
84
+ public static readonly id = 'organizeImports' ;
85
+ public static minVersion = API . v280 ;
86
+ public static title = localize ( 'organizeImportsAction.title' , "Organize Imports" ) ;
87
+ public readonly mode = OrganizeImportsMode . All ;
88
+ }
89
+
90
+ class SortImportsCommand extends BaseOrganizeImportsCommand {
91
+ public static readonly id = 'sortImports' ;
92
+ public static minVersion = API . v430 ;
93
+ public static title = localize ( 'sortImportsAction.title' , "Sort Imports" ) ;
94
+ public readonly mode = OrganizeImportsMode . SortAndCombine ;
95
+ public static context = 'tsSupportsSortImports' ;
96
+ }
97
+
98
+ class RemoveUnusedImportsCommand extends BaseOrganizeImportsCommand {
99
+ public static readonly id = 'removeUnusedImports' ;
100
+ public static minVersion = API . v490 ;
101
+ public static title = localize ( 'removeUnusedImportsAction.title' , "Remove Unused Imports" ) ;
102
+ public readonly mode = OrganizeImportsMode . RemoveUnused ;
103
+ public static context = 'tsSupportsRemoveUnusedImports' ;
104
+ }
105
+
106
+ interface OrganizeImportsCommandClass {
107
+ readonly id : string ;
108
+ readonly title : string ;
109
+ readonly context ?: string ;
110
+ readonly minVersion : API ;
111
+ new ( id : string , client : ITypeScriptServiceClient , telemetryReporter : TelemetryReporter ) : BaseOrganizeImportsCommand ;
112
+ }
113
+
64
114
class ImportsCodeActionProvider implements vscode . CodeActionProvider {
65
115
66
116
static register (
67
117
client : ITypeScriptServiceClient ,
68
- minVersion : API ,
69
118
kind : vscode . CodeActionKind ,
70
- title : string ,
71
- sortOnly : boolean ,
119
+ Command : OrganizeImportsCommandClass ,
72
120
commandManager : CommandManager ,
73
121
fileConfigurationManager : FileConfigurationManager ,
74
122
telemetryReporter : TelemetryReporter ,
75
123
selector : DocumentSelector
76
124
) : vscode . Disposable {
77
125
return conditionalRegistration ( [
78
- requireMinVersion ( client , minVersion ) ,
126
+ requireMinVersion ( client , Command . minVersion ) ,
79
127
requireSomeCapability ( client , ClientCapability . Semantic ) ,
80
128
] , ( ) => {
81
- const provider = new ImportsCodeActionProvider ( client , kind , title , sortOnly , commandManager , fileConfigurationManager , telemetryReporter ) ;
129
+ const provider = new ImportsCodeActionProvider ( client , kind , Command , commandManager , fileConfigurationManager , telemetryReporter ) ;
82
130
return vscode . languages . registerCodeActionsProvider ( selector . semantic , provider , {
83
131
providedCodeActionKinds : [ kind ]
84
132
} ) ;
@@ -88,13 +136,25 @@ class ImportsCodeActionProvider implements vscode.CodeActionProvider {
88
136
public constructor (
89
137
private readonly client : ITypeScriptServiceClient ,
90
138
private readonly kind : vscode . CodeActionKind ,
91
- private readonly title : string ,
92
- private readonly sortOnly : boolean ,
139
+ private readonly Command : OrganizeImportsCommandClass ,
93
140
commandManager : CommandManager ,
94
141
private readonly fileConfigManager : FileConfigurationManager ,
95
142
telemetryReporter : TelemetryReporter ,
96
143
) {
97
- commandManager . register ( new OrganizeImportsCommand ( client , telemetryReporter ) ) ;
144
+ commandManager . register ( new Command ( `typescript.${ Command . id } ` , client , telemetryReporter ) ) ;
145
+ if ( Command !== OrganizeImportsCommand ) {
146
+ // The non-built-in variants have get duplicated with javascript-specific ids
147
+ // can show "JavasScript" as the category
148
+ commandManager . register ( new Command ( `javascript.${ Command . id } ` , client , telemetryReporter ) ) ;
149
+ }
150
+
151
+ if ( Command . context ) {
152
+ updateContext ( ) ;
153
+ client . onTsServerStarted ( ( ) => updateContext ( ) ) ;
154
+ function updateContext ( ) {
155
+ vscode . commands . executeCommand ( 'setContext' , Command . context , client . apiVersion . gte ( Command . minVersion ) ) ;
156
+ }
157
+ }
98
158
}
99
159
100
160
public provideCodeActions (
@@ -114,8 +174,8 @@ class ImportsCodeActionProvider implements vscode.CodeActionProvider {
114
174
115
175
this . fileConfigManager . ensureConfigurationForDocument ( document , token ) ;
116
176
117
- const action = new vscode . CodeAction ( this . title , this . kind ) ;
118
- action . command = { title : '' , command : OrganizeImportsCommand . Id , arguments : [ file , this . sortOnly ] } ;
177
+ const action = new vscode . CodeAction ( this . Command . title , this . kind ) ;
178
+ action . command = { title : '' , command : this . Command . id , arguments : [ file ] } ;
119
179
return [ action ] ;
120
180
}
121
181
}
@@ -130,21 +190,26 @@ export function register(
130
190
return vscode . Disposable . from (
131
191
ImportsCodeActionProvider . register (
132
192
client ,
133
- API . v280 ,
134
193
vscode . CodeActionKind . SourceOrganizeImports ,
135
- localize ( 'organizeImportsAction.title' , "Organize Imports" ) ,
136
- false ,
194
+ OrganizeImportsCommand ,
195
+ commandManager ,
196
+ fileConfigurationManager ,
197
+ telemetryReporter ,
198
+ selector
199
+ ) ,
200
+ ImportsCodeActionProvider . register (
201
+ client ,
202
+ vscode . CodeActionKind . Source . append ( SortImportsCommand . id ) ,
203
+ SortImportsCommand ,
137
204
commandManager ,
138
205
fileConfigurationManager ,
139
206
telemetryReporter ,
140
207
selector
141
208
) ,
142
209
ImportsCodeActionProvider . register (
143
210
client ,
144
- API . v430 ,
145
- vscode . CodeActionKind . Source . append ( 'sortImports' ) ,
146
- localize ( 'sortImportsAction.title' , "Sort Imports" ) ,
147
- true ,
211
+ vscode . CodeActionKind . Source . append ( RemoveUnusedImportsCommand . id ) ,
212
+ RemoveUnusedImportsCommand ,
148
213
commandManager ,
149
214
fileConfigurationManager ,
150
215
telemetryReporter ,
0 commit comments