Skip to content

Commit 9e8425d

Browse files
committed
update reference if files created, deleted, changes
1 parent 95804ee commit 9e8425d

File tree

5 files changed

+72
-15
lines changed

5 files changed

+72
-15
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ All notable changes to the "robotcode" extension will be documented in this file
44

55
## [Unreleased]
66

7-
- Optimize reference code lenses.
7+
- Optimize reference handling.
8+
- This allows updating references when creating and deleting files, if necessary.
89

910
## 0.14.4
1011

robotcode/language_server/common/parts/code_lens.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from __future__ import annotations
22

3+
import asyncio
34
from asyncio import CancelledError
45
from typing import TYPE_CHECKING, Any, List, Optional
56

67
from ....jsonrpc2.protocol import rpc_method
7-
from ....utils.async_tools import async_tasking_event, threaded
8+
from ....utils.async_tools import async_tasking_event, create_sub_task, threaded
89
from ....utils.logging import LoggingDescriptor
910
from ..decorators import language_id_filter
1011
from ..has_extend_capabilities import HasExtendCapabilities
@@ -29,6 +30,7 @@ class CodeLensProtocolPart(LanguageServerProtocolPart, HasExtendCapabilities):
2930

3031
def __init__(self, parent: LanguageServerProtocol) -> None:
3132
super().__init__(parent)
33+
self.refresh_task: Optional[asyncio.Task[Any]] = None
3234

3335
@async_tasking_event
3436
async def collect(sender, document: TextDocument) -> Optional[List[CodeLens]]: # NOSONAR
@@ -86,7 +88,19 @@ async def _code_lens_resolve(self, params: CodeLens, *args: Any, **kwargs: Any)
8688

8789
return params
8890

89-
async def refresh(self) -> None:
91+
async def __do_refresh(self, now: bool = False) -> None:
92+
if not now:
93+
await asyncio.sleep(1)
94+
95+
await self.__refresh()
96+
97+
async def refresh(self, now: bool = False) -> None:
98+
if self.refresh_task is not None and not self.refresh_task.done():
99+
self.refresh_task.get_loop().call_soon_threadsafe(self.refresh_task.cancel)
100+
101+
self.refresh_task = create_sub_task(self.__do_refresh(now), loop=self.parent.diagnostics.diagnostics_loop)
102+
103+
async def __refresh(self) -> None:
90104
if not (
91105
self.parent.client_capabilities is not None
92106
and self.parent.client_capabilities.workspace is not None

robotcode/language_server/robotframework/parts/codelens.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ def __init__(self, parent: RobotLanguageServerProtocol) -> None:
3131
self._running_task: Set[Tuple[TextDocument, KeywordDoc]] = set()
3232

3333
parent.diagnostics.on_workspace_loaded.add(self.codelens_refresh)
34+
parent.robot_references.cache_cleared.add(self.codelens_refresh)
3435

36+
@language_id("robotframework")
3537
async def codelens_refresh(self, sender: Any) -> None: # NOSONAR
3638
await self.parent.code_lens.refresh()
3739

@@ -124,13 +126,6 @@ async def find_refs() -> None:
124126
if document is None or kw_doc is None:
125127
return
126128

127-
# await run_coroutine_in_thread(
128-
# self.parent.robot_references.find_keyword_references,
129-
# document,
130-
# kw_doc,
131-
# include_declaration=False,
132-
# )
133-
134129
await self.parent.robot_references.find_keyword_references(
135130
document, kw_doc, include_declaration=False
136131
)

robotcode/language_server/robotframework/parts/references.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,21 @@
1919
from ....utils.logging import LoggingDescriptor
2020
from ....utils.uri import Uri
2121
from ...common.decorators import language_id
22-
from ...common.lsp_types import Location, Position, ReferenceContext
22+
from ...common.lsp_types import (
23+
FileEvent,
24+
Location,
25+
Position,
26+
ReferenceContext,
27+
WatchKind,
28+
)
2329
from ...common.text_document import TextDocument
2430
from ..diagnostics.entities import LocalVariableDefinition, VariableDefinition
25-
from ..diagnostics.library_doc import KeywordDoc, LibraryDoc
31+
from ..diagnostics.library_doc import (
32+
RESOURCE_FILE_EXTENSION,
33+
ROBOT_FILE_EXTENSION,
34+
KeywordDoc,
35+
LibraryDoc,
36+
)
2637
from ..utils.ast_utils import (
2738
HasTokens,
2839
get_nodes_at_position,
@@ -47,18 +58,34 @@ class RobotReferencesProtocolPart(RobotLanguageServerProtocolPart, ModelHelperMi
4758
def __init__(self, parent: RobotLanguageServerProtocol) -> None:
4859
super().__init__(parent)
4960

50-
parent.references.collect.add(self.collect)
51-
parent.documents.did_change.add(self.document_did_change)
5261
self._keyword_reference_cache = AsyncSimpleLRUCache(max_items=None)
5362
self._variable_reference_cache = AsyncSimpleLRUCache(max_items=None)
5463

64+
parent.on_initialized.add(self.on_initialized)
65+
66+
parent.references.collect.add(self.collect)
67+
parent.documents.did_change.add(self.document_did_change)
68+
5569
@async_event
5670
async def cache_cleared(sender) -> None: # NOSONAR
5771
...
5872

73+
async def on_initialized(self, sender: Any) -> None:
74+
await self.parent.workspace.add_file_watcher(
75+
self.on_file_changed,
76+
f"**/*.{{{ROBOT_FILE_EXTENSION[1:]},{RESOURCE_FILE_EXTENSION[1:]}}}",
77+
WatchKind.CREATE | WatchKind.DELETE,
78+
)
79+
80+
async def on_file_changed(self, sender: Any, files: List[FileEvent]) -> None:
81+
await self.clear_cache()
82+
5983
@language_id("robotframework")
6084
@threaded()
6185
async def document_did_change(self, sender: Any, document: TextDocument) -> None:
86+
await self.clear_cache()
87+
88+
async def clear_cache(self) -> None:
6289
await self._keyword_reference_cache.clear()
6390
await self._variable_reference_cache.clear()
6491

robotcode/language_server/robotframework/parts/robot_workspace.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
from ....utils.async_tools import Event, threaded
77
from ....utils.glob_path import iter_files
88
from ....utils.logging import LoggingDescriptor
9-
from ....utils.uri import Uri
9+
from ....utils.uri import InvalidUriError, Uri
1010
from ...common.decorators import language_id
11+
from ...common.lsp_types import FileChangeType, FileEvent, WatchKind
1112
from ...common.parts.diagnostics import (
1213
AnalysisProgressMode,
1314
DiagnosticsMode,
@@ -35,8 +36,27 @@ def __init__(self, parent: RobotLanguageServerProtocol) -> None:
3536
self.parent.diagnostics.load_workspace_documents.add(self._load_workspace_documents)
3637
self.parent.diagnostics.on_get_diagnostics_mode.add(self.on_get_diagnostics_mode)
3738
self.parent.diagnostics.on_get_analysis_progress_mode.add(self.on_get_analysis_progress_mode)
39+
self.parent.on_initialized.add(self.on_initialized)
3840
self.workspace_loaded = Event()
3941

42+
async def on_initialized(self, sender: Any) -> None:
43+
await self.parent.workspace.add_file_watcher(
44+
self.on_file_changed, f"**/*.{{{ROBOT_FILE_EXTENSION[1:]},{RESOURCE_FILE_EXTENSION[1:]}}}", WatchKind.CREATE
45+
)
46+
47+
async def on_file_changed(self, sender: Any, files: List[FileEvent]) -> None: #
48+
for fe in [f for f in files if f.type == FileChangeType.CREATED]:
49+
doc_uri = Uri(fe.uri)
50+
try:
51+
path = doc_uri.to_path()
52+
if path.suffix in [ROBOT_FILE_EXTENSION, RESOURCE_FILE_EXTENSION]:
53+
document = await self.parent.documents.get_or_open_document(path, "robotframework")
54+
if not document.opened_in_editor:
55+
await (await self.parent.documents_cache.get_namespace(document)).ensure_initialized()
56+
57+
except InvalidUriError:
58+
pass
59+
4060
@language_id("robotframework")
4161
async def _on_read_document_text(self, sender: Any, uri: Uri) -> Optional[str]:
4262
from robot.utils import FileReader

0 commit comments

Comments
 (0)