internal/lsp: fix formatting bug that keeps adding extra newlines
If a file ends with an empty newline, go/token treats the newline as the final character of the previous line. VSCode, however, treats this as a final line with no characters. We handle this by determining if the file we are formatting ends with a newline character and updating the protocol ranges accordingly. Change-Id: Id8be0fd776ae65c8f0f937f3e718825e407cb217 Reviewed-on: https://go-review.googlesource.com/c/150338 Reviewed-by: Ian Cottrell <iancottrell@google.com> Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
fc4f04983f
commit
b6bf295893
|
@ -277,21 +277,36 @@ func formatRange(ctx context.Context, v *source.View, uri protocol.DocumentURI,
|
|||
} else {
|
||||
r = fromProtocolRange(tok, *rng)
|
||||
}
|
||||
content, err := f.Read()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
edits, err := source.Format(ctx, f, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toProtocolEdits(tok, edits), nil
|
||||
return toProtocolEdits(tok, content, edits), nil
|
||||
}
|
||||
|
||||
func toProtocolEdits(f *token.File, edits []source.TextEdit) []protocol.TextEdit {
|
||||
func toProtocolEdits(tok *token.File, content []byte, edits []source.TextEdit) []protocol.TextEdit {
|
||||
if edits == nil {
|
||||
return nil
|
||||
}
|
||||
// When a file ends with an empty line, the newline character is counted
|
||||
// as part of the previous line. This causes the formatter to insert
|
||||
// another unnecessary newline on each formatting. We handle this case by
|
||||
// checking if the file already ends with a newline character.
|
||||
hasExtraNewline := content[len(content)-1] == '\n'
|
||||
result := make([]protocol.TextEdit, len(edits))
|
||||
for i, edit := range edits {
|
||||
rng := toProtocolRange(tok, edit.Range)
|
||||
// If the edit ends at the end of the file, add the extra line.
|
||||
if hasExtraNewline && tok.Offset(edit.Range.End) == len(content) {
|
||||
rng.End.Line++
|
||||
rng.End.Character = 0
|
||||
}
|
||||
result[i] = protocol.TextEdit{
|
||||
Range: toProtocolRange(f, edit.Range),
|
||||
Range: rng,
|
||||
NewText: edit.NewText,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue