12
12
Awaitable ,
13
13
Callable ,
14
14
Dict ,
15
+ Iterable ,
15
16
Iterator ,
16
17
List ,
17
18
Optional ,
47
48
KeywordDoc ,
48
49
KeywordMatcher ,
49
50
)
50
- from ..diagnostics .namespace import Namespace
51
+ from ..diagnostics .namespace import DocumentType , Namespace
51
52
from ..utils .ast_utils import (
52
53
HasTokens ,
53
54
Token ,
66
67
67
68
from .protocol_part import RobotLanguageServerProtocolPart
68
69
70
+ DEFAULT_SECTIONS_STYLE = "*** {name}s ***"
71
+ DEFAULT_SECTIONS_STYLE_NEW = "*** {name} ***"
72
+
69
73
70
74
class RobotCompletionProtocolPart (RobotLanguageServerProtocolPart ):
71
75
_logger = LoggingDescriptor ()
@@ -79,9 +83,10 @@ def __init__(self, parent: RobotLanguageServerProtocol) -> None:
79
83
async def get_section_style (self , document : TextDocument ) -> str :
80
84
if (folder := self .parent .workspace .get_workspace_folder (document .uri )) is not None :
81
85
config = await self .parent .workspace .get_configuration (SyntaxConfig , folder .uri )
82
- return config .section_style or DEFAULT_SECTIONS_STYLE
86
+ if config .section_style is not None :
87
+ return config .section_style
83
88
84
- return DEFAULT_SECTIONS_STYLE
89
+ return DEFAULT_SECTIONS_STYLE if get_robot_version () < ( 5 , 1 ) else DEFAULT_SECTIONS_STYLE_NEW
85
90
86
91
@language_id ("robotframework" )
87
92
@trigger_characters (
@@ -143,9 +148,8 @@ async def resolve(self, sender: Any, completion_item: CompletionItem) -> Complet
143
148
]
144
149
145
150
SECTIONS = ["Test Case" , "Setting" , "Variable" , "Keyword" , "Comment" , "Task" ]
146
- DEFAULT_SECTIONS_STYLE = "*** {name}s ***"
147
151
148
- SETTINGS = [
152
+ SUITE_SETTINGS = [
149
153
"Documentation" ,
150
154
"Metadata" ,
151
155
"Suite Setup" ,
@@ -165,6 +169,7 @@ async def resolve(self, sender: Any, completion_item: CompletionItem) -> Complet
165
169
"Task Timeout" ,
166
170
]
167
171
172
+
168
173
TESTCASE_SETTINGS = ["Documentation" , "Tags" , "Setup" , "Teardown" , "Template" , "Timeout" ]
169
174
KEYWORD_SETTINGS = ["Documentation" , "Tags" , "Arguments" , "Return" , "Teardown" , "Timeout" ]
170
175
@@ -345,12 +350,21 @@ async def resolve(self, completion_item: CompletionItem) -> CompletionItem:
345
350
346
351
return completion_item
347
352
348
- async def create_section_completion_items (self , range : Optional [Range ]) -> List [CompletionItem ]:
353
+ async def create_headers_completion_items (self , range : Optional [Range ]) -> List [CompletionItem ]:
354
+ if self .namespace .languages is None :
355
+ headers : Iterable [str ] = SECTIONS
356
+ else :
357
+ headers = self .namespace .languages .headers .keys ()
358
+
349
359
return [
350
360
CompletionItem (
351
361
label = s [0 ],
352
362
kind = CompletionItemKind .CLASS ,
353
363
detail = "Section" ,
364
+ # this is to get the english version in the documentation
365
+ documentation = self .namespace .languages .headers .get (s [1 ])
366
+ if self .namespace .languages is not None
367
+ else None ,
354
368
sort_text = f"100_{ s [1 ]} " ,
355
369
insert_text_format = InsertTextFormat .PLAINTEXT ,
356
370
text_edit = TextEdit (
@@ -360,7 +374,7 @@ async def create_section_completion_items(self, range: Optional[Range]) -> List[
360
374
if range is not None
361
375
else None ,
362
376
)
363
- for s in ((self .section_style .format (name = k ), k ) for k in SECTIONS )
377
+ for s in ((self .section_style .format (name = k ), k ) for k in headers )
364
378
]
365
379
366
380
async def create_environment_variables_completion_items (self , range : Optional [Range ]) -> List [CompletionItem ]:
@@ -415,6 +429,25 @@ async def create_variables_completion_items(
415
429
]
416
430
417
431
async def create_settings_completion_items (self , range : Optional [Range ]) -> List [CompletionItem ]:
432
+ from robot .parsing .lexer .settings import (
433
+ InitFileSettings ,
434
+ ResourceFileSettings ,
435
+ TestCaseFileSettings ,
436
+ )
437
+
438
+ doc_type = await self .parent .documents_cache .get_document_type (self .document )
439
+
440
+ settings_class = TestCaseFileSettings
441
+ if doc_type == DocumentType .RESOURCE :
442
+ settings_class = ResourceFileSettings
443
+ elif doc_type == DocumentType .INIT :
444
+ settings_class = InitFileSettings
445
+
446
+ settings = {* settings_class .names , * settings_class .aliases .keys ()}
447
+
448
+ if self .namespace .languages is not None :
449
+ settings = {k for k , v in self .namespace .languages .settings .items () if v in settings }
450
+
418
451
return [
419
452
CompletionItem (
420
453
label = setting ,
@@ -424,7 +457,7 @@ async def create_settings_completion_items(self, range: Optional[Range]) -> List
424
457
insert_text_format = InsertTextFormat .PLAINTEXT ,
425
458
text_edit = TextEdit (range = range , new_text = setting ) if range is not None else None ,
426
459
)
427
- for setting in SETTINGS
460
+ for setting in settings
428
461
]
429
462
430
463
async def create_keyword_snippet_completion_items (self , range : Optional [Range ]) -> List [CompletionItem ]:
@@ -442,6 +475,13 @@ async def create_keyword_snippet_completion_items(self, range: Optional[Range])
442
475
]
443
476
444
477
async def create_testcase_settings_completion_items (self , range : Optional [Range ]) -> List [CompletionItem ]:
478
+ from robot .parsing .lexer .settings import TestCaseSettings
479
+
480
+ settings = {* TestCaseSettings .names , * TestCaseSettings .aliases .keys ()}
481
+
482
+ if self .namespace .languages is not None :
483
+ settings = {k for k , v in self .namespace .languages .settings .items () if v in settings }
484
+
445
485
return [
446
486
CompletionItem (
447
487
label = f"[{ setting } ]" ,
@@ -451,10 +491,17 @@ async def create_testcase_settings_completion_items(self, range: Optional[Range]
451
491
insert_text_format = InsertTextFormat .PLAINTEXT ,
452
492
text_edit = TextEdit (range = range , new_text = f"[{ setting } ]" ) if range is not None else None ,
453
493
)
454
- for setting in TESTCASE_SETTINGS
494
+ for setting in settings
455
495
]
456
496
457
497
async def create_keyword_settings_completion_items (self , range : Optional [Range ]) -> List [CompletionItem ]:
498
+ from robot .parsing .lexer .settings import KeywordSettings
499
+
500
+ settings = {* KeywordSettings .names , * KeywordSettings .aliases .keys ()}
501
+
502
+ if self .namespace .languages is not None :
503
+ settings = {k for k , v in self .namespace .languages .settings .items () if v in settings }
504
+
458
505
return [
459
506
CompletionItem (
460
507
label = f"[{ setting } ]" ,
@@ -464,7 +511,7 @@ async def create_keyword_settings_completion_items(self, range: Optional[Range])
464
511
insert_text_format = InsertTextFormat .PLAINTEXT ,
465
512
text_edit = TextEdit (range = range , new_text = f"[{ setting } ]" ) if range is not None else None ,
466
513
)
467
- for setting in KEYWORD_SETTINGS
514
+ for setting in settings
468
515
]
469
516
470
517
def get_keyword_snipped_text (self , kw : KeywordDoc , in_template : bool ) -> str :
@@ -739,18 +786,18 @@ async def complete_default(
739
786
and (position .is_in_range (r ))
740
787
and (only_stars or value .startswith ("*" ) or position .character == 0 )
741
788
):
742
- return await self .create_section_completion_items (r )
789
+ return await self .create_headers_completion_items (r )
743
790
elif len (statement_node .tokens ) > 1 and only_stars :
744
791
r1 = range_from_token (statement_node .tokens [1 ])
745
792
ws = whitespace_at_begin_of_token (statement_node .tokens [1 ])
746
793
if ws > 0 :
747
794
r1 .end .character = r1 .start .character + ws
748
795
if position .is_in_range (r1 ):
749
796
r .end = r1 .end
750
- return await self .create_section_completion_items (r )
797
+ return await self .create_headers_completion_items (r )
751
798
752
799
elif position .character == 0 :
753
- return await self .create_section_completion_items (None )
800
+ return await self .create_headers_completion_items (None )
754
801
755
802
if len (nodes_at_position ) > 1 and isinstance (nodes_at_position [0 ], HasTokens ):
756
803
node = nodes_at_position [0 ]
@@ -1261,6 +1308,10 @@ async def complete_LibraryImport( # noqa: N802
1261
1308
import_token = import_node .get_token (RobotToken .LIBRARY )
1262
1309
if import_token is None :
1263
1310
return []
1311
+
1312
+ if position .is_in_range (range_from_token (import_token )):
1313
+ return []
1314
+
1264
1315
import_token_index = import_node .tokens .index (import_token )
1265
1316
1266
1317
async def complete_import () -> Optional [List [CompletionItem ]]:
@@ -1507,6 +1558,10 @@ async def complete_ResourceImport( # noqa: N802
1507
1558
import_token = import_node .get_token (Token .RESOURCE )
1508
1559
if import_token is None :
1509
1560
return []
1561
+
1562
+ if position .is_in_range (range_from_token (import_token )):
1563
+ return []
1564
+
1510
1565
import_token_index = import_node .tokens .index (import_token )
1511
1566
1512
1567
if len (import_node .tokens ) > import_token_index + 2 :
@@ -1606,8 +1661,13 @@ async def complete_VariablesImport( # noqa: N802
1606
1661
1607
1662
import_node = cast (VariablesImport , node )
1608
1663
import_token = import_node .get_token (Token .VARIABLES )
1664
+
1609
1665
if import_token is None :
1610
1666
return []
1667
+
1668
+ if position .is_in_range (range_from_token (import_token )):
1669
+ return []
1670
+
1611
1671
import_token_index = import_node .tokens .index (import_token )
1612
1672
1613
1673
if len (import_node .tokens ) > import_token_index + 2 :
0 commit comments