0
# Workspace Management
1
2
Document and workspace management with Jedi integration, configuration handling, and LSP workspace features. Provides comprehensive document lifecycle management, notebook support, and workspace-level operations like diagnostics publishing and progress reporting.
3
4
## Capabilities
5
6
### Workspace Class
7
8
Main workspace management class handling documents, configuration, and LSP workspace operations.
9
10
```python { .api }
11
class Workspace:
12
# LSP method constants
13
M_PUBLISH_DIAGNOSTICS = "textDocument/publishDiagnostics"
14
M_PROGRESS = "$/progress"
15
M_INITIALIZE_PROGRESS = "window/workDoneProgress/create"
16
M_APPLY_EDIT = "workspace/applyEdit"
17
M_SHOW_MESSAGE = "window/showMessage"
18
M_LOG_MESSAGE = "window/logMessage"
19
20
def __init__(self, root_uri, endpoint, config=None):
21
"""
22
Initialize workspace.
23
24
Parameters:
25
- root_uri: str, workspace root URI
26
- endpoint: LSP endpoint for communication
27
- config: Config instance
28
"""
29
30
@property
31
def documents(self):
32
"""
33
Get managed documents.
34
35
Returns:
36
dict: URI to Document mapping
37
"""
38
39
@property
40
def root_path(self):
41
"""
42
Get workspace root filesystem path.
43
44
Returns:
45
str: Root path
46
"""
47
48
@property
49
def root_uri(self):
50
"""
51
Get workspace root URI.
52
53
Returns:
54
str: Root URI
55
"""
56
57
def is_local(self):
58
"""
59
Check if workspace is on local filesystem.
60
61
Returns:
62
bool: True if local filesystem
63
"""
64
65
def get_document(self, doc_uri):
66
"""
67
Get or create document.
68
69
Parameters:
70
- doc_uri: str, document URI
71
72
Returns:
73
Document: Document instance
74
"""
75
76
def get_cell_document(self, doc_uri):
77
"""
78
Get cell document for notebooks.
79
80
Parameters:
81
- doc_uri: str, cell document URI
82
83
Returns:
84
Cell: Cell document instance
85
"""
86
87
def get_maybe_document(self, doc_uri):
88
"""
89
Get document if it exists.
90
91
Parameters:
92
- doc_uri: str, document URI
93
94
Returns:
95
Document or None: Document if exists
96
"""
97
98
def put_document(self, doc_uri, source, version=None):
99
"""
100
Store document.
101
102
Parameters:
103
- doc_uri: str, document URI
104
- source: str, document source code
105
- version: int, document version
106
107
Returns:
108
Document: Document instance
109
"""
110
111
def put_notebook_document(self, doc_uri, notebook_type, cells, version=None, metadata=None):
112
"""
113
Store notebook document.
114
115
Parameters:
116
- doc_uri: str, notebook URI
117
- notebook_type: str, notebook type
118
- cells: list, notebook cells
119
- version: int, notebook version
120
- metadata: dict, notebook metadata
121
122
Returns:
123
Notebook: Notebook instance
124
"""
125
126
def add_notebook_cells(self, doc_uri, cells, start):
127
"""
128
Add cells to notebook.
129
130
Parameters:
131
- doc_uri: str, notebook URI
132
- cells: list, cells to add
133
- start: int, insertion index
134
"""
135
136
def remove_notebook_cells(self, doc_uri, start, delete_count):
137
"""
138
Remove cells from notebook.
139
140
Parameters:
141
- doc_uri: str, notebook URI
142
- start: int, start index
143
- delete_count: int, number of cells to remove
144
"""
145
146
def update_notebook_metadata(self, doc_uri, metadata):
147
"""
148
Update notebook metadata.
149
150
Parameters:
151
- doc_uri: str, notebook URI
152
- metadata: dict, new metadata
153
"""
154
155
def put_cell_document(self, doc_uri, notebook_uri, language_id, source, version=None):
156
"""
157
Store cell document.
158
159
Parameters:
160
- doc_uri: str, cell URI
161
- notebook_uri: str, parent notebook URI
162
- language_id: str, cell language
163
- source: str, cell source code
164
- version: int, cell version
165
166
Returns:
167
Cell: Cell instance
168
"""
169
170
def rm_document(self, doc_uri):
171
"""
172
Remove document.
173
174
Parameters:
175
- doc_uri: str, document URI
176
"""
177
178
def update_document(self, doc_uri, change, version=None):
179
"""
180
Update document with incremental changes.
181
182
Parameters:
183
- doc_uri: str, document URI
184
- change: dict, LSP text document content change
185
- version: int, new document version
186
187
Returns:
188
Document: Updated document
189
"""
190
191
def temp_document(self, source, path=None):
192
"""
193
Create temporary document context manager.
194
195
Parameters:
196
- source: str, document source
197
- path: str, optional file path
198
199
Returns:
200
ContextManager[Document]: Temporary document
201
"""
202
203
def update_config(self, settings):
204
"""
205
Update workspace configuration.
206
207
Parameters:
208
- settings: dict, new settings
209
"""
210
211
def apply_edit(self, edit):
212
"""
213
Apply workspace edit.
214
215
Parameters:
216
- edit: dict, LSP WorkspaceEdit
217
218
Returns:
219
dict: Applied edit response
220
"""
221
222
def publish_diagnostics(self, doc_uri, diagnostics, doc_version=None):
223
"""
224
Publish diagnostics for document.
225
226
Parameters:
227
- doc_uri: str, document URI
228
- diagnostics: list, diagnostic dicts
229
- doc_version: int, document version
230
"""
231
232
def report_progress(self, title, message=None, percentage=None, skip_token_initialization=False):
233
"""
234
Report progress to client.
235
236
Parameters:
237
- title: str, progress title
238
- message: str, progress message
239
- percentage: int, completion percentage
240
- skip_token_initialization: bool, skip token creation
241
"""
242
243
def log_message(self, message, msg_type=1):
244
"""
245
Send log message to client.
246
247
Parameters:
248
- message: str, log message
249
- msg_type: int, message type (1=Error, 2=Warning, 3=Info, 4=Log)
250
"""
251
252
def show_message(self, message, msg_type=3):
253
"""
254
Show message to user.
255
256
Parameters:
257
- message: str, message text
258
- msg_type: int, message type (1=Error, 2=Warning, 3=Info, 4=Log)
259
"""
260
261
def source_roots(self, document_path):
262
"""
263
Get source roots for document.
264
265
Parameters:
266
- document_path: str, document path
267
268
Returns:
269
list: Source root paths
270
"""
271
272
def close(self):
273
"""Clean up workspace resources."""
274
```
275
276
### Document Class
277
278
Represents a text document with LSP functionality and Jedi integration.
279
280
```python { .api }
281
class Document:
282
def __init__(self, uri, workspace, source=None, version=None):
283
"""
284
Initialize document.
285
286
Parameters:
287
- uri: str, document URI
288
- workspace: Workspace instance
289
- source: str, document source code
290
- version: int, document version
291
"""
292
293
@property
294
def uri(self):
295
"""
296
Get document URI.
297
298
Returns:
299
str: Document URI
300
"""
301
302
@property
303
def version(self):
304
"""
305
Get document version.
306
307
Returns:
308
int: Document version
309
"""
310
311
@property
312
def path(self):
313
"""
314
Get document filesystem path.
315
316
Returns:
317
str: Filesystem path
318
"""
319
320
@property
321
def dot_path(self):
322
"""
323
Get Python dot-notation path.
324
325
Returns:
326
str: Python module path
327
"""
328
329
@property
330
def filename(self):
331
"""
332
Get document filename.
333
334
Returns:
335
str: Base filename
336
"""
337
338
@property
339
def shared_data(self):
340
"""
341
Get shared plugin data storage.
342
343
Returns:
344
dict: Shared data dictionary
345
"""
346
347
@property
348
def source(self):
349
"""
350
Get document source code.
351
352
Returns:
353
str: Source code
354
"""
355
356
@property
357
def lines(self):
358
"""
359
Get document lines.
360
361
Returns:
362
list: Document lines
363
"""
364
365
def update_config(self, settings):
366
"""
367
Update document configuration.
368
369
Parameters:
370
- settings: dict, new settings
371
"""
372
373
def apply_change(self, change):
374
"""
375
Apply incremental change to document.
376
377
Parameters:
378
- change: dict, LSP TextDocumentContentChangeEvent
379
"""
380
381
def offset_at_position(self, position):
382
"""
383
Get byte offset for LSP position.
384
385
Parameters:
386
- position: dict, LSP position with 'line' and 'character'
387
388
Returns:
389
int: Byte offset
390
"""
391
392
def word_at_position(self, position):
393
"""
394
Get word at LSP position.
395
396
Parameters:
397
- position: dict, LSP position with 'line' and 'character'
398
399
Returns:
400
str: Word at position
401
"""
402
403
def jedi_script(self, position=None, use_document_path=False):
404
"""
405
Get Jedi Script for code intelligence.
406
407
Parameters:
408
- position: dict, LSP position
409
- use_document_path: bool, use document path for Jedi
410
411
Returns:
412
jedi.Script: Jedi script instance
413
"""
414
415
def jedi_names(self, all_scopes=False, definitions=True, references=False):
416
"""
417
Get Jedi names from document.
418
419
Parameters:
420
- all_scopes: bool, include all scopes
421
- definitions: bool, include definitions
422
- references: bool, include references
423
424
Returns:
425
list: Jedi Name objects
426
"""
427
428
def sys_path(self, environment=None):
429
"""
430
Get sys.path for document.
431
432
Parameters:
433
- environment: jedi.Environment, Jedi environment
434
435
Returns:
436
list: sys.path entries
437
"""
438
```
439
440
### Notebook Class
441
442
Represents a notebook document with multiple cells.
443
444
```python { .api }
445
class Notebook:
446
def __init__(self, uri, workspace, notebook_type, cells=None, version=None, metadata=None):
447
"""
448
Initialize notebook.
449
450
Parameters:
451
- uri: str, notebook URI
452
- workspace: Workspace instance
453
- notebook_type: str, notebook type
454
- cells: list, notebook cells
455
- version: int, notebook version
456
- metadata: dict, notebook metadata
457
"""
458
459
@property
460
def uri(self):
461
"""Get notebook URI."""
462
463
@property
464
def notebook_type(self):
465
"""Get notebook type."""
466
467
@property
468
def workspace(self):
469
"""Get parent workspace."""
470
471
@property
472
def version(self):
473
"""Get notebook version."""
474
475
@property
476
def cells(self):
477
"""Get notebook cells."""
478
479
@property
480
def metadata(self):
481
"""Get notebook metadata."""
482
483
def add_cells(self, new_cells, start):
484
"""
485
Add cells at position.
486
487
Parameters:
488
- new_cells: list, cells to add
489
- start: int, insertion position
490
"""
491
492
def remove_cells(self, start, delete_count):
493
"""
494
Remove cells.
495
496
Parameters:
497
- start: int, start position
498
- delete_count: int, number of cells to remove
499
"""
500
501
def cell_data(self):
502
"""
503
Get cell data mapping.
504
505
Returns:
506
dict: Cell URI to data mapping
507
"""
508
509
def jedi_names(self, up_to_cell_uri=None, all_scopes=False, definitions=True, references=False):
510
"""
511
Get Jedi names up to specific cell.
512
513
Parameters:
514
- up_to_cell_uri: str, stop at this cell URI
515
- all_scopes: bool, include all scopes
516
- definitions: bool, include definitions
517
- references: bool, include references
518
519
Returns:
520
list: Jedi Name objects
521
"""
522
```
523
524
### Cell Class
525
526
Represents a notebook cell as a document.
527
528
```python { .api }
529
class Cell(Document):
530
def __init__(self, uri, notebook_uri, workspace, language_id, source=None, version=None):
531
"""
532
Initialize cell.
533
534
Parameters:
535
- uri: str, cell URI
536
- notebook_uri: str, parent notebook URI
537
- workspace: Workspace instance
538
- language_id: str, cell language
539
- source: str, cell source code
540
- version: int, cell version
541
"""
542
543
@property
544
def language_id(self):
545
"""
546
Get cell language.
547
548
Returns:
549
str: Language identifier
550
"""
551
552
@property
553
def notebook_uri(self):
554
"""
555
Get parent notebook URI.
556
557
Returns:
558
str: Notebook URI
559
"""
560
561
@property
562
def line_count(self):
563
"""
564
Get number of lines in cell.
565
566
Returns:
567
int: Line count
568
"""
569
```
570
571
## Usage Examples
572
573
### Basic Workspace Operations
574
575
```python
576
from pylsp.workspace import Workspace
577
578
# Create workspace
579
workspace = Workspace("file:///path/to/project", endpoint, config)
580
581
# Add document
582
doc = workspace.put_document("file:///path/to/file.py", "print('hello')", version=1)
583
584
# Update document
585
workspace.update_document("file:///path/to/file.py", {
586
"range": {
587
"start": {"line": 0, "character": 0},
588
"end": {"line": 0, "character": 5}
589
},
590
"text": "print"
591
}, version=2)
592
593
# Get document
594
doc = workspace.get_document("file:///path/to/file.py")
595
print(doc.source) # Updated source
596
597
# Remove document
598
workspace.rm_document("file:///path/to/file.py")
599
```
600
601
### Document Intelligence with Jedi
602
603
```python
604
from pylsp.workspace import Document
605
606
# Get Jedi script for completions
607
script = document.jedi_script({"line": 0, "character": 5})
608
completions = script.complete()
609
610
# Get definitions
611
definitions = script.goto(follow_imports=True)
612
613
# Get word at position
614
word = document.word_at_position({"line": 0, "character": 5})
615
616
# Get byte offset
617
offset = document.offset_at_position({"line": 1, "character": 10})
618
```
619
620
### Notebook Support
621
622
```python
623
# Create notebook
624
notebook = workspace.put_notebook_document(
625
"file:///notebook.ipynb",
626
"jupyter-notebook",
627
[
628
{"kind": 2, "language": "python", "source": "print('hello')"},
629
{"kind": 1, "language": "markdown", "source": "# Title"}
630
],
631
version=1
632
)
633
634
# Add cells
635
notebook.add_cells([
636
{"kind": 2, "language": "python", "source": "x = 42"}
637
], start=1)
638
639
# Get cell document
640
cell_doc = workspace.get_cell_document("file:///notebook.ipynb#cell-1")
641
```
642
643
### Diagnostics and Progress
644
645
```python
646
# Publish diagnostics
647
workspace.publish_diagnostics("file:///file.py", [
648
{
649
"range": {
650
"start": {"line": 0, "character": 0},
651
"end": {"line": 0, "character": 5}
652
},
653
"message": "Syntax error",
654
"severity": 1 # Error
655
}
656
])
657
658
# Report progress
659
workspace.report_progress("Processing", "Analyzing file.py", 50)
660
661
# Show message
662
workspace.show_message("Analysis complete", msg_type=3) # Info
663
```
664
665
### Temporary Documents
666
667
```python
668
# Use temporary document for analysis
669
with workspace.temp_document("def func(): pass", "/tmp/temp.py") as temp_doc:
670
script = temp_doc.jedi_script()
671
completions = script.complete()
672
print(f"Found {len(completions)} completions")
673
# Document automatically cleaned up
674
```