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})
seqCtrlDelete = string([]byte{27, 91, 51, 59, 53, 126})
seqCtrlDelete2 = string([]byte{27, 91, 77})
seqAltDelete = string([]byte{27, 91, 51, 59, 51, 126})
seqShiftTab = string([]byte{27, 91, 90})
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
seqAltBackspace = string([]byte{27, 127})
)

View File

@ -183,26 +183,41 @@ func (rl *Instance) deleteToEnd() {
rl.line = rl.line[:rl.pos]
}
// @TODO(Renzix): move to emacs sepecific file
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)
if len(split) == 0 {
return
}
word := rTrimWhiteSpace(split[index])
word := strings.TrimSpace(split[index])
switch {
case len(split) == 0:
return
case index == len(split)-1 && pos >= len(word)-1:
return
case pos >= len(word)-1:
word = rTrimWhiteSpace(split[index+1])
adjust = len(split[index]) - pos
adjust += len(word)
case pos == len(word) && index != len(split)-1:
extrawhitespace := len(strings.TrimLeft(split[index], " ")) - len(word)
word = split[index+1]
adjust = len(word) + extrawhitespace
default:
adjust = len(word) - pos
}
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.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:
rl.resetVirtualComp(false)
// 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.updateHelpers()
case seqCtrlDelete, seqCtrlDelete2:
case seqCtrlDelete, seqCtrlDelete2, seqAltD:
if rl.modeTabCompletion {
rl.resetVirtualComp(false)
}
// This is only available in Insert mode
if rl.modeViMode != VimInsert {
return
}
rl.saveToRegister(rl.emacsForwardWord(tokeniseLine))
// vi delete, emacs forward, funny huh
rl.viDeleteByAdjust(rl.emacsForwardWord(tokeniseLine))
rl.updateHelpers()
case seqAltDelete:
if rl.modeTabCompletion {
rl.resetVirtualComp(false)
}
rl.saveToRegister(-rl.emacsBackwardWord(tokeniseLine))
rl.viDeleteByAdjust(-rl.emacsBackwardWord(tokeniseLine))
rl.updateHelpers()
default:
if rl.modeTabFind {
return