github.com/jmigpin/editor@v1.6.0/util/iout/iorw/rwundo/mergeedits.go (about) 1 package rwundo 2 3 import ( 4 "bytes" 5 "unicode" 6 ) 7 8 ////godebug:annotatefile 9 10 func tryToMergeLastTwoEdits(hl *HList) { 11 editsL, elemsL := hl.NDoneBack(2) 12 if len(editsL) != 2 { 13 return 14 } 15 if insertConsecutiveLetters(editsL[0], editsL[1]) || 16 consecutiveSpaces(editsL[0], editsL[1]) { 17 hl.mergeToDoneBack(elemsL[0]) 18 } 19 } 20 21 //---------- 22 23 func insertConsecutiveLetters(ed1, ed2 *Edits) bool { 24 urs1 := ed1.Entries() 25 prev := urs1[0] 26 if !urIsLetterInsert(prev) { 27 return false 28 } 29 for i := 1; i < len(urs1); i++ { 30 e := urs1[i] 31 if !urIsLetterInsert(e) { 32 return false 33 } 34 if !urConsecutive(prev, e) { 35 return false 36 } 37 prev = e 38 } 39 urs2 := ed2.Entries() 40 for i := 0; i < len(urs2); i++ { 41 e := urs2[i] 42 if !urIsLetterInsert(e) { 43 return false 44 } 45 if !urConsecutive(prev, e) { 46 return false 47 } 48 prev = e 49 } 50 return true 51 } 52 53 //---------- 54 55 func consecutiveSpaces(ed1, ed2 *Edits) bool { 56 urs1 := ed1.Entries() 57 prev := urs1[0] 58 if !urIsSpace(prev) { 59 return false 60 } 61 for i := 1; i < len(urs1); i++ { 62 e := urs1[i] 63 if !urIsSpace(e) { 64 return false 65 } 66 if !urConsecutiveEitherSide(prev, e) { 67 return false 68 } 69 prev = e 70 } 71 urs2 := ed2.Entries() 72 for i := 0; i < len(urs2); i++ { 73 e := urs2[i] 74 if !urIsSpace(e) { 75 return false 76 } 77 if !urConsecutiveEitherSide(prev, e) { 78 return false 79 } 80 prev = e 81 } 82 return true 83 } 84 85 //---------- 86 87 func urIsLetterInsert(ur *UndoRedo) bool { 88 if ur.IsInsertOnly() { 89 r := []rune(string(ur.I)) 90 return len(r) == 1 && unicode.IsLetter(r[0]) 91 } 92 return false 93 } 94 95 func urIsSpace(ur *UndoRedo) bool { 96 return len(bytes.TrimSpace(ur.D)) == 0 && len(bytes.TrimSpace(ur.I)) == 0 97 } 98 99 func urConsecutive(ur1, ur2 *UndoRedo) bool { 100 return ur1.Index+len(ur1.I) == ur2.Index 101 } 102 103 func urConsecutiveEitherSide(ur1, ur2 *UndoRedo) bool { 104 return ur1.Index+len(ur1.I) == ur2.Index || // moved to the right 105 ur1.Index == ur2.Index+len(ur2.I) || // moved to the left 106 ur1.Index == ur2.Index // stayed in place 107 }