Skip to content

Commit

Permalink
Completions for Variables section in Settings. Fixes #744
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Sep 7, 2022
1 parent 7346e7f commit 09a67f1
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import os.path
from robocorp_ls_core.robotframework_log import get_logger
from typing import Optional, List
from typing import Optional, List, Tuple
from robotframework_ls.impl.protocols import ICompletionContext
from robocorp_ls_core.lsp import CompletionItemTypedDict
from robocorp_ls_core.basic import normalize_filename
from robotframework_ls.impl.robot_constants import (
ROBOT_AND_TXT_FILE_EXTENSIONS,
LIBRARY_FILE_EXTENSIONS,
VARIABLE_FILE_EXTENSIONS,
)

log = get_logger(__name__)
Expand Down Expand Up @@ -98,8 +99,17 @@ def normfile(path):


def _get_completions(
completion_context, token, match_libs, extensions, skip_current
completion_context: ICompletionContext,
token,
match_libs,
extensions: Tuple[str, ...],
skip_current: bool,
) -> List[CompletionItemTypedDict]:
"""
:param skip_current:
If we'd get a match for the current (.robot or .resource)
file it will not be added.
"""
from robotframework_ls.impl.string_matcher import RobotStringMatcher
from robocorp_ls_core import uris
from robotframework_ls.impl.robot_constants import BUILTIN_LIB, RESERVED_LIB
Expand Down Expand Up @@ -185,34 +195,67 @@ def _get_library_completions(
)


def _get_variable_completions(
completion_context, token
) -> List[CompletionItemTypedDict]:
return _get_completions(
completion_context,
token,
True,
LIBRARY_FILE_EXTENSIONS + VARIABLE_FILE_EXTENSIONS,
skip_current=False,
)


class _Requisites(object):
def __init__(self, token, is_library: bool):
def __init__(self, token, found_type: str):
self.token = token
self.is_library = is_library
self._type = found_type

@property
def is_library(self):
return self._type == "library"

@property
def is_resource(self):
return self._type == "resource"

@property
def is_variables(self):
return self._type == "variables"


def get_requisites(completion_context: ICompletionContext) -> Optional[_Requisites]:
from robotframework_ls.impl import ast_utils

token_info = completion_context.get_current_token()
if token_info is not None:
# Library
token = ast_utils.get_library_import_name_token(
token_info.node, token_info.token
)
if token is not None:
return _Requisites(token, True)
else:
token = ast_utils.get_resource_import_name_token(
token_info.node, token_info.token
)
if token is not None:
return _Requisites(token, False)
return _Requisites(token, "library")

# Resource
token = ast_utils.get_resource_import_name_token(
token_info.node, token_info.token
)
if token is not None:
return _Requisites(token, "resource")

# Variable
token = ast_utils.get_variables_import_name_token(
token_info.node, token_info.token
)
if token is not None:
return _Requisites(token, "variables")
return None


def complete(completion_context: ICompletionContext) -> List[CompletionItemTypedDict]:
"""
Provides the completions for 'Library' and 'Resource' imports.
Provides the completions for 'Library', 'Resource' and 'Variables' imports.
"""
try:

Expand All @@ -222,9 +265,13 @@ def complete(completion_context: ICompletionContext) -> List[CompletionItemTyped

if requisites.is_library:
return _get_library_completions(completion_context, requisites.token)
else:

elif requisites.is_library:
return _get_resource_completions(completion_context, requisites.token)

elif requisites.is_variables:
return _get_variable_completions(completion_context, requisites.token)

except:
log.exception()

Expand Down
18 changes: 10 additions & 8 deletions robotframework-ls/src/robotframework_ls/impl/variable_types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional, Tuple
from typing import Optional, Tuple, Any

from robocorp_ls_core.cache import instance_cache
from robocorp_ls_core.protocols import check_implements
Expand Down Expand Up @@ -120,14 +120,16 @@ def __str__(self):


class VariableFoundFromSettings(object):
variable_kind = VariableKind.SETTINGS
variable_kind: str = VariableKind.SETTINGS

def __init__(self, variable_name, variable_value, source="", lineno=0):
self.completion_context = None
self.variable_name = variable_name
self.variable_value = str(variable_value)
self._source = source
self._lineno = lineno
def __init__(
self, variable_name: str, variable_value: Any, source: str = "", lineno: int = 0
):
self.completion_context: Optional[ICompletionContext] = None
self.variable_name: str = variable_name
self.variable_value: str = str(variable_value)
self._source: str = source
self._lineno: int = lineno
self.stack: Optional[Tuple[INode, ...]] = None

@property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,43 @@ def check():
# The libspec generation will run in a thread at startup, thus, we need
# to wait for this condition to be reached.
wait_for_expected_func_return(check, ["libraries.lib_in_pythonpath"])


def test_variables_completions_basic(
data_regression, workspace, cases, libspec_manager, workspace_dir
):
from robotframework_ls.impl import filesystem_section_completions
from robotframework_ls.impl.completion_context import CompletionContext

cases.copy_to("case_search_pythonpath_variable", workspace_dir)

# Must be .py, .yaml and .yml files or just plain python modules (such as my.module).
workspace.set_root(workspace_dir, libspec_manager=libspec_manager)
doc = workspace.put_doc("my.robot")
doc.source = """*** Settings ***
Variables ./var"""

completions = filesystem_section_completions.complete(
CompletionContext(doc, workspace=workspace.ws)
)
data_regression.check(completions)


def test_variables_completions_py(
data_regression, workspace, cases, libspec_manager, workspace_dir
):
from robotframework_ls.impl import filesystem_section_completions
from robotframework_ls.impl.completion_context import CompletionContext

cases.copy_to("case_search_pythonpath_variable", workspace_dir)

# Must be .py, .yaml and .yml files or just plain python modules (such as my.module).
workspace.set_root(workspace_dir, libspec_manager=libspec_manager)
doc = workspace.put_doc("my.robot")
doc.source = """*** Settings ***
Variables ./variables/var_i"""

completions = filesystem_section_completions.complete(
CompletionContext(doc, workspace=workspace.ws)
)
data_regression.check(completions)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
- deprecated: false
documentation: ''
insertText: var_in_init/
insertTextFormat: 2
kind: 9
label: var_in_init/
preselect: false
textEdit:
newText: var_in_init/
range:
end:
character: 25
line: 1
start:
character: 22
line: 1
- deprecated: false
documentation: ''
insertText: variables/
insertTextFormat: 2
kind: 9
label: variables/
preselect: false
textEdit:
newText: variables/
range:
end:
character: 25
line: 1
start:
character: 22
line: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- deprecated: false
documentation: ''
insertText: var_in_pythonpath.py
insertTextFormat: 2
kind: 9
label: var_in_pythonpath.py
preselect: false
textEdit:
newText: var_in_pythonpath.py
range:
end:
character: 37
line: 1
start:
character: 32
line: 1

0 comments on commit 09a67f1

Please sign in to comment.