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
This commit is contained in:
Junegunn Choi 2020-11-24 19:36:58 +09:00
parent 1efef88b6e
commit 3fe8eeedc5
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
5 changed files with 87 additions and 5 deletions

View File

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

View File

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

View File

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

View File

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

View File

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