3
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
- import * as fs from 'fs' ;
7
6
import * as nls from 'vscode-nls' ;
8
7
const localize = nls . loadMessageBundle ( ) ;
9
8
@@ -13,13 +12,17 @@ import {
13
12
DocumentSemanticTokensProvider , DocumentRangeSemanticTokensProvider , SemanticTokens , window , commands
14
13
} from 'vscode' ;
15
14
import {
16
- LanguageClient , LanguageClientOptions , ServerOptions , TransportKind , RequestType , TextDocumentPositionParams , DocumentRangeFormattingParams ,
17
- DocumentRangeFormattingRequest , ProvideCompletionItemsSignature , TextDocumentIdentifier , RequestType0 , Range as LspRange
15
+ LanguageClientOptions , RequestType , TextDocumentPositionParams , DocumentRangeFormattingParams ,
16
+ DocumentRangeFormattingRequest , ProvideCompletionItemsSignature , TextDocumentIdentifier , RequestType0 , Range as LspRange , NotificationType , CommonLanguageClient
18
17
} from 'vscode-languageclient' ;
19
18
import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared' ;
20
19
import { activateTagClosing } from './tagClosing' ;
21
- import TelemetryReporter from 'vscode-extension-telemetry' ;
22
- import { getCustomDataPathsInAllWorkspaces , getCustomDataPathsFromAllExtensions } from './customData' ;
20
+ import { RequestService } from './requests' ;
21
+ import { getCustomDataSource } from './customData' ;
22
+
23
+ namespace CustomDataChangedNotification {
24
+ export const type : NotificationType < string [ ] > = new NotificationType ( 'html/customDataChanged' ) ;
25
+ }
23
26
24
27
namespace TagCloseRequest {
25
28
export const type : RequestType < TextDocumentPositionParams , string , any , any > = new RequestType ( 'html/tag' ) ;
@@ -46,44 +49,33 @@ namespace SettingIds {
46
49
47
50
}
48
51
49
- interface IPackageInfo {
50
- name : string ;
51
- version : string ;
52
- aiKey : string ;
53
- main : string ;
52
+ export interface TelemetryReporter {
53
+ sendTelemetryEvent ( eventName : string , properties ?: {
54
+ [ key : string ] : string ;
55
+ } , measurements ?: {
56
+ [ key : string ] : number ;
57
+ } ) : void ;
54
58
}
55
59
56
- let telemetryReporter : TelemetryReporter | null ;
57
-
58
-
59
- export function activate ( context : ExtensionContext ) {
60
- let toDispose = context . subscriptions ;
60
+ export type LanguageClientConstructor = ( name : string , description : string , clientOptions : LanguageClientOptions ) => CommonLanguageClient ;
61
61
62
- let clientPackageJSON = getPackageInfo ( context ) ;
63
- telemetryReporter = new TelemetryReporter ( clientPackageJSON . name , clientPackageJSON . version , clientPackageJSON . aiKey ) ;
62
+ export interface Runtime {
63
+ TextDecoder : { new ( encoding ?: string ) : { decode ( buffer : ArrayBuffer ) : string ; } } ;
64
+ fs ?: RequestService ;
65
+ telemetry ?: TelemetryReporter ;
66
+ }
64
67
65
- const serverMain = `./server/${ clientPackageJSON . main . indexOf ( '/dist/' ) !== - 1 ? 'dist' : 'out' } /htmlServerMain` ;
66
- const serverModule = context . asAbsolutePath ( serverMain ) ;
68
+ export function startClient ( context : ExtensionContext , newLanguageClient : LanguageClientConstructor , runtime : Runtime ) {
67
69
68
- // The debug options for the server
69
- let debugOptions = { execArgv : [ '--nolazy' , '--inspect=6045' ] } ;
70
+ let toDispose = context . subscriptions ;
70
71
71
- // If the extension is launch in debug mode the debug server options are use
72
- // Otherwise the run options are used
73
- let serverOptions : ServerOptions = {
74
- run : { module : serverModule , transport : TransportKind . ipc } ,
75
- debug : { module : serverModule , transport : TransportKind . ipc , options : debugOptions }
76
- } ;
77
72
78
73
let documentSelector = [ 'html' , 'handlebars' ] ;
79
74
let embeddedLanguages = { css : true , javascript : true } ;
80
75
81
76
let rangeFormatting : Disposable | undefined = undefined ;
82
77
83
- let dataPaths = [
84
- ...getCustomDataPathsInAllWorkspaces ( workspace . workspaceFolders ) ,
85
- ...getCustomDataPathsFromAllExtensions ( )
86
- ] ;
78
+ const customDataSource = getCustomDataSource ( context . subscriptions ) ;
87
79
88
80
// Options to control the language client
89
81
let clientOptions : LanguageClientOptions = {
@@ -93,7 +85,7 @@ export function activate(context: ExtensionContext) {
93
85
} ,
94
86
initializationOptions : {
95
87
embeddedLanguages,
96
- dataPaths ,
88
+ handledSchemas : [ 'file' ] ,
97
89
provideFormatter : false , // tell the server to not provide formatting capability and ignore the `html.format.enable` setting.
98
90
} ,
99
91
middleware : {
@@ -123,12 +115,18 @@ export function activate(context: ExtensionContext) {
123
115
} ;
124
116
125
117
// Create the language client and start the client.
126
- let client = new LanguageClient ( 'html' , localize ( 'htmlserver.name' , 'HTML Language Server' ) , serverOptions , clientOptions ) ;
118
+ let client = newLanguageClient ( 'html' , localize ( 'htmlserver.name' , 'HTML Language Server' ) , clientOptions ) ;
127
119
client . registerProposedFeatures ( ) ;
128
120
129
121
let disposable = client . start ( ) ;
130
122
toDispose . push ( disposable ) ;
131
123
client . onReady ( ) . then ( ( ) => {
124
+
125
+ client . sendNotification ( CustomDataChangedNotification . type , customDataSource . uris ) ;
126
+ customDataSource . onDidChange ( ( ) => {
127
+ client . sendNotification ( CustomDataChangedNotification . type , customDataSource . uris ) ;
128
+ } ) ;
129
+
132
130
let tagRequestor = ( document : TextDocument , position : Position ) => {
133
131
let param = client . code2ProtocolConverter . asTextDocumentPositionParams ( document , position ) ;
134
132
return client . sendRequest ( TagCloseRequest . type , param ) ;
@@ -137,9 +135,7 @@ export function activate(context: ExtensionContext) {
137
135
toDispose . push ( disposable ) ;
138
136
139
137
disposable = client . onTelemetry ( e => {
140
- if ( telemetryReporter ) {
141
- telemetryReporter . sendTelemetryEvent ( e . key , e . data ) ;
142
- }
138
+ runtime . telemetry ?. sendTelemetryEvent ( e . key , e . data ) ;
143
139
} ) ;
144
140
toDispose . push ( disposable ) ;
145
141
@@ -201,7 +197,7 @@ export function activate(context: ExtensionContext) {
201
197
return client . sendRequest ( DocumentRangeFormattingRequest . type , params , token ) . then (
202
198
client . protocol2CodeConverter . asTextEdits ,
203
199
( error ) => {
204
- client . logFailedRequest ( DocumentRangeFormattingRequest . type , error ) ;
200
+ client . handleFailedRequest ( DocumentRangeFormattingRequest . type , error , [ ] ) ;
205
201
return Promise . resolve ( [ ] ) ;
206
202
}
207
203
) ;
@@ -319,17 +315,3 @@ export function activate(context: ExtensionContext) {
319
315
320
316
toDispose . push ( ) ;
321
317
}
322
-
323
- function getPackageInfo ( context : ExtensionContext ) : IPackageInfo {
324
- const location = context . asAbsolutePath ( './package.json' ) ;
325
- try {
326
- return JSON . parse ( fs . readFileSync ( location ) . toString ( ) ) ;
327
- } catch ( e ) {
328
- console . log ( `Problems reading ${ location } : ${ e } ` ) ;
329
- return { name : '' , version : '' , aiKey : '' , main : '' } ;
330
- }
331
- }
332
-
333
- export function deactivate ( ) : Promise < any > {
334
- return telemetryReporter ? telemetryReporter . dispose ( ) : Promise . resolve ( null ) ;
335
- }
0 commit comments