Skip to content

Commit 58ca9f2

Browse files
committed
Handle surrogate pair when converting from LSP encoding
1 parent a51329a commit 58ca9f2

2 files changed

Lines changed: 17 additions & 0 deletions

File tree

ycmd/completers/language_server/language_server_protocol.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,12 @@ def UTF16CodeUnitsToCodepoints( line_value, code_unit_offset ):
823823
# is one-past-the-end of the string in unicode codepoints
824824
return len( line_value ) + 1
825825

826+
hi_byte_at_offset = value_as_utf16_bytes[byte_offset_utf16 + 1]
827+
if 0xdc <= hi_byte_at_offset <= 0xdf:
828+
# If we are in the middle of a surrogate pair, then advance the offset
829+
# further to skip the pair
830+
code_unit_offset += 1
831+
826832
bytes_included = value_as_utf16_bytes[ : code_unit_offset * 2 ]
827833
return len( bytes_included.decode( 'utf-16-le' ) )
828834

ycmd/tests/language_server/language_server_protocol_test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,14 @@ def test_CodepointsToUTF16CodeUnitsAndReverse( self ):
204204
equal_to( code_units ) )
205205
assert_that( lsp.UTF16CodeUnitsToCodepoints( line_value, code_units ),
206206
equal_to( codepoints ) )
207+
208+
def test_CodepointsToUTF16CodeUnitsSurrogate( self ):
209+
for line_value, codepoints, code_units in [
210+
( '😉', 1, 1 ),
211+
( 'f😉', 2, 2 ),
212+
]:
213+
with self.subTest( line_value = line_value,
214+
codepoints = codepoints,
215+
code_units = code_units ):
216+
assert_that( lsp.UTF16CodeUnitsToCodepoints( line_value, code_units ),
217+
equal_to( codepoints ) )

0 commit comments

Comments
 (0)