Skip to content

Commit 3d89dc0

Browse files
committed
implement setting for filtering default language in completion
1 parent be8b790 commit 3d89dc0

File tree

10 files changed

+142
-60
lines changed

10 files changed

+142
-60
lines changed

CHANGELOG.md

+2-1
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-
- Correct naming for setting `robotcode.syntax.sectionStyle` to `robotcode.syntax.headerStyle`
7+
- Add a the setting `robotcode.completion.filterDefaultLanguage` to filter english language in completion, if there is another language defined for workspace or in file
8+
- Correct naming for setting `robotcode.syntax.sectionStyle` to `robotcode.completion.headerStyle`
89
- Filter singular header forms for robotframework >= 6
910

1011
## 0.13.18

package.json

+13-7
Original file line numberDiff line numberDiff line change
@@ -438,12 +438,6 @@
438438
"description": "Default setting for where to launch the debug target: internal console, integrated terminal, or external terminal.",
439439
"scope": "resource"
440440
},
441-
"robotcode.syntax.headerStyle": {
442-
"type": "string",
443-
"default": null,
444-
"markdownDescription": "Defines the header style format. If not defined ```*** {name} ***``` is used.",
445-
"scope": "resource"
446-
},
447441
"robotcode.robocop.enabled": {
448442
"type": "boolean",
449443
"default": true,
@@ -552,6 +546,18 @@
552546
"type": "integer",
553547
"default": 3199,
554548
"description": "Defines the endport for searching a free port for the documentation server."
549+
},
550+
"robotcode.completion.filterDefaultLanguage": {
551+
"type": "boolean",
552+
"default": true,
553+
"markdownDescription": "Filter default language (English) for completion if there is another language defined.",
554+
"scope": "resource"
555+
},
556+
"robotcode.completion.headerStyle": {
557+
"type": "string",
558+
"default": null,
559+
"markdownDescription": "Defines the header style format. If not defined ```*** {name} ***``` is used.",
560+
"scope": "resource"
555561
}
556562
}
557563
}
@@ -943,4 +949,4 @@
943949
"webpack": "^5.74.0",
944950
"webpack-cli": "^4.10.0"
945951
}
946-
}
952+
}

robotcode/language_server/common/text_document.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,14 @@ async def get_cache(
216216

217217
reference = self.__get_cache_reference(entry)
218218

219-
with self._lock:
220-
e = self._cache[reference]
221-
222-
async with e.lock:
223-
if not e.has_data:
224-
e.data = await entry(self, *args, **kwargs)
225-
e.has_data = True
219+
# with self._lock:
220+
e = self._cache[reference]
221+
222+
if not e.has_data:
223+
async with e.lock:
224+
if not e.has_data:
225+
e.data = await entry(self, *args, **kwargs)
226+
e.has_data = True
226227

227228
return cast(_T, e.data)
228229

robotcode/language_server/robotframework/configuration.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ def get_rpa_mode(self) -> Optional[bool]:
4545
return None
4646

4747

48-
@config_section("robotcode.syntax")
48+
@config_section("robotcode.completion")
4949
@dataclass
50-
class SyntaxConfig(ConfigBase):
50+
class CompletionConfig(ConfigBase):
51+
filter_default_language: bool = True
5152
header_style: Optional[str] = None
5253

5354

@@ -94,7 +95,7 @@ class DocumentationServerConfig(ConfigBase):
9495
class RobotCodeConfig(ConfigBase):
9596
language_server: LanguageServerConfig = field(default_factory=LanguageServerConfig)
9697
robot: RobotConfig = field(default_factory=RobotConfig)
97-
syntax: SyntaxConfig = field(default_factory=SyntaxConfig)
98+
syntax: CompletionConfig = field(default_factory=CompletionConfig)
9899
workspace: WorkspaceConfig = field(default_factory=WorkspaceConfig)
99100
analysis: AnalysisConfig = field(default_factory=AnalysisConfig)
100101
documentation_server: DocumentationServerConfig = field(default_factory=DocumentationServerConfig)

robotcode/language_server/robotframework/diagnostics/namespace.py

+2
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ def __init__(
553553
document: Optional[TextDocument] = None,
554554
document_type: Optional[DocumentType] = None,
555555
languages: Optional[Languages] = None,
556+
workspace_languages: Optional[Languages] = None,
556557
) -> None:
557558
super().__init__()
558559

@@ -563,6 +564,7 @@ def __init__(
563564
self._document = weakref.ref(document) if document is not None else None
564565
self.document_type: Optional[DocumentType] = document_type
565566
self.languages = languages
567+
self.workspace_languages = workspace_languages
566568

567569
self._libraries: OrderedDict[str, LibraryEntry] = OrderedDict()
568570
self._libraries_matchers: Optional[Dict[KeywordMatcher, LibraryEntry]] = None

robotcode/language_server/robotframework/parts/code_action.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ class ConvertUriParams(Model):
6161
</head>
6262
<body>
6363
<div id="content">
64-
<h1>
64+
<h3>
6565
${type}: ${message}
66-
</h1>
66+
</h3>
6767
<pre>
6868
${stacktrace}
6969
</pre>

robotcode/language_server/robotframework/parts/completion.py

+73-12
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
TextEdit,
4242
)
4343
from ...common.text_document import TextDocument
44-
from ..configuration import SyntaxConfig
44+
from ..configuration import CompletionConfig
4545
from ..diagnostics.entities import VariableDefinitionType
4646
from ..diagnostics.library_doc import (
4747
CompleteResultKind,
@@ -81,11 +81,15 @@ def __init__(self, parent: RobotLanguageServerProtocol) -> None:
8181
parent.completion.collect.add(self.collect)
8282
parent.completion.resolve.add(self.resolve)
8383

84-
async def get_header_style(self, document: TextDocument) -> str:
84+
async def get_config(self, document: TextDocument) -> CompletionConfig:
8585
if (folder := self.parent.workspace.get_workspace_folder(document.uri)) is not None:
86-
config = await self.parent.workspace.get_configuration(SyntaxConfig, folder.uri)
87-
if config.header_style is not None:
88-
return config.header_style
86+
return await self.parent.workspace.get_configuration(CompletionConfig, folder.uri)
87+
88+
return CompletionConfig()
89+
90+
async def get_header_style(self, config: CompletionConfig) -> str:
91+
if config.header_style is not None:
92+
return config.header_style
8993

9094
return DEFAULT_HEADER_STYLE if get_robot_version() < (5, 1) else DEFAULT_HEADER_STYLE_51
9195

@@ -116,8 +120,10 @@ async def collect(
116120

117121
model = await self.parent.documents_cache.get_model(document, False)
118122

123+
config = await self.get_config(document)
124+
119125
return await CompletionCollector(
120-
self.parent, document, model, namespace, await self.get_header_style(document)
126+
self.parent, document, model, namespace, await self.get_header_style(config), config
121127
).collect(
122128
position,
123129
context,
@@ -135,8 +141,10 @@ async def resolve(self, sender: Any, completion_item: CompletionItem) -> Complet
135141
namespace = await self.parent.documents_cache.get_namespace(document)
136142
model = await self.parent.documents_cache.get_model(document, False)
137143
if namespace is not None:
144+
config = await self.get_config(document)
145+
138146
return await CompletionCollector(
139-
self.parent, document, model, namespace, await self.get_header_style(document)
147+
self.parent, document, model, namespace, await self.get_header_style(config), config
140148
).resolve(completion_item)
141149

142150
return completion_item
@@ -231,12 +239,14 @@ def __init__(
231239
model: ast.AST,
232240
namespace: Namespace,
233241
header_style: str,
242+
config: CompletionConfig,
234243
) -> None:
235244
self.parent = parent
236245
self.header_style = header_style
237246
self.document = document
238247
self.model = model
239248
self.namespace = namespace
249+
self.config = config
240250

241251
async def _find_methods(self, cls: Type[Any]) -> AsyncGenerator[_CompleteMethod, None]:
242252
if cls is ast.AST:
@@ -399,7 +409,16 @@ async def create_headers_completion_items(self, range: Optional[Range]) -> List[
399409
if self.namespace.languages is None:
400410
headers: Iterable[str] = HEADERS
401411
else:
402-
headers = itertools.chain(*(lang.headers for lang in self.namespace.languages))
412+
languages = self.namespace.languages.languages
413+
414+
if (
415+
self.config.filter_default_language
416+
and len(self.namespace.languages.languages) > 1
417+
and self.config.filter_default_language
418+
):
419+
languages = [v for v in languages if v.code != "en"]
420+
421+
headers = itertools.chain(*(lang.headers.keys() for lang in languages))
403422

404423
return [
405424
CompletionItem(
@@ -419,7 +438,7 @@ async def create_headers_completion_items(self, range: Optional[Range]) -> List[
419438
if range is not None
420439
else None,
421440
)
422-
for s in ((self.header_style.format(name=k), k) for k in headers)
441+
for s in ((self.header_style.format(name=k), k) for k in (v.title() for v in headers))
423442
]
424443

425444
async def create_environment_variables_completion_items(self, range: Optional[Range]) -> List[CompletionItem]:
@@ -491,13 +510,27 @@ async def create_settings_completion_items(self, range: Optional[Range]) -> List
491510
settings = {*settings_class.names, *settings_class.aliases.keys()}
492511

493512
if self.namespace.languages is not None:
494-
settings = {k for k, v in self.namespace.languages.settings.items() if v in settings}
513+
514+
if self.config.filter_default_language and len(self.namespace.languages.languages) > 1:
515+
languages = self.namespace.languages.languages
516+
517+
if self.config.filter_default_language:
518+
languages = [v for v in languages if v.code != "en"]
519+
520+
items: Iterable[Tuple[str, str]] = itertools.chain(*(lang.settings.items() for lang in languages))
521+
else:
522+
items = self.namespace.languages.settings.items()
523+
524+
settings = {k.title() for k, v in items if v in settings}
495525

496526
return [
497527
CompletionItem(
498528
label=setting,
499529
kind=CompletionItemKind.KEYWORD,
500530
detail="Setting",
531+
documentation=self.namespace.languages.settings.get(setting)
532+
if self.namespace.languages is not None
533+
else None,
501534
sort_text=f"090_{setting}",
502535
insert_text_format=InsertTextFormat.PLAINTEXT,
503536
text_edit=TextEdit(range=range, new_text=setting) if range is not None else None,
@@ -525,12 +558,26 @@ async def create_testcase_settings_completion_items(self, range: Optional[Range]
525558
settings = {*TestCaseSettings.names, *TestCaseSettings.aliases.keys()}
526559

527560
if self.namespace.languages is not None:
528-
settings = {k for k, v in self.namespace.languages.settings.items() if v in settings}
561+
562+
if self.config.filter_default_language and len(self.namespace.languages.languages) > 1:
563+
languages = self.namespace.languages.languages
564+
565+
if self.config.filter_default_language:
566+
languages = [v for v in languages if v.code != "en"]
567+
568+
items: Iterable[Tuple[str, str]] = itertools.chain(*(lang.settings.items() for lang in languages))
569+
else:
570+
items = self.namespace.languages.settings.items()
571+
572+
settings = {k.title() for k, v in items if v in settings}
529573

530574
return [
531575
CompletionItem(
532576
label=f"[{setting}]",
533577
kind=CompletionItemKind.KEYWORD,
578+
documentation=self.namespace.languages.settings.get(setting)
579+
if self.namespace.languages is not None
580+
else None,
534581
detail="Setting",
535582
sort_text=f"070_{setting}",
536583
insert_text_format=InsertTextFormat.PLAINTEXT,
@@ -563,12 +610,26 @@ async def create_keyword_settings_completion_items(self, range: Optional[Range])
563610
settings = {*KeywordSettings.names, *KeywordSettings.aliases.keys()}
564611

565612
if self.namespace.languages is not None:
566-
settings = {k for k, v in self.namespace.languages.settings.items() if v in settings}
613+
614+
if self.config.filter_default_language and len(self.namespace.languages.languages) > 1:
615+
languages = self.namespace.languages.languages
616+
617+
if self.config.filter_default_language:
618+
languages = [v for v in languages if v.code != "en"]
619+
620+
items: Iterable[Tuple[str, str]] = itertools.chain(*(lang.settings.items() for lang in languages))
621+
else:
622+
items = self.namespace.languages.settings.items()
623+
624+
settings = {k.title() for k, v in items if v in settings}
567625

568626
return [
569627
CompletionItem(
570628
label=f"[{setting}]",
571629
kind=CompletionItemKind.KEYWORD,
630+
documentation=self.namespace.languages.settings.get(setting)
631+
if self.namespace.languages is not None
632+
else None,
572633
detail="Setting",
573634
sort_text=f"070_{setting}",
574635
insert_text_format=InsertTextFormat.PLAINTEXT,

robotcode/language_server/robotframework/parts/documents_cache.py

+19-11
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
Iterable,
1212
List,
1313
Optional,
14+
Tuple,
1415
Union,
1516
cast,
1617
)
@@ -93,23 +94,28 @@ async def get_workspace_languages(self, document_or_uri: Union[TextDocument, Uri
9394

9495
return cast(Languages, RobotLanguages(result.languages))
9596

96-
async def build_languages_from_model(self, document: TextDocument, model: ast.AST) -> Optional[Languages]:
97+
async def build_languages_from_model(
98+
self, document: TextDocument, model: ast.AST
99+
) -> Tuple[Optional[Languages], Optional[Languages]]:
97100
if get_robot_version() < (5, 1):
98-
return None
101+
return (None, None)
99102

100103
from robot.conf.languages import Languages as RobotLanguages
101104
from robot.parsing.model.blocks import File
102105

103106
workspace_langs = await self.get_workspace_languages(document)
104107

105-
return cast(
106-
Languages,
107-
RobotLanguages(
108-
[
109-
*(workspace_langs.languages if workspace_langs else []),
110-
*(model.languages if isinstance(model, File) else []),
111-
]
108+
return (
109+
cast(
110+
Languages,
111+
RobotLanguages(
112+
[
113+
*(workspace_langs.languages if workspace_langs else []),
114+
*(model.languages if isinstance(model, File) else []),
115+
]
116+
),
112117
),
118+
workspace_langs,
113119
)
114120

115121
async def get_document_type(self, document: TextDocument) -> DocumentType:
@@ -405,9 +411,11 @@ async def __get_namespace_for_document_type(
405411

406412
imports_manager = await self.get_imports_manager(document)
407413

408-
languages = await self.build_languages_from_model(document, model)
414+
languages, workspace_languages = await self.build_languages_from_model(document, model)
409415

410-
result = Namespace(imports_manager, model, str(document.uri.to_path()), document, document_type, languages)
416+
result = Namespace(
417+
imports_manager, model, str(document.uri.to_path()), document, document_type, languages, workspace_languages
418+
)
411419
result.has_invalidated.add(self.__invalidate_namespace)
412420
result.has_imports_changed.add(self.__invalidate_namespace)
413421

0 commit comments

Comments
 (0)