Fix left-most diff cases.
[lightning.git] / hgvs / diff.go
index e25e13b9200cdd4fd687271213b84b0d25f4743c..780cfacf10c1d3ba3b802f8c249fce4d1eef6031 100644 (file)
@@ -23,6 +23,10 @@ func (v *Variant) String() string {
        switch {
        case len(v.New) == 0 && len(v.Ref) == 0:
                return fmt.Sprintf("%d=", v.Position)
+       case len(v.New) == 1 && v.New == v.Ref:
+               return fmt.Sprintf("%d=", v.Position)
+       case v.New == v.Ref:
+               return fmt.Sprintf("%d_%d=", v.Position, v.Position+len(v.Ref)-1)
        case len(v.New) == 0 && len(v.Ref) == 1:
                return fmt.Sprintf("%ddel", v.Position)
        case len(v.New) == 0:
@@ -89,6 +93,17 @@ func Diff(a, b string, timeout time.Duration) ([]Variant, bool) {
                                v.New += diffs[i].Text
                        }
                }
+               if len(v.Ref) == 2 && len(v.New) == 2 {
+                       v1 := v
+                       v1.Ref = v1.Ref[:1]
+                       v1.New = v1.New[:1]
+                       v.Ref = v.Ref[1:]
+                       v.New = v.New[1:]
+                       v.Position++
+                       v.Left = v1.Ref
+                       pos++
+                       variants = append(variants, v1)
+               }
                pos += len(v.Ref)
                variants = append(variants, v)
                left = ""
@@ -129,6 +144,27 @@ func cleanup(in []diffmatchpatch.Diff) (out []diffmatchpatch.Diff) {
                        in[i+1] = ins
                        in[i+2] = eq
                }
+               // when diffmatchpatch says [=yyyyXXXX, delX, =zzz],
+               // we really want [=yyyy, delX, =XXXXzzz] (ditto for
+               // ins instead of del)
+               if i < len(in)-2 &&
+                       d.Type == diffmatchpatch.DiffEqual &&
+                       in[i+1].Type != diffmatchpatch.DiffEqual &&
+                       in[i+2].Type == diffmatchpatch.DiffEqual &&
+                       len(in[i+1].Text) <= len(d.Text) {
+                       for cut := 0; cut < len(d.Text); cut++ {
+                               skip := strings.Index(d.Text[cut:], in[i+1].Text)
+                               if skip < 0 {
+                                       break
+                               }
+                               cut += skip
+                               if d.Text[cut:]+in[i+1].Text == in[i+1].Text+d.Text[cut:] {
+                                       in[i+2].Text = d.Text[cut:] + in[i+2].Text
+                                       d.Text = d.Text[:cut]
+                                       break
+                               }
+                       }
+               }
                // diffmatchpatch solves diff("AXX","XXX") with
                // [delA,=XX,insX] but we prefer to spell it
                // [delA,insX,=XX].
@@ -189,6 +225,17 @@ func cleanup(in []diffmatchpatch.Diff) (out []diffmatchpatch.Diff) {
                }
                out = append(out, d)
        }
+       // for i := 0; i < len(out)-1; i++ {
+       //      if out[i].Type == diffmatchpatch.DiffDelete && len(out[i].Text) == 2 &&
+       //              out[i+1].Type == diffmatchpatch.DiffInsert && len(out[i+1].Text) == 2 {
+       //              out = append(out, diffmatchpatch.Diff{}, diffmatchpatch.Diff{})
+       //              copy(out[i+4:], out[i+2:])
+       //              out[i+2] = diffmatchpatch.Diff{diffmatchpatch.DiffDelete, out[i].Text[1:]}
+       //              out[i+3] = diffmatchpatch.Diff{diffmatchpatch.DiffInsert, out[i+1].Text[1:]}
+       //              out[i].Text = out[i].Text[:1]
+       //              out[i+1].Text = out[i+1].Text[:1]
+       //      }
+       // }
        return
 }