Skip to content

Commit c60499d

Browse files
committed
more feedback
1 parent 4b93ab2 commit c60499d

File tree

4 files changed

+53
-43
lines changed

4 files changed

+53
-43
lines changed

LSP.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ This separation means language experts can focus on building great language serv
2828

2929
The LSP architecture has three main components:
3030

31-
```
31+
```text
3232
┌─────────────────┐ JSON-RPC ┌─────────────────┐
3333
│ │ ◄──────────────────────► │ │
3434
│ Editor/IDE │ (WebSocket/stdio) │ Language Server │
@@ -82,7 +82,7 @@ The LSP servers run as background processes—you don't need to start them manua
8282

8383
The LSP server is a **separate process** that runs alongside your notebook environment:
8484

85-
```
85+
```text
8686
┌──────────────────────────────────────────────┐
8787
│ Deepnote Toolkit Environment │
8888
│ │
@@ -118,19 +118,19 @@ This separation is crucial because:
118118

119119
The LSP server provides IDE-quality features that traditional notebooks lack:
120120

121-
**Real-Time Analysis**
121+
#### Real-Time Analysis
122122

123123
- Parses your code without executing it
124124
- Tracks imports, variable definitions, and function signatures
125125
- Provides instant feedback on syntax errors and potential issues
126126

127-
**Context-Aware Intelligence**
127+
#### Context-Aware Intelligence
128128

129129
- Understands your project structure
130130
- Knows about imported libraries and their APIs
131131
- Tracks variable types and usage patterns
132132

133-
**Multi-Language Support**
133+
#### Multi-Language Support
134134

135135
- Python blocks get Python-specific intelligence
136136
- SQL blocks get SQL-specific intelligence
@@ -140,7 +140,7 @@ The LSP server provides IDE-quality features that traditional notebooks lack:
140140

141141
Notebooks present unique challenges for LSP because they're not traditional files. Here's how Deepnote solves this:
142142

143-
**Virtual Document Model**
143+
#### Virtual Document Model
144144

145145
```python
146146
# Cell 1
@@ -166,7 +166,7 @@ This allows the language server to understand:
166166
- Variables defined in previous cells
167167
- The overall execution context of your notebook
168168

169-
**Cell Independence**
169+
#### Cell Independence
170170

171171
Unlike execution (which can happen in any order), LSP analysis respects cell order in the notebook. This means you get accurate intelligence even if you haven't executed cells yet.
172172

@@ -180,7 +180,7 @@ Deepnote maintains forks of well-established LSP servers:
180180
- Built on top of Jedi for static analysis
181181
- Supports plugins for additional features (linting, formatting)
182182

183-
**sql-language-server**
183+
#### sql-language-server
184184

185185
- Provides SQL-specific intelligence
186186
- Understands database schemas
@@ -299,7 +299,7 @@ The Deepnote VS Code extension provides seamless LSP integration for `.deepnote`
299299

300300
The extension integrates with LSP through a dedicated client manager:
301301

302-
```
302+
```text
303303
┌─────────────────────────────────────────────────────┐
304304
│ VS Code Extension │
305305
│ │
@@ -340,7 +340,7 @@ When you open a `.deepnote` file in VS Code:
340340

341341
The `DeepnoteLspClientManager` (in `src/kernels/deepnote/deepnoteLspClientManager.node.ts`) handles:
342342

343-
**Client Lifecycle**
343+
#### Client Lifecycle
344344
```typescript
345345
// When kernel starts
346346
await lspClientManager.startLspClients(
@@ -353,12 +353,12 @@ await lspClientManager.startLspClients(
353353
await lspClientManager.stopLspClients(notebookUri);
354354
```
355355

356-
**Per-Notebook Isolation**
356+
#### Per-Notebook Isolation
357357
- Each notebook gets its own LSP client instance
358358
- Clients are isolated to prevent conflicts
359359
- Automatic cleanup when notebooks close
360360

361-
**Duplicate Prevention**
361+
#### Duplicate Prevention
362362
- Prevents multiple clients for the same notebook
363363
- Reuses existing clients when possible
364364
- Graceful handling of client errors
@@ -407,25 +407,25 @@ This ensures code intelligence works in:
407407

408408
### Features Provided
409409

410-
**Real-Time Code Intelligence**
410+
#### Real-Time Code Intelligence
411411
- Autocomplete as you type in notebook cells
412412
- Hover documentation for functions and variables
413413
- Signature help for function parameters
414414
- Error detection before execution
415415

416-
**Context Awareness**
416+
#### Context Awareness
417417
- Understands imports and dependencies from the venv
418418
- Knows about variables defined in earlier cells
419419
- Provides relevant suggestions based on cell context
420420

421-
**Integration with Kernel**
421+
#### Integration with Kernel
422422
- LSP runs alongside the Deepnote kernel
423423
- Both share the same Python environment
424424
- Consistent experience between static analysis and execution
425425

426426
### Implementation Details
427427

428-
**Service Registration**
428+
#### Service Registration
429429

430430
The LSP client manager is registered as a singleton service:
431431

@@ -437,7 +437,7 @@ serviceManager.addSingleton<IDeepnoteLspClientManager>(
437437
);
438438
```
439439

440-
**Kernel Lifecycle Integration**
440+
#### Kernel Lifecycle Integration
441441

442442
The manager integrates with kernel auto-selection:
443443

@@ -452,7 +452,7 @@ await this.lspClientManager.startLspClients(
452452
);
453453
```
454454

455-
**Error Handling**
455+
#### Error Handling
456456

457457
The implementation gracefully handles:
458458
- Missing `python-lsp-server` installation
@@ -462,17 +462,17 @@ The implementation gracefully handles:
462462

463463
### User Experience
464464

465-
**Transparent Operation**
465+
#### Transparent Operation
466466
- No manual configuration required
467467
- Automatically starts with notebooks
468468
- Seamlessly integrates with VS Code features
469469

470-
**Performance**
470+
#### Performance
471471
- Lightweight per-notebook clients
472472
- Fast response times for code intelligence
473473
- Minimal impact on notebook execution
474474

475-
**Reliability**
475+
#### Reliability
476476
- Robust error handling
477477
- Automatic reconnection on failures
478478
- Clean shutdown on notebook close

cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"pids",
5757
"Pids",
5858
"plotly",
59+
"pylsp",
5960
"PYTHONHOME",
6061
"Reselecting",
6162
"scipy",

src/kernels/deepnote/deepnoteLspClientManager.node.ts

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ export class DeepnoteLspClientManager
4545
return;
4646
}
4747

48-
// Check for cancellation before starting
4948
if (token?.isCancellationRequested) {
5049
return;
5150
}
@@ -71,15 +70,16 @@ export class DeepnoteLspClientManager
7170
this.pendingStarts.set(notebookKey, true);
7271

7372
try {
74-
// Check cancellation before expensive operation
7573
if (token?.isCancellationRequested) {
7674
return;
7775
}
7876

7977
const pythonClient = await this.createPythonLspClient(notebookUri, interpreter, token);
8078

81-
// Check cancellation after client creation
8279
if (token?.isCancellationRequested) {
80+
// Clean up the client if cancellation occurred after creation
81+
await pythonClient.stop();
82+
await pythonClient.dispose();
8383
return;
8484
}
8585

@@ -115,29 +115,28 @@ export class DeepnoteLspClientManager
115115

116116
logger.info(`Stopping LSP clients for ${notebookKey}`);
117117

118-
try {
119-
if (clientInfo.pythonClient) {
120-
if (token?.isCancellationRequested) {
121-
return;
122-
}
118+
// Stop all clients without intermediate cancellation checks to ensure complete cleanup
119+
if (clientInfo.pythonClient) {
120+
try {
123121
await clientInfo.pythonClient.stop();
124122
await clientInfo.pythonClient.dispose();
123+
} catch (error) {
124+
logger.error(`Error stopping Python client for ${notebookKey}:`, error);
125125
}
126+
}
126127

127-
if (clientInfo.sqlClient) {
128-
if (token?.isCancellationRequested) {
129-
return;
130-
}
128+
if (clientInfo.sqlClient) {
129+
try {
131130
await clientInfo.sqlClient.stop();
132131
await clientInfo.sqlClient.dispose();
132+
} catch (error) {
133+
logger.error(`Error stopping SQL client for ${notebookKey}:`, error);
133134
}
135+
}
134136

135-
this.clients.delete(notebookKey);
137+
this.clients.delete(notebookKey);
136138

137-
logger.info(`LSP clients stopped for ${notebookKey}`);
138-
} catch (error) {
139-
logger.error(`Error stopping LSP clients for ${notebookKey}:`, error);
140-
}
139+
logger.info(`LSP clients stopped for ${notebookKey}`);
141140
}
142141

143142
public async stopAllClients(token?: vscode.CancellationToken): Promise<void> {
@@ -156,13 +155,23 @@ export class DeepnoteLspClientManager
156155
}
157156

158157
if (clientInfo.pythonClient) {
159-
stopPromises.push(clientInfo.pythonClient.stop().catch(noop));
160-
stopPromises.push(clientInfo.pythonClient.dispose().catch(noop));
158+
// Chain stop() and dispose() sequentially for each client
159+
stopPromises.push(
160+
clientInfo.pythonClient
161+
.stop()
162+
.catch(noop)
163+
.then(() => clientInfo.pythonClient!.dispose().catch(noop))
164+
);
161165
}
162166

163167
if (clientInfo.sqlClient) {
164-
stopPromises.push(clientInfo.sqlClient.stop().catch(noop));
165-
stopPromises.push(clientInfo.sqlClient.dispose().catch(noop));
168+
// Chain stop() and dispose() sequentially for each client
169+
stopPromises.push(
170+
clientInfo.sqlClient
171+
.stop()
172+
.catch(noop)
173+
.then(() => clientInfo.sqlClient!.dispose().catch(noop))
174+
);
166175
}
167176
}
168177

src/notebooks/deepnote/deepnoteKernelAutoSelector.node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ export class DeepnoteKernelAutoSelector implements IDeepnoteKernelAutoSelector,
576576
} as PythonEnvironment;
577577

578578
try {
579-
await this.lspClientManager.startLspClients(serverInfo, notebook.uri, lspInterpreter);
579+
await this.lspClientManager.startLspClients(serverInfo, notebook.uri, lspInterpreter, progressToken);
580580

581581
logger.info(`✓ LSP clients started for ${notebookKey}`);
582582
} catch (error) {

0 commit comments

Comments
 (0)