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
pull/2266/head
Junegunn Choi 4 years ago
parent 1efef88b6e
commit 3fe8eeedc5
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

@ -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

@ -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":

@ -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]

@ -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}
}

@ -98,6 +98,11 @@ const (
AltLeft
AltRight
AltSUp
AltSDown
AltSLeft
AltSRight
Alt0
)

Loading…
Cancel
Save