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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. 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 .SH NAME
fzf - a command-line fuzzy finder fzf - a command-line fuzzy finder
@ -712,6 +712,14 @@ e.g.
.br .br
\fIshift-right\fR \fIshift-right\fR
.br .br
\fIalt-shift-up\fR
.br
\fIalt-shift-down\fR
.br
\fIalt-shift-left\fR
.br
\fIalt-shift-right\fR
.br
\fIleft-click\fR \fIleft-click\fR
.br .br
\fIright-click\fR \fIright-click\fR

@ -524,6 +524,14 @@ func parseKeyChords(str string, message string) map[int]string {
chord = tui.PgUp chord = tui.PgUp
case "pgdn", "page-down": case "pgdn", "page-down":
chord = tui.PgDn 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": case "shift-up":
chord = tui.SUp chord = tui.SUp
case "shift-down": case "shift-down":

@ -463,20 +463,54 @@ func (r *LightRenderer) escSequence(sz *int) Event {
} }
return Event{Invalid, 0, nil} return Event{Invalid, 0, nil}
case ';': case ';':
if len(r.buffer) != 6 { if len(r.buffer) < 6 {
return Event{Invalid, 0, nil} return Event{Invalid, 0, nil}
} }
*sz = 6 *sz = 6
switch r.buffer[4] { switch r.buffer[4] {
case '2', '5': case '1', '2', '3', '5':
switch r.buffer[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': case 'A':
if alt {
return Event{AltUp, 0, nil}
}
if altShift {
return Event{AltSUp, 0, nil}
}
return Event{SUp, 0, nil} return Event{SUp, 0, nil}
case 'B': case 'B':
if alt {
return Event{AltDown, 0, nil}
}
if altShift {
return Event{AltSDown, 0, nil}
}
return Event{SDown, 0, nil} return Event{SDown, 0, nil}
case 'C': case 'C':
if alt {
return Event{AltRight, 0, nil}
}
if altShift {
return Event{AltSRight, 0, nil}
}
return Event{SRight, 0, nil} return Event{SRight, 0, nil}
case 'D': case 'D':
if alt {
return Event{AltLeft, 0, nil}
}
if altShift {
return Event{AltSLeft, 0, nil}
}
return Event{SLeft, 0, nil} return Event{SLeft, 0, nil}
} }
} // r.buffer[4] } // r.buffer[4]

@ -222,7 +222,10 @@ func (r *FullscreenRenderer) GetChar() Event {
// process keyboard: // process keyboard:
case *tcell.EventKey: 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 { keyfn := func(r rune) int {
if alt { if alt {
return CtrlAltA - 'a' + int(r) return CtrlAltA - 'a' + int(r)
@ -297,21 +300,45 @@ func (r *FullscreenRenderer) GetChar() Event {
return Event{BSpace, 0, nil} return Event{BSpace, 0, nil}
case tcell.KeyUp: case tcell.KeyUp:
if altShift {
return Event{AltSUp, 0, nil}
}
if shift {
return Event{SUp, 0, nil}
}
if alt { if alt {
return Event{AltUp, 0, nil} return Event{AltUp, 0, nil}
} }
return Event{Up, 0, nil} return Event{Up, 0, nil}
case tcell.KeyDown: case tcell.KeyDown:
if altShift {
return Event{AltSDown, 0, nil}
}
if shift {
return Event{SDown, 0, nil}
}
if alt { if alt {
return Event{AltDown, 0, nil} return Event{AltDown, 0, nil}
} }
return Event{Down, 0, nil} return Event{Down, 0, nil}
case tcell.KeyLeft: case tcell.KeyLeft:
if altShift {
return Event{AltSLeft, 0, nil}
}
if shift {
return Event{SLeft, 0, nil}
}
if alt { if alt {
return Event{AltLeft, 0, nil} return Event{AltLeft, 0, nil}
} }
return Event{Left, 0, nil} return Event{Left, 0, nil}
case tcell.KeyRight: case tcell.KeyRight:
if altShift {
return Event{AltSRight, 0, nil}
}
if shift {
return Event{SRight, 0, nil}
}
if alt { if alt {
return Event{AltRight, 0, nil} return Event{AltRight, 0, nil}
} }

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

Loading…
Cancel
Save