Skip to content

Commit

Permalink
fix: respect client's preferred encoding when possible
Browse files Browse the repository at this point in the history
Previously, `pygls` would always use `UTF-16` except when the client
tried to hide the fact that it supports `UTF-16` (which the LSP spec
requires it to do in all cases). Now, `pygls` will choose the editor's
preferred encoding.

When it is `UTF-32`, `pygls` saves a bit of computation in most
position codec related operations (`X_to_client_units` +
`client_num_units` are faster, `X_from_client_units` is about the
same), which is great. When it is `UTF-16` or `UTF-8`, the
computational load is about the same.

Closes: openlawlibrary#445
  • Loading branch information
nthykier committed Apr 6, 2024
1 parent 850b86c commit ae17dac
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
23 changes: 13 additions & 10 deletions pygls/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
logger = logging.getLogger(__name__)
T = TypeVar("T")

_SUPPORTED_ENCODINGS = frozenset(
[
types.PositionEncodingKind.Utf8,
types.PositionEncodingKind.Utf16,
types.PositionEncodingKind.Utf32,
]
)


def get_capability(
client_capabilities: types.ClientCapabilities, field: str, default: Any = None
Expand Down Expand Up @@ -401,16 +409,11 @@ def _with_position_encodings(self):
if encodings is None:
return self

if types.PositionEncodingKind.Utf16 in encodings:
return self

if types.PositionEncodingKind.Utf32 in encodings:
self.server_cap.position_encoding = types.PositionEncodingKind.Utf32
return self

if types.PositionEncodingKind.Utf8 in encodings:
self.server_cap.position_encoding = types.PositionEncodingKind.Utf8
return self
# We match client preference where this an overlap between its and our supported encodings.
for encoding in encodings:
if encoding in _SUPPORTED_ENCODINGS:
self.server_cap.position_encoding = encoding
return self

logger.warning(f"Unknown `PositionEncoding`s: {encodings}")

Expand Down
13 changes: 13 additions & 0 deletions tests/test_feature_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,19 @@ def server_capabilities(**kwargs):
]
)
),
server_capabilities(position_encoding=lsp.PositionEncodingKind.Utf8),
),
(
lsp.INITIALIZE,
None,
lsp.ClientCapabilities(
general=lsp.GeneralClientCapabilities(
position_encodings=[
lsp.PositionEncodingKind.Utf32,
lsp.PositionEncodingKind.Utf8,
]
)
),
server_capabilities(position_encoding=lsp.PositionEncodingKind.Utf32),
),
(
Expand Down

0 comments on commit ae17dac

Please sign in to comment.