From 3fe8eeedc5f5180f9c9db76fca26844f8c6acf37 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Tue, 24 Nov 2020 19:36:58 +0900 Subject: [PATCH] Fix handling of arrow keys with alt and/or shift modifier Fix #2254 - Properly handle extra chars in the buffer. Patch suggested by @mckelly2833. - Support alt-arrow sequences in \e[1;3A format - Support shift-alt-arrow sequences in \e[1;10A format --- man/man1/fzf.1 | 10 +++++++++- src/options.go | 8 ++++++++ src/tui/light.go | 40 +++++++++++++++++++++++++++++++++++++--- src/tui/tcell.go | 29 ++++++++++++++++++++++++++++- src/tui/tui.go | 5 +++++ 5 files changed, 87 insertions(+), 5 deletions(-) diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 99147403..0efa4750 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. -.TH fzf 1 "Nov 2020" "fzf 0.24.3" "fzf - a command-line fuzzy finder" +.TH fzf 1 "Nov 2020" "fzf 0.24.4" "fzf - a command-line fuzzy finder" .SH NAME fzf - a command-line fuzzy finder @@ -712,6 +712,14 @@ e.g. .br \fIshift-right\fR .br +\fIalt-shift-up\fR +.br +\fIalt-shift-down\fR +.br +\fIalt-shift-left\fR +.br +\fIalt-shift-right\fR +.br \fIleft-click\fR .br \fIright-click\fR diff --git a/src/options.go b/src/options.go index d7e1eaa6..0a6dcf99 100644 --- a/src/options.go +++ b/src/options.go @@ -524,6 +524,14 @@ func parseKeyChords(str string, message string) map[int]string { chord = tui.PgUp case "pgdn", "page-down": chord = tui.PgDn + case "alt-shift-up", "shift-alt-up": + chord = tui.AltSUp + case "alt-shift-down", "shift-alt-down": + chord = tui.AltSDown + case "alt-shift-left", "shift-alt-left": + chord = tui.AltSLeft + case "alt-shift-right", "shift-alt-right": + chord = tui.AltSRight case "shift-up": chord = tui.SUp case "shift-down": diff --git a/src/tui/light.go b/src/tui/light.go index ad536f6d..4f50d687 100644 --- a/src/tui/light.go +++ b/src/tui/light.go @@ -463,20 +463,54 @@ func (r *LightRenderer) escSequence(sz *int) Event { } return Event{Invalid, 0, nil} case ';': - if len(r.buffer) != 6 { + if len(r.buffer) < 6 { return Event{Invalid, 0, nil} } *sz = 6 switch r.buffer[4] { - case '2', '5': - switch r.buffer[5] { + case '1', '2', '3', '5': + alt := r.buffer[4] == '3' + altShift := r.buffer[4] == '1' && r.buffer[5] == '0' + char := r.buffer[5] + if altShift { + if len(r.buffer) < 7 { + return Event{Invalid, 0, nil} + } + *sz = 7 + char = r.buffer[6] + } + switch char { case 'A': + if alt { + return Event{AltUp, 0, nil} + } + if altShift { + return Event{AltSUp, 0, nil} + } return Event{SUp, 0, nil} case 'B': + if alt { + return Event{AltDown, 0, nil} + } + if altShift { + return Event{AltSDown, 0, nil} + } return Event{SDown, 0, nil} case 'C': + if alt { + return Event{AltRight, 0, nil} + } + if altShift { + return Event{AltSRight, 0, nil} + } return Event{SRight, 0, nil} case 'D': + if alt { + return Event{AltLeft, 0, nil} + } + if altShift { + return Event{AltSLeft, 0, nil} + } return Event{SLeft, 0, nil} } } // r.buffer[4] diff --git a/src/tui/tcell.go b/src/tui/tcell.go index 4f80d069..16d3151a 100644 --- a/src/tui/tcell.go +++ b/src/tui/tcell.go @@ -222,7 +222,10 @@ func (r *FullscreenRenderer) GetChar() Event { // process keyboard: case *tcell.EventKey: - alt := (ev.Modifiers() & tcell.ModAlt) > 0 + mods := ev.Modifiers() + alt := (mods & tcell.ModAlt) > 0 + shift := (mods & tcell.ModShift) > 0 + altShift := alt && shift keyfn := func(r rune) int { if alt { return CtrlAltA - 'a' + int(r) @@ -297,21 +300,45 @@ func (r *FullscreenRenderer) GetChar() Event { return Event{BSpace, 0, nil} case tcell.KeyUp: + if altShift { + return Event{AltSUp, 0, nil} + } + if shift { + return Event{SUp, 0, nil} + } if alt { return Event{AltUp, 0, nil} } return Event{Up, 0, nil} case tcell.KeyDown: + if altShift { + return Event{AltSDown, 0, nil} + } + if shift { + return Event{SDown, 0, nil} + } if alt { return Event{AltDown, 0, nil} } return Event{Down, 0, nil} case tcell.KeyLeft: + if altShift { + return Event{AltSLeft, 0, nil} + } + if shift { + return Event{SLeft, 0, nil} + } if alt { return Event{AltLeft, 0, nil} } return Event{Left, 0, nil} case tcell.KeyRight: + if altShift { + return Event{AltSRight, 0, nil} + } + if shift { + return Event{SRight, 0, nil} + } if alt { return Event{AltRight, 0, nil} } diff --git a/src/tui/tui.go b/src/tui/tui.go index 0feea038..e07e6618 100644 --- a/src/tui/tui.go +++ b/src/tui/tui.go @@ -98,6 +98,11 @@ const ( AltLeft AltRight + AltSUp + AltSDown + AltSLeft + AltSRight + Alt0 )