.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / github.com / google / go-cmp@v0.5.4 / cmp / internal / diff / debug_enable.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/github.com/google/go-cmp@v0.5.4/cmp/internal/diff/debug_enable.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/github.com/google/go-cmp@v0.5.4/cmp/internal/diff/debug_enable.go
new file mode 100644 (file)
index 0000000..4b91dbc
--- /dev/null
@@ -0,0 +1,122 @@
+// Copyright 2017, 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.
+
+// +build cmp_debug
+
+package diff
+
+import (
+       "fmt"
+       "strings"
+       "sync"
+       "time"
+)
+
+// The algorithm can be seen running in real-time by enabling debugging:
+//     go test -tags=cmp_debug -v
+//
+// Example output:
+//     === RUN   TestDifference/#34
+//     ┌───────────────────────────────┐
+//     │ \ · · · · · · · · · · · · · · │
+//     │ · # · · · · · · · · · · · · · │
+//     │ · \ · · · · · · · · · · · · · │
+//     │ · · \ · · · · · · · · · · · · │
+//     │ · · · X # · · · · · · · · · · │
+//     │ · · · # \ · · · · · · · · · · │
+//     │ · · · · · # # · · · · · · · · │
+//     │ · · · · · # \ · · · · · · · · │
+//     │ · · · · · · · \ · · · · · · · │
+//     │ · · · · · · · · \ · · · · · · │
+//     │ · · · · · · · · · \ · · · · · │
+//     │ · · · · · · · · · · \ · · # · │
+//     │ · · · · · · · · · · · \ # # · │
+//     │ · · · · · · · · · · · # # # · │
+//     │ · · · · · · · · · · # # # # · │
+//     │ · · · · · · · · · # # # # # · │
+//     │ · · · · · · · · · · · · · · \ │
+//     └───────────────────────────────┘
+//     [.Y..M.XY......YXYXY.|]
+//
+// The grid represents the edit-graph where the horizontal axis represents
+// list X and the vertical axis represents list Y. The start of the two lists
+// is the top-left, while the ends are the bottom-right. The '·' represents
+// an unexplored node in the graph. The '\' indicates that the two symbols
+// from list X and Y are equal. The 'X' indicates that two symbols are similar
+// (but not exactly equal) to each other. The '#' indicates that the two symbols
+// are different (and not similar). The algorithm traverses this graph trying to
+// make the paths starting in the top-left and the bottom-right connect.
+//
+// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents
+// the currently established path from the forward and reverse searches,
+// separated by a '|' character.
+
+const (
+       updateDelay  = 100 * time.Millisecond
+       finishDelay  = 500 * time.Millisecond
+       ansiTerminal = true // ANSI escape codes used to move terminal cursor
+)
+
+var debug debugger
+
+type debugger struct {
+       sync.Mutex
+       p1, p2           EditScript
+       fwdPath, revPath *EditScript
+       grid             []byte
+       lines            int
+}
+
+func (dbg *debugger) Begin(nx, ny int, f EqualFunc, p1, p2 *EditScript) EqualFunc {
+       dbg.Lock()
+       dbg.fwdPath, dbg.revPath = p1, p2
+       top := "┌─" + strings.Repeat("──", nx) + "┐\n"
+       row := "│ " + strings.Repeat("· ", nx) + "│\n"
+       btm := "└─" + strings.Repeat("──", nx) + "┘\n"
+       dbg.grid = []byte(top + strings.Repeat(row, ny) + btm)
+       dbg.lines = strings.Count(dbg.String(), "\n")
+       fmt.Print(dbg)
+
+       // Wrap the EqualFunc so that we can intercept each result.
+       return func(ix, iy int) (r Result) {
+               cell := dbg.grid[len(top)+iy*len(row):][len("│ ")+len("· ")*ix:][:len("·")]
+               for i := range cell {
+                       cell[i] = 0 // Zero out the multiple bytes of UTF-8 middle-dot
+               }
+               switch r = f(ix, iy); {
+               case r.Equal():
+                       cell[0] = '\\'
+               case r.Similar():
+                       cell[0] = 'X'
+               default:
+                       cell[0] = '#'
+               }
+               return
+       }
+}
+
+func (dbg *debugger) Update() {
+       dbg.print(updateDelay)
+}
+
+func (dbg *debugger) Finish() {
+       dbg.print(finishDelay)
+       dbg.Unlock()
+}
+
+func (dbg *debugger) String() string {
+       dbg.p1, dbg.p2 = *dbg.fwdPath, dbg.p2[:0]
+       for i := len(*dbg.revPath) - 1; i >= 0; i-- {
+               dbg.p2 = append(dbg.p2, (*dbg.revPath)[i])
+       }
+       return fmt.Sprintf("%s[%v|%v]\n\n", dbg.grid, dbg.p1, dbg.p2)
+}
+
+func (dbg *debugger) print(d time.Duration) {
+       if ansiTerminal {
+               fmt.Printf("\x1b[%dA", dbg.lines) // Reset terminal cursor
+       }
+       fmt.Print(dbg)
+       time.Sleep(d)
+}