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

View File

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

View File

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

View File

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

View File

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