Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pygls 1.0.0a0 #230

Merged
merged 8 commits into from
Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions jedi_language_server/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
"""Jedi Language Server."""
import sys

if sys.version_info < (3, 8):
from importlib_metadata import version
else:
from importlib.metadata import version

__version__ = version("jedi-language-server")
22 changes: 2 additions & 20 deletions jedi_language_server/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,13 @@
import logging
import sys

from . import __version__
from .server import SERVER


def get_version() -> str:
"""Get the program version."""
# pylint: disable=import-outside-toplevel
try:
# Type checker for Python < 3.8 fails.
# Since this ony happens here, we just ignore.
from importlib.metadata import version # type: ignore
except ImportError:
try:
# Below ignored both because this a redefinition from above, and
# because importlib_metadata isn't known by mypy. Ignored because
# this is intentional.
from importlib_metadata import version # type: ignore
except ImportError:
print(
"Error: unable to get version. "
"If using Python < 3.8, you must install "
"`importlib_metadata` to get the version.",
file=sys.stderr,
)
sys.exit(1)
return version("jedi-language-server")
return __version__


def cli() -> None:
Expand Down
2 changes: 1 addition & 1 deletion jedi_language_server/initialization_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

from typing import List, Optional, Pattern, Set

from lsprotocol.types import MarkupKind
from pydantic import BaseModel, Field
from pygls.lsp.types import MarkupKind

# pylint: disable=missing-class-docstring
# pylint: disable=too-few-public-methods
Expand Down
15 changes: 12 additions & 3 deletions jedi_language_server/jedi_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import jedi.settings
from jedi import Project, Script
from jedi.api.classes import BaseName, Completion, Name, ParamName, Signature
from pygls.lsp.types import (
from lsprotocol.types import (
CompletionItem,
CompletionItemKind,
Diagnostic,
Expand Down Expand Up @@ -150,14 +150,23 @@ def lsp_document_symbols(names: List[Name]) -> List[DocumentSymbol]:
accessible with dot notation are removed from display. See comments
inline for cleaning steps.
"""
# pylint: disable=too-many-branches
_name_lookup: Dict[Name, DocumentSymbol] = {}
results: List[DocumentSymbol] = []
for name in names:
symbol_range = _document_symbol_range(name)
if symbol_range is None:
continue

selection_range = lsp_range(name)
if selection_range is None:
continue

symbol = DocumentSymbol(
name=name.name,
kind=get_lsp_symbol_type(name.type),
range=_document_symbol_range(name),
selection_range=lsp_range(name),
range=symbol_range,
selection_range=selection_range,
detail=name.description,
children=[],
)
Expand Down
2 changes: 1 addition & 1 deletion jedi_language_server/pygls_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from typing import Optional

from pygls.lsp.types import Position, Range
from lsprotocol.types import Position, Range
from pygls.workspace import Document


Expand Down
68 changes: 38 additions & 30 deletions jedi_language_server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,27 @@
import itertools
from typing import Any, List, Optional, Union

from jedi import Project
from jedi import Project, __version__
from jedi.api.refactoring import RefactoringError
from pydantic import ValidationError
from pygls.lsp.methods import (
CODE_ACTION,
COMPLETION,
from lsprotocol.types import (
COMPLETION_ITEM_RESOLVE,
DEFINITION,
DOCUMENT_HIGHLIGHT,
DOCUMENT_SYMBOL,
HOVER,
INITIALIZE,
REFERENCES,
RENAME,
SIGNATURE_HELP,
TEXT_DOCUMENT_CODE_ACTION,
TEXT_DOCUMENT_COMPLETION,
TEXT_DOCUMENT_DEFINITION,
TEXT_DOCUMENT_DID_CHANGE,
TEXT_DOCUMENT_DID_CLOSE,
TEXT_DOCUMENT_DID_OPEN,
TEXT_DOCUMENT_DID_SAVE,
TYPE_DEFINITION,
TEXT_DOCUMENT_DOCUMENT_HIGHLIGHT,
TEXT_DOCUMENT_DOCUMENT_SYMBOL,
TEXT_DOCUMENT_HOVER,
TEXT_DOCUMENT_REFERENCES,
TEXT_DOCUMENT_RENAME,
TEXT_DOCUMENT_SIGNATURE_HELP,
TEXT_DOCUMENT_TYPE_DEFINITION,
WORKSPACE_DID_CHANGE_CONFIGURATION,
WORKSPACE_SYMBOL,
)
from pygls.lsp.types import (
CodeAction,
CodeActionKind,
CodeActionOptions,
Expand Down Expand Up @@ -66,6 +63,8 @@
WorkspaceEdit,
WorkspaceSymbolParams,
)
from pydantic import ValidationError
from pygls.capabilities import get_capability
from pygls.protocol import LanguageServerProtocol, lsp_method
from pygls.server import LanguageServer

Expand Down Expand Up @@ -126,7 +125,7 @@ def lsp_initialize(self, params: InitializeParams) -> InitializeResult:
server.feature(TEXT_DOCUMENT_DID_CLOSE)(did_close)

if server.initialization_options.hover.enable:
server.feature(HOVER)(hover)
server.feature(TEXT_DOCUMENT_HOVER)(hover)

initialize_result: InitializeResult = super().lsp_initialize(params)
workspace_options = initialization_options.workspace
Expand Down Expand Up @@ -160,7 +159,11 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)


SERVER = JediLanguageServer(protocol_cls=JediLanguageServerProtocol)
SERVER = JediLanguageServer(
name="jedi-language-server",
version=__version__,
protocol_cls=JediLanguageServerProtocol,
)


# Server capabilities
Expand All @@ -178,7 +181,7 @@ def completion_item_resolve(


@SERVER.feature(
COMPLETION,
TEXT_DOCUMENT_COMPLETION,
CompletionOptions(
trigger_characters=[".", "'", '"'], resolve_provider=True
),
Expand All @@ -205,8 +208,10 @@ def completion(
for comp in completions_jedi_raw
if not any(i.match(comp.name) for i in ignore_patterns)
)
snippet_support = server.client_capabilities.get_capability(
"text_document.completion.completion_item.snippet_support", False
snippet_support = get_capability(
server.client_capabilities,
"text_document.completion.completion_item.snippet_support",
False,
)
markup_kind = _choose_markup(server)
is_import_context = jedi_utils.is_import(
Expand Down Expand Up @@ -244,7 +249,8 @@ def completion(


@SERVER.feature(
SIGNATURE_HELP, SignatureHelpOptions(trigger_characters=["(", ","])
TEXT_DOCUMENT_SIGNATURE_HELP,
SignatureHelpOptions(trigger_characters=["(", ","]),
)
def signature_help(
server: JediLanguageServer, params: TextDocumentPositionParams
Expand Down Expand Up @@ -290,7 +296,7 @@ def signature_help(
)


@SERVER.feature(DEFINITION)
@SERVER.feature(TEXT_DOCUMENT_DEFINITION)
def definition(
server: JediLanguageServer, params: TextDocumentPositionParams
) -> Optional[List[Location]]:
Expand All @@ -311,7 +317,7 @@ def definition(
return definitions if definitions else None


@SERVER.feature(TYPE_DEFINITION)
@SERVER.feature(TEXT_DOCUMENT_TYPE_DEFINITION)
def type_definition(
server: JediLanguageServer, params: TextDocumentPositionParams
) -> Optional[List[Location]]:
Expand All @@ -328,7 +334,7 @@ def type_definition(
return definitions if definitions else None


@SERVER.feature(DOCUMENT_HIGHLIGHT)
@SERVER.feature(TEXT_DOCUMENT_DOCUMENT_HIGHLIGHT)
def highlight(
server: JediLanguageServer, params: TextDocumentPositionParams
) -> Optional[List[DocumentHighlight]]:
Expand Down Expand Up @@ -384,7 +390,7 @@ def hover(
return Hover(contents=contents, range=_range)


@SERVER.feature(REFERENCES)
@SERVER.feature(TEXT_DOCUMENT_REFERENCES)
def references(
server: JediLanguageServer, params: TextDocumentPositionParams
) -> Optional[List[Location]]:
Expand All @@ -401,7 +407,7 @@ def references(
return locations if locations else None


@SERVER.feature(DOCUMENT_SYMBOL)
@SERVER.feature(TEXT_DOCUMENT_DOCUMENT_SYMBOL)
def document_symbol(
server: JediLanguageServer, params: DocumentSymbolParams
) -> Optional[Union[List[DocumentSymbol], List[SymbolInformation]]]:
Expand All @@ -426,7 +432,8 @@ def document_symbol(
document = server.workspace.get_document(params.text_document.uri)
jedi_script = jedi_utils.script(server.project, document)
names = jedi_script.get_names(all_scopes=True, definitions=True)
if server.client_capabilities.get_capability(
if get_capability(
server.client_capabilities,
"text_document.document_symbol.hierarchical_document_symbol_support",
False,
):
Expand Down Expand Up @@ -499,7 +506,7 @@ def workspace_symbol(
return symbols if symbols else None


@SERVER.feature(RENAME)
@SERVER.feature(TEXT_DOCUMENT_RENAME)
def rename(
server: JediLanguageServer, params: RenameParams
) -> Optional[WorkspaceEdit]:
Expand All @@ -518,7 +525,7 @@ def rename(


@SERVER.feature(
CODE_ACTION,
TEXT_DOCUMENT_CODE_ACTION,
CodeActionOptions(
code_action_kinds=[
CodeActionKind.RefactorInline,
Expand Down Expand Up @@ -702,7 +709,8 @@ def did_close_default(
def _choose_markup(server: JediLanguageServer) -> MarkupKind:
"""Returns the preferred or first of supported markup kinds."""
markup_preferred = server.initialization_options.markup_kind_preferred
markup_supported = server.client_capabilities.get_capability(
markup_supported = get_capability(
server.client_capabilities,
"text_document.completion.completion_item.documentation_format",
[MarkupKind.PlainText],
)
Expand Down
18 changes: 10 additions & 8 deletions jedi_language_server/text_edit_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
from typing import Iterator, List, NamedTuple, Union

from jedi.api.refactoring import ChangedFile, Refactoring
from pygls.lsp.types import (
from lsprotocol.types import (
AnnotatedTextEdit,
CreateFile,
DeleteFile,
OptionalVersionedTextDocumentIdentifier,
Position,
Range,
RenameFile,
RenameFileOptions,
ResourceOperationKind,
TextDocumentEdit,
TextEdit,
VersionedTextDocumentIdentifier,
)
from pygls.workspace import Document, Workspace

Expand All @@ -36,7 +38,7 @@ def is_valid_python(code: str) -> bool:
def lsp_document_changes(
workspace: Workspace,
refactoring: Refactoring,
) -> List[Union[TextDocumentEdit, RenameFile]]:
) -> List[Union[TextDocumentEdit, RenameFile, CreateFile, DeleteFile]]:
"""Get lsp text document edits from Jedi refactoring.

This is the main public function that you probably want
Expand All @@ -59,7 +61,7 @@ def lsp_renames(self) -> Iterator[RenameFile]:
"""Get all File rename operations."""
for old_name, new_name in self.refactoring.get_renames():
yield RenameFile(
kind=ResourceOperationKind.Rename,
kind="rename",
old_uri=old_name.as_uri(),
new_uri=new_name.as_uri(),
options=RenameFileOptions(
Expand All @@ -77,7 +79,7 @@ def lsp_text_document_edits(self) -> Iterator[TextDocumentEdit]:
text_edits = lsp_text_edits(document, changed_file)
if text_edits:
yield TextDocumentEdit(
text_document=VersionedTextDocumentIdentifier(
text_document=OptionalVersionedTextDocumentIdentifier(
uri=uri,
version=version,
),
Expand All @@ -90,7 +92,7 @@ def lsp_text_document_edits(self) -> Iterator[TextDocumentEdit]:

def lsp_text_edits(
document: Document, changed_file: ChangedFile
) -> List[TextEdit]:
) -> List[Union[TextEdit, AnnotatedTextEdit]]:
"""Take a jedi `ChangedFile` and convert to list of text edits.

Handles inserts, replaces, and deletions within a text file.
Expand All @@ -103,7 +105,7 @@ def lsp_text_edits(

old_code = document.source
position_lookup = PositionLookup(old_code)
text_edits = []
text_edits: List[Union[TextEdit, AnnotatedTextEdit]] = []
for opcode in get_opcodes(old_code, new_code):
if opcode.op in _OPCODES_CHANGE:
start = position_lookup.get(opcode.old_start)
Expand Down
2 changes: 1 addition & 1 deletion jedi_language_server/type_map.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Jedi types mapped to LSP types."""

from pygls.lsp.types import CompletionItemKind, SymbolKind
from lsprotocol.types import CompletionItemKind, SymbolKind

# See docs:
# https://jedi.readthedocs.io/en/latest/docs/api-classes.html?highlight=type#jedi.api.classes.BaseName.type
Expand Down
Loading