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  }