Skip to content

Commit 483b9ac

Browse files
committed
feat: complete reserved tags in Tags settings
Closes [ENHANCEMENT] Support Reserved Tags #103
1 parent 735a209 commit 483b9ac

File tree

3 files changed

+128
-4
lines changed

3 files changed

+128
-4
lines changed

packages/language_server/src/robotcode/language_server/robotframework/diagnostics/library_doc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ def var_repr(value: Any) -> str:
867867
if isinstance(value, str) and value == "":
868868
return "${EMPTY}"
869869

870-
if isinstance(value, str) and value == "\\ \\":
870+
if isinstance(value, str) and value == " ":
871871
return "${SPACE}"
872872

873873
if isinstance(value, str):

packages/language_server/src/robotcode/language_server/robotframework/parts/completion.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,3 +2109,107 @@ async def complete_Fixture( # noqa: N802
21092109
return None
21102110

21112111
return await self._complete_KeywordCall_or_Fixture(RobotToken.NAME, node, nodes_at_position, position, context)
2112+
2113+
async def create_tags_completion_items(self, range: Optional[Range]) -> List[CompletionItem]:
2114+
built_in_tags = {
2115+
"robot:continue-on-failure",
2116+
"robot:stop-on-failure",
2117+
"robot:no-dry-run",
2118+
"robot:exit",
2119+
}
2120+
2121+
if get_robot_version() >= (5, 0):
2122+
built_in_tags.add("robot:skip")
2123+
built_in_tags.add("robot:skip-on-failure")
2124+
built_in_tags.add("robot:exclude")
2125+
built_in_tags.add("robot:recursive-continue-on-failure")
2126+
2127+
if get_robot_version() >= (6, 0):
2128+
built_in_tags.add("robot:recursive-stop-on-failure")
2129+
built_in_tags.add("robot:private")
2130+
2131+
if get_robot_version() >= (6, 1):
2132+
built_in_tags.add("robot:flatten")
2133+
2134+
return [
2135+
CompletionItem(
2136+
label=tag,
2137+
kind=CompletionItemKind.ENUM_MEMBER,
2138+
detail="Reserved Tag",
2139+
sort_text=f"080_{tag}",
2140+
insert_text_format=InsertTextFormat.PLAIN_TEXT,
2141+
text_edit=TextEdit(range=range, new_text=f"{tag}") if range is not None else None,
2142+
)
2143+
for tag in built_in_tags
2144+
]
2145+
2146+
async def _complete_ForceTags_or_KeywordTags_or_DefaultTags_Tags( # noqa: N802
2147+
self,
2148+
node: ast.AST,
2149+
nodes_at_position: List[ast.AST],
2150+
position: Position,
2151+
context: Optional[CompletionContext],
2152+
) -> Union[List[CompletionItem], CompletionList, None]:
2153+
from robot.parsing.lexer.tokens import Token as RobotToken
2154+
from robot.parsing.model.statements import Statement
2155+
2156+
statement = cast(Statement, node)
2157+
tokens = get_tokens_at_position(statement, position)
2158+
2159+
if not tokens:
2160+
return None
2161+
2162+
if tokens[-1].type == RobotToken.ARGUMENT:
2163+
return await self.create_tags_completion_items(range_from_token(tokens[-1]))
2164+
2165+
if len(tokens) > 1 and tokens[-2].type == RobotToken.ARGUMENT:
2166+
return await self.create_tags_completion_items(range_from_token(tokens[-2]))
2167+
2168+
if whitespace_at_begin_of_token(tokens[-1]) >= 2:
2169+
return await self.create_tags_completion_items(None)
2170+
2171+
return None
2172+
2173+
async def complete_ForceTags( # noqa: N802
2174+
self,
2175+
node: ast.AST,
2176+
nodes_at_position: List[ast.AST],
2177+
position: Position,
2178+
context: Optional[CompletionContext],
2179+
) -> Union[List[CompletionItem], CompletionList, None]:
2180+
return await self._complete_ForceTags_or_KeywordTags_or_DefaultTags_Tags(
2181+
node, nodes_at_position, position, context
2182+
)
2183+
2184+
async def complete_KeywordTags( # noqa: N802
2185+
self,
2186+
node: ast.AST,
2187+
nodes_at_position: List[ast.AST],
2188+
position: Position,
2189+
context: Optional[CompletionContext],
2190+
) -> Union[List[CompletionItem], CompletionList, None]:
2191+
return await self._complete_ForceTags_or_KeywordTags_or_DefaultTags_Tags(
2192+
node, nodes_at_position, position, context
2193+
)
2194+
2195+
async def complete_DefaultTags( # noqa: N802
2196+
self,
2197+
node: ast.AST,
2198+
nodes_at_position: List[ast.AST],
2199+
position: Position,
2200+
context: Optional[CompletionContext],
2201+
) -> Union[List[CompletionItem], CompletionList, None]:
2202+
return await self._complete_ForceTags_or_KeywordTags_or_DefaultTags_Tags(
2203+
node, nodes_at_position, position, context
2204+
)
2205+
2206+
async def complete_Tags( # noqa: N802
2207+
self,
2208+
node: ast.AST,
2209+
nodes_at_position: List[ast.AST],
2210+
position: Position,
2211+
context: Optional[CompletionContext],
2212+
) -> Union[List[CompletionItem], CompletionList, None]:
2213+
return await self._complete_ForceTags_or_KeywordTags_or_DefaultTags_Tags(
2214+
node, nodes_at_position, position, context
2215+
)

syntaxes/robotframework.tmLanguage.json

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
}
9292
},
9393
"setting": {
94-
"contentName": "string.unquoted.argument.robotframework",
94+
"contentName": "variable.parameter.argument.robotframework",
9595
"begin": "(?i)^(\\S+( \\S+)*)(?= {2}| ?\\t| ?$)",
9696
"beginCaptures": {
9797
"1": {
@@ -115,8 +115,28 @@
115115
]
116116
},
117117
"testcase_settings": {
118-
"match": "\\[.*?\\]",
119-
"name": "keyword.control.settings.robotframework"
118+
"contentName": "variable.parameter.argument.robotframework",
119+
"begin": "(\\[.*?\\])(?= {2}| ?\\t| ?$)",
120+
"beginCaptures": {
121+
"0": {
122+
"name": "keyword.control.settings.robotframework"
123+
}
124+
},
125+
"end": "^(?!\\s*\\.\\.\\.)",
126+
"patterns": [
127+
{
128+
"include": "#escape"
129+
},
130+
{
131+
"include": "#comment"
132+
},
133+
{
134+
"include": "#variables"
135+
},
136+
{
137+
"include": "#line_continuation"
138+
}
139+
]
120140
},
121141
"keyword_call": {
122142
"contentName": "string.unquoted.argument.robotframework",

0 commit comments

Comments
 (0)