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

refactor: rename server Position to PositionCodec, instantiate it in Workspace #383

Merged
merged 1 commit into from
Oct 2, 2023
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
58 changes: 32 additions & 26 deletions pygls/workspace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,77 +5,83 @@

from .workspace import Workspace
from .text_document import TextDocument
from .position import Position
from .position_codec import PositionCodec

Workspace = Workspace
TextDocument = TextDocument
Position = Position
PositionCodec = PositionCodec

# For backwards compatibility
Document = TextDocument


def utf16_unit_offset(chars: str):
warnings.warn(
"'utf16_unit_offset' has been deprecated, use "
"'Position.utf16_unit_offset' instead",
"'utf16_unit_offset' has been deprecated, instead use "
"'PositionCodec.utf16_unit_offset' via 'workspace.position_codec' "
"or 'text_document.position_codec'",
DeprecationWarning,
stacklevel=2,
)
_position = Position()
return _position.utf16_unit_offset(chars)
_codec = PositionCodec()
return _codec.utf16_unit_offset(chars)


def utf16_num_units(chars: str):
warnings.warn(
"'utf16_num_units' has been deprecated, use "
"'Position.client_num_units' instead",
"'utf16_num_units' has been deprecated, instead use "
"'PositionCodec.client_num_units' via 'workspace.position_codec' "
"or 'text_document.position_codec'",
DeprecationWarning,
stacklevel=2,
)
_position = Position()
return _position.client_num_units(chars)
_codec = PositionCodec()
return _codec.client_num_units(chars)


def position_from_utf16(lines: List[str], position: types.Position):
warnings.warn(
"'position_from_utf16' has been deprecated, use "
"'Position.position_from_client_units' instead",
"'position_from_utf16' has been deprecated, instead use "
"'PositionCodec.position_from_client_units' via "
"'workspace.position_codec' or 'text_document.position_codec'",
DeprecationWarning,
stacklevel=2,
)
_position = Position()
return _position.position_from_client_units(lines, position)
_codec = PositionCodec()
return _codec.position_from_client_units(lines, position)


def position_to_utf16(lines: List[str], position: types.Position):
warnings.warn(
"'position_to_utf16' has been deprecated, use "
"'Position.position_to_client_units' instead",
"'position_to_utf16' has been deprecated, instead use "
"'PositionCodec.position_to_client_units' via "
"'workspace.position_codec' or 'text_document.position_codec'",
DeprecationWarning,
stacklevel=2,
)
_position = Position()
return _position.position_to_client_units(lines, position)
_codec = PositionCodec()
return _codec.position_to_client_units(lines, position)


def range_from_utf16(lines: List[str], range: types.Range):
warnings.warn(
"'range_from_utf16' has been deprecated, use "
"'Position.range_from_client_units' instead",
"'range_from_utf16' has been deprecated, instead use "
"'PositionCodec.range_from_client_units' via "
"'workspace.position_codec' or 'text_document.position_codec'",
DeprecationWarning,
stacklevel=2,
)
_position = Position()
return _position.range_from_client_units(lines, range)
_codec = PositionCodec()
return _codec.range_from_client_units(lines, range)


def range_to_utf16(lines: List[str], range: types.Range):
warnings.warn(
"'range_to_utf16' has been deprecated, use "
"'Position.range_to_client_units' instead",
"'range_to_utf16' has been deprecated, instead use "
"'PositionCodec.range_to_client_units' via 'workspace.position_codec' "
"or 'text_document.position_codec'",
DeprecationWarning,
stacklevel=2,
)
_position = Position()
return _position.range_to_client_units(lines, range)
_codec = PositionCodec()
return _codec.range_to_client_units(lines, range)
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
log = logging.getLogger(__name__)


class Position:
class PositionCodec:
def __init__(
self,
encoding: Optional[
Expand Down Expand Up @@ -121,7 +121,9 @@ def position_from_client_units(
break

_current_char = _line[utf32_index]
_is_double_width = Position.is_char_beyond_multilingual_plane(_current_char)
_is_double_width = PositionCodec.is_char_beyond_multilingual_plane(
_current_char
)
if _is_double_width:
if self.encoding == types.PositionEncodingKind.Utf32:
_client_index += 1
Expand Down
24 changes: 14 additions & 10 deletions pygls/workspace/text_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
import logging
import os
import re
from typing import List, Optional, Pattern, Union
from typing import List, Optional, Pattern

from lsprotocol import types

from pygls.uris import to_fs_path
from .position import Position
from .position_codec import PositionCodec

# TODO: this is not the best e.g. we capture numbers
RE_END_WORD = re.compile("^[A-Za-z_0-9]*")
Expand All @@ -43,9 +43,7 @@ def __init__(
language_id: Optional[str] = None,
local: bool = True,
sync_kind: types.TextDocumentSyncKind = types.TextDocumentSyncKind.Incremental,
position_encoding: Optional[
Union[types.PositionEncodingKind, str]
] = types.PositionEncodingKind.Utf16,
position_codec: Optional[PositionCodec] = None,
):
self.uri = uri
self.version = version
Expand All @@ -65,11 +63,15 @@ def __init__(
)
self._is_sync_kind_none = sync_kind == types.TextDocumentSyncKind.None_

self.position = Position(encoding=position_encoding)
self._position_codec = position_codec if position_codec else PositionCodec()

def __str__(self):
return str(self.uri)

@property
def position_codec(self) -> PositionCodec:
return self._position_codec

def _apply_incremental_change(
self, change: types.TextDocumentContentChangeEvent_Type1
) -> None:
Expand All @@ -78,7 +80,7 @@ def _apply_incremental_change(
text = change.text
change_range = change.range

range = self.position.range_from_client_units(lines, change_range)
range = self._position_codec.range_from_client_units(lines, change_range)
start_line = range.start.line
start_col = range.start.character
end_line = range.end.line
Expand Down Expand Up @@ -165,11 +167,13 @@ def lines(self) -> List[str]:
def offset_at_position(self, client_position: types.Position) -> int:
"""Return the character offset pointed at by the given client_position."""
lines = self.lines
server_position = self.position.position_from_client_units(
server_position = self._position_codec.position_from_client_units(
lines, client_position
)
row, col = server_position.line, server_position.character
return col + sum(self.position.client_num_units(line) for line in lines[:row])
return col + sum(
self._position_codec.client_num_units(line) for line in lines[:row]
)

@property
def source(self) -> str:
Expand Down Expand Up @@ -217,7 +221,7 @@ def word_at_position(
if client_position.line >= len(lines):
return ""

server_position = self.position.position_from_client_units(
server_position = self._position_codec.position_from_client_units(
lines, client_position
)
row, col = server_position.line, server_position.character
Expand Down
12 changes: 11 additions & 1 deletion pygls/workspace/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
)
from pygls.uris import to_fs_path, uri_scheme
from pygls.workspace.text_document import TextDocument
from pygls.workspace.position_codec import PositionCodec

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -60,11 +61,20 @@ def __init__(
self._folders: Dict[str, WorkspaceFolder] = {}
self._docs: Dict[str, TextDocument] = {}
self._position_encoding = position_encoding
self._position_codec = PositionCodec(encoding=position_encoding)

if workspace_folders is not None:
for folder in workspace_folders:
self.add_folder(folder)

@property
def position_encoding(self) -> Optional[Union[PositionEncodingKind, str]]:
return self._position_encoding

@property
def position_codec(self) -> PositionCodec:
return self._position_codec

def _create_text_document(
self,
doc_uri: str,
Expand All @@ -78,7 +88,7 @@ def _create_text_document(
version=version,
language_id=language_id,
sync_kind=self._sync_kind,
position_encoding=self._position_encoding,
position_codec=self._position_codec,
)

def add_folder(self, folder: WorkspaceFolder):
Expand Down
Loading
Loading