@@ -36,14 +36,20 @@ import {
3636} from 'aws-core-vscode/shared'
3737import { activate } from './chat/activation'
3838import { AmazonQResourcePaths } from './lspInstaller'
39+ import { LspClient } from 'aws-core-vscode/amazonq'
3940
4041const localize = nls . loadMessageBundle ( )
4142const logger = getLogger ( 'amazonqLsp.lspClient' )
4243
4344export async function startLanguageServer (
4445 extensionContext : vscode . ExtensionContext ,
4546 resourcePaths : AmazonQResourcePaths
46- ) {
47+ ) : Promise < LanguageClient > {
48+ if ( LspClient . instance . client ) {
49+ logger . info ( 'Language server already running, skipping initialization' )
50+ return LspClient . instance . client
51+ }
52+
4753 const toDispose = extensionContext . subscriptions
4854
4955 const serverModule = resourcePaths . lsp
@@ -156,129 +162,131 @@ export async function startLanguageServer(
156162 } ) ,
157163 }
158164
159- const client = new LanguageClient (
165+ LspClient . instance . client = new LanguageClient (
160166 clientId ,
161167 localize ( 'amazonq.server.name' , 'Amazon Q Language Server' ) ,
162168 serverOptions ,
163169 clientOptions
164170 )
171+ const client = LspClient . instance . client
165172
166173 const disposable = client . start ( )
167174 toDispose . push ( disposable )
168175
169176 const auth = new AmazonQLspAuth ( client )
170177
171- return client . onReady ( ) . then ( async ( ) => {
172- await auth . refreshConnection ( )
178+ await client . onReady ( )
179+ await auth . refreshConnection ( )
173180
174- if ( Experiments . instance . get ( 'amazonqLSPInline' , false ) ) {
175- const inlineManager = new InlineCompletionManager ( client )
176- inlineManager . registerInlineCompletion ( )
177- toDispose . push (
178- inlineManager ,
179- Commands . register ( { id : 'aws.amazonq.invokeInlineCompletion' , autoconnect : true } , async ( ) => {
180- await vscode . commands . executeCommand ( 'editor.action.inlineSuggest.trigger' )
181- } ) ,
182- vscode . workspace . onDidCloseTextDocument ( async ( ) => {
183- await vscode . commands . executeCommand ( 'aws.amazonq.rejectCodeSuggestion' )
184- } )
185- )
186- }
181+ if ( Experiments . instance . get ( 'amazonqLSPInline' , false ) ) {
182+ const inlineManager = new InlineCompletionManager ( client )
183+ inlineManager . registerInlineCompletion ( )
184+ toDispose . push (
185+ inlineManager ,
186+ Commands . register ( { id : 'aws.amazonq.invokeInlineCompletion' , autoconnect : true } , async ( ) => {
187+ await vscode . commands . executeCommand ( 'editor.action.inlineSuggest.trigger' )
188+ } ) ,
189+ vscode . workspace . onDidCloseTextDocument ( async ( ) => {
190+ await vscode . commands . executeCommand ( 'aws.amazonq.rejectCodeSuggestion' )
191+ } )
192+ )
193+ }
187194
188- if ( Experiments . instance . get ( 'amazonqChatLSP' , true ) ) {
189- await activate ( client , encryptionKey , resourcePaths . ui )
190- }
195+ if ( Experiments . instance . get ( 'amazonqChatLSP' , true ) ) {
196+ await activate ( client , encryptionKey , resourcePaths . ui )
197+ }
191198
192- const refreshInterval = auth . startTokenRefreshInterval ( 10 * oneSecond )
199+ const refreshInterval = auth . startTokenRefreshInterval ( 10 * oneSecond )
193200
194- const sendProfileToLsp = async ( ) => {
195- try {
196- const result = await client . sendRequest ( updateConfigurationRequestType . method , {
197- section : 'aws.q' ,
198- settings : {
199- profileArn : AuthUtil . instance . regionProfileManager . activeRegionProfile ?. arn ,
200- } ,
201- } )
202- client . info (
203- `Client: Updated Amazon Q Profile ${ AuthUtil . instance . regionProfileManager . activeRegionProfile ?. arn } to Amazon Q LSP` ,
204- result
205- )
206- } catch ( err ) {
207- client . error ( 'Error when setting Q Developer Profile to Amazon Q LSP' , err )
208- }
201+ const sendProfileToLsp = async ( ) => {
202+ try {
203+ const result = await client . sendRequest ( updateConfigurationRequestType . method , {
204+ section : 'aws.q' ,
205+ settings : {
206+ profileArn : AuthUtil . instance . regionProfileManager . activeRegionProfile ?. arn ,
207+ } ,
208+ } )
209+ client . info (
210+ `Client: Updated Amazon Q Profile ${ AuthUtil . instance . regionProfileManager . activeRegionProfile ?. arn } to Amazon Q LSP` ,
211+ result
212+ )
213+ } catch ( err ) {
214+ client . error ( 'Error when setting Q Developer Profile to Amazon Q LSP' , err )
209215 }
216+ }
210217
211- // send profile to lsp once.
212- void sendProfileToLsp ( )
218+ // send profile to lsp once.
219+ void sendProfileToLsp ( )
213220
214- toDispose . push (
215- AuthUtil . instance . auth . onDidChangeActiveConnection ( async ( ) => {
216- await auth . refreshConnection ( )
217- } ) ,
218- AuthUtil . instance . auth . onDidDeleteConnection ( async ( ) => {
219- client . sendNotification ( notificationTypes . deleteBearerToken . method )
220- } ) ,
221- AuthUtil . instance . regionProfileManager . onDidChangeRegionProfile ( sendProfileToLsp ) ,
222- vscode . commands . registerCommand ( 'aws.amazonq.getWorkspaceId' , async ( ) => {
223- const requestType = new RequestType < GetConfigurationFromServerParams , ResponseMessage , Error > (
224- 'aws/getConfigurationFromServer'
225- )
226- const workspaceIdResp = await client . sendRequest ( requestType . method , {
227- section : 'aws.q.workspaceContext' ,
228- } )
229- return workspaceIdResp
230- } ) ,
231- vscode . workspace . onDidCreateFiles ( ( e ) => {
232- client . sendNotification ( 'workspace/didCreateFiles' , {
233- files : e . files . map ( ( it ) => {
234- return { uri : it . fsPath }
235- } ) ,
236- } as CreateFilesParams )
237- } ) ,
238- vscode . workspace . onDidDeleteFiles ( ( e ) => {
239- client . sendNotification ( 'workspace/didDeleteFiles' , {
240- files : e . files . map ( ( it ) => {
241- return { uri : it . fsPath }
221+ toDispose . push (
222+ AuthUtil . instance . auth . onDidChangeActiveConnection ( async ( ) => {
223+ await auth . refreshConnection ( )
224+ } ) ,
225+ AuthUtil . instance . auth . onDidDeleteConnection ( async ( ) => {
226+ client . sendNotification ( notificationTypes . deleteBearerToken . method )
227+ } ) ,
228+ AuthUtil . instance . regionProfileManager . onDidChangeRegionProfile ( sendProfileToLsp ) ,
229+ vscode . commands . registerCommand ( 'aws.amazonq.getWorkspaceId' , async ( ) => {
230+ const requestType = new RequestType < GetConfigurationFromServerParams , ResponseMessage , Error > (
231+ 'aws/getConfigurationFromServer'
232+ )
233+ const workspaceIdResp = await client . sendRequest ( requestType . method , {
234+ section : 'aws.q.workspaceContext' ,
235+ } )
236+ return workspaceIdResp
237+ } ) ,
238+ vscode . workspace . onDidCreateFiles ( ( e ) => {
239+ client . sendNotification ( 'workspace/didCreateFiles' , {
240+ files : e . files . map ( ( it ) => {
241+ return { uri : it . fsPath }
242+ } ) ,
243+ } as CreateFilesParams )
244+ } ) ,
245+ vscode . workspace . onDidDeleteFiles ( ( e ) => {
246+ client . sendNotification ( 'workspace/didDeleteFiles' , {
247+ files : e . files . map ( ( it ) => {
248+ return { uri : it . fsPath }
249+ } ) ,
250+ } as DeleteFilesParams )
251+ } ) ,
252+ vscode . workspace . onDidRenameFiles ( ( e ) => {
253+ client . sendNotification ( 'workspace/didRenameFiles' , {
254+ files : e . files . map ( ( it ) => {
255+ return { oldUri : it . oldUri . fsPath , newUri : it . newUri . fsPath }
256+ } ) ,
257+ } as RenameFilesParams )
258+ } ) ,
259+ vscode . workspace . onDidSaveTextDocument ( ( e ) => {
260+ client . sendNotification ( 'workspace/didSaveTextDocument' , {
261+ textDocument : {
262+ uri : e . uri . fsPath ,
263+ } ,
264+ } as DidSaveTextDocumentParams )
265+ } ) ,
266+ vscode . workspace . onDidChangeWorkspaceFolders ( ( e ) => {
267+ client . sendNotification ( 'workspace/didChangeWorkspaceFolder' , {
268+ event : {
269+ added : e . added . map ( ( it ) => {
270+ return {
271+ name : it . name ,
272+ uri : it . uri . fsPath ,
273+ } as WorkspaceFolder
242274 } ) ,
243- } as DeleteFilesParams )
244- } ) ,
245- vscode . workspace . onDidRenameFiles ( ( e ) => {
246- client . sendNotification ( 'workspace/didRenameFiles' , {
247- files : e . files . map ( ( it ) => {
248- return { oldUri : it . oldUri . fsPath , newUri : it . newUri . fsPath }
275+ removed : e . removed . map ( ( it ) => {
276+ return {
277+ name : it . name ,
278+ uri : it . uri . fsPath ,
279+ } as WorkspaceFolder
249280 } ) ,
250- } as RenameFilesParams )
251- } ) ,
252- vscode . workspace . onDidSaveTextDocument ( ( e ) => {
253- client . sendNotification ( 'workspace/didSaveTextDocument' , {
254- textDocument : {
255- uri : e . uri . fsPath ,
256- } ,
257- } as DidSaveTextDocumentParams )
258- } ) ,
259- vscode . workspace . onDidChangeWorkspaceFolders ( ( e ) => {
260- client . sendNotification ( 'workspace/didChangeWorkspaceFolder' , {
261- event : {
262- added : e . added . map ( ( it ) => {
263- return {
264- name : it . name ,
265- uri : it . uri . fsPath ,
266- } as WorkspaceFolder
267- } ) ,
268- removed : e . removed . map ( ( it ) => {
269- return {
270- name : it . name ,
271- uri : it . uri . fsPath ,
272- } as WorkspaceFolder
273- } ) ,
274- } ,
275- } as DidChangeWorkspaceFoldersParams )
276- } ) ,
277- { dispose : ( ) => clearInterval ( refreshInterval ) } ,
278- // Set this inside onReady so that it only triggers on subsequent language server starts (not the first)
279- onServerRestartHandler ( client , auth )
280- )
281- } )
281+ } ,
282+ } as DidChangeWorkspaceFoldersParams )
283+ } ) ,
284+ { dispose : ( ) => clearInterval ( refreshInterval ) } ,
285+ // Set this inside onReady so that it only triggers on subsequent language server starts (not the first)
286+ onServerRestartHandler ( client , auth )
287+ )
288+
289+ return client
282290}
283291
284292/**
0 commit comments