robotcode-language-server 2.6.2__py3-none-any.whl → 2.8.0.dev548__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. robotcode/language_server/__version__.py +1 -1
  2. robotcode/language_server/common/parts/diagnostics.py +50 -17
  3. robotcode/language_server/common/parts/documents.py +34 -31
  4. robotcode/language_server/common/parts/workspace.py +57 -55
  5. robotcode/language_server/common/protocol.py +3 -1
  6. robotcode/language_server/robotframework/configuration.py +3 -0
  7. robotcode/language_server/robotframework/parts/code_action_documentation.py +440 -129
  8. robotcode/language_server/robotframework/parts/code_action_helper_mixin.py +17 -2
  9. robotcode/language_server/robotframework/parts/code_action_quick_fixes.py +6 -25
  10. robotcode/language_server/robotframework/parts/code_action_refactor.py +8 -6
  11. robotcode/language_server/robotframework/parts/code_lens.py +3 -4
  12. robotcode/language_server/robotframework/parts/completion.py +193 -21
  13. robotcode/language_server/robotframework/parts/debugging_utils.py +75 -6
  14. robotcode/language_server/robotframework/parts/diagnostics.py +15 -3
  15. robotcode/language_server/robotframework/parts/documents_cache.py +5 -1
  16. robotcode/language_server/robotframework/parts/hover.py +103 -21
  17. robotcode/language_server/robotframework/parts/http_server.py +17 -7
  18. robotcode/language_server/robotframework/parts/inline_value.py +69 -7
  19. robotcode/language_server/robotframework/parts/keywords_treeview.py +151 -53
  20. robotcode/language_server/robotframework/parts/model_variables.py +331 -0
  21. robotcode/language_server/robotframework/parts/references.py +47 -31
  22. robotcode/language_server/robotframework/parts/rename.py +1 -2
  23. robotcode/language_server/robotframework/parts/robot_workspace.py +229 -25
  24. robotcode/language_server/robotframework/parts/selection_range.py +26 -13
  25. robotcode/language_server/robotframework/parts/semantic_tokens.py +414 -113
  26. robotcode/language_server/robotframework/parts/signature_help.py +162 -70
  27. robotcode/language_server/robotframework/protocol.py +1 -0
  28. {robotcode_language_server-2.6.2.dist-info → robotcode_language_server-2.8.0.dev548.dist-info}/METADATA +7 -6
  29. {robotcode_language_server-2.6.2.dist-info → robotcode_language_server-2.8.0.dev548.dist-info}/RECORD +31 -30
  30. {robotcode_language_server-2.6.2.dist-info → robotcode_language_server-2.8.0.dev548.dist-info}/WHEEL +1 -1
  31. {robotcode_language_server-2.6.2.dist-info → robotcode_language_server-2.8.0.dev548.dist-info}/entry_points.txt +0 -0
@@ -1 +1 @@
1
- __version__ = "2.6.2"
1
+ __version__ = "2.8.0-dev.548"
@@ -8,7 +8,7 @@ from contextlib import contextmanager
8
8
  from dataclasses import dataclass, field
9
9
  from enum import Enum
10
10
  from threading import Event, Timer
11
- from typing import TYPE_CHECKING, Any, Dict, Final, Iterator, List, Optional, Union, cast
11
+ from typing import TYPE_CHECKING, Any, Dict, Final, Iterator, List, Optional, Tuple, Union, cast
12
12
 
13
13
  from robotcode.core.concurrent import Lock, RLock, Task, check_current_task_canceled, run_as_task
14
14
  from robotcode.core.event import event
@@ -75,6 +75,8 @@ class DiagnosticsData:
75
75
  force: bool = False
76
76
  single: bool = False
77
77
  skipped_entries: bool = False
78
+ # counts every mark, also one that finds `force` already set
79
+ marks: int = 0
78
80
 
79
81
 
80
82
  class DiagnosticsCollectType(Enum):
@@ -85,6 +87,12 @@ class DiagnosticsCollectType(Enum):
85
87
  class DiagnosticsProtocolPart(LanguageServerProtocolPart):
86
88
  _logger: Final = LoggingDescriptor()
87
89
 
90
+ # Seconds of the delays that gather changes before the analysis reacts to them.
91
+ _break_diagnostics_loop_delay: float = 1
92
+ _diagnostics_loop_idle_interval: float = 1
93
+ _document_diagnostics_debounce: float = 0.75
94
+ _refresh_delay: float = 1
95
+
88
96
  def __init__(self, protocol: "LanguageServerProtocol") -> None:
89
97
  super().__init__(protocol)
90
98
 
@@ -103,8 +111,8 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
103
111
  self.parent.documents.on_document_cache_invalidated.add(self._on_document_cache_invalidated)
104
112
  self.parent.documents.did_close.add(self.on_did_close)
105
113
 
106
- self.in_get_workspace_diagnostics_event = Event()
107
- self.workspace_diagnostics_started_event = Event()
114
+ # set while no document needs an update; the loop clears it again when a pass finds work
115
+ self.workspace_analyzed_event = Event()
108
116
 
109
117
  self.client_supports_pull = False
110
118
 
@@ -238,6 +246,7 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
238
246
  needs_break = needs_break or doc.opened_in_editor
239
247
  doc.set_data(DiagnosticsProtocolPart, None)
240
248
  with self.get_diagnostics_data(doc) as data:
249
+ data.marks += 1
241
250
  if data.force:
242
251
  continue
243
252
  needs_break = True
@@ -264,12 +273,14 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
264
273
  for doc in self.parent.documents.documents:
265
274
  with self.get_diagnostics_data(doc) as data:
266
275
  data.force = True
276
+ data.marks += 1
267
277
 
268
278
  if refresh:
269
279
  self.refresh()
270
280
 
271
281
  def force_refresh_document(self, document: TextDocument, refresh: bool = True, single: bool = False) -> None:
272
282
  with self.get_diagnostics_data(document) as data:
283
+ data.marks += 1
273
284
  if data.force:
274
285
  return
275
286
  data.force = True
@@ -308,7 +319,9 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
308
319
  self.break_diagnostics_timer = None
309
320
 
310
321
  if not now:
311
- self.break_diagnostics_timer = Timer(1, self._break_workspace_diagnostics_loop)
322
+ self.break_diagnostics_timer = Timer(
323
+ self._break_diagnostics_loop_delay, self._break_workspace_diagnostics_loop
324
+ )
312
325
  self.break_diagnostics_timer.start()
313
326
  return
314
327
 
@@ -320,7 +333,7 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
320
333
  if self._current_diagnostics_task is not None and not self._current_diagnostics_task.done():
321
334
  self._current_diagnostics_task.cancel()
322
335
 
323
- def _analyse_document(self, document: TextDocument) -> List[Union[DiagnosticsResult, None, BaseException]]:
336
+ def _analyse_document(self, document: TextDocument) -> List[Union[DiagnosticsResult, BaseException, None]]:
324
337
  return self.analyze(
325
338
  self,
326
339
  document,
@@ -332,6 +345,10 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
332
345
  with self.get_diagnostics_data(document) as data:
333
346
  return data.force or document.version != data.version or data.skipped_entries
334
347
 
348
+ def _is_current_document(self, document: TextDocument) -> bool:
349
+ """Whether the documents manager still holds `document` for its URI; a document closed for good is gone."""
350
+ return self.parent.documents.get(document.uri) is document
351
+
335
352
  @_logger.call
336
353
  def run_workspace_diagnostics(self) -> None:
337
354
  self._logger.debug("start workspace diagnostics loop")
@@ -341,8 +358,6 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
341
358
  check_current_task_canceled()
342
359
 
343
360
  self.on_workspace_diagnostics_start(self)
344
- self.in_get_workspace_diagnostics_event.clear()
345
- self.workspace_diagnostics_started_event.set()
346
361
  done_something = False
347
362
 
348
363
  try:
@@ -352,11 +367,15 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
352
367
  [doc for doc in self.parent.documents.documents if self._doc_need_update(doc)],
353
368
  key=lambda d: not d.opened_in_editor,
354
369
  )
370
+ noted_marks: Dict[TextDocument, Tuple[DiagnosticsData, int]] = {}
355
371
 
356
372
  if len(documents) == 0:
357
- check_current_task_canceled(1)
373
+ self.workspace_analyzed_event.set()
374
+ check_current_task_canceled(self._diagnostics_loop_idle_interval)
358
375
  continue
359
376
 
377
+ self.workspace_analyzed_event.clear()
378
+
360
379
  with self._logger.measure_time(
361
380
  lambda: f"analyzing workspace for {len(documents)} documents",
362
381
  context_name="workspace_diagnostics",
@@ -387,6 +406,9 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
387
406
  self.on_workspace_diagnostics_break(self)
388
407
  break
389
408
 
409
+ if not self._is_current_document(document):
410
+ continue
411
+
390
412
  done_something = True
391
413
 
392
414
  analysis_mode = self.get_analysis_progress_mode(document.uri)
@@ -403,6 +425,7 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
403
425
  progress.report(f"Analyze {i + 1}/{len(documents)}", current=i + 1)
404
426
 
405
427
  try:
428
+ noted_marks[document] = self._note_marks(document)
406
429
  with self._current_diagnostics_task_lock:
407
430
  self._current_diagnostics_task = run_as_task(self._analyse_document, document)
408
431
  self._current_diagnostics_task.result(self._diagnostics_task_timeout)
@@ -453,7 +476,7 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
453
476
  self.on_workspace_diagnostics_break(self)
454
477
  break
455
478
 
456
- self.reset_document_diagnostics_data(document)
479
+ self.reset_document_diagnostics_data(document, noted_marks.get(document))
457
480
 
458
481
  with self.parent.window.progress(
459
482
  "Collect Diagnostics",
@@ -472,9 +495,12 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
472
495
  self.on_workspace_diagnostics_break(self)
473
496
  break
474
497
 
498
+ if not self._is_current_document(document):
499
+ continue
500
+
475
501
  mode = self.get_diagnostics_mode(document.uri)
476
502
  if mode == DiagnosticsMode.OFF:
477
- self.reset_document_diagnostics_data(document)
503
+ self.reset_document_diagnostics_data(document, noted_marks.get(document))
478
504
  continue
479
505
 
480
506
  done_something = True
@@ -527,16 +553,23 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
527
553
  except BaseException as e:
528
554
  self._logger.exception(e)
529
555
  finally:
530
- self.workspace_diagnostics_started_event.clear()
531
- self.in_get_workspace_diagnostics_event.set()
532
556
  self.on_workspace_diagnostics_end(self)
533
557
 
534
558
  if not done_something:
535
- check_current_task_canceled(1)
559
+ check_current_task_canceled(self._diagnostics_loop_idle_interval)
536
560
 
537
- def reset_document_diagnostics_data(self, document: TextDocument) -> None:
561
+ def _note_marks(self, document: TextDocument) -> Tuple[DiagnosticsData, int]:
562
+ """The diagnostics data of `document` and its count of marks, as the loop notes them when it analyzes it."""
563
+ with self.get_diagnostics_data(document) as data:
564
+ return data, data.marks
565
+
566
+ def reset_document_diagnostics_data(
567
+ self, document: TextDocument, noted_marks: Optional[Tuple[DiagnosticsData, int]] = None
568
+ ) -> None:
538
569
  with self.get_diagnostics_data(document) as data:
539
- data.force = False
570
+ # a mark since the analysis noted in `noted_marks` keeps the document for the next pass
571
+ if noted_marks is None or (noted_marks[0] is data and noted_marks[1] == data.marks):
572
+ data.force = False
540
573
  data.version = document.version
541
574
  data.skipped_entries = False
542
575
  data.single = False
@@ -593,7 +626,7 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
593
626
  collect_slow: bool,
594
627
  ) -> None:
595
628
  if debounce:
596
- check_current_task_canceled(0.75)
629
+ check_current_task_canceled(self._document_diagnostics_debounce)
597
630
 
598
631
  data.skipped_entries = False
599
632
  collected_keys: List[Any] = []
@@ -745,7 +778,7 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
745
778
  self.refresh_timer = None
746
779
 
747
780
  if not now:
748
- self.refresh_timer = Timer(1, self._refresh)
781
+ self.refresh_timer = Timer(self._refresh_delay, self._refresh)
749
782
  self.refresh_timer.start()
750
783
  return
751
784
 
@@ -25,7 +25,6 @@ from robotcode.core.lsp.types import (
25
25
  TextDocumentSaveReason,
26
26
  TextDocumentSyncKind,
27
27
  TextDocumentSyncOptions,
28
- TextEdit,
29
28
  VersionedTextDocumentIdentifier,
30
29
  WatchKind,
31
30
  WillSaveTextDocumentParams,
@@ -85,11 +84,8 @@ class TextDocumentProtocolPart(LanguageServerProtocolPart, DocumentsManager):
85
84
  self.close_document(document, True)
86
85
 
87
86
  elif change.type == FileChangeType.CHANGED:
88
- document.apply_full_change(
89
- None,
90
- self.read_document_text(document.uri, language_id_filter(document)),
91
- save=True,
92
- )
87
+ text, disk_info = self.read_document_text_with_disk_info(document.uri, language_id_filter(document))
88
+ document.apply_full_change(None, text, save=True, disk_info=disk_info)
93
89
  self.did_change(
94
90
  self,
95
91
  document,
@@ -142,7 +138,13 @@ class TextDocumentProtocolPart(LanguageServerProtocolPart, DocumentsManager):
142
138
  if document is not None:
143
139
  document.opened_in_editor = False
144
140
 
145
- self.close_document(document)
141
+ if document.uri.scheme == "file" and not document.uri.to_path().exists():
142
+ # deleted while it was open in the editor: handled like a deleted file, which drops the document
143
+ self.parent.workspace.did_change_watched_files(
144
+ self.parent.workspace, [FileEvent(str(document.uri), FileChangeType.DELETED)]
145
+ )
146
+ else:
147
+ self.close_document(document)
146
148
 
147
149
  @rpc_method(name="textDocument/willSave", param_type=WillSaveTextDocumentParams)
148
150
  @__logger.call
@@ -172,33 +174,34 @@ class TextDocumentProtocolPart(LanguageServerProtocolPart, DocumentsManager):
172
174
  )
173
175
 
174
176
  if document is not None:
175
- if text is not None:
176
- normalized_text = self._normalize_line_endings(text)
177
-
178
- text_changed = document.text() != normalized_text
179
- if text_changed:
180
- document.save(None, text)
181
- self.did_change(
182
- self,
183
- document,
184
- callback_filter=language_id_filter(document),
185
- )
177
+ if text is not None and document.text() != self._normalize_line_endings(text):
178
+ document.save(None, text)
179
+ self.did_change(
180
+ self,
181
+ document,
182
+ callback_filter=language_id_filter(document),
183
+ )
184
+ else:
185
+ # closing the document reverts it to the saved text
186
+ document.mark_saved()
186
187
 
187
188
  self.did_save(self, document, callback_filter=language_id_filter(document))
188
189
 
189
- @rpc_method(
190
- name="textDocument/willSaveWaitUntil",
191
- param_type=WillSaveTextDocumentParams,
192
- )
193
- @__logger.call
194
- def _text_document_will_save_wait_until(
195
- self,
196
- text_document: TextDocumentIdentifier,
197
- reason: TextDocumentSaveReason,
198
- *args: Any,
199
- **kwargs: Any,
200
- ) -> List[TextEdit]:
201
- return []
190
+ # willSaveWaitUntil stays commented out until the server returns edits for it, see the text document sync
191
+ # options of the protocol.
192
+ # @rpc_method(
193
+ # name="textDocument/willSaveWaitUntil",
194
+ # param_type=WillSaveTextDocumentParams,
195
+ # )
196
+ # @__logger.call
197
+ # def _text_document_will_save_wait_until(
198
+ # self,
199
+ # text_document: TextDocumentIdentifier,
200
+ # reason: TextDocumentSaveReason,
201
+ # *args: Any,
202
+ # **kwargs: Any,
203
+ # ) -> List[TextEdit]:
204
+ # return []
202
205
 
203
206
  @rpc_method(name="textDocument/didChange", param_type=DidChangeTextDocumentParams)
204
207
  @__logger.call
@@ -8,7 +8,6 @@ from typing import (
8
8
  Dict,
9
9
  Final,
10
10
  List,
11
- Mapping,
12
11
  Optional,
13
12
  Tuple,
14
13
  Type,
@@ -43,7 +42,6 @@ from robotcode.core.lsp.types import (
43
42
  ServerCapabilities,
44
43
  ServerCapabilitiesWorkspaceType,
45
44
  TextDocumentEdit,
46
- TextEdit,
47
45
  WatchKind,
48
46
  WorkspaceEdit,
49
47
  WorkspaceFoldersChangeEvent,
@@ -117,6 +115,8 @@ class Workspace(LanguageServerProtocolPart, CoreWorkspace, FileWatcherManagerBas
117
115
  workspace_folders=WorkspaceFoldersServerCapabilities(
118
116
  supported=True, change_notifications=str(uuid.uuid4())
119
117
  ),
118
+ # The will* operations stay unregistered until the server returns edits for them: clients wait for their
119
+ # answer before they create, rename or delete the files.
120
120
  file_operations=FileOperationOptions(
121
121
  did_create=FileOperationRegistrationOptions(
122
122
  filters=[
@@ -125,13 +125,13 @@ class Workspace(LanguageServerProtocolPart, CoreWorkspace, FileWatcherManagerBas
125
125
  )
126
126
  ]
127
127
  ),
128
- will_create=FileOperationRegistrationOptions(
129
- filters=[
130
- FileOperationFilter(
131
- pattern=FileOperationPattern(glob=f"**/*.{{{','.join(self.parent.file_extensions)}}}")
132
- )
133
- ]
134
- ),
128
+ # will_create=FileOperationRegistrationOptions(
129
+ # filters=[
130
+ # FileOperationFilter(
131
+ # pattern=FileOperationPattern(glob=f"**/*.{{{','.join(self.parent.file_extensions)}}}")
132
+ # )
133
+ # ]
134
+ # ),
135
135
  did_rename=FileOperationRegistrationOptions(
136
136
  filters=[
137
137
  FileOperationFilter(
@@ -139,13 +139,13 @@ class Workspace(LanguageServerProtocolPart, CoreWorkspace, FileWatcherManagerBas
139
139
  )
140
140
  ]
141
141
  ),
142
- will_rename=FileOperationRegistrationOptions(
143
- filters=[
144
- FileOperationFilter(
145
- pattern=FileOperationPattern(glob=f"**/*.{{{','.join(self.parent.file_extensions)}}}")
146
- )
147
- ]
148
- ),
142
+ # will_rename=FileOperationRegistrationOptions(
143
+ # filters=[
144
+ # FileOperationFilter(
145
+ # pattern=FileOperationPattern(glob=f"**/*.{{{','.join(self.parent.file_extensions)}}}")
146
+ # )
147
+ # ]
148
+ # ),
149
149
  did_delete=FileOperationRegistrationOptions(
150
150
  filters=[
151
151
  FileOperationFilter(
@@ -153,13 +153,13 @@ class Workspace(LanguageServerProtocolPart, CoreWorkspace, FileWatcherManagerBas
153
153
  )
154
154
  ]
155
155
  ),
156
- will_delete=FileOperationRegistrationOptions(
157
- filters=[
158
- FileOperationFilter(
159
- pattern=FileOperationPattern(glob=f"**/*.{{{','.join(self.parent.file_extensions)}}}")
160
- )
161
- ]
162
- ),
156
+ # will_delete=FileOperationRegistrationOptions(
157
+ # filters=[
158
+ # FileOperationFilter(
159
+ # pattern=FileOperationPattern(glob=f"**/*.{{{','.join(self.parent.file_extensions)}}}")
160
+ # )
161
+ # ]
162
+ # ),
163
163
  ),
164
164
  )
165
165
 
@@ -180,60 +180,62 @@ class Workspace(LanguageServerProtocolPart, CoreWorkspace, FileWatcherManagerBas
180
180
  self._settings_cache.clear()
181
181
  self.did_change_configuration(self, settings)
182
182
 
183
- @event
184
- def will_create_files(sender, files: List[str]) -> Optional[Mapping[str, List[TextEdit]]]: ...
183
+ # The will* events and their handlers stay commented out until the server returns edits for them, see
184
+ # extend_capabilities.
185
+ # @event
186
+ # def will_create_files(sender, files: List[str]) -> Optional[Mapping[str, List[TextEdit]]]: ...
185
187
 
186
188
  @event
187
189
  def did_create_files(sender, files: List[str]) -> None: ...
188
190
 
189
- @event
190
- def will_rename_files(sender, files: List[Tuple[str, str]]) -> None: ...
191
+ # @event
192
+ # def will_rename_files(sender, files: List[Tuple[str, str]]) -> None: ...
191
193
 
192
194
  @event
193
195
  def did_rename_files(sender, files: List[Tuple[str, str]]) -> None: ...
194
196
 
195
- @event
196
- def will_delete_files(sender, files: List[str]) -> None: ...
197
+ # @event
198
+ # def will_delete_files(sender, files: List[str]) -> None: ...
197
199
 
198
200
  @event
199
201
  def did_delete_files(sender, files: List[str]) -> None: ...
200
202
 
201
- @rpc_method(name="workspace/willCreateFiles", param_type=CreateFilesParams, threaded=True)
202
- def _workspace_will_create_files(
203
- self, files: List[FileCreate], *args: Any, **kwargs: Any
204
- ) -> Optional[WorkspaceEdit]:
205
- results = self.will_create_files(self, [f.uri for f in files])
206
- if len(results) == 0:
207
- return None
208
-
209
- result: Dict[str, List[TextEdit]] = {}
210
- for e in results:
211
- if e is not None and isinstance(e, Mapping):
212
- result.update(e)
213
-
214
- # TODO: support full WorkspaceEdit
215
-
216
- return WorkspaceEdit(changes=result)
203
+ # @rpc_method(name="workspace/willCreateFiles", param_type=CreateFilesParams, threaded=True)
204
+ # def _workspace_will_create_files(
205
+ # self, files: List[FileCreate], *args: Any, **kwargs: Any
206
+ # ) -> Optional[WorkspaceEdit]:
207
+ # results = self.will_create_files(self, [f.uri for f in files])
208
+ # if len(results) == 0:
209
+ # return None
210
+ #
211
+ # result: Dict[str, List[TextEdit]] = {}
212
+ # for e in results:
213
+ # if e is not None and isinstance(e, Mapping):
214
+ # result.update(e)
215
+ #
216
+ # # TODO: support full WorkspaceEdit
217
+ #
218
+ # return WorkspaceEdit(changes=result)
217
219
 
218
220
  @rpc_method(name="workspace/didCreateFiles", param_type=CreateFilesParams, threaded=True)
219
221
  def _workspace_did_create_files(self, files: List[FileCreate], *args: Any, **kwargs: Any) -> None:
220
222
  self.did_create_files(self, [f.uri for f in files])
221
223
 
222
- @rpc_method(name="workspace/willRenameFiles", param_type=RenameFilesParams, threaded=True)
223
- def _workspace_will_rename_files(self, files: List[FileRename], *args: Any, **kwargs: Any) -> None:
224
- self.will_rename_files(self, [(f.old_uri, f.new_uri) for f in files])
225
-
226
- # TODO: return WorkspaceEdit
224
+ # @rpc_method(name="workspace/willRenameFiles", param_type=RenameFilesParams, threaded=True)
225
+ # def _workspace_will_rename_files(self, files: List[FileRename], *args: Any, **kwargs: Any) -> None:
226
+ # self.will_rename_files(self, [(f.old_uri, f.new_uri) for f in files])
227
+ #
228
+ # # TODO: return WorkspaceEdit
227
229
 
228
230
  @rpc_method(name="workspace/didRenameFiles", param_type=RenameFilesParams, threaded=True)
229
231
  def _workspace_did_rename_files(self, files: List[FileRename], *args: Any, **kwargs: Any) -> None:
230
232
  self.did_rename_files(self, [(f.old_uri, f.new_uri) for f in files])
231
233
 
232
- @rpc_method(name="workspace/willDeleteFiles", param_type=DeleteFilesParams, threaded=True)
233
- def _workspace_will_delete_files(self, files: List[FileDelete], *args: Any, **kwargs: Any) -> None:
234
- self.will_delete_files(self, [f.uri for f in files])
235
-
236
- # TODO: return WorkspaceEdit
234
+ # @rpc_method(name="workspace/willDeleteFiles", param_type=DeleteFilesParams, threaded=True)
235
+ # def _workspace_will_delete_files(self, files: List[FileDelete], *args: Any, **kwargs: Any) -> None:
236
+ # self.will_delete_files(self, [f.uri for f in files])
237
+ #
238
+ # # TODO: return WorkspaceEdit
237
239
 
238
240
  @rpc_method(name="workspace/didDeleteFiles", param_type=DeleteFilesParams, threaded=True)
239
241
  def _workspace_did_delete_files(self, files: List[FileDelete], *args: Any, **kwargs: Any) -> None:
@@ -151,7 +151,9 @@ class LanguageServerProtocol(JsonRPCProtocol):
151
151
  open_close=True,
152
152
  change=TextDocumentSyncKind.INCREMENTAL,
153
153
  will_save=True,
154
- will_save_wait_until=True,
154
+ # willSaveWaitUntil stays unregistered until the server returns edits for it: clients wait for its
155
+ # answer before they save.
156
+ # will_save_wait_until=True,
155
157
  save=SaveOptions(include_text=True),
156
158
  )
157
159
  )
@@ -25,6 +25,8 @@ class LanguageServerConfig(ConfigBase):
25
25
  class CompletionConfig(ConfigBase):
26
26
  filter_default_language: bool = False
27
27
  header_style: Optional[str] = None
28
+ hide_private_keywords: bool = True
29
+ hide_deprecated_keywords: bool = False
28
30
 
29
31
 
30
32
  @config_section("robotcode.robocop")
@@ -61,6 +63,7 @@ class AnalysisConfig(ConfigBase):
61
63
  progress_mode: AnalysisProgressMode = AnalysisProgressMode.OFF
62
64
  references_code_lens: bool = False
63
65
  find_unused_references: bool = False
66
+ file_check_interval: int = 5
64
67
  cache: CacheConfig = field(default_factory=CacheConfig)
65
68
  robot: AnalysisRobotConfig = field(default_factory=AnalysisRobotConfig)
66
69
  modifiers: AnalysisDiagnosticModifiersConfig = field(default_factory=AnalysisDiagnosticModifiersConfig)