@@ -7,20 +7,32 @@ import {
7
7
RevealOutputChannelOn ,
8
8
ServerOptions ,
9
9
} from 'vscode-languageclient/node' ;
10
- import { RestartServerCommandName , StartServerCommandName , StopServerCommandName } from './commands/constants' ;
10
+ import * as constants from './commands/constants' ;
11
11
import * as DocsBrowser from './docsBrowser' ;
12
12
import { HlsError , MissingToolError , NoMatchingHls } from './errors' ;
13
13
import { findHaskellLanguageServer , HlsExecutable , IEnvVars } from './hlsBinaries' ;
14
14
import { addPathToProcessPath , comparePVP , callAsync } from './utils' ;
15
15
import { Config , initConfig , initLoggerFromConfig , logConfig } from './config' ;
16
+ import { HaskellStatusBar } from './statusBar' ;
17
+
18
+ /**
19
+ * Global information about the running clients.
20
+ */
21
+ type Client = {
22
+ client : LanguageClient ;
23
+ config : Config ;
24
+ } ;
16
25
17
26
// The current map of documents & folders to language servers.
18
27
// It may be null to indicate that we are in the process of launching a server,
19
28
// in which case don't try to launch another one for that uri
20
- const clients : Map < string , LanguageClient | null > = new Map ( ) ;
29
+ const clients : Map < string , Client | null > = new Map ( ) ;
21
30
22
31
// This is the entrypoint to our extension
23
32
export async function activate ( context : ExtensionContext ) {
33
+ const statusBar = new HaskellStatusBar ( context . extension . packageJSON . version as string | undefined ) ;
34
+ context . subscriptions . push ( statusBar ) ;
35
+
24
36
// (Possibly) launch the language server every time a document is opened, so
25
37
// it works across multiple workspace folders. Eventually, haskell-lsp should
26
38
// just support
@@ -37,41 +49,69 @@ export async function activate(context: ExtensionContext) {
37
49
const client = clients . get ( folder . uri . toString ( ) ) ;
38
50
if ( client ) {
39
51
const uri = folder . uri . toString ( ) ;
40
- client . info ( `Deleting folder for clients: ${ uri } ` ) ;
52
+ client . client . info ( `Deleting folder for clients: ${ uri } ` ) ;
41
53
clients . delete ( uri ) ;
42
- client . info ( 'Stopping the server' ) ;
43
- await client . stop ( ) ;
54
+ client . client . info ( 'Stopping the server' ) ;
55
+ await client . client . stop ( ) ;
44
56
}
45
57
}
46
58
} ) ;
47
59
48
60
// Register editor commands for HIE, but only register the commands once at activation.
49
- const restartCmd = commands . registerCommand ( RestartServerCommandName , async ( ) => {
61
+ const restartCmd = commands . registerCommand ( constants . RestartServerCommandName , async ( ) => {
50
62
for ( const langClient of clients . values ( ) ) {
51
- langClient ?. info ( 'Stopping the server' ) ;
52
- await langClient ?. stop ( ) ;
53
- langClient ?. info ( 'Starting the server' ) ;
54
- await langClient ?. start ( ) ;
63
+ langClient ?. client . info ( 'Stopping the server' ) ;
64
+ await langClient ?. client . stop ( ) ;
65
+ langClient ?. client . info ( 'Starting the server' ) ;
66
+ await langClient ?. client . start ( ) ;
55
67
}
56
68
} ) ;
57
69
58
70
context . subscriptions . push ( restartCmd ) ;
59
71
60
- const stopCmd = commands . registerCommand ( StopServerCommandName , async ( ) => {
72
+ const openLogsCmd = commands . registerCommand ( constants . OpenLogsCommandName , ( ) => {
73
+ for ( const langClient of clients . values ( ) ) {
74
+ langClient ?. config . outputChannel . show ( ) ;
75
+ }
76
+ } ) ;
77
+
78
+ context . subscriptions . push ( openLogsCmd ) ;
79
+
80
+ const restartExtensionCmd = commands . registerCommand ( constants . RestartExtensionCommandName , async ( ) => {
81
+ for ( const langClient of clients . values ( ) ) {
82
+ langClient ?. client . info ( 'Stopping the server' ) ;
83
+ await langClient ?. client . stop ( ) ;
84
+ }
85
+ clients . clear ( ) ;
86
+
87
+ for ( const document of workspace . textDocuments ) {
88
+ await activateServer ( context , document ) ;
89
+ }
90
+ } ) ;
91
+
92
+ context . subscriptions . push ( restartExtensionCmd ) ;
93
+
94
+ const showVersionsCmd = commands . registerCommand ( constants . ShowExtensionVersions , ( ) => {
95
+ void window . showInformationMessage ( `Extension Version: ${ context . extension . packageJSON . version ?? '<unknown>' } ` ) ;
96
+ } ) ;
97
+
98
+ context . subscriptions . push ( showVersionsCmd ) ;
99
+
100
+ const stopCmd = commands . registerCommand ( constants . StopServerCommandName , async ( ) => {
61
101
for ( const langClient of clients . values ( ) ) {
62
- langClient ?. info ( 'Stopping the server' ) ;
63
- await langClient ?. stop ( ) ;
64
- langClient ?. info ( 'Server stopped' ) ;
102
+ langClient ?. client . info ( 'Stopping the server' ) ;
103
+ await langClient ?. client . stop ( ) ;
104
+ langClient ?. client . info ( 'Server stopped' ) ;
65
105
}
66
106
} ) ;
67
107
68
108
context . subscriptions . push ( stopCmd ) ;
69
109
70
- const startCmd = commands . registerCommand ( StartServerCommandName , async ( ) => {
110
+ const startCmd = commands . registerCommand ( constants . StartServerCommandName , async ( ) => {
71
111
for ( const langClient of clients . values ( ) ) {
72
- langClient ?. info ( 'Starting the server' ) ;
73
- await langClient ?. start ( ) ;
74
- langClient ?. info ( 'Server started' ) ;
112
+ langClient ?. client . info ( 'Starting the server' ) ;
113
+ await langClient ?. client . start ( ) ;
114
+ langClient ?. client . info ( 'Server started' ) ;
75
115
}
76
116
} ) ;
77
117
@@ -83,6 +123,9 @@ export async function activate(context: ExtensionContext) {
83
123
84
124
const openOnHackageDisposable = DocsBrowser . registerDocsOpenOnHackage ( ) ;
85
125
context . subscriptions . push ( openOnHackageDisposable ) ;
126
+
127
+ statusBar . refresh ( ) ;
128
+ statusBar . show ( ) ;
86
129
}
87
130
88
131
async function activateServer ( context : ExtensionContext , document : TextDocument ) {
@@ -178,7 +221,7 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
178
221
logger . info ( `Support for '.cabal' files: ${ cabalFileSupport } ` ) ;
179
222
180
223
switch ( cabalFileSupport ) {
181
- case 'automatic' :
224
+ case 'automatic' : {
182
225
const hlsVersion = await callAsync (
183
226
hlsExecutable . location ,
184
227
[ '--numeric-version' ] ,
@@ -193,6 +236,7 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
193
236
documentSelector . push ( cabalDocumentSelector ) ;
194
237
}
195
238
break ;
239
+ }
196
240
case 'enable' :
197
241
documentSelector . push ( cabalDocumentSelector ) ;
198
242
break ;
@@ -230,7 +274,10 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
230
274
231
275
// Finally start the client and add it to the list of clients.
232
276
logger . info ( 'Starting language server' ) ;
233
- clients . set ( clientsKey , langClient ) ;
277
+ clients . set ( clientsKey , {
278
+ client : langClient ,
279
+ config,
280
+ } ) ;
234
281
await langClient . start ( ) ;
235
282
}
236
283
@@ -290,7 +337,7 @@ export async function deactivate() {
290
337
const promises : Thenable < void > [ ] = [ ] ;
291
338
for ( const client of clients . values ( ) ) {
292
339
if ( client ) {
293
- promises . push ( client . stop ( ) ) ;
340
+ promises . push ( client . client . stop ( ) ) ;
294
341
}
295
342
}
296
343
await Promise . all ( promises ) ;
0 commit comments