Skip to content

Commit

Permalink
internal/lsp: fix formatting bug that keeps adding extra newlines
Browse files Browse the repository at this point in the history
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 <[email protected]>
Run-TryBot: Rebecca Stambler <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
stamblerre committed Nov 20, 2018
1 parent fc4f049 commit b6bf295
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions internal/lsp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Expand Down

0 comments on commit b6bf295

Please sign in to comment.