Exemplo n.º 1
0
    def request_completions(self, event: utils.EventWithData) -> None:
        if self._lsp_client.state != lsp.ClientState.NORMAL:
            self.log.warning(
                f"autocompletions requested but langserver state == {self._lsp_client.state!r}"
            )
            return

        tab = event.widget
        assert isinstance(tab, tabs.FileTab) and tab.path is not None
        request = event.data_class(autocomplete.Request)

        lsp_id = self._lsp_client.completions(
            text_document_position=lsp.TextDocumentPosition(
                textDocument=lsp.TextDocumentIdentifier(uri=tab.path.as_uri()),
                position=_position_tk2lsp(request.cursor_pos),
            ),
            context=lsp.CompletionContext(
                # FIXME: this isn't always the case, porcupine can also trigger
                #        it automagically
                triggerKind=lsp.CompletionTriggerKind.INVOKED
            ),
        )

        assert lsp_id not in self._lsp_id_to_tab_and_request
        self._lsp_id_to_tab_and_request[lsp_id] = (tab, request)
Exemplo n.º 2
0
def do_stuff_with_a_langserver(tmp_path, filename, file_content, language_id,
                               command):
    path = tmp_path / filename
    path.write_text(file_content)

    with run_langserver(tmp_path, command) as (lsp_client, event_iter):
        inited = next(event_iter)
        assert isinstance(inited, lsp.Initialized)
        lsp_client.did_open(
            lsp.TextDocumentItem(uri=path.as_uri(),
                                 languageId=language_id,
                                 text=file_content,
                                 version=0))

        diagnostics = next(event_iter)
        assert isinstance(diagnostics, lsp.PublishDiagnostics)
        assert diagnostics.uri == path.as_uri()

        event_id = lsp_client.completions(
            text_document_position=lsp.TextDocumentPosition(
                textDocument=lsp.TextDocumentIdentifier(uri=path.as_uri()),
                position=lsp.Position(
                    # first line = 0, first column = 0
                    line=file_content.count("\n"),
                    character=len(file_content.split("\n")[-1]),
                ),
            ),
            context=lsp.CompletionContext(
                triggerKind=lsp.CompletionTriggerKind.INVOKED),
        )
        completions = next(event_iter)
        assert completions.message_id == event_id

        return (diagnostics, completions)
Exemplo n.º 3
0
def do_server_method(tserver, method, text, file_uri, response_type=None):
    def doc_pos():  # SKIP
        x, y = get_meth_text_pos(text=text, method=method)
        return lsp.TextDocumentPosition(
            textDocument=lsp.TextDocumentIdentifier(uri=file_uri),
            position=lsp.Position(line=y, character=x),
        )

    if not response_type:
        response_type = RESPONSE_TYPES[method]

    if method == METHOD_COMPLETION:
        event_id = tserver.lsp_client.completion(
            text_document_position=doc_pos(),
            context=lsp.CompletionContext(
                triggerKind=lsp.CompletionTriggerKind.INVOKED),
        )
    elif method == METHOD_HOVER:
        event_id = tserver.lsp_client.hover(text_document_position=doc_pos())

    elif method == METHOD_SIG_HELP:
        event_id = tserver.lsp_client.signatureHelp(
            text_document_position=doc_pos())

    elif method == METHOD_DEFINITION:
        event_id = tserver.lsp_client.definition(
            text_document_position=doc_pos())

    elif method == METHOD_REFERENCES:
        event_id = tserver.lsp_client.references(
            text_document_position=doc_pos())

    elif method == METHOD_IMPLEMENTATION:
        event_id = tserver.lsp_client.implementation(
            text_document_position=doc_pos())

    elif method == METHOD_DECLARATION:
        event_id = tserver.lsp_client.declaration(
            text_document_position=doc_pos())

    elif method == METHOD_TYPEDEF:
        event_id = tserver.lsp_client.typeDefinition(
            text_document_position=doc_pos())

    elif method == METHOD_DOC_SYMBOLS:
        _docid = lsp.TextDocumentIdentifier(uri=file_uri)
        event_id = tserver.lsp_client.documentSymbol(text_document=_docid)

    else:
        raise NotImplementedError(method)

    # "blocking" -- will wait for message
    resp = tserver.get_msg_by_type(response_type)
    assert not hasattr(resp, "message_id") or resp.message_id == event_id
    return resp
Exemplo n.º 4
0
def test_pyls(server_pyls):
    tserver, project_root = server_pyls

    text = textwrap.dedent(f"""\
        import sys
        def do_foo(): #{METHOD_DEFINITION}-5
            sys.getdefaultencoding() #{METHOD_HOVER}-5
        def do_bar(): #{METHOD_REFERENCES}-5
            sys.intern("hey") #{METHOD_SIG_HELP}-2

        do_ #{METHOD_COMPLETION}-1""")
    filename = "foo.py"
    path = project_root / filename
    path.write_text(text)
    language_id = "python"

    inited = tserver.get_msg_by_type(lsp.Initialized)

    tserver.lsp_client.did_open(
        lsp.TextDocumentItem(uri=path.as_uri(),
                             languageId=language_id,
                             text=text,
                             version=0))

    # Dignostics #####
    diagnostics = tserver.get_msg_by_type(lsp.PublishDiagnostics)
    assert diagnostics.uri == path.as_uri()

    diag_msgs = [diag.message for diag in diagnostics.diagnostics]
    assert "undefined name 'do_'" in diag_msgs
    assert "E302 expected 2 blank lines, found 0" in diag_msgs
    assert "W292 no newline at end of file" in diag_msgs

    do_meth_params = {
        "tserver": tserver,
        "text": text,
        "file_uri": path.as_uri()
    }

    # Completion #####
    completions = do_server_method(**do_meth_params, method=METHOD_COMPLETION)
    assert [item.label for item in completions.completion_list.items] == [
        "do_bar()",
        "do_foo()",
    ]

    # Hover #####
    hover = do_server_method(**do_meth_params, method=METHOD_HOVER)
    # NOTE: crude because response changes from one Python version to another
    assert "getdefaultencoding() -> str" in str(hover.contents)

    # signatureHelp #####
    sighelp = do_server_method(**do_meth_params, method=METHOD_SIG_HELP)

    assert len(sighelp.signatures) > 0
    active_sig = sighelp.signatures[sighelp.activeSignature]
    assert isinstance(active_sig, lsp.SignatureInformation)
    assert len(active_sig.parameters) > 0
    assert isinstance(active_sig.parameters[0], lsp.ParameterInformation)

    # definition #####
    definitions = do_server_method(**do_meth_params, method=METHOD_DEFINITION)

    assert isinstance(definitions.result, lsp.Location) or len(
        definitions.result) == 1
    item = (definitions.result[0]
            if isinstance(definitions.result, list) else definitions.result)
    assert isinstance(item, (lsp.Location, lsp.LocationLink))
    if isinstance(item, lsp.Location):
        assert item.uri == path.as_uri()
        definition_line = next(i for i, line in enumerate(text.splitlines())
                               if METHOD_DEFINITION in line)
        assert item.range.start.line == definition_line
    else:  # LocationLink
        raise NotImplementedError("pyls `LocationLink` definition results")

    # references #####
    refs = do_server_method(**do_meth_params, method=METHOD_REFERENCES)

    assert len(refs.result) == 1
    item = refs.result[0]
    assert isinstance(item, lsp.Location)
    ref_line = next(i for i, line in enumerate(text.splitlines())
                    if METHOD_REFERENCES in line)
    assert item.range.start.line == ref_line

    # documentSymbol #####
    doc_symbols = do_server_method(**do_meth_params, method=METHOD_DOC_SYMBOLS)
    assert len(doc_symbols.result) == 3
    symb_names = {s.name for s in doc_symbols.result}
    assert symb_names == {"sys", "do_foo", "do_bar"}

    # formatting #####
    tserver.lsp_client.formatting(
        text_document=lsp.TextDocumentIdentifier(uri=path.as_uri()),
        options=lsp.FormattingOptions(tabSize=4, insertSpaces=True),
    )
    formatting = tserver.get_msg_by_type(RESPONSE_TYPES[METHOD_FORMAT_DOC])
    assert formatting.result

    # Error -- method not supported by server #####
    tserver.lsp_client.workspace_symbol()
    err = tserver.get_msg_by_type(lsp.ResponseError)
    assert err.message == "Method Not Found: workspace/symbol"
Exemplo n.º 5
0
 def doc_pos():  # SKIP
     x, y = get_meth_text_pos(text=text, method=method)
     return lsp.TextDocumentPosition(
         textDocument=lsp.TextDocumentIdentifier(uri=file_uri),
         position=lsp.Position(line=y, character=x),
     )