feat: added forward/backward word keybinds (#139)

Added emacsForwardWord and emacsBackwardWord which is used by M-f and
M-b directly. Also added M-d to ctrl delete and removed the bad old
funcion in favor of the fancy new one. Lastly I added alt delete which
deletes with emacsBackwardWord. Works identically to gnu readline

Co-authored-by: Renzix <DanielDeBruno@renzix.com>
pull/143/head
Renzix 2022-04-14 07:42:46 -04:00 committed by GitHub
parent ded0be275f
commit 7f161e6683
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 13 deletions

View File

@ -50,8 +50,12 @@ var (
seqDelete2 = string([]byte{27, 91, 80}) seqDelete2 = string([]byte{27, 91, 80})
seqCtrlDelete = string([]byte{27, 91, 51, 59, 53, 126}) seqCtrlDelete = string([]byte{27, 91, 51, 59, 53, 126})
seqCtrlDelete2 = string([]byte{27, 91, 77}) seqCtrlDelete2 = string([]byte{27, 91, 77})
seqAltDelete = string([]byte{27, 91, 51, 59, 51, 126})
seqShiftTab = string([]byte{27, 91, 90}) seqShiftTab = string([]byte{27, 91, 90})
seqAltQuote = string([]byte{27, 34}) // Added for showing registers ^[" seqAltQuote = string([]byte{27, 34}) // Added for showing registers ^["
seqAltB = string([]byte{27, 98})
seqAltD = string([]byte{27, 100})
seqAltF = string([]byte{27, 102})
seqAltR = string([]byte{27, 114}) // Used for alternative history seqAltR = string([]byte{27, 114}) // Used for alternative history
seqAltBackspace = string([]byte{27, 127}) seqAltBackspace = string([]byte{27, 127})
) )

View File

@ -183,26 +183,41 @@ func (rl *Instance) deleteToEnd() {
rl.line = rl.line[:rl.pos] rl.line = rl.line[:rl.pos]
} }
// @TODO(Renzix): move to emacs sepecific file
func (rl *Instance) emacsForwardWord(tokeniser tokeniser) (adjust int) { func (rl *Instance) emacsForwardWord(tokeniser tokeniser) (adjust int) {
// when emacs has more specific stuff, move this in a file with then
split, index, pos := tokeniser(rl.line, rl.pos) split, index, pos := tokeniser(rl.line, rl.pos)
if len(split) == 0 { if len(split) == 0 {
return return
} }
word := rTrimWhiteSpace(split[index]) word := strings.TrimSpace(split[index])
switch { switch {
case len(split) == 0: case len(split) == 0:
return return
case index == len(split)-1 && pos >= len(word)-1: case pos == len(word) && index != len(split)-1:
return extrawhitespace := len(strings.TrimLeft(split[index], " ")) - len(word)
case pos >= len(word)-1: word = split[index+1]
word = rTrimWhiteSpace(split[index+1]) adjust = len(word) + extrawhitespace
adjust = len(split[index]) - pos
adjust += len(word)
default: default:
adjust = len(word) - pos adjust = len(word) - pos
} }
return return
} }
func (rl *Instance) emacsBackwardWord(tokeniser tokeniser) (adjust int) {
split, index, pos := tokeniser(rl.line, rl.pos)
if len(split) == 0 {
return
}
switch {
case len(split) == 0:
return
case pos == 0 && index != 0:
adjust = len(split[index-1])
default:
adjust = pos
}
return
}

View File

@ -761,6 +761,34 @@ func (rl *Instance) escapeSeq(r []rune) {
rl.pos = len(rl.line) rl.pos = len(rl.line)
rl.viUndoSkipAppend = true rl.viUndoSkipAppend = true
case seqAltB:
if rl.modeTabCompletion {
return
}
// This is only available in Insert mode
if rl.modeViMode != VimInsert {
return
}
move := rl.emacsBackwardWord(tokeniseLine)
rl.moveCursorByAdjust(-move)
rl.updateHelpers()
case seqAltF:
if rl.modeTabCompletion {
return
}
// This is only available in Insert mode
if rl.modeViMode != VimInsert {
return
}
move := rl.emacsForwardWord(tokeniseLine)
rl.moveCursorByAdjust(move)
rl.updateHelpers()
case seqAltR: case seqAltR:
rl.resetVirtualComp(false) rl.resetVirtualComp(false)
// For some modes only, if we are in vim Keys mode, // For some modes only, if we are in vim Keys mode,
@ -792,19 +820,23 @@ func (rl *Instance) escapeSeq(r []rune) {
rl.viDeleteByAdjust(rl.viJumpB(tokeniseLine)) rl.viDeleteByAdjust(rl.viJumpB(tokeniseLine))
rl.updateHelpers() rl.updateHelpers()
case seqCtrlDelete, seqCtrlDelete2: case seqCtrlDelete, seqCtrlDelete2, seqAltD:
if rl.modeTabCompletion { if rl.modeTabCompletion {
rl.resetVirtualComp(false) rl.resetVirtualComp(false)
} }
// This is only available in Insert mode
if rl.modeViMode != VimInsert {
return
}
rl.saveToRegister(rl.emacsForwardWord(tokeniseLine)) rl.saveToRegister(rl.emacsForwardWord(tokeniseLine))
// vi delete, emacs forward, funny huh // vi delete, emacs forward, funny huh
rl.viDeleteByAdjust(rl.emacsForwardWord(tokeniseLine)) rl.viDeleteByAdjust(rl.emacsForwardWord(tokeniseLine))
rl.updateHelpers() rl.updateHelpers()
case seqAltDelete:
if rl.modeTabCompletion {
rl.resetVirtualComp(false)
}
rl.saveToRegister(-rl.emacsBackwardWord(tokeniseLine))
rl.viDeleteByAdjust(-rl.emacsBackwardWord(tokeniseLine))
rl.updateHelpers()
default: default:
if rl.modeTabFind { if rl.modeTabFind {
return return