-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
internal/lsp: abstract the diff library so it can be substituted
this moves the actual diff algorithm into a different package and then provides hooks so it can be easily replaced with an alternate algorithm. Change-Id: Ia0359f58878493599ea0e0fda8920f21100e16f1 Reviewed-on: https://go-review.googlesource.com/c/tools/+/190898 Run-TryBot: Ian Cottrell <iancottrell@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
- Loading branch information
Showing
18 changed files
with
192 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright 2019 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package diff supports a pluggable diff algorithm. | ||
package diff | ||
|
||
import ( | ||
"sort" | ||
|
||
"golang.org/x/tools/internal/span" | ||
) | ||
|
||
// TextEdit represents a change to a section of a document. | ||
// The text within the specified span should be replaced by the supplied new text. | ||
type TextEdit struct { | ||
Span span.Span | ||
NewText string | ||
} | ||
|
||
var ( | ||
ComputeEdits func(uri span.URI, before, after string) []TextEdit | ||
ApplyEdits func(before string, edits []TextEdit) string | ||
ToUnified func(from, to string, before string, edits []TextEdit) string | ||
) | ||
|
||
func SortTextEdits(d []TextEdit) { | ||
// Use a stable sort to maintain the order of edits inserted at the same position. | ||
sort.SliceStable(d, func(i int, j int) bool { | ||
return span.Compare(d[i].Span, d[j].Span) < 0 | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright 2019 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package diff | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"golang.org/x/tools/internal/lsp/diff/myers" | ||
"golang.org/x/tools/internal/span" | ||
) | ||
|
||
func init() { | ||
ComputeEdits = myersComputeEdits | ||
ApplyEdits = myersApplyEdits | ||
ToUnified = myersToUnified | ||
} | ||
|
||
func myersComputeEdits(uri span.URI, before, after string) []TextEdit { | ||
u := myers.SplitLines(before) | ||
f := myers.SplitLines(after) | ||
return myersDiffToEdits(uri, myers.Operations(u, f)) | ||
} | ||
|
||
func myersApplyEdits(before string, edits []TextEdit) string { | ||
ops := myersEditsToDiff(edits) | ||
return strings.Join(myers.ApplyEdits(myers.SplitLines(before), ops), "") | ||
} | ||
|
||
func myersToUnified(from, to string, before string, edits []TextEdit) string { | ||
u := myers.SplitLines(before) | ||
ops := myersEditsToDiff(edits) | ||
return fmt.Sprint(myers.ToUnified(from, to, u, ops)) | ||
} | ||
|
||
func myersDiffToEdits(uri span.URI, ops []*myers.Op) []TextEdit { | ||
edits := make([]TextEdit, 0, len(ops)) | ||
for _, op := range ops { | ||
s := span.New(uri, span.NewPoint(op.I1+1, 1, 0), span.NewPoint(op.I2+1, 1, 0)) | ||
switch op.Kind { | ||
case myers.Delete: | ||
// Delete: unformatted[i1:i2] is deleted. | ||
edits = append(edits, TextEdit{Span: s}) | ||
case myers.Insert: | ||
// Insert: formatted[j1:j2] is inserted at unformatted[i1:i1]. | ||
if content := strings.Join(op.Content, ""); content != "" { | ||
edits = append(edits, TextEdit{Span: s, NewText: content}) | ||
} | ||
} | ||
} | ||
return edits | ||
} | ||
|
||
func myersEditsToDiff(edits []TextEdit) []*myers.Op { | ||
iToJ := 0 | ||
ops := make([]*myers.Op, len(edits)) | ||
for i, edit := range edits { | ||
i1 := edit.Span.Start().Line() - 1 | ||
i2 := edit.Span.End().Line() - 1 | ||
kind := myers.Insert | ||
if edit.NewText == "" { | ||
kind = myers.Delete | ||
} | ||
ops[i] = &myers.Op{ | ||
Kind: kind, | ||
Content: myers.SplitLines(edit.NewText), | ||
I1: i1, | ||
I2: i2, | ||
J1: i1 + iToJ, | ||
} | ||
if kind == myers.Insert { | ||
iToJ += len(ops[i].Content) | ||
} else { | ||
iToJ -= i2 - i1 | ||
} | ||
} | ||
return ops | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.