@@ -910,7 +910,7 @@ export class TW {
910
910
}
911
911
912
912
private lastTriggerCharacters : Set < string > | undefined
913
- private completionRegistration : Disposable | undefined
913
+ private completionRegistration : Promise < Disposable > | undefined
914
914
private async updateTriggerCharacters ( ) {
915
915
// If the client does not suppory dynamic registration of completions then
916
916
// we cannot update the set of trigger characters
@@ -941,24 +941,27 @@ export class TW {
941
941
942
942
this . lastTriggerCharacters = chars
943
943
944
- // TODO: This might technically be a race condition if:
945
- // - There are multiple workspace roots
946
- // - There are multiple projects with different separators
947
- //
948
- // Everything up to this point is synchronous including the bailout code
949
- // so it *should* be fine
944
+ let current = this . completionRegistration
945
+ this . completionRegistration = this . connection . client . register ( CompletionRequest . type , {
946
+ documentSelector : null ,
947
+ resolveProvider : true ,
948
+ triggerCharacters : Array . from ( chars ) ,
949
+ } )
950
+
951
+ // NOTE:
952
+ // This weird setup works around a race condition where multiple projects
953
+ // with different separators update their capabilities at the same time. It
954
+ // is extremely unlikely but it could cause `CompletionRequest` to be
955
+ // registered more than once with the LSP client.
950
956
//
951
- // The proper fix here is to:
957
+ // We store the promises meaning everything up to this point is synchronous
958
+ // so it should be fine but really the proper fix here is to:
952
959
// - Refactor workspace folder initialization so discovery, initialization,
953
960
// file events, config watchers, etc… are all shared.
954
961
// - Remove the need for the "restart" concept in the server for as much as
955
962
// possible. Each project should be capable of reloading its modules.
956
- this . completionRegistration ?. dispose ( )
957
- this . completionRegistration = await this . connection . client . register ( CompletionRequest . type , {
958
- documentSelector : null ,
959
- resolveProvider : true ,
960
- triggerCharacters : Array . from ( chars ) ,
961
- } )
963
+ await current ?. then ( ( r ) => r . dispose ( ) )
964
+ await this . completionRegistration
962
965
}
963
966
964
967
private getProject ( document : TextDocumentIdentifier ) : ProjectService {
@@ -1149,7 +1152,7 @@ export class TW {
1149
1152
this . commonRegistrations = undefined
1150
1153
1151
1154
this . lastTriggerCharacters . clear ( )
1152
- this . completionRegistration ?. dispose ( )
1155
+ this . completionRegistration ?. then ( ( r ) => r . dispose ( ) )
1153
1156
this . completionRegistration = undefined
1154
1157
1155
1158
this . disposables . forEach ( ( d ) => d . dispose ( ) )
0 commit comments