chore: more server fixes
This commit is contained in:
parent
7b9363c828
commit
bbcc718c8d
3 changed files with 19 additions and 17 deletions
|
|
@ -12,8 +12,11 @@ universes u
|
|||
structure String :=
|
||||
(data : List Char)
|
||||
|
||||
/-- A character position in an UTF-8 encoded string.
|
||||
To represent codepoint positions, use a plain `Nat`. -/
|
||||
/-- A byte position in a `String`. Internally, `String`s are UTF-8 encoded.
|
||||
Codepoint positions (counting the Unicode codepoints rather than bytes)
|
||||
are represented by plain `Nat`s instead.
|
||||
Indexing a `String` by a byte position is constant-time, while codepoint
|
||||
positions need to be translated internally to byte positions in linear-time. -/
|
||||
abbrev String.Pos := Nat
|
||||
|
||||
structure Substring :=
|
||||
|
|
|
|||
|
|
@ -72,12 +72,5 @@ text.source.codepointPosToUtf8PosFrom colPos chr
|
|||
def leanPosToLspPos (text : FileMap) : Lean.Position → Lsp.Position
|
||||
| ⟨ln, col⟩ => ⟨ln-1, text.source.codepointPosToUtf16PosFrom col (text.positions.get! $ ln - 1)⟩
|
||||
|
||||
def replaceLspRange (text : FileMap) (r : Lsp.Range) (newText : String) : FileMap :=
|
||||
let start := text.lspPosToUtf8Pos r.start;
|
||||
let «end» := text.lspPosToUtf8Pos r.«end»;
|
||||
let pre := text.source.extract 0 start;
|
||||
let post := text.source.extract «end» text.source.bsize;
|
||||
(pre ++ newText ++ post).toFileMap
|
||||
|
||||
end FileMap
|
||||
end Lean
|
||||
|
|
|
|||
|
|
@ -130,17 +130,23 @@ writeLspNotification "textDocument/publishDiagnostics"
|
|||
|
||||
def handleDidOpen (p : DidOpenTextDocumentParams) : ServerM Unit := do
|
||||
let doc := p.textDocument;
|
||||
-- LSP is EOL agnostic, so we first split on "\r\n" to avoid possibly redundant line breaks.
|
||||
let splitOnEOLs (s : String) : List String := (do
|
||||
line ← s.splitOn "\r\n";
|
||||
line ← line.splitOn "\n";
|
||||
line ← line.splitOn "\r";
|
||||
pure line);
|
||||
let text := ("\n".intercalate $ splitOnEOLs doc.text).toFileMap;
|
||||
-- NOTE(WN): `toFileMap` marks line beginnings as immediately following
|
||||
-- "\n", which should be enough to handle both LF and CRLF correctly.
|
||||
-- This is because LSP always refers to characters by (line, column),
|
||||
-- so if we get the line number correct it shouldn't matter that there
|
||||
-- is a CR there.
|
||||
let text := doc.text.toFileMap;
|
||||
(msgLog, newDoc) ← monadLift $ compileDocument doc.version text;
|
||||
updateOpenDocuments doc.uri newDoc;
|
||||
sendDiagnostics doc.uri newDoc msgLog
|
||||
|
||||
private def replaceLspRange (text : FileMap) (r : Lsp.Range) (newText : String) : FileMap :=
|
||||
let start := text.lspPosToUtf8Pos r.start;
|
||||
let «end» := text.lspPosToUtf8Pos r.«end»;
|
||||
let pre := text.source.extract 0 start;
|
||||
let post := text.source.extract «end» text.source.bsize;
|
||||
(pre ++ newText ++ post).toFileMap
|
||||
|
||||
def handleDidChange (p : DidChangeTextDocumentParams) : ServerM Unit := do
|
||||
let docId := p.textDocument;
|
||||
let changes := p.contentChanges;
|
||||
|
|
@ -152,7 +158,7 @@ else changes.forM $ fun change =>
|
|||
match change with
|
||||
| TextDocumentContentChangeEvent.rangeChange (range : Range) (newText : String) => do
|
||||
let startOff := oldDoc.text.lspPosToUtf8Pos range.start;
|
||||
let newDocText := oldDoc.text.replaceLspRange range newText;
|
||||
let newDocText := replaceLspRange oldDoc.text range newText;
|
||||
(msgLog, newDoc) ← monadLift $
|
||||
updateDocument oldDoc startOff newVersion newDocText;
|
||||
updateOpenDocuments docId.uri newDoc;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue