fix: UTF-16 strikes again
We need to report the jump target range in terms of a UTF-16 offset within the line, but to compute that we would have to load the target file, file-map it, and resolve that way each time the go-to-def handler runs. As an alternative, this stores the UTF-16 offsets in `DeclarationRange`.
This commit is contained in:
parent
e627ad308d
commit
90075153b3
3 changed files with 24 additions and 9 deletions
|
|
@ -9,8 +9,15 @@ import Lean.AuxRecursor
|
|||
namespace Lean
|
||||
|
||||
structure DeclarationRange where
|
||||
pos : Position
|
||||
endPos : Position
|
||||
pos : Position
|
||||
/-- A precomputed UTF-16 `character` field as in `Lean.Lsp.Position`. We need to store this
|
||||
because LSP clients want us to report the range in terms of UTF-16, but converting a Unicode
|
||||
codepoint stored in `Lean.Position` to UTF-16 requires loading and mapping the target source
|
||||
file, which is IO-heavy. -/
|
||||
charUtf16 : Nat
|
||||
endPos : Position
|
||||
/-- See `charUtf16`. -/
|
||||
endCharUtf16 : Nat
|
||||
deriving Inhabited, DecidableEq, Repr
|
||||
|
||||
structure DeclarationRanges where
|
||||
|
|
|
|||
|
|
@ -5,14 +5,21 @@ Authors: Leonardo de Moura
|
|||
-/
|
||||
import Lean.DeclarationRange
|
||||
import Lean.Elab.Log
|
||||
import Lean.Data.Lsp.Utf16
|
||||
|
||||
namespace Lean.Elab
|
||||
|
||||
def getDeclarationRange [Monad m] [MonadFileMap m] (stx : Syntax) : m DeclarationRange := do
|
||||
let pos := stx.getPos.getD 0
|
||||
let endPos := stx.getTailPos.getD pos
|
||||
let fileMap ← getFileMap
|
||||
return { pos := fileMap.toPosition pos, endPos := fileMap.toPosition endPos }
|
||||
let pos := stx.getPos.getD 0
|
||||
let endPos := stx.getTailPos.getD pos |> fileMap.toPosition
|
||||
let pos := pos |> fileMap.toPosition
|
||||
return {
|
||||
pos := pos
|
||||
charUtf16 := fileMap.leanPosToLspPos pos |>.character
|
||||
endPos := endPos
|
||||
endCharUtf16 := fileMap.leanPosToLspPos endPos |>.character
|
||||
}
|
||||
|
||||
/--
|
||||
For most builtin declarations, the selection range is just its name, which is stored in the second position.
|
||||
|
|
|
|||
|
|
@ -414,13 +414,14 @@ section RequestHandling
|
|||
let ranges? ← ci.runMetaM i.lctx <| findDeclarationRanges? n
|
||||
|
||||
if let (some ranges, some mod) := (ranges?, mod?) then
|
||||
let rangeToLspRange (r : DeclarationRange) : Lsp.Range :=
|
||||
⟨text.leanPosToLspPos r.pos, text.leanPosToLspPos r.endPos⟩
|
||||
let declRangeToLspRange (r : DeclarationRange) : Lsp.Range :=
|
||||
{ start := ⟨r.pos.line - 1, r.charUtf16⟩
|
||||
«end» := ⟨r.endPos.line - 1, r.endCharUtf16⟩ }
|
||||
let ll : LocationLink := {
|
||||
originSelectionRange? := some ⟨text.utf8PosToLspPos i.pos?.get!, text.utf8PosToLspPos i.tailPos?.get!⟩
|
||||
targetUri := mod
|
||||
targetRange := rangeToLspRange ranges.range
|
||||
targetSelectionRange := rangeToLspRange ranges.selectionRange
|
||||
targetRange := declRangeToLspRange ranges.range
|
||||
targetSelectionRange := declRangeToLspRange ranges.selectionRange
|
||||
}
|
||||
return #[ll]
|
||||
return #[]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue