From de2a8aee060fa870f17cdd08b9ce5e0cd0287718 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 20 Mar 2018 12:14:30 +0200 Subject: Add some vim-style keybindings to advanced inputfields --- ui/widget/advanced-inputfield.go | 60 +++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/ui/widget/advanced-inputfield.go b/ui/widget/advanced-inputfield.go index 6cb1d00..fed6444 100644 --- a/ui/widget/advanced-inputfield.go +++ b/ui/widget/advanced-inputfield.go @@ -68,6 +68,8 @@ type AdvancedInputField struct { // disables masking. maskCharacter rune + vimBindings bool + // An optional function which may reject the last character that was entered. accept func(text string, ch rune) bool @@ -403,32 +405,46 @@ func (field *AdvancedInputField) InputHandler() func(event *tcell.EventKey, setF break } leftPart := SubstringBefore(field.text, field.cursorOffset) - rightPart := field.text[len(leftPart):] - rightPartRunes := []rune(rightPart) - rightPartRunes = rightPartRunes[1:] - rightPart = string(rightPartRunes) + // Take everything after the left part minus the first character. + rightPart := string([]rune(field.text[len(leftPart):])[1:]) + field.text = leftPart + rightPart - case tcell.KeyBackspace, tcell.KeyBackspace2: // Delete last character. - if field.cursorOffset == 0 { + case tcell.KeyCtrlU: + if !field.vimBindings { break } - if key == tcell.KeyBackspace { // Ctrl+backspace - leftPart := SubstringBefore(field.text, field.cursorOffset) - rightPart := field.text[len(leftPart):] - replacement := lastWord.ReplaceAllString(leftPart, "") - field.text = replacement + rightPart - - field.cursorOffset -= runewidth.StringWidth(leftPart) - runewidth.StringWidth(replacement) - } else { // Just backspace - leftPart := SubstringBefore(field.text, field.cursorOffset) - rightPart := field.text[len(leftPart):] - leftPartRunes := []rune(leftPart) - leftPartRunes = leftPartRunes[0 : len(leftPartRunes)-1] - leftPart = string(leftPartRunes) - removedChar := field.text[len(leftPart) : len(field.text)-len(rightPart)] - field.text = leftPart + rightPart - field.cursorOffset -= runewidth.StringWidth(removedChar) + field.text = "" + field.cursorOffset = 0 + case tcell.KeyCtrlW: + if !field.vimBindings { + break } + fallthrough + case tcell.KeyBackspace: // Delete last word + leftPart := SubstringBefore(field.text, field.cursorOffset) + rightPart := field.text[len(leftPart):] + replacement := lastWord.ReplaceAllString(leftPart, "") + field.text = replacement + rightPart + + field.cursorOffset -= runewidth.StringWidth(leftPart) - runewidth.StringWidth(replacement) + case tcell.KeyBackspace2: // Delete last character + if field.cursorOffset == 0 { + break + } + leftPart := SubstringBefore(field.text, field.cursorOffset) + rightPart := field.text[len(leftPart):] + + // Take everything before the right part minus the last character. + leftPartRunes := []rune(leftPart) + leftPartRunes = leftPartRunes[0 : len(leftPartRunes)-1] + leftPart = string(leftPartRunes) + + // Figure out what character was removed to correctly decrease cursorOffset. + removedChar := field.text[len(leftPart) : len(field.text)-len(rightPart)] + + field.text = leftPart + rightPart + + field.cursorOffset -= runewidth.StringWidth(removedChar) case tcell.KeyTab: // Tab-completion if field.tabComplete != nil { oldWidth := runewidth.StringWidth(field.text) -- cgit v1.2.3