6
6
import * as vscode from 'vscode' ;
7
7
import * as nls from 'vscode-nls' ;
8
8
import { CommandManager } from '../commands/commandManager' ;
9
- import { ITypeScriptServiceClient } from '../typescriptService' ;
9
+ import { ClientCapability , ITypeScriptServiceClient } from '../typescriptService' ;
10
10
import { ActiveJsTsEditorTracker } from '../utils/activeJsTsEditorTracker' ;
11
11
import { Disposable } from '../utils/dispose' ;
12
12
import { jsTsLanguageModes , isSupportedLanguageMode } from '../utils/languageModeIds' ;
@@ -15,11 +15,13 @@ import { isImplicitProjectConfigFile, openOrCreateConfig, openProjectConfigForFi
15
15
const localize = nls . loadMessageBundle ( ) ;
16
16
17
17
18
- namespace ProjectInfoState {
19
- export const enum Type { None , Pending , Resolved }
18
+ namespace IntellisenseState {
19
+ export const enum Type { None , Pending , Resolved , SyntaxOnly }
20
20
21
21
export const None = Object . freeze ( { type : Type . None } as const ) ;
22
22
23
+ export const SyntaxOnly = Object . freeze ( { type : Type . SyntaxOnly } as const ) ;
24
+
23
25
export class Pending {
24
26
public readonly type = Type . Pending ;
25
27
@@ -39,18 +41,18 @@ namespace ProjectInfoState {
39
41
) { }
40
42
}
41
43
42
- export type State = typeof None | Pending | Resolved ;
44
+ export type State = typeof None | Pending | Resolved | typeof SyntaxOnly ;
43
45
}
44
46
45
- export class ProjectStatus extends Disposable {
47
+ export class IntellisenseStatus extends Disposable {
46
48
47
49
public readonly openOpenConfigCommandId = '_typescript.openConfig' ;
48
50
public readonly createConfigCommandId = '_typescript.createConfig' ;
49
51
50
52
private readonly _statusItem : vscode . LanguageStatusItem ;
51
53
52
54
private _ready = false ;
53
- private _state : ProjectInfoState . State = ProjectInfoState . None ;
55
+ private _state : IntellisenseState . State = IntellisenseState . None ;
54
56
55
57
constructor (
56
58
private readonly _client : ITypeScriptServiceClient ,
@@ -60,15 +62,14 @@ export class ProjectStatus extends Disposable {
60
62
super ( ) ;
61
63
62
64
this . _statusItem = this . _register ( vscode . languages . createLanguageStatusItem ( 'typescript.projectStatus' , jsTsLanguageModes ) ) ;
63
- this . _statusItem . name = localize ( 'statusItem.name' , "Project config" ) ;
64
- this . _statusItem . text = 'TSConfig' ;
65
+ this . _statusItem . name = localize ( 'statusItem.name' , "JS/TS IntelliSense Status" ) ;
65
66
66
67
commandManager . register ( {
67
68
id : this . openOpenConfigCommandId ,
68
69
execute : async ( rootPath : string ) => {
69
- if ( this . _state . type === ProjectInfoState . Type . Resolved ) {
70
+ if ( this . _state . type === IntellisenseState . Type . Resolved ) {
70
71
await openProjectConfigOrPromptToCreate ( ProjectType . TypeScript , this . _client , rootPath , this . _state . configFile ) ;
71
- } else if ( this . _state . type === ProjectInfoState . Type . Pending ) {
72
+ } else if ( this . _state . type === IntellisenseState . Type . Pending ) {
72
73
await openProjectConfigForFile ( ProjectType . TypeScript , this . _client , this . _state . resource ) ;
73
74
}
74
75
} ,
@@ -89,79 +90,96 @@ export class ProjectStatus extends Disposable {
89
90
}
90
91
91
92
private async updateStatus ( ) {
92
- const editor = this . _activeTextEditorManager . activeJsTsEditor ;
93
- if ( ! editor ) {
94
- this . updateState ( ProjectInfoState . None ) ;
93
+ const doc = this . _activeTextEditorManager . activeJsTsEditor ?. document ;
94
+ if ( ! doc || ! isSupportedLanguageMode ( doc ) ) {
95
+ this . updateState ( IntellisenseState . None ) ;
95
96
return ;
96
97
}
97
98
98
- const doc = editor . document ;
99
- if ( isSupportedLanguageMode ( doc ) ) {
100
- const file = this . _client . toOpenedFilePath ( doc , { suppressAlertOnFailure : true } ) ;
101
- if ( file ) {
102
- if ( ! this . _ready ) {
103
- return ;
104
- }
99
+ if ( ! this . _client . hasCapabilityForResource ( doc . uri , ClientCapability . Semantic ) ) {
100
+ this . updateState ( IntellisenseState . SyntaxOnly ) ;
101
+ return ;
102
+ }
105
103
106
- const pendingState = new ProjectInfoState . Pending ( doc . uri ) ;
107
- this . updateState ( pendingState ) ;
104
+ const file = this . _client . toOpenedFilePath ( doc , { suppressAlertOnFailure : true } ) ;
105
+ if ( ! file ) {
106
+ this . updateState ( IntellisenseState . None ) ;
107
+ return ;
108
+ }
108
109
109
- const response = await this . _client . execute ( 'projectInfo' , { file, needFileNameList : false } , pendingState . cancellation . token ) ;
110
- if ( response . type === 'response' && response . body ) {
111
- if ( this . _state === pendingState ) {
112
- this . updateState ( new ProjectInfoState . Resolved ( doc . uri , response . body . configFileName ) ) ;
113
- }
114
- }
115
- return ;
116
- }
110
+ if ( ! this . _ready ) {
111
+ return ;
117
112
}
118
113
119
- this . updateState ( ProjectInfoState . None ) ;
114
+ const pendingState = new IntellisenseState . Pending ( doc . uri ) ;
115
+ this . updateState ( pendingState ) ;
116
+
117
+ const response = await this . _client . execute ( 'projectInfo' , { file, needFileNameList : false } , pendingState . cancellation . token ) ;
118
+ if ( response . type === 'response' && response . body ) {
119
+ if ( this . _state === pendingState ) {
120
+ this . updateState ( new IntellisenseState . Resolved ( doc . uri , response . body . configFileName ) ) ;
121
+ }
122
+ }
120
123
}
121
124
122
- private updateState ( newState : ProjectInfoState . State ) : void {
125
+ private updateState ( newState : IntellisenseState . State ) : void {
123
126
if ( this . _state === newState ) {
124
127
return ;
125
128
}
126
129
127
- if ( this . _state . type === ProjectInfoState . Type . Pending ) {
130
+ if ( this . _state . type === IntellisenseState . Type . Pending ) {
128
131
this . _state . cancellation . cancel ( ) ;
129
132
this . _state . cancellation . dispose ( ) ;
130
133
}
131
134
132
135
this . _state = newState ;
133
136
134
137
switch ( this . _state . type ) {
135
- case ProjectInfoState . Type . None :
138
+ case IntellisenseState . Type . None :
136
139
break ;
137
140
138
- case ProjectInfoState . Type . Pending :
139
- this . _statusItem . detail = '$(loading~spin)' ;
141
+ case IntellisenseState . Type . Pending :
142
+ this . _statusItem . text = '$(loading~spin)' ;
143
+ this . _statusItem . detail = localize ( 'pending.detail' , 'Loading IntelliSense status' ) ;
140
144
this . _statusItem . command = undefined ;
141
145
break ;
142
146
143
- case ProjectInfoState . Type . Resolved :
147
+ case IntellisenseState . Type . Resolved :
144
148
const rootPath = this . _client . getWorkspaceRootForResource ( this . _state . resource ) ;
145
149
if ( ! rootPath ) {
146
150
return ;
147
151
}
148
152
149
153
if ( isImplicitProjectConfigFile ( this . _state . configFile ) ) {
150
- this . _statusItem . detail = localize ( 'item.noTsConfig.detail' , "None" ) ;
154
+ this . _statusItem . text = localize ( 'resolved.detail.noTsConfig' , "No tsconfig" ) ;
155
+ this . _statusItem . detail = undefined ;
151
156
this . _statusItem . command = {
152
157
command : this . createConfigCommandId ,
153
- title : localize ( 'create .command' , "Create tsconfig" ) ,
158
+ title : localize ( 'resolved .command.title.create ' , "Create tsconfig" ) ,
154
159
arguments : [ rootPath ] ,
155
160
} ;
156
161
} else {
157
- this . _statusItem . detail = vscode . workspace . asRelativePath ( this . _state . configFile ) ;
162
+ this . _statusItem . text = vscode . workspace . asRelativePath ( this . _state . configFile ) ;
163
+ this . _statusItem . detail = undefined ;
158
164
this . _statusItem . command = {
159
165
command : this . openOpenConfigCommandId ,
160
- title : localize ( 'item .command' , "Open config file" ) ,
166
+ title : localize ( 'resolved .command.title.open ' , "Open config file" ) ,
161
167
arguments : [ rootPath ] ,
162
168
} ;
163
169
}
164
170
break ;
171
+
172
+ case IntellisenseState . Type . SyntaxOnly :
173
+ this . _statusItem . text = localize ( 'syntaxOnly.text' , 'Partial Mode' ) ;
174
+ this . _statusItem . detail = localize ( 'syntaxOnly.detail' , 'Project Wide IntelliSense not available' ) ;
175
+ this . _statusItem . command = {
176
+ title : localize ( 'syntaxOnly.command.title.learnMore' , "Learn More" ) ,
177
+ command : 'vscode.open' ,
178
+ arguments : [
179
+ vscode . Uri . parse ( 'https://go.microsoft.com/fwlink/?linkid=2114477' ) , // TODO: add proper link once published
180
+ ]
181
+ } ;
182
+ break ;
165
183
}
166
184
}
167
185
}
0 commit comments