Skip to content

Commit 080ab83

Browse files
committed
fix(langserver): correct some completion quirks at line or file ends
1 parent 625eab4 commit 080ab83

File tree

6 files changed

+37
-55
lines changed

6 files changed

+37
-55
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ put this to the `settings.json`
262262
}
263263
},
264264
{
265-
"scope": "constant.character.escape.robotframework",
265+
"scope": "string.unquoted.escape.robotframework",
266266
"settings": {
267267
//"foreground": "#FF0000",
268268
}

package.json

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@
9797
"[robotframework]": {
9898
"editor.wordBasedSuggestions": false,
9999
"editor.semanticHighlighting.enabled": true,
100-
"editor.inlayHints.enabled": "offUnlessPressed"
100+
"editor.inlayHints.enabled": "offUnlessPressed",
101+
"editor.quickSuggestionsDelay": 100,
102+
"editor.quickSuggestions": {
103+
"strings": "on"
104+
}
101105
},
102106
"editor.tokenColorCustomizations": {
103107
"textMateRules": [
@@ -114,7 +118,7 @@
114118
}
115119
},
116120
{
117-
"scope": "constant.character.embeddedArgument.robotframework",
121+
"scope": "string.unquoted.embeddedArgument.robotframework",
118122
"settings": {
119123
"fontStyle": "italic"
120124
}
@@ -182,7 +186,7 @@
182186
}
183187
},
184188
{
185-
"scope": "constant.character.character.escape.robotframework",
189+
"scope": "string.unquoted.character.escape.robotframework",
186190
"settings": {}
187191
}
188192
]
@@ -245,10 +249,10 @@
245249
"keyword.operator.for.robotframework"
246250
],
247251
"argument": [
248-
"constant.character.argument.robotframework"
252+
"string.unquoted.argument.robotframework"
249253
],
250254
"embeddedArgument": [
251-
"constant.character.embeddedArgument.robotframework"
255+
"string.unquoted.embeddedArgument.robotframework"
252256
],
253257
"variable": [
254258
"variable.other.readwrite.robotframework"
@@ -279,7 +283,7 @@
279283
"punctuation.definition.variable.end.robotframework"
280284
],
281285
"escape": [
282-
"constant.character.character.escape.robotframework"
286+
"string.unquoted.character.escape.robotframework"
283287
],
284288
"namespace": [
285289
"entity.other.namespace.robotframework"
@@ -328,7 +332,7 @@
328332
"args": {
329333
"text": " "
330334
},
331-
"when": "editorLangId == robotframework && editorTextFocus && !editorHasSelection && !inSnippetMode && !suggestWidgetVisible && config.robotcode.editor.4SpacesTab && !inlineSuggestionVisible"
335+
"when": "editorLangId == robotframework && editorTextFocus && config.robotcode.editor.4SpacesTab && !editorHasSelection && !inSnippetMode && !suggestWidgetVisible && !inlineSuggestionVisible"
332336
}
333337
],
334338
"configuration": [

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import asyncio
34
from asyncio import CancelledError
45
from itertools import chain
56
from typing import TYPE_CHECKING, Any, Final, List, Optional, Union, cast
@@ -12,6 +13,7 @@
1213
CompletionList,
1314
CompletionOptions,
1415
CompletionParams,
16+
CompletionTriggerKind,
1517
InsertReplaceEdit,
1618
Position,
1719
ServerCapabilities,
@@ -90,14 +92,19 @@ async def _text_document_completion(
9092
) -> Union[List[CompletionItem], CompletionList, None]:
9193
results: List[Union[List[CompletionItem], CompletionList]] = []
9294

95+
if context is not None and context.trigger_kind == CompletionTriggerKind.TRIGGER_CHARACTER:
96+
await asyncio.sleep(0.25)
97+
9398
document = await self.parent.documents.get(text_document.uri)
9499
if document is None:
95100
return None
96101

102+
p = document.position_from_utf16(position)
103+
97104
for result in await self.collect(
98105
self,
99106
document,
100-
document.position_from_utf16(position),
107+
p,
101108
context,
102109
callback_filter=language_id_filter(document),
103110
):

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,11 @@ def resolve(
472472
)
473473
return cast(Tuple[List[Any], List[Tuple[str, Any]]], resolver.resolve(arguments, variables))
474474

475-
positional, named = NamedArgumentResolver(self.__robot_arguments).resolve(arguments, variables)
475+
class MyNamedArgumentResolver(NamedArgumentResolver):
476+
def _raise_positional_after_named(self) -> None:
477+
pass
478+
479+
positional, named = MyNamedArgumentResolver(self.__robot_arguments).resolve(arguments, variables)
476480
positional, named = VariableReplacer(resolve_variables_until).replace(positional, named, variables)
477481
positional, named = DictToKwargs(self.__robot_arguments, dict_to_kwargs).handle(positional, named)
478482
return positional, named

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

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
CompletionItem,
3333
CompletionItemKind,
3434
CompletionList,
35-
CompletionTriggerKind,
3635
InsertTextFormat,
3736
MarkupContent,
3837
MarkupKind,
@@ -262,7 +261,7 @@ async def _find_methods(self, cls: Type[Any]) -> AsyncIterator[_CompleteMethod]:
262261
async def collect(
263262
self, position: Position, context: Optional[CompletionContext]
264263
) -> Union[List[CompletionItem], CompletionList, None]:
265-
result_nodes = await get_nodes_at_position(self.model, position)
264+
result_nodes = await get_nodes_at_position(self.model, position, include_end=True)
266265

267266
result_nodes.reverse()
268267

@@ -980,7 +979,7 @@ async def complete_default(
980979
if len(nodes_at_position) > 1 and isinstance(nodes_at_position[0], HasTokens):
981980
node = nodes_at_position[0]
982981

983-
tokens_at_position = get_tokens_at_position(node, position)
982+
tokens_at_position = get_tokens_at_position(node, position, True)
984983
if not tokens_at_position:
985984
return None
986985

@@ -1051,14 +1050,6 @@ async def complete_SettingSection( # noqa: N802
10511050
) -> Union[List[CompletionItem], CompletionList, None]:
10521051
from robot.parsing.model.statements import SectionHeader, Statement
10531052

1054-
# TODO should this be configurable?
1055-
if (
1056-
context is not None
1057-
and context.trigger_kind == CompletionTriggerKind.TRIGGER_CHARACTER
1058-
and context.trigger_character in [" ", "\t"]
1059-
):
1060-
return None
1061-
10621053
if nodes_at_position.index(node) > 0 and not isinstance(nodes_at_position[0], SectionHeader):
10631054
node_at_pos = nodes_at_position[0]
10641055
if (
@@ -1094,14 +1085,6 @@ async def _complete_TestCase_or_Keyword( # noqa: N802
10941085
from robot.parsing.lexer.tokens import Token as RobotToken
10951086
from robot.parsing.model.statements import KeywordName, Statement, TestCaseName
10961087

1097-
# TODO should this be configurable?
1098-
if (
1099-
context is not None
1100-
and context.trigger_kind == CompletionTriggerKind.TRIGGER_CHARACTER
1101-
and context.trigger_character in [" ", "\t"]
1102-
):
1103-
return None
1104-
11051088
index = 0
11061089
in_assign = False
11071090

@@ -1262,14 +1245,6 @@ async def _complete_SuiteSetup_or_SuiteTeardown_or_TestTemplate( # noqa: N802
12621245
) -> Union[List[CompletionItem], CompletionList, None]:
12631246
from robot.parsing.model.statements import Statement, TestTemplate
12641247

1265-
# TODO should this be configurable?
1266-
if (
1267-
context is not None
1268-
and context.trigger_kind == CompletionTriggerKind.TRIGGER_CHARACTER
1269-
and context.trigger_character in [" ", "\t"]
1270-
):
1271-
return None
1272-
12731248
statement_node = cast(Statement, node)
12741249
if len(statement_node.tokens) > 1:
12751250
token = cast(Token, statement_node.tokens[1])
@@ -1387,14 +1362,6 @@ async def complete_Setup_or_Teardown_or_Template( # noqa: N802
13871362
) -> Union[List[CompletionItem], CompletionList, None]:
13881363
from robot.parsing.model.statements import Statement, Template
13891364

1390-
# TODO should this be configurable?
1391-
if (
1392-
context is not None
1393-
and context.trigger_kind == CompletionTriggerKind.TRIGGER_CHARACTER
1394-
and context.trigger_character in [" ", "\t"]
1395-
):
1396-
return None
1397-
13981365
statement_node = cast(Statement, node)
13991366
if len(statement_node.tokens) > 2:
14001367
token = cast(Token, statement_node.tokens[2])
@@ -1589,7 +1556,7 @@ async def complete_arguments() -> Optional[List[CompletionItem]]:
15891556

15901557
kw_node = cast(Statement, node)
15911558

1592-
tokens_at_position = get_tokens_at_position(kw_node, position)
1559+
tokens_at_position = get_tokens_at_position(kw_node, position, True)
15931560

15941561
if not tokens_at_position:
15951562
return None
@@ -1853,7 +1820,7 @@ async def complete_arguments() -> Optional[List[CompletionItem]]:
18531820

18541821
kw_node = cast(Statement, node)
18551822

1856-
tokens_at_position = get_tokens_at_position(kw_node, position)
1823+
tokens_at_position = get_tokens_at_position(kw_node, position, True)
18571824

18581825
if not tokens_at_position:
18591826
return None
@@ -1893,16 +1860,13 @@ async def _complete_KeywordCall_or_Fixture( # noqa: N802
18931860
from robot.parsing.lexer.tokens import Token as RobotToken
18941861
from robot.parsing.model.statements import Statement
18951862

1896-
# if context is None or context.trigger_kind != CompletionTriggerKind.INVOKED:
1897-
# return []
1898-
18991863
kw_node = cast(Statement, node)
19001864

19011865
keyword_token = kw_node.get_token(keyword_name_token_type)
19021866
if keyword_token is None:
19031867
return None
19041868

1905-
tokens_at_position = get_tokens_at_position(kw_node, position)
1869+
tokens_at_position = get_tokens_at_position(kw_node, position, include_end=True)
19061870

19071871
if not tokens_at_position:
19081872
return None
@@ -1912,6 +1876,9 @@ async def _complete_KeywordCall_or_Fixture( # noqa: N802
19121876
if token_at_position.type not in [RobotToken.ARGUMENT, RobotToken.EOL, RobotToken.SEPARATOR]:
19131877
return None
19141878

1879+
if len(tokens_at_position) > 1 and tokens_at_position[-2].type == RobotToken.KEYWORD:
1880+
return None
1881+
19151882
keyword_doc_and_token: Optional[Tuple[Optional[KeywordDoc], Token]] = None
19161883

19171884
keyword_token = kw_node.get_token(keyword_name_token_type)
@@ -2258,7 +2225,7 @@ async def _complete_ForceTags_or_KeywordTags_or_DefaultTags_Tags( # noqa: N802
22582225
from robot.parsing.model.statements import Statement
22592226

22602227
statement = cast(Statement, node)
2261-
tokens = get_tokens_at_position(statement, position)
2228+
tokens = get_tokens_at_position(statement, position, True)
22622229

22632230
if not tokens:
22642231
return None

syntaxes/robotframework.tmLanguage.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"variable_setting": {
1010
"name": "meta.variable.assign.robotframework",
11-
"contentName": "constant.character.argument.robotframework",
11+
"contentName": "string.unquoted.argument.robotframework",
1212
"begin": "^(?:([$@&%]\\{)(.+?}*)(\\})( ?=)?)",
1313
"beginCaptures": {
1414
"1": {
@@ -140,7 +140,7 @@
140140
},
141141
"keyword_call": {
142142
"name": "meta.keyword-call.content.robotframework",
143-
"contentName": "constant.character.argument.robotframework",
143+
"contentName": "string.unquoted.argument.robotframework",
144144
"begin": "^(?!(?: {2,}| ?\\t ?)+(?:(?=[$\\[@&%]|\\.)))(?: {2,}| ?\\t ?)+(.*?)(?= {2,}| ?\\t ?| ?$)",
145145
"end": "^(?!\\s*\\.\\.\\.)",
146146
"beginCaptures": {
@@ -173,7 +173,7 @@
173173
},
174174
"returning_keyword": {
175175
"name": "meta.returning-keyword.robotframework",
176-
"contentName": "constant.character.argument.robotframework",
176+
"contentName": "string.unquoted.argument.robotframework",
177177
"begin": "(?<=\\s)(?=\\s*(?:(?=[$@&])))((?:\\s)*(?:[$&@]{(?:.*?)}(?:\\[.*?\\])?(?: ?=?\\s*))*)(.*?)(?: {2,}| ?\\t ?|$)",
178178
"beginCaptures": {
179179
"1": {

0 commit comments

Comments
 (0)