@@ -6,11 +6,10 @@ import { inject, injectable } from 'inversify';
6
6
import { DiagnosticSeverity } from 'vscode' ;
7
7
import '../../../common/extensions' ;
8
8
import * as nls from 'vscode-nls' ;
9
+ import * as path from 'path' ;
9
10
import { IDisposableRegistry , Resource } from '../../../common/types' ;
10
11
import { IInterpreterService } from '../../../interpreter/contracts' ;
11
12
import { IServiceContainer } from '../../../ioc/types' ;
12
- import { sendTelemetryEvent } from '../../../telemetry' ;
13
- import { EventName } from '../../../telemetry/constants' ;
14
13
import { BaseDiagnostic , BaseDiagnosticsService } from '../base' ;
15
14
import { IDiagnosticsCommandFactory } from '../commands/types' ;
16
15
import { DiagnosticCodes } from '../constants' ;
@@ -23,28 +22,44 @@ import {
23
22
IDiagnosticMessageOnCloseHandler ,
24
23
} from '../types' ;
25
24
import { Common } from '../../../common/utils/localize' ;
25
+ import { Commands } from '../../../common/constants' ;
26
+ import { IWorkspaceService } from '../../../common/application/types' ;
27
+ import { sendTelemetryEvent } from '../../../telemetry' ;
28
+ import { EventName } from '../../../telemetry/constants' ;
26
29
27
30
const localize : nls . LocalizeFunc = nls . loadMessageBundle ( ) ;
28
31
29
32
const messages = {
30
33
[ DiagnosticCodes . NoPythonInterpretersDiagnostic ] : localize (
31
34
'DiagnosticCodes.NoPythonInterpretersDiagnostic' ,
32
- 'Python is not installed . Please download and install Python before using the extension .' ,
35
+ 'No Python interpreter is selected . Please select a Python interpreter to enable features such as IntelliSense, linting, and debugging .' ,
33
36
) ,
34
- [ DiagnosticCodes . NoCurrentlySelectedPythonInterpreterDiagnostic ] : localize (
37
+ [ DiagnosticCodes . InvalidPythonInterpreterDiagnostic ] : localize (
35
38
'DiagnosticCodes.NoCurrentlySelectedPythonInterpreterDiagnostic' ,
36
- 'No Python interpreter is selected. You need to select a Python interpreter to enable features such as IntelliSense, linting, and debugging.' ,
39
+ 'An Invalid Python interpreter is selected{0}, please try changing it to enable features such as IntelliSense, linting, and debugging.' ,
37
40
) ,
38
41
} ;
39
42
40
43
export class InvalidPythonInterpreterDiagnostic extends BaseDiagnostic {
41
44
constructor (
42
- code :
43
- | DiagnosticCodes . NoPythonInterpretersDiagnostic
44
- | DiagnosticCodes . NoCurrentlySelectedPythonInterpreterDiagnostic ,
45
+ code : DiagnosticCodes . NoPythonInterpretersDiagnostic | DiagnosticCodes . InvalidPythonInterpreterDiagnostic ,
45
46
resource : Resource ,
47
+ workspaceService : IWorkspaceService ,
48
+ scope = DiagnosticScope . WorkspaceFolder ,
46
49
) {
47
- super ( code , messages [ code ] , DiagnosticSeverity . Error , DiagnosticScope . WorkspaceFolder , resource ) ;
50
+ let formatArg = '' ;
51
+ if (
52
+ workspaceService . workspaceFile &&
53
+ workspaceService . workspaceFolders &&
54
+ workspaceService . workspaceFolders ?. length > 1
55
+ ) {
56
+ // Specify folder name in case of multiroot scenarios
57
+ const folder = workspaceService . getWorkspaceFolder ( resource ) ;
58
+ if ( folder ) {
59
+ formatArg = ` ${ localize ( 'Common.forWorkspace' , 'for workspace' ) } ${ path . basename ( folder . uri . fsPath ) } ` ;
60
+ }
61
+ }
62
+ super ( code , messages [ code ] . format ( formatArg ) , DiagnosticSeverity . Error , scope , resource , undefined , 'always' ) ;
48
63
}
49
64
}
50
65
@@ -57,37 +72,51 @@ export class InvalidPythonInterpreterService extends BaseDiagnosticsService {
57
72
@inject ( IDisposableRegistry ) disposableRegistry : IDisposableRegistry ,
58
73
) {
59
74
super (
60
- [
61
- DiagnosticCodes . NoPythonInterpretersDiagnostic ,
62
- DiagnosticCodes . NoCurrentlySelectedPythonInterpreterDiagnostic ,
63
- ] ,
75
+ [ DiagnosticCodes . NoPythonInterpretersDiagnostic , DiagnosticCodes . InvalidPythonInterpreterDiagnostic ] ,
64
76
serviceContainer ,
65
77
disposableRegistry ,
66
78
false ,
67
79
) ;
68
80
}
69
81
70
82
public async diagnose ( resource : Resource ) : Promise < IDiagnostic [ ] > {
83
+ const workspaceService = this . serviceContainer . get < IWorkspaceService > ( IWorkspaceService ) ;
71
84
const interpreterService = this . serviceContainer . get < IInterpreterService > ( IInterpreterService ) ;
72
85
const hasInterpreters = await interpreterService . hasInterpreters ( ) ;
73
86
74
87
if ( ! hasInterpreters ) {
75
- return [ new InvalidPythonInterpreterDiagnostic ( DiagnosticCodes . NoPythonInterpretersDiagnostic , resource ) ] ;
88
+ return [
89
+ new InvalidPythonInterpreterDiagnostic (
90
+ DiagnosticCodes . NoPythonInterpretersDiagnostic ,
91
+ resource ,
92
+ workspaceService ,
93
+ DiagnosticScope . Global ,
94
+ ) ,
95
+ ] ;
76
96
}
77
97
78
98
const currentInterpreter = await interpreterService . getActiveInterpreter ( resource ) ;
79
99
if ( ! currentInterpreter ) {
80
100
return [
81
101
new InvalidPythonInterpreterDiagnostic (
82
- DiagnosticCodes . NoCurrentlySelectedPythonInterpreterDiagnostic ,
102
+ DiagnosticCodes . InvalidPythonInterpreterDiagnostic ,
83
103
resource ,
104
+ workspaceService ,
84
105
) ,
85
106
] ;
86
107
}
87
-
88
108
return [ ] ;
89
109
}
90
110
111
+ public async validateInterpreterPathInSettings ( resource : Resource ) : Promise < boolean > {
112
+ const diagnostics = await this . diagnose ( resource ) ;
113
+ if ( ! diagnostics . length ) {
114
+ return true ;
115
+ }
116
+ this . handle ( diagnostics ) . ignoreErrors ( ) ;
117
+ return false ;
118
+ }
119
+
91
120
protected async onHandle ( diagnostics : IDiagnostic [ ] ) : Promise < void > {
92
121
if ( diagnostics . length === 0 ) {
93
122
return ;
@@ -110,33 +139,15 @@ export class InvalidPythonInterpreterService extends BaseDiagnosticsService {
110
139
111
140
private getCommandPrompts ( diagnostic : IDiagnostic ) : { prompt : string ; command ?: IDiagnosticCommand } [ ] {
112
141
const commandFactory = this . serviceContainer . get < IDiagnosticsCommandFactory > ( IDiagnosticsCommandFactory ) ;
113
- switch ( diagnostic . code ) {
114
- case DiagnosticCodes . NoPythonInterpretersDiagnostic : {
115
- return [
116
- {
117
- prompt : Common . download ,
118
- command : commandFactory . createCommand ( diagnostic , {
119
- type : 'launch' ,
120
- options : 'https://www.python.org/downloads' ,
121
- } ) ,
122
- } ,
123
- ] ;
124
- }
125
- case DiagnosticCodes . NoCurrentlySelectedPythonInterpreterDiagnostic : {
126
- return [
127
- {
128
- prompt : Common . selectPythonInterpreter ,
129
- command : commandFactory . createCommand ( diagnostic , {
130
- type : 'executeVSCCommand' ,
131
- options : 'python.setInterpreter' ,
132
- } ) ,
133
- } ,
134
- ] ;
135
- }
136
- default : {
137
- throw new Error ( "Invalid diagnostic for 'InvalidPythonInterpreterService'" ) ;
138
- }
139
- }
142
+ return [
143
+ {
144
+ prompt : Common . selectPythonInterpreter ,
145
+ command : commandFactory . createCommand ( diagnostic , {
146
+ type : 'executeVSCCommand' ,
147
+ options : Commands . Set_Interpreter ,
148
+ } ) ,
149
+ } ,
150
+ ] ;
140
151
}
141
152
}
142
153
0 commit comments