You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on May 8, 2019. It is now read-only.
When auto-completing a line that contains an emoji (or any other multi-byte unicode character) the suggestions stop working.
For instance, typing let 💯 = Foo( does accurately bring up the suggestion box. However the suggestions are not relevant to the location of the current cursor position.
Overview
The problem is that FullTextDocument does not handle Unicode characters.
For example, say we have two Swift source documents:
ascii.swift
structFoo{letbar:Int}letx=Foo()
unicode.swift
struct Foo {
let bar: Int
}
let 💯 = Foo()
Both source documents have the same number of code points, e.g., 46, but they have a different number of bytes, e.g., 46 for ascii.swift and 49 for unicode.swift.
Therefore, if you were to ask for the byte-offset of the closing parenthesis in ascii.swift it would be 45. Compare that with unicode.swift which would have the value 48.
Example
Using the same above documents, ascii.swift and unicode.swift.
import*asfsfrom'fs';import{TextDocument,Position}from'vscode-languageserver';constascii='/path/to/ascii.swift';constunicode='/path/to/unicode.swift';// Load the text documentsletasciiBuffer: Promise<Buffer>=newPromise((resolve,reject)=>{fs.readFile(ascii,(err,data)=>{if(err){reject(err);}else{resolve(data);}});});letunicodeBuffer: Promise<Buffer>=newPromise((resolve,reject)=>{fs.readFile(unicode,(err,data)=>{if(err){reject(err);}else{resolve(data);}});});// REMEMBER Position is zero indexed!// https://github.com/Microsoft/vscode-languageserver-node/blob/a9f36d43a789e6fd9c16e5e50fc818eb35d097db/types/src/main.ts#L12letposition=Position.create(4,12);letasciiByteOffset=asciiBuffer.then((buffer)=>TextDocument.create(ascii,'swift',1,buffer.toString('utf8'))).then((document)=>document.offsetAt(position)).then(console.log);// logs 45 ✅letunicodeByteOffset=unicodeBuffer.then((buffer)=>TextDocument.create(unicode,'swift',1,buffer.toString('utf8'))).then((document)=>document.offsetAt(position)).then(console.log);// logs 45 ❌
Resolution?
One idea that I've been working towards is creating a new class UnicodeTextDocument that conforms to the TextDocument interface.
Which could serve as a drop-in replacement for TextDocument that transparently provides byte-offset.
Sadly this is probably going to roll into the next (or a subsequent) release. It turns out this is going to be more in-depth than I hoped.
Basically it boils down to the fact that the TextDocument's method, offsetAt is not a byte aware offset, like SourceKit requires. This means we need to write a byte aware version of TextDocument and/or offsetAt.
When auto-completing a line that contains an emoji (or any other multi-byte unicode character) the suggestions stop working.
For instance, typing
let 💯 = Foo(
does accurately bring up the suggestion box. However the suggestions are not relevant to the location of the current cursor position.Overview
The problem is that
FullTextDocument
does not handle Unicode characters.For example, say we have two Swift source documents:
ascii.swift
unicode.swift
Both source documents have the same number of code points, e.g., 46, but they have a different number of bytes, e.g., 46 for
ascii.swift
and 49 forunicode.swift
.Therefore, if you were to ask for the byte-offset of the closing parenthesis in
ascii.swift
it would be45
. Compare that withunicode.swift
which would have the value48
.Example
Using the same above documents,
ascii.swift
andunicode.swift
.Resolution?
One idea that I've been working towards is creating a new class
UnicodeTextDocument
that conforms to theTextDocument
interface.Which could serve as a drop-in replacement for
TextDocument
that transparently provides byte-offset.Such that you could do:
The text was updated successfully, but these errors were encountered: