@@ -31,6 +31,14 @@ export async function activate(context: vscode.ExtensionContext) {
3131 ) ,
3232 )
3333
34+ const tokensProvider = new TokensProvider ( context )
35+ context . subscriptions . push (
36+ vscode . workspace . registerTextDocumentContentProvider (
37+ "squawk-tokens" ,
38+ tokensProvider ,
39+ ) ,
40+ )
41+
3442 context . subscriptions . push (
3543 vscode . commands . registerCommand ( "squawk.serverVersion" , ( ) => {
3644 try {
@@ -82,9 +90,7 @@ export async function activate(context: vscode.ExtensionContext) {
8290 await startServer ( context )
8391}
8492
85- export async function deactivate ( ) {
86- await client ?. stop ( )
87- }
93+ export async function deactivate ( ) { }
8894
8995function isSqlDocument ( document : vscode . TextDocument ) : boolean {
9096 return document . languageId === "sql" || document . languageId === "postgres"
@@ -166,14 +172,17 @@ function getSquawkPath(context: vscode.ExtensionContext): vscode.Uri {
166172}
167173
168174async function startServer ( context : vscode . ExtensionContext ) {
169- if ( client ?. state === State . Running ) {
170- log . info ( "Server is already running" )
171- return
172- }
173-
174- if ( client ?. state === State . Starting ) {
175- log . info ( "Server is already starting" )
176- return
175+ const state = client ?. state
176+ switch ( state ) {
177+ case State . Running :
178+ case State . Starting :
179+ log . info ( "Server is already running" )
180+ break
181+ case State . Stopped :
182+ case undefined :
183+ break
184+ default :
185+ assertNever ( state )
177186 }
178187
179188 log . info ( "Starting Squawk Language Server..." )
@@ -212,6 +221,7 @@ async function startServer(context: vscode.ExtensionContext) {
212221 onClientStateChange . fire ( event )
213222 } ) ,
214223 )
224+ context . subscriptions . push ( client )
215225
216226 log . info ( "server starting..." )
217227 try {
@@ -315,6 +325,78 @@ class SyntaxTreeProvider implements vscode.TextDocumentContentProvider {
315325 }
316326 }
317327}
328+
329+ class TokensProvider implements vscode . TextDocumentContentProvider {
330+ _eventEmitter = new vscode . EventEmitter < vscode . Uri > ( )
331+ _activeEditor : vscode . TextEditor | undefined
332+ _uri = vscode . Uri . parse ( "squawk-tokens://tokens/tokens.rast" )
333+
334+ constructor ( context : vscode . ExtensionContext ) {
335+ context . subscriptions . push (
336+ vscode . window . onDidChangeActiveTextEditor ( ( editor ) => {
337+ this . _onDidChangeActiveTextEditor ( editor )
338+ } ) ,
339+ )
340+ context . subscriptions . push (
341+ vscode . workspace . onDidChangeTextDocument ( ( event ) => {
342+ this . _onDidChangeTextDocument ( event . document )
343+ } ) ,
344+ )
345+ context . subscriptions . push (
346+ vscode . commands . registerCommand ( "squawk.showTokens" , async ( ) => {
347+ const doc = await vscode . workspace . openTextDocument ( this . _uri )
348+ await vscode . window . showTextDocument ( doc , vscode . ViewColumn . Beside )
349+ } ) ,
350+ )
351+
352+ // initial kick off to make sure we have the editor set
353+ this . _onDidChangeActiveTextEditor ( vscode . window . activeTextEditor )
354+ }
355+
356+ onDidChange = this . _eventEmitter . event
357+
358+ _onDidChangeActiveTextEditor ( editor : vscode . TextEditor | undefined ) {
359+ if ( editor && isSqlEditor ( editor ) ) {
360+ this . _activeEditor = editor
361+ this . _eventEmitter . fire ( this . _uri )
362+ }
363+ }
364+
365+ _onDidChangeTextDocument ( document : vscode . TextDocument ) {
366+ if (
367+ isSqlDocument ( document ) &&
368+ this . _activeEditor &&
369+ document === this . _activeEditor . document
370+ ) {
371+ this . _eventEmitter . fire ( this . _uri )
372+ }
373+ }
374+
375+ async provideTextDocumentContent ( _uri : vscode . Uri ) : Promise < string > {
376+ try {
377+ const document = this . _activeEditor ?. document
378+ if ( ! document ) {
379+ return "Error: no active editor found"
380+ }
381+ if ( ! client ) {
382+ return "Error: no client found"
383+ }
384+ const text = document . getText ( )
385+ const uri = document . uri . toString ( )
386+ log . info ( `Requesting tokens for: ${ uri } ` )
387+ const response = await client . sendRequest < string > ( "squawk/tokens" , {
388+ textDocument : { uri } ,
389+ text,
390+ } )
391+ log . info ( "Tokens received" )
392+ return response
393+ } catch ( error ) {
394+ log . error ( `Failed to get tokens:` , error )
395+ return `Error: Failed to get tokens: ${ String ( error ) } `
396+ }
397+ }
398+ }
399+
318400function assertNever ( param : never ) : never {
319401 throw new Error ( `should never get here, but got ${ String ( param ) } ` )
320402}
0 commit comments