Skip to content

Commit 7272eed

Browse files
committed
testing new lsp.ts
1 parent 9fc316a commit 7272eed

File tree

2 files changed

+224
-225
lines changed

2 files changed

+224
-225
lines changed

vscode/extension/src/extension.ts

Lines changed: 117 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,69 @@
1-
import { format } from './commands/format'
1+
/**********************************************************************
2+
* Extension entry point *
3+
*********************************************************************/
4+
25
import * as vscode from 'vscode'
3-
import {
4-
createOutputChannel,
5-
onDidChangeConfiguration,
6-
registerCommand,
7-
} from './utilities/common/vscodeapi'
8-
import { registerLogger, traceInfo, traceVerbose } from './utilities/common/log'
9-
import { onDidChangePythonInterpreter } from './utilities/common/python'
10-
import { LSPClient } from './lsp/lsp'
11-
import { AuthenticationProviderTobikoCloud } from './auth/auth'
6+
7+
import { format } from './commands/format'
128
import { signOut } from './commands/signout'
139
import { signIn } from './commands/signin'
1410
import { signInSpecifyFlow } from './commands/signinSpecifyFlow'
1511
import { renderModel, reRenderModelForSourceFile } from './commands/renderModel'
1612
import { stop } from './commands/stop'
1713
import { printEnvironment } from './commands/printEnvironment'
18-
import { isErr } from '@bus/result'
14+
15+
import {
16+
createOutputChannel,
17+
onDidChangeConfiguration,
18+
registerCommand,
19+
} from './utilities/common/vscodeapi'
20+
import {
21+
registerLogger,
22+
traceInfo,
23+
traceVerbose,
24+
traceError,
25+
} from './utilities/common/log'
26+
import { onDidChangePythonInterpreter } from './utilities/common/python'
27+
import { sleep } from './utilities/sleep'
1928
import { handleError } from './utilities/errors'
29+
2030
import { selector, completionProvider } from './completion/completion'
2131
import { LineagePanel } from './webviews/lineagePanel'
2232
import { RenderedModelProvider } from './providers/renderedModelProvider'
23-
import { sleep } from './utilities/sleep'
33+
2434
import {
2535
controller as testController,
2636
setupTestController,
2737
} from './tests/tests'
2838

39+
import { isErr } from '@bus/result'
40+
import { AuthenticationProviderTobikoCloud } from './auth/auth'
41+
import { LSPClient } from './lsp/lsp'
42+
43+
/* ------------------------------------------------------------------ */
44+
/* Globals */
45+
/* ------------------------------------------------------------------ */
46+
47+
/** Singleton LSP client for the extension. */
2948
let lspClient: LSPClient | undefined
3049

31-
// This method is called when your extension is activated
32-
// Your extension is activated the very first time the command is executed
50+
/** Handle to the (single) test controller disposable so we can replace it on restart. */
51+
let testControllerDisposable: vscode.Disposable | undefined
52+
53+
/* ------------------------------------------------------------------ */
54+
/* Activation */
55+
/* ------------------------------------------------------------------ */
56+
3357
export async function activate(context: vscode.ExtensionContext) {
58+
/* ---------- logging / output ---------- */
3459
const extensionOutputChannel = createOutputChannel('sqlmesh')
3560
context.subscriptions.push(
3661
extensionOutputChannel,
3762
registerLogger(extensionOutputChannel),
3863
)
3964
traceInfo('Activating SQLMesh extension')
4065

41-
traceInfo('Registering authentication provider')
66+
/* ---------- authentication provider ---------- */
4267
const authProvider = new AuthenticationProviderTobikoCloud()
4368
context.subscriptions.push(
4469
vscode.authentication.registerAuthenticationProvider(
@@ -48,33 +73,71 @@ export async function activate(context: vscode.ExtensionContext) {
4873
{ supportsMultipleAccounts: false },
4974
),
5075
)
51-
traceInfo('Authentication provider registered')
5276

77+
/* ---------- helper: (re)start the LSP ---------- */
78+
const restartLsp = async (invokedByUser = false): Promise<void> => {
79+
if (!lspClient) {
80+
lspClient = new LSPClient()
81+
}
82+
83+
traceVerbose('Restarting SQLMesh LSP client')
84+
const result = await lspClient.restart(invokedByUser)
85+
if (isErr(result)) {
86+
await handleError(
87+
authProvider,
88+
restartLsp,
89+
result.error,
90+
'LSP restart failed',
91+
)
92+
return
93+
}
94+
95+
/* push once – avoid duplicate disposables on multiple restarts */
96+
if (!context.subscriptions.includes(lspClient)) {
97+
context.subscriptions.push(lspClient)
98+
}
99+
100+
/* Replace the test controller each time we restart the client */
101+
if (testControllerDisposable) {
102+
testControllerDisposable.dispose()
103+
}
104+
testControllerDisposable = setupTestController(lspClient)
105+
context.subscriptions.push(testControllerDisposable)
106+
}
107+
108+
/* ---------- commands needing the restart helper ---------- */
53109
context.subscriptions.push(
54110
vscode.commands.registerCommand(
55111
'sqlmesh.signin',
56-
signIn(authProvider, async () => {
57-
traceInfo('Restarting LSP after sign-in')
58-
await restart()
59-
}),
112+
signIn(authProvider, () => restartLsp()),
60113
),
61-
)
62-
context.subscriptions.push(
63114
vscode.commands.registerCommand(
64115
'sqlmesh.signinSpecifyFlow',
65-
signInSpecifyFlow(authProvider, async () => {
66-
traceInfo('Restarting LSP after sign-in')
67-
await restart()
68-
}),
116+
signInSpecifyFlow(authProvider, () => restartLsp()),
69117
),
70-
)
71-
context.subscriptions.push(
72118
vscode.commands.registerCommand('sqlmesh.signout', signOut(authProvider)),
73119
)
74120

121+
/* ---------- Instantiate the LSP client (once) ---------- */
75122
lspClient = new LSPClient()
123+
const startResult = await lspClient.start()
124+
if (isErr(startResult)) {
125+
await handleError(
126+
authProvider,
127+
restartLsp,
128+
startResult.error,
129+
'Failed to start LSP',
130+
)
131+
return // abort activation – nothing else to do
132+
}
133+
134+
context.subscriptions.push(lspClient)
135+
136+
/* ---------- test controller (initial) ---------- */
137+
testControllerDisposable = setupTestController(lspClient)
138+
context.subscriptions.push(testControllerDisposable, testController)
76139

77-
// Create and register the rendered model provider
140+
/* ---------- renderedmodel provider & webview ---------- */
78141
const renderedModelProvider = new RenderedModelProvider()
79142
context.subscriptions.push(
80143
vscode.workspace.registerTextDocumentContentProvider(
@@ -91,7 +154,6 @@ export async function activate(context: vscode.ExtensionContext) {
91154
),
92155
)
93156

94-
// Register the webview
95157
const lineagePanel = new LineagePanel(context.extensionUri, lspClient)
96158
context.subscriptions.push(
97159
vscode.window.registerWebviewViewProvider(
@@ -100,11 +162,10 @@ export async function activate(context: vscode.ExtensionContext) {
100162
),
101163
)
102164

103-
// Add file save listener for auto-rerendering models
165+
/* Re‑render model automatically when its source file is saved */
104166
context.subscriptions.push(
105167
vscode.workspace.onDidSaveTextDocument(async document => {
106168
if (
107-
lspClient &&
108169
renderedModelProvider.hasRenderedModelForSource(
109170
document.uri.toString(true),
110171
)
@@ -119,73 +180,25 @@ export async function activate(context: vscode.ExtensionContext) {
119180
}),
120181
)
121182

122-
const restart = async (invokedByUser = false) => {
123-
if (lspClient) {
124-
traceVerbose('Restarting LSP client')
125-
const restartResult = await lspClient.restart(invokedByUser)
126-
if (isErr(restartResult)) {
127-
return handleError(
128-
authProvider,
129-
restart,
130-
restartResult.error,
131-
'LSP restart failed',
132-
)
133-
}
134-
context.subscriptions.push(lspClient)
135-
context.subscriptions.push(setupTestController(lspClient))
136-
} else {
137-
lspClient = new LSPClient()
138-
const result = await lspClient.start(invokedByUser)
139-
if (isErr(result)) {
140-
return handleError(
141-
authProvider,
142-
restart,
143-
result.error,
144-
'Failed to start LSP',
145-
)
146-
} else {
147-
context.subscriptions.push(lspClient)
148-
context.subscriptions.push(setupTestController(lspClient))
149-
}
150-
}
151-
}
152-
183+
/* ---------- miscellaneous commands ---------- */
153184
context.subscriptions.push(
154185
vscode.commands.registerCommand(
155186
'sqlmesh.format',
156-
format(authProvider, lspClient, restart),
187+
format(authProvider, lspClient, restartLsp),
157188
),
189+
registerCommand('sqlmesh.restart', () => restartLsp(true)),
190+
registerCommand('sqlmesh.stop', stop(lspClient)),
191+
registerCommand('sqlmesh.printEnvironment', printEnvironment()),
158192
)
159193

194+
/* ---------- configuration / environment change listeners ---------- */
160195
context.subscriptions.push(
161-
onDidChangePythonInterpreter(async () => {
162-
await restart()
163-
}),
164-
onDidChangeConfiguration(async () => {
165-
await restart()
166-
}),
167-
registerCommand(`sqlmesh.restart`, async () => {
168-
await restart(true)
169-
}),
170-
registerCommand(`sqlmesh.stop`, stop(lspClient)),
171-
registerCommand(`sqlmesh.printEnvironment`, printEnvironment()),
196+
onDidChangePythonInterpreter(() => restartLsp()),
197+
onDidChangeConfiguration(() => restartLsp()),
172198
)
173199

174-
const result = await lspClient.start()
175-
if (isErr(result)) {
176-
return handleError(
177-
authProvider,
178-
restart,
179-
result.error,
180-
'Failed to start LSP',
181-
)
182-
} else {
183-
context.subscriptions.push(lspClient)
184-
context.subscriptions.push(setupTestController(lspClient))
185-
context.subscriptions.push(testController)
186-
}
187-
188-
if (lspClient && !lspClient.hasCompletionCapability()) {
200+
/* ---------- completion provider fallback ---------- */
201+
if (!lspClient.hasCompletionCapability()) {
189202
context.subscriptions.push(
190203
vscode.languages.registerCompletionItemProvider(
191204
selector,
@@ -194,12 +207,22 @@ export async function activate(context: vscode.ExtensionContext) {
194207
)
195208
}
196209

197-
traceInfo('Extension activated')
210+
traceInfo('SQLMesh extension activated')
198211
}
199212

200-
// This method is called when your extension is deactivated
213+
/* ------------------------------------------------------------------ */
214+
/* De‑activation */
215+
/* ------------------------------------------------------------------ */
216+
201217
export async function deactivate() {
202-
if (lspClient) {
203-
await lspClient.dispose()
218+
try {
219+
if (testControllerDisposable) {
220+
testControllerDisposable.dispose()
221+
}
222+
if (lspClient) {
223+
await lspClient.dispose()
224+
}
225+
} catch (e) {
226+
traceError(`Error during deactivate: ${e}`)
204227
}
205228
}

0 commit comments

Comments
 (0)