44 * ------------------------------------------------------------------------------------------ */
55
66import * as vscode from 'vscode' ;
7- import { StaticRegistrationOptions , TextDocumentContentRefreshRequest , TextDocumentContentRequest , type ClientCapabilities , type ServerCapabilities , type TextDocumentContentParams , type TextDocumentContentRegistrationOptions } from 'vscode-languageserver-protocol' ;
7+ import { StaticRegistrationOptions , TextDocumentContentRefreshRequest , TextDocumentContentRequest , type ClientCapabilities , type RegistrationType , type ServerCapabilities , type TextDocumentContentParams , type TextDocumentContentRegistrationOptions } from 'vscode-languageserver-protocol' ;
88
9- import { WorkspaceFeature , ensure , type FeatureClient } from './features' ;
9+ import { ensure , type DynamicFeature , type FeatureClient , type FeatureState , type RegistrationData } from './features' ;
1010import * as UUID from './utils/uuid' ;
1111
1212
@@ -19,14 +19,35 @@ export interface TextDocumentContentMiddleware {
1919}
2020
2121export interface TextDocumentContentProviderShape {
22- provider : vscode . TextDocumentContentProvider ;
22+ scheme : string ;
2323 onDidChangeEmitter : vscode . EventEmitter < vscode . Uri > ;
24+ provider : vscode . TextDocumentContentProvider ;
2425}
2526
26- export class TextDocumentContentFeature extends WorkspaceFeature < TextDocumentContentRegistrationOptions , TextDocumentContentProviderShape , TextDocumentContentMiddleware > {
27+ export class TextDocumentContentFeature implements DynamicFeature < TextDocumentContentRegistrationOptions > {
28+
29+ private readonly _client : FeatureClient < TextDocumentContentMiddleware > ;
30+ private readonly _registrations : Map < string , { disposable : vscode . Disposable ; providers : TextDocumentContentProviderShape [ ] } > = new Map ( ) ;
2731
2832 constructor ( client : FeatureClient < TextDocumentContentMiddleware > ) {
29- super ( client , TextDocumentContentRequest . type ) ;
33+ this . _client = client ;
34+ }
35+
36+ public getState ( ) : FeatureState {
37+ const registrations = this . _registrations . size > 0 ;
38+ return { kind : 'workspace' , id : TextDocumentContentRequest . method , registrations } ;
39+ }
40+
41+ public get registrationType ( ) : RegistrationType < TextDocumentContentRegistrationOptions > {
42+ return TextDocumentContentRequest . type ;
43+ }
44+
45+ public getProviders ( ) : TextDocumentContentProviderShape [ ] {
46+ const result : TextDocumentContentProviderShape [ ] = [ ] ;
47+ for ( const registration of this . _registrations . values ( ) ) {
48+ result . push ( ...registration . providers ) ;
49+ }
50+ return result ;
3051 }
3152
3253 public fillClientCapabilities ( capabilities : ClientCapabilities ) : void {
@@ -38,8 +59,12 @@ export class TextDocumentContentFeature extends WorkspaceFeature<TextDocumentCon
3859 const client = this . _client ;
3960 client . onRequest ( TextDocumentContentRefreshRequest . type , async ( params ) => {
4061 const uri = client . protocol2CodeConverter . asUri ( params . uri ) ;
41- for ( const provider of this . getProviders ( ) ) {
42- provider . onDidChangeEmitter . fire ( uri ) ;
62+ for ( const registrations of this . _registrations . values ( ) ) {
63+ for ( const provider of registrations . providers ) {
64+ if ( provider . scheme !== uri . scheme ) {
65+ provider . onDidChangeEmitter . fire ( uri ) ;
66+ }
67+ }
4368 }
4469 } ) ;
4570
@@ -54,7 +79,18 @@ export class TextDocumentContentFeature extends WorkspaceFeature<TextDocumentCon
5479 } ) ;
5580 }
5681
57- protected registerLanguageProvider ( options : TextDocumentContentRegistrationOptions ) : [ vscode . Disposable , TextDocumentContentProviderShape ] {
82+ public register ( data : RegistrationData < TextDocumentContentRegistrationOptions > ) : void {
83+ const registrations : TextDocumentContentProviderShape [ ] = [ ] ;
84+ const disposables : vscode . Disposable [ ] = [ ] ;
85+ for ( const scheme of data . registerOptions . schemes ) {
86+ const [ disposable , registration ] = this . registerTextDocumentContentProvider ( scheme ) ;
87+ registrations . push ( registration ) ;
88+ disposables . push ( disposable ) ;
89+ }
90+ this . _registrations . set ( data . id , { disposable : vscode . Disposable . from ( ...disposables ) , providers : registrations } ) ;
91+ }
92+
93+ private registerTextDocumentContentProvider ( scheme : string ) : [ vscode . Disposable , TextDocumentContentProviderShape ] {
5894 const eventEmitter : vscode . EventEmitter < vscode . Uri > = new vscode . EventEmitter < vscode . Uri > ( ) ;
5995 const provider : vscode . TextDocumentContentProvider = {
6096 onDidChange : eventEmitter . event ,
@@ -79,6 +115,21 @@ export class TextDocumentContentFeature extends WorkspaceFeature<TextDocumentCon
79115 : provideTextDocumentContent ( uri , token ) ;
80116 }
81117 } ;
82- return [ vscode . workspace . registerTextDocumentContentProvider ( options . scheme , provider ) , { provider, onDidChangeEmitter : eventEmitter } ] ;
118+ return [ vscode . workspace . registerTextDocumentContentProvider ( scheme , provider ) , { scheme, onDidChangeEmitter : eventEmitter , provider } ] ;
119+ }
120+
121+ public unregister ( id : string ) : void {
122+ const registration = this . _registrations . get ( id ) ;
123+ if ( registration !== undefined ) {
124+ this . _registrations . delete ( id ) ;
125+ registration . disposable . dispose ( ) ;
126+ }
127+ }
128+
129+ public clear ( ) : void {
130+ this . _registrations . forEach ( ( registration ) => {
131+ registration . disposable . dispose ( ) ;
132+ } ) ;
133+ this . _registrations . clear ( ) ;
83134 }
84135}
0 commit comments