@@ -2,7 +2,7 @@ import * as net from "net";
2
2
import * as path from "path" ;
3
3
import * as vscode from "vscode" ;
4
4
import { LanguageClient , LanguageClientOptions , ServerOptions } from "vscode-languageclient/node" ;
5
- import { sleep } from "./utils" ;
5
+ import { sleep , Mutex } from "./utils" ;
6
6
7
7
const LANGUAGE_SERVER_DEFAULT_TCP_PORT = 6610 ;
8
8
const LANGUAGE_SERVER_DEFAULT_HOST = "127.0.0.1" ;
@@ -40,8 +40,21 @@ function getPythonCommand(folder: vscode.WorkspaceFolder | undefined): string |
40
40
return result ;
41
41
}
42
42
43
+ let clientsMutex = new Mutex ( ) ;
43
44
let clients : Map < string , LanguageClient > = new Map ( ) ;
44
45
46
+ async function pythonExcetionDidChangeExecutionDetails ( uri : vscode . Uri | undefined ) {
47
+ if ( uri && clients . has ( uri . toString ( ) ) ) {
48
+ await clientsMutex . dispatch ( async ( ) => {
49
+ let client = clients . get ( uri . toString ( ) ) ;
50
+ clients . delete ( uri . toString ( ) ) ;
51
+ await client ?. stop ( ) ;
52
+ } ) ;
53
+
54
+ await getLanguageClientForResource ( uri ) ;
55
+ }
56
+ }
57
+
45
58
let _sortedWorkspaceFolders : string [ ] | undefined ;
46
59
function sortedWorkspaceFolders ( ) : string [ ] {
47
60
if ( _sortedWorkspaceFolders === undefined ) {
@@ -61,7 +74,6 @@ function sortedWorkspaceFolders(): string[] {
61
74
}
62
75
return _sortedWorkspaceFolders ;
63
76
}
64
- vscode . workspace . onDidChangeWorkspaceFolders ( ( ) => ( _sortedWorkspaceFolders = undefined ) ) ;
65
77
66
78
function getOuterMostWorkspaceFolder ( folder : vscode . WorkspaceFolder ) : vscode . WorkspaceFolder {
67
79
let sorted = sortedWorkspaceFolders ( ) ;
@@ -84,64 +96,73 @@ async function getLanguageClientForDocument(document: vscode.TextDocument): Prom
84
96
}
85
97
86
98
async function getLanguageClientForResource ( resource : string | vscode . Uri ) : Promise < LanguageClient | undefined > {
87
- let uri = resource instanceof vscode . Uri ? resource : vscode . Uri . parse ( resource ) ;
88
- let workspaceFolder = vscode . workspace . getWorkspaceFolder ( uri ) ;
99
+ let client = await clientsMutex . dispatch ( async ( ) => {
100
+ let uri = resource instanceof vscode . Uri ? resource : vscode . Uri . parse ( resource ) ;
101
+ let workspaceFolder = vscode . workspace . getWorkspaceFolder ( uri ) ;
89
102
90
- if ( ! workspaceFolder ) {
91
- return ;
92
- }
103
+ if ( ! workspaceFolder ) {
104
+ return undefined ;
105
+ }
93
106
94
- workspaceFolder = getOuterMostWorkspaceFolder ( workspaceFolder ) ;
107
+ workspaceFolder = getOuterMostWorkspaceFolder ( workspaceFolder ) ;
95
108
96
- var result = clients . get ( workspaceFolder . uri . toString ( ) ) ;
109
+ var result = clients . get ( workspaceFolder . uri . toString ( ) ) ;
97
110
98
- if ( ! result ) {
99
- let config = vscode . workspace . getConfiguration ( CONFIG_SECTION , uri ) ;
111
+ if ( ! result ) {
112
+ let config = vscode . workspace . getConfiguration ( CONFIG_SECTION , uri ) ;
100
113
101
- let mode = config . get < string > ( "languageServer.mode" , "stdio" ) ;
114
+ let mode = config . get < string > ( "languageServer.mode" , "stdio" ) ;
102
115
103
- const serverOptions : ServerOptions =
104
- mode === "tcp" ? getServerOptionsTCP ( workspaceFolder ) : getServerOptionsStdIo ( workspaceFolder ) ;
105
- let name = `RobotCode Language Server mode=${ mode } for workspace folder "${ workspaceFolder . name } "` ;
116
+ const serverOptions : ServerOptions =
117
+ mode === "tcp" ? getServerOptionsTCP ( workspaceFolder ) : getServerOptionsStdIo ( workspaceFolder ) ;
118
+ let name = `RobotCode Language Server mode=${ mode } for workspace folder "${ workspaceFolder . name } "` ;
106
119
107
- let outputChannel = mode === "stdio" ? vscode . window . createOutputChannel ( name ) : undefined ;
120
+ let outputChannel = mode === "stdio" ? vscode . window . createOutputChannel ( name ) : undefined ;
108
121
109
- let clientOptions : LanguageClientOptions = {
110
- documentSelector : [
111
- { scheme : "file" , language : "robotframework" , pattern : `${ workspaceFolder . uri . fsPath } /**/*` } ,
112
- ] ,
113
- synchronize : {
114
- configurationSection : [ CONFIG_SECTION , "python" ] ,
115
- } ,
116
- initializationOptions : {
117
- storageUri : extensionContext ?. storageUri ?. toString ( ) ,
118
- globalStorageUri : extensionContext ?. globalStorageUri ?. toString ( ) ,
119
- } ,
120
- diagnosticCollectionName : "robotcode" ,
121
- workspaceFolder : workspaceFolder ,
122
- outputChannel : outputChannel ,
123
- markdown : {
124
- isTrusted : true ,
125
- } ,
126
- progressOnInitialization : true ,
127
- } ;
122
+ let clientOptions : LanguageClientOptions = {
123
+ documentSelector : [
124
+ { scheme : "file" , language : "robotframework" , pattern : `${ workspaceFolder . uri . fsPath } /**/*` } ,
125
+ ] ,
126
+ synchronize : {
127
+ configurationSection : [ CONFIG_SECTION , "python" ] ,
128
+ } ,
129
+ initializationOptions : {
130
+ storageUri : extensionContext ?. storageUri ?. toString ( ) ,
131
+ globalStorageUri : extensionContext ?. globalStorageUri ?. toString ( ) ,
132
+ } ,
133
+ diagnosticCollectionName : "robotcode" ,
134
+ workspaceFolder : workspaceFolder ,
135
+ outputChannel : outputChannel ,
136
+ markdown : {
137
+ isTrusted : true ,
138
+ } ,
139
+ progressOnInitialization : true ,
140
+ } ;
128
141
129
- OUTPUT_CHANNEL . appendLine ( `start Language client: ${ name } ` ) ;
130
- result = new LanguageClient ( name , serverOptions , clientOptions ) ;
131
- clients . set ( workspaceFolder . uri . toString ( ) , result ) ;
142
+ OUTPUT_CHANNEL . appendLine ( `start Language client: ${ name } ` ) ;
143
+ result = new LanguageClient ( name , serverOptions , clientOptions ) ;
144
+ clients . set ( workspaceFolder . uri . toString ( ) , result ) ;
145
+ }
146
+ return result ;
147
+ } ) ;
132
148
133
- result . start ( ) ;
134
- }
149
+ if ( client ) {
150
+ if ( client . needsStart ( ) ) {
151
+ client . start ( ) ;
152
+ }
135
153
136
- var counter = 0 ;
137
- while ( ! result . initializeResult && counter < 10_000 ) {
138
- await sleep ( 100 ) ;
139
- counter ++ ;
140
- }
154
+ var counter = 0 ;
155
+ while ( ! client . initializeResult && counter < 10_000 ) {
156
+ await sleep ( 100 ) ;
157
+ counter ++ ;
158
+ }
141
159
142
- await result . onReady ( ) ;
160
+ await client . onReady ( ) . catch ( ( reason ) => {
161
+ OUTPUT_CHANNEL . appendLine ( "puhhh: " + reason ) ;
162
+ } ) ;
163
+ }
143
164
144
- return result ;
165
+ return client ;
145
166
}
146
167
147
168
function getServerOptionsTCP ( folder : vscode . WorkspaceFolder ) {
@@ -173,7 +194,7 @@ function getServerOptionsStdIo(folder: vscode.WorkspaceFolder) {
173
194
174
195
let pythonCommand = getPythonCommand ( folder ) ;
175
196
176
- if ( pythonCommand === undefined ) {
197
+ if ( ! pythonCommand ) {
177
198
throw new Error ( "Can't find a valid python executable." ) ;
178
199
}
179
200
@@ -481,6 +502,7 @@ export async function activateAsync(context: vscode.ExtensionContext) {
481
502
OUTPUT_CHANNEL . appendLine ( "Python Extension is active" ) ;
482
503
483
504
context . subscriptions . push (
505
+ pythonExtension . exports . settings . onDidChangeExecutionDetails ( pythonExcetionDidChangeExecutionDetails ) ,
484
506
vscode . commands . registerCommand ( "robotcode.runSuite" , async ( resource ) => {
485
507
return await debugSuiteOrTestcase ( resource ?? vscode . window . activeTextEditor ?. document . uri , undefined , {
486
508
noDebug : true ,
@@ -520,13 +542,17 @@ export async function activateAsync(context: vscode.ExtensionContext) {
520
542
return await debugSuiteOrTestcase ( res , realTest ) ;
521
543
}
522
544
) ,
523
- vscode . workspace . onDidChangeWorkspaceFolders ( ( event ) => {
545
+ vscode . workspace . onDidChangeWorkspaceFolders ( async ( event ) => {
524
546
for ( let folder of event . removed ) {
525
- let client = clients . get ( folder . uri . toString ( ) ) ;
526
- if ( client ) {
527
- clients . delete ( folder . uri . toString ( ) ) ;
528
- client . stop ( ) ;
529
- }
547
+ await clientsMutex . dispatch ( async ( ) => {
548
+ _sortedWorkspaceFolders = undefined ;
549
+
550
+ let client = clients . get ( folder . uri . toString ( ) ) ;
551
+ if ( client ) {
552
+ clients . delete ( folder . uri . toString ( ) ) ;
553
+ client . stop ( ) ;
554
+ }
555
+ } ) ;
530
556
}
531
557
} ) ,
532
558
vscode . debug . registerDebugConfigurationProvider ( "robotcode" , new RobotCodeDebugConfigurationProvider ( ) ) ,
@@ -603,7 +629,7 @@ export async function activateAsync(context: vscode.ExtensionContext) {
603
629
604
630
vscode . workspace . onDidChangeConfiguration ( ( event ) => {
605
631
for ( let s of [
606
- "python.pythonPath" ,
632
+ // "python.pythonPath",
607
633
"robotcode.python" ,
608
634
"robotcode.languageServer.mode" ,
609
635
"robotcode.languageServer.tcpPort" ,
@@ -669,10 +695,10 @@ export async function activateAsync(context: vscode.ExtensionContext) {
669
695
) ;
670
696
671
697
for ( let document of vscode . workspace . textDocuments ) {
672
- await getLanguageClientForDocument ( document ) ;
698
+ getLanguageClientForDocument ( document ) ;
673
699
}
674
700
675
- await updateEditorContext ( ) ;
701
+ updateEditorContext ( ) ;
676
702
}
677
703
678
704
function displayProgress ( promise : Promise < any > ) {
0 commit comments