github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/vimdelete.go (about) 1 package readline 2 3 import "strings" 4 5 func (rl *Instance) vimDeleteStr(r []rune) string { 6 // TODO: test me 7 //defer func() { rl.modeViMode = vimKeys }() 8 9 var output string 10 switch r[0] { 11 case 'b': 12 output = rl.viDeleteByAdjustStr(rl.viJumpB(tokeniseLine)) 13 14 case 'B': 15 output = rl.viDeleteByAdjustStr(rl.viJumpB(tokeniseSplitSpaces)) 16 17 case 'd': 18 rl.clearPrompt() 19 rl.resetHelpers() 20 rl.getHintText() 21 22 case 'e': 23 output = rl.viDeleteByAdjustStr(rl.viJumpE(tokeniseLine) + 1) 24 25 case 'E': 26 output = rl.viDeleteByAdjustStr(rl.viJumpE(tokeniseSplitSpaces) + 1) 27 28 case 'w': 29 output = rl.viDeleteByAdjustStr(rl.viJumpW(tokeniseLine)) 30 31 case 'W': 32 output = rl.viDeleteByAdjustStr(rl.viJumpW(tokeniseSplitSpaces)) 33 34 case '%': 35 output = rl.viDeleteByAdjustStr(rl.viJumpBracket()) 36 37 case 27: 38 if len(r) > 1 && '1' <= r[1] && r[1] <= '9' { 39 output = rl.vimDeleteTokenStr(r[1]) 40 if output != "" { 41 rl.modeViMode = vimKeys 42 return output 43 } 44 } 45 fallthrough 46 47 default: 48 rl.viUndoSkipAppend = true 49 } 50 51 rl.modeViMode = vimKeys 52 53 return output 54 } 55 56 func (rl *Instance) viDeleteByAdjustStr(adjust int) string { 57 if adjust == 0 { 58 rl.viUndoSkipAppend = true 59 return "" 60 } 61 62 // Separate out the cursor movement from the logic so we can run tests on 63 // the logic 64 newLine, backOne := rl.viDeleteByAdjustLogic(&adjust) 65 66 rl.line.Set(rl, newLine) 67 68 output := rl.echoStr() 69 70 if adjust < 0 { 71 output += rl.moveCursorByRuneAdjustStr(adjust) 72 } 73 74 if backOne { 75 output += moveCursorBackwardsStr(1) 76 rl.line.SetRunePos(rl.line.RunePos() - 1) 77 } 78 79 return output 80 } 81 82 func (rl *Instance) viDeleteByAdjustLogic(adjust *int) (newLine []rune, backOne bool) { 83 switch { 84 case rl.line.RuneLen() == 0: 85 *adjust = 0 86 newLine = []rune{} 87 88 case rl.line.RunePos()+*adjust > rl.line.RuneLen()-1: 89 *adjust -= (rl.line.RunePos() + *adjust) - (rl.line.RuneLen() - 1) 90 fallthrough 91 92 case rl.line.RunePos()+*adjust == rl.line.RuneLen()-1: 93 newLine = rl.line.Runes()[:rl.line.RunePos()] 94 backOne = true 95 96 case rl.line.RunePos()+*adjust < 0: 97 *adjust = rl.line.RunePos() 98 fallthrough 99 100 case rl.line.RunePos()+*adjust == 0: 101 newLine = rl.line.Runes()[rl.line.RunePos():] 102 103 case *adjust < 0: 104 newLine = append(rl.line.Runes()[:rl.line.RunePos()+*adjust], rl.line.Runes()[rl.line.RunePos():]...) 105 106 default: 107 newLine = append(rl.line.Runes()[:rl.line.RunePos()], rl.line.Runes()[rl.line.RunePos()+*adjust:]...) 108 } 109 110 return 111 } 112 113 func (rl *Instance) vimDeleteTokenStr(r rune) string { 114 tokens, _, _ := tokeniseSplitSpaces(rl.line.Runes(), 0) 115 pos := int(r) - 48 // convert ASCII to integer 116 if pos > len(tokens) { 117 return "" 118 } 119 120 s := rl.line.String() 121 newLine := strings.Replace(s, tokens[pos-1], "", -1) 122 if newLine == s { 123 return "" 124 } 125 126 output := moveCursorBackwardsStr(rl.line.CellPos()) 127 output += strings.Repeat(" ", rl.line.CellLen()) 128 output += moveCursorBackwardsStr(rl.line.CellLen() - rl.line.CellPos()) 129 130 rl.line.Set(rl, []rune(newLine)) 131 132 output += rl.echoStr() 133 134 if rl.line.RunePos() > rl.line.RuneLen() { 135 output += "\r" //moveCursorBackwardsStr(GetTermWidth()) 136 output += moveCursorForwardsStr(rl.promptLen + rl.line.CellLen() - 1) 137 // ^ this is lazy 138 rl.line.SetRunePos(rl.line.RuneLen() - 1) 139 } 140 141 return output 142 }