m/fzf
1
0
mirror of https://github.com/junegunn/fzf.git synced 2025-11-08 11:23:47 -05:00

Add keybindings for CTRL, ALT, SHIFT + UP, DOWN, RIGHT, LEFT, HOME, END, BACKSPACE, DELETE & more (#3996)

* Added tests for `LightRenderer`

* Added common SHIFT, ALT and ALT+SHIFT key sequences

* Added common CTRL key sequences

* Added common CTRL+ALT, CTRL+SHIFT, CTRL+ALT+SHIFT key sequences

* Added proper xterm META modifier handling

according to defc6dd568/input.c (L357-L375)

* Fix `ctrl-backspace` and `ctrl-alt-backspace`

* Fix broken tcell tests on windows by swallowing Resize events

* Added tests for  FullscreenRenderer

* Removed own fork of tcell and updated tcell to 2.9.0

tcell 2.9.0 is needed for `Ctrl-Alt-*` and `Ctrl-Alt-Shift-*` shortcuts in Windows

* Replace conditional checks with switch statements to improve readability

* Replace long conditionals with constant slices to improve readability

* Bind `ctrl-bspace` (`ctrl-h`) to `backward-delete-char` by default

Since we now distinguish between Backspace and Ctrl-Backspace, Ctrl-Backspace should trigger the same action as Backspace by default. In that way nothing changes for the user but you can bind other actions to Ctrl-Backspace when desired.
This commit is contained in:
Massimo Mund
2025-09-05 07:56:51 +02:00
committed by GitHub
parent 129cb23078
commit 9ed971cc90
9 changed files with 1229 additions and 118 deletions

View File

@@ -1473,12 +1473,22 @@ e.g.
.br
\fIalt\-right\fR
.br
\fIalt\-home\fR
.br
\fIalt\-end\fR
.br
\fIalt\-backspace\fR (\fIalt\-bspace\fR \fIalt\-bs\fR)
.br
\fIalt\-delete\fR
.br
\fIalt\-page\-up\fR
.br
\fIalt\-page\-down\fR
.br
\fIalt\-enter\fR
.br
\fIalt\-space\fR
.br
\fIalt\-backspace\fR (\fIalt\-bspace\fR \fIalt\-bs\fR)
.br
\fItab\fR
.br
\fIshift\-tab\fR (\fIbtab\fR)
@@ -1505,6 +1515,26 @@ e.g.
.br
\fIpage\-down\fR (\fIpgdn\fR)
.br
\fIctrl\-up\fR
.br
\fIctrl\-down\fR
.br
\fIctrl\-left\fR
.br
\fIctrl\-right\fR
.br
\fIctrl\-home\fR
.br
\fIctrl\-end\fR
.br
\fIctrl\-backspace\fR (\fIctrl\-bspace\fR \fIctrl\-bs\fR)
.br
\fIctrl\-delete\fR
.br
\fIctrl\-page\-up\fR
.br
\fIctrl\-page\-down\fR
.br
\fIshift\-up\fR
.br
\fIshift\-down\fR
@@ -1513,8 +1543,16 @@ e.g.
.br
\fIshift\-right\fR
.br
\fIshift\-home\fR
.br
\fIshift\-end\fR
.br
\fIshift\-delete\fR
.br
\fIshift\-page\-up\fR
.br
\fIshift\-page\-down\fR
.br
\fIalt\-shift\-up\fR
.br
\fIalt\-shift\-down\fR
@@ -1523,6 +1561,72 @@ e.g.
.br
\fIalt\-shift\-right\fR
.br
\fIalt\-shift\-home\fR
.br
\fIalt\-shift\-end\fR
.br
\fIalt\-shift\-delete\fR
.br
\fIalt\-shift\-page\-up\fR
.br
\fIalt\-shift\-page\-down\fR
.br
\fIctrl\-alt\-up\fR
.br
\fIctrl\-alt\-down\fR
.br
\fIctrl\-alt\-left\fR
.br
\fIctrl\-alt\-right\fR
.br
\fIctrl\-alt\-home\fR
.br
\fIctrl\-alt\-end\fR
.br
\fIctrl\-alt\-backspace\fR (\fIctrl\-alt\-bspace\fR \fIctrl\-alt\-bs\fR)
.br
\fIctrl\-alt\-delete\fR
.br
\fIctrl\-alt\-page\-up\fR
.br
\fIctrl\-alt\-page\-down\fR
.br
\fIctrl\-shift\-up\fR
.br
\fIctrl\-shift\-down\fR
.br
\fIctrl\-shift\-left\fR
.br
\fIctrl\-shift\-right\fR
.br
\fIctrl\-shift\-home\fR
.br
\fIctrl\-shift\-end\fR
.br
\fIctrl\-shift\-delete\fR
.br
\fIctrl\-shift\-page\-up\fR
.br
\fIctrl\-shift\-page\-down\fR
.br
\fIctrl\-alt\-shift\-up\fR
.br
\fIctrl\-alt\-shift\-down\fR
.br
\fIctrl\-alt\-shift\-left\fR
.br
\fIctrl\-alt\-shift\-right\fR
.br
\fIctrl\-alt\-shift\-home\fR
.br
\fIctrl\-alt\-shift\-end\fR
.br
\fIctrl\-alt\-shift\-delete\fR
.br
\fIctrl\-alt\-shift\-page\-up\fR
.br
\fIctrl\-alt\-shift\-page\-down\fR
.br
\fIleft\-click\fR
.br
\fIright\-click\fR
@@ -1547,6 +1651,8 @@ e.g.
.br
or any single character
Note that some terminal emulators may not support \fIctrl-*\fR bindings.
.SS AVAILABLE EVENTS:
\fIstart\fR
.RS
@@ -1699,7 +1805,7 @@ A key or an event can be bound to one or more of the following actions.
\fBaccept\-non\-empty\fR (same as \fBaccept\fR except that it prevents fzf from exiting without selection)
\fBaccept\-or\-print\-query\fR (same as \fBaccept\fR except that it prints the query when there's no match)
\fBbackward\-char\fR \fIctrl\-b left\fR
\fBbackward\-delete\-char\fR \fIctrl\-h bspace\fR
\fBbackward\-delete\-char\fR \fIctrl\-h ctrl\-bspace bspace\fR
\fBbackward\-delete\-char/eof\fR (same as \fBbackward\-delete\-char\fR except aborts fzf if query is empty)
\fBbackward\-kill\-word\fR \fIalt\-bs\fR
\fBbackward\-word\fR \fIalt\-b shift\-left\fR

View File

@@ -974,8 +974,6 @@ func parseKeyChords(str string, message string) (map[tui.Event]string, []tui.Eve
add(tui.Backspace)
case "ctrl-space":
add(tui.CtrlSpace)
case "ctrl-delete":
add(tui.CtrlDelete)
case "ctrl-^", "ctrl-6":
add(tui.CtrlCaret)
case "ctrl-/", "ctrl-_":
@@ -1022,6 +1020,10 @@ func parseKeyChords(str string, message string) (map[tui.Event]string, []tui.Eve
list = append(list, evt)
case "alt-bs", "alt-bspace", "alt-backspace":
add(tui.AltBackspace)
case "ctrl-bs", "ctrl-bspace", "ctrl-backspace":
add(tui.CtrlBackspace)
case "ctrl-alt-bs", "ctrl-alt-bspace", "ctrl-alt-backspace":
add(tui.CtrlAltBackspace)
case "alt-up":
add(tui.AltUp)
case "alt-down":
@@ -1030,6 +1032,16 @@ func parseKeyChords(str string, message string) (map[tui.Event]string, []tui.Eve
add(tui.AltLeft)
case "alt-right":
add(tui.AltRight)
case "alt-home":
add(tui.AltHome)
case "alt-end":
add(tui.AltEnd)
case "alt-delete":
add(tui.AltDelete)
case "alt-page-up":
add(tui.AltPageUp)
case "alt-page-down":
add(tui.AltPageDown)
case "tab":
add(tui.Tab)
case "btab", "shift-tab":
@@ -1056,6 +1068,88 @@ func parseKeyChords(str string, message string) (map[tui.Event]string, []tui.Eve
add(tui.AltShiftLeft)
case "alt-shift-right", "shift-alt-right":
add(tui.AltShiftRight)
case "alt-shift-home", "shift-alt-home":
add(tui.AltShiftHome)
case "alt-shift-end", "shift-alt-end":
add(tui.AltShiftEnd)
case "alt-shift-delete", "shift-alt-delete":
add(tui.AltShiftDelete)
case "alt-shift-page-up", "shift-alt-page-up":
add(tui.AltShiftPageUp)
case "alt-shift-page-down", "shift-alt-page-down":
add(tui.AltShiftPageDown)
case "ctrl-up":
add(tui.CtrlUp)
case "ctrl-down":
add(tui.CtrlDown)
case "ctrl-right":
add(tui.CtrlRight)
case "ctrl-left":
add(tui.CtrlLeft)
case "ctrl-home":
add(tui.CtrlHome)
case "ctrl-end":
add(tui.CtrlEnd)
case "ctrl-delete":
add(tui.CtrlDelete)
case "ctrl-page-up":
add(tui.CtrlPageUp)
case "ctrl-page-down":
add(tui.CtrlPageDown)
case "ctrl-alt-up", "alt-ctrl-up":
add(tui.CtrlAltUp)
case "ctrl-alt-down", "alt-ctrl-down":
add(tui.CtrlAltDown)
case "ctrl-alt-right", "alt-ctrl-right":
add(tui.CtrlAltRight)
case "ctrl-alt-left", "alt-ctrl-left":
add(tui.CtrlAltLeft)
case "ctrl-alt-home", "alt-ctrl-home":
add(tui.CtrlAltHome)
case "ctrl-alt-end", "alt-ctrl-end":
add(tui.CtrlAltEnd)
case "ctrl-alt-delete", "alt-ctrl-delete":
add(tui.CtrlAltDelete)
case "ctrl-alt-page-up", "alt-ctrl-page-up":
add(tui.CtrlAltPageUp)
case "ctrl-alt-page-down", "alt-ctrl-page-down":
add(tui.CtrlAltPageDown)
case "ctrl-shift-up", "shift-ctrl-up":
add(tui.CtrlShiftUp)
case "ctrl-shift-down", "shift-ctrl-down":
add(tui.CtrlShiftDown)
case "ctrl-shift-right", "shift-ctrl-right":
add(tui.CtrlShiftRight)
case "ctrl-shift-left", "shift-ctrl-left":
add(tui.CtrlShiftLeft)
case "ctrl-shift-home", "shift-ctrl-home":
add(tui.CtrlShiftHome)
case "ctrl-shift-end", "shift-ctrl-end":
add(tui.CtrlShiftEnd)
case "ctrl-shift-delete", "shift-ctrl-delete":
add(tui.CtrlShiftDelete)
case "ctrl-shift-page-up", "shift-ctrl-page-up":
add(tui.CtrlShiftPageUp)
case "ctrl-shift-page-down", "shift-ctrl-page-down":
add(tui.CtrlShiftPageDown)
case "ctrl-alt-shift-up":
add(tui.CtrlAltShiftUp)
case "ctrl-alt-shift-down":
add(tui.CtrlAltShiftDown)
case "ctrl-alt-shift-right":
add(tui.CtrlAltShiftRight)
case "ctrl-alt-shift-left":
add(tui.CtrlAltShiftLeft)
case "ctrl-alt-shift-home":
add(tui.CtrlAltShiftHome)
case "ctrl-alt-shift-end":
add(tui.CtrlAltShiftEnd)
case "ctrl-alt-shift-delete":
add(tui.CtrlAltShiftDelete)
case "ctrl-alt-shift-page-up":
add(tui.CtrlAltShiftPageUp)
case "ctrl-alt-shift-page-down":
add(tui.CtrlAltShiftPageDown)
case "shift-up":
add(tui.ShiftUp)
case "shift-down":
@@ -1064,8 +1158,16 @@ func parseKeyChords(str string, message string) (map[tui.Event]string, []tui.Eve
add(tui.ShiftLeft)
case "shift-right":
add(tui.ShiftRight)
case "shift-home":
add(tui.ShiftHome)
case "shift-end":
add(tui.ShiftEnd)
case "shift-delete":
add(tui.ShiftDelete)
case "shift-page-up":
add(tui.ShiftPageUp)
case "shift-page-down":
add(tui.ShiftPageDown)
case "left-click":
add(tui.LeftClick)
case "right-click":

View File

@@ -782,6 +782,7 @@ func defaultKeymap() map[tui.Event][]*action {
add(tui.CtrlF, actForwardChar)
add(tui.CtrlH, actBackwardDeleteChar)
add(tui.Backspace, actBackwardDeleteChar)
add(tui.CtrlBackspace, actBackwardDeleteChar)
add(tui.Tab, actToggleDown)
add(tui.ShiftTab, actToggleUp)
add(tui.CtrlJ, actDown)

View File

@@ -37,86 +37,137 @@ func _() {
_ = x[CtrlZ-26]
_ = x[Esc-27]
_ = x[CtrlSpace-28]
_ = x[CtrlDelete-29]
_ = x[CtrlBackSlash-30]
_ = x[CtrlRightBracket-31]
_ = x[CtrlCaret-32]
_ = x[CtrlSlash-33]
_ = x[ShiftTab-34]
_ = x[Backspace-35]
_ = x[Delete-36]
_ = x[PageUp-37]
_ = x[PageDown-38]
_ = x[Up-39]
_ = x[Down-40]
_ = x[Left-41]
_ = x[Right-42]
_ = x[Home-43]
_ = x[End-44]
_ = x[Insert-45]
_ = x[ShiftUp-46]
_ = x[ShiftDown-47]
_ = x[ShiftLeft-48]
_ = x[ShiftRight-49]
_ = x[ShiftDelete-50]
_ = x[F1-51]
_ = x[F2-52]
_ = x[F3-53]
_ = x[F4-54]
_ = x[F5-55]
_ = x[F6-56]
_ = x[F7-57]
_ = x[F8-58]
_ = x[F9-59]
_ = x[F10-60]
_ = x[F11-61]
_ = x[F12-62]
_ = x[AltBackspace-63]
_ = x[AltUp-64]
_ = x[AltDown-65]
_ = x[AltLeft-66]
_ = x[AltRight-67]
_ = x[AltShiftUp-68]
_ = x[AltShiftDown-69]
_ = x[AltShiftLeft-70]
_ = x[AltShiftRight-71]
_ = x[Alt-72]
_ = x[CtrlAlt-73]
_ = x[Invalid-74]
_ = x[Fatal-75]
_ = x[BracketedPasteBegin-76]
_ = x[BracketedPasteEnd-77]
_ = x[Mouse-78]
_ = x[DoubleClick-79]
_ = x[LeftClick-80]
_ = x[RightClick-81]
_ = x[SLeftClick-82]
_ = x[SRightClick-83]
_ = x[ScrollUp-84]
_ = x[ScrollDown-85]
_ = x[SScrollUp-86]
_ = x[SScrollDown-87]
_ = x[PreviewScrollUp-88]
_ = x[PreviewScrollDown-89]
_ = x[Resize-90]
_ = x[Change-91]
_ = x[BackwardEOF-92]
_ = x[Start-93]
_ = x[Load-94]
_ = x[Focus-95]
_ = x[One-96]
_ = x[Zero-97]
_ = x[Result-98]
_ = x[Jump-99]
_ = x[JumpCancel-100]
_ = x[ClickHeader-101]
_ = x[ClickFooter-102]
_ = x[Multi-103]
_ = x[CtrlBackSlash-29]
_ = x[CtrlRightBracket-30]
_ = x[CtrlCaret-31]
_ = x[CtrlSlash-32]
_ = x[ShiftTab-33]
_ = x[Backspace-34]
_ = x[Delete-35]
_ = x[PageUp-36]
_ = x[PageDown-37]
_ = x[Up-38]
_ = x[Down-39]
_ = x[Left-40]
_ = x[Right-41]
_ = x[Home-42]
_ = x[End-43]
_ = x[Insert-44]
_ = x[ShiftUp-45]
_ = x[ShiftDown-46]
_ = x[ShiftLeft-47]
_ = x[ShiftRight-48]
_ = x[ShiftDelete-49]
_ = x[ShiftHome-50]
_ = x[ShiftEnd-51]
_ = x[ShiftPageUp-52]
_ = x[ShiftPageDown-53]
_ = x[F1-54]
_ = x[F2-55]
_ = x[F3-56]
_ = x[F4-57]
_ = x[F5-58]
_ = x[F6-59]
_ = x[F7-60]
_ = x[F8-61]
_ = x[F9-62]
_ = x[F10-63]
_ = x[F11-64]
_ = x[F12-65]
_ = x[AltBackspace-66]
_ = x[AltUp-67]
_ = x[AltDown-68]
_ = x[AltLeft-69]
_ = x[AltRight-70]
_ = x[AltDelete-71]
_ = x[AltHome-72]
_ = x[AltEnd-73]
_ = x[AltPageUp-74]
_ = x[AltPageDown-75]
_ = x[AltShiftUp-76]
_ = x[AltShiftDown-77]
_ = x[AltShiftLeft-78]
_ = x[AltShiftRight-79]
_ = x[AltShiftDelete-80]
_ = x[AltShiftHome-81]
_ = x[AltShiftEnd-82]
_ = x[AltShiftPageUp-83]
_ = x[AltShiftPageDown-84]
_ = x[CtrlUp-85]
_ = x[CtrlDown-86]
_ = x[CtrlLeft-87]
_ = x[CtrlRight-88]
_ = x[CtrlHome-89]
_ = x[CtrlEnd-90]
_ = x[CtrlBackspace-91]
_ = x[CtrlDelete-92]
_ = x[CtrlPageUp-93]
_ = x[CtrlPageDown-94]
_ = x[Alt-95]
_ = x[CtrlAlt-96]
_ = x[CtrlAltUp-97]
_ = x[CtrlAltDown-98]
_ = x[CtrlAltLeft-99]
_ = x[CtrlAltRight-100]
_ = x[CtrlAltHome-101]
_ = x[CtrlAltEnd-102]
_ = x[CtrlAltBackspace-103]
_ = x[CtrlAltDelete-104]
_ = x[CtrlAltPageUp-105]
_ = x[CtrlAltPageDown-106]
_ = x[CtrlShiftUp-107]
_ = x[CtrlShiftDown-108]
_ = x[CtrlShiftLeft-109]
_ = x[CtrlShiftRight-110]
_ = x[CtrlShiftHome-111]
_ = x[CtrlShiftEnd-112]
_ = x[CtrlShiftDelete-113]
_ = x[CtrlShiftPageUp-114]
_ = x[CtrlShiftPageDown-115]
_ = x[CtrlAltShiftUp-116]
_ = x[CtrlAltShiftDown-117]
_ = x[CtrlAltShiftLeft-118]
_ = x[CtrlAltShiftRight-119]
_ = x[CtrlAltShiftHome-120]
_ = x[CtrlAltShiftEnd-121]
_ = x[CtrlAltShiftDelete-122]
_ = x[CtrlAltShiftPageUp-123]
_ = x[CtrlAltShiftPageDown-124]
_ = x[Invalid-125]
_ = x[Fatal-126]
_ = x[BracketedPasteBegin-127]
_ = x[BracketedPasteEnd-128]
_ = x[Mouse-129]
_ = x[DoubleClick-130]
_ = x[LeftClick-131]
_ = x[RightClick-132]
_ = x[SLeftClick-133]
_ = x[SRightClick-134]
_ = x[ScrollUp-135]
_ = x[ScrollDown-136]
_ = x[SScrollUp-137]
_ = x[SScrollDown-138]
_ = x[PreviewScrollUp-139]
_ = x[PreviewScrollDown-140]
_ = x[Resize-141]
_ = x[Change-142]
_ = x[BackwardEOF-143]
_ = x[Start-144]
_ = x[Load-145]
_ = x[Focus-146]
_ = x[One-147]
_ = x[Zero-148]
_ = x[Result-149]
_ = x[Jump-150]
_ = x[JumpCancel-151]
_ = x[ClickHeader-152]
_ = x[ClickFooter-153]
_ = x[Multi-154]
}
const _EventType_name = "RuneCtrlACtrlBCtrlCCtrlDCtrlECtrlFCtrlGCtrlHTabCtrlJCtrlKCtrlLEnterCtrlNCtrlOCtrlPCtrlQCtrlRCtrlSCtrlTCtrlUCtrlVCtrlWCtrlXCtrlYCtrlZEscCtrlSpaceCtrlDeleteCtrlBackSlashCtrlRightBracketCtrlCaretCtrlSlashShiftTabBackspaceDeletePageUpPageDownUpDownLeftRightHomeEndInsertShiftUpShiftDownShiftLeftShiftRightShiftDeleteF1F2F3F4F5F6F7F8F9F10F11F12AltBackspaceAltUpAltDownAltLeftAltRightAltShiftUpAltShiftDownAltShiftLeftAltShiftRightAltCtrlAltInvalidFatalBracketedPasteBeginBracketedPasteEndMouseDoubleClickLeftClickRightClickSLeftClickSRightClickScrollUpScrollDownSScrollUpSScrollDownPreviewScrollUpPreviewScrollDownResizeChangeBackwardEOFStartLoadFocusOneZeroResultJumpJumpCancelClickHeaderClickFooterMulti"
const _EventType_name = "RuneCtrlACtrlBCtrlCCtrlDCtrlECtrlFCtrlGCtrlHTabCtrlJCtrlKCtrlLEnterCtrlNCtrlOCtrlPCtrlQCtrlRCtrlSCtrlTCtrlUCtrlVCtrlWCtrlXCtrlYCtrlZEscCtrlSpaceCtrlBackSlashCtrlRightBracketCtrlCaretCtrlSlashShiftTabBackspaceDeletePageUpPageDownUpDownLeftRightHomeEndInsertShiftUpShiftDownShiftLeftShiftRightShiftDeleteShiftHomeShiftEndShiftPageUpShiftPageDownF1F2F3F4F5F6F7F8F9F10F11F12AltBackspaceAltUpAltDownAltLeftAltRightAltDeleteAltHomeAltEndAltPageUpAltPageDownAltShiftUpAltShiftDownAltShiftLeftAltShiftRightAltShiftDeleteAltShiftHomeAltShiftEndAltShiftPageUpAltShiftPageDownCtrlUpCtrlDownCtrlLeftCtrlRightCtrlHomeCtrlEndCtrlBackspaceCtrlDeleteCtrlPageUpCtrlPageDownAltCtrlAltCtrlAltUpCtrlAltDownCtrlAltLeftCtrlAltRightCtrlAltHomeCtrlAltEndCtrlAltBackspaceCtrlAltDeleteCtrlAltPageUpCtrlAltPageDownCtrlShiftUpCtrlShiftDownCtrlShiftLeftCtrlShiftRightCtrlShiftHomeCtrlShiftEndCtrlShiftDeleteCtrlShiftPageUpCtrlShiftPageDownCtrlAltShiftUpCtrlAltShiftDownCtrlAltShiftLeftCtrlAltShiftRightCtrlAltShiftHomeCtrlAltShiftEndCtrlAltShiftDeleteCtrlAltShiftPageUpCtrlAltShiftPageDownInvalidFatalBracketedPasteBeginBracketedPasteEndMouseDoubleClickLeftClickRightClickSLeftClickSRightClickScrollUpScrollDownSScrollUpSScrollDownPreviewScrollUpPreviewScrollDownResizeChangeBackwardEOFStartLoadFocusOneZeroResultJumpJumpCancelClickHeaderClickFooterMulti"
var _EventType_index = [...]uint16{0, 4, 9, 14, 19, 24, 29, 34, 39, 44, 47, 52, 57, 62, 67, 72, 77, 82, 87, 92, 97, 102, 107, 112, 117, 122, 127, 132, 135, 144, 154, 167, 183, 192, 201, 209, 218, 224, 230, 238, 240, 244, 248, 253, 257, 260, 266, 273, 282, 291, 301, 312, 314, 316, 318, 320, 322, 324, 326, 328, 330, 333, 336, 339, 351, 356, 363, 370, 378, 388, 400, 412, 425, 428, 435, 442, 447, 466, 483, 488, 499, 508, 518, 528, 539, 547, 557, 566, 577, 592, 609, 615, 621, 632, 637, 641, 646, 649, 653, 659, 663, 673, 684, 695, 700}
var _EventType_index = [...]uint16{0, 4, 9, 14, 19, 24, 29, 34, 39, 44, 47, 52, 57, 62, 67, 72, 77, 82, 87, 92, 97, 102, 107, 112, 117, 122, 127, 132, 135, 144, 157, 173, 182, 191, 199, 208, 214, 220, 228, 230, 234, 238, 243, 247, 250, 256, 263, 272, 281, 291, 302, 311, 319, 330, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, 364, 367, 370, 382, 387, 394, 401, 409, 418, 425, 431, 440, 451, 461, 473, 485, 498, 512, 524, 535, 549, 565, 571, 579, 587, 596, 604, 611, 624, 634, 644, 656, 659, 666, 675, 686, 697, 709, 720, 730, 746, 759, 772, 787, 798, 811, 824, 838, 851, 863, 878, 893, 910, 924, 940, 956, 973, 989, 1004, 1022, 1040, 1060, 1067, 1072, 1091, 1108, 1113, 1124, 1133, 1143, 1153, 1164, 1172, 1182, 1191, 1202, 1217, 1234, 1240, 1246, 1257, 1262, 1266, 1271, 1274, 1278, 1284, 1288, 1298, 1309, 1320, 1325}
func (i EventType) String() string {
if i < 0 || i >= EventType(len(_EventType_index)-1) {

View File

@@ -335,6 +335,8 @@ func (r *LightRenderer) GetChar() Event {
return Event{CtrlQ, 0, nil}
case 127:
return Event{Backspace, 0, nil}
case 8:
return Event{CtrlBackspace, 0, nil}
case 0:
return Event{CtrlSpace, 0, nil}
case 28:
@@ -381,6 +383,9 @@ func (r *LightRenderer) escSequence(sz *int) Event {
}
*sz = 2
if r.buffer[1] == 8 {
return Event{CtrlAltBackspace, 0, nil}
}
if r.buffer[1] >= 1 && r.buffer[1] <= 'z'-'a'+1 {
return CtrlAltKey(rune(r.buffer[1] + 'a' - 1))
}
@@ -473,22 +478,136 @@ func (r *LightRenderer) escSequence(sz *int) Event {
if r.buffer[3] == '~' {
return Event{Delete, 0, nil}
}
if len(r.buffer) == 7 && r.buffer[6] == '~' && r.buffer[4] == '1' {
switch r.buffer[5] {
case '0':
return Event{AltShiftDelete, 0, nil}
case '1':
return Event{AltDelete, 0, nil}
case '2':
return Event{AltShiftDelete, 0, nil}
case '3':
return Event{CtrlAltDelete, 0, nil}
case '4':
return Event{CtrlAltShiftDelete, 0, nil}
case '5':
return Event{CtrlAltDelete, 0, nil}
case '6':
return Event{CtrlAltShiftDelete, 0, nil}
}
}
if len(r.buffer) == 6 && r.buffer[5] == '~' {
*sz = 6
switch r.buffer[4] {
case '5':
return Event{CtrlDelete, 0, nil}
case '2':
return Event{ShiftDelete, 0, nil}
case '3':
return Event{AltDelete, 0, nil}
case '4':
return Event{AltShiftDelete, 0, nil}
case '5':
return Event{CtrlDelete, 0, nil}
case '6':
return Event{CtrlShiftDelete, 0, nil}
case '7':
return Event{CtrlAltDelete, 0, nil}
case '8':
return Event{CtrlAltShiftDelete, 0, nil}
case '9':
return Event{AltDelete, 0, nil}
}
}
return Event{Invalid, 0, nil}
case '4':
return Event{End, 0, nil}
case '5':
return Event{PageUp, 0, nil}
if r.buffer[3] == '~' {
return Event{PageUp, 0, nil}
}
if len(r.buffer) == 7 && r.buffer[6] == '~' && r.buffer[4] == '1' {
switch r.buffer[5] {
case '0':
return Event{AltShiftPageUp, 0, nil}
case '1':
return Event{AltPageUp, 0, nil}
case '2':
return Event{AltShiftPageUp, 0, nil}
case '3':
return Event{CtrlAltPageUp, 0, nil}
case '4':
return Event{CtrlAltShiftPageUp, 0, nil}
case '5':
return Event{CtrlAltPageUp, 0, nil}
case '6':
return Event{CtrlAltShiftPageUp, 0, nil}
}
}
if len(r.buffer) == 6 && r.buffer[5] == '~' {
*sz = 6
switch r.buffer[4] {
case '2':
return Event{ShiftPageUp, 0, nil}
case '3':
return Event{AltPageUp, 0, nil}
case '4':
return Event{AltShiftPageUp, 0, nil}
case '5':
return Event{CtrlPageUp, 0, nil}
case '6':
return Event{CtrlShiftPageUp, 0, nil}
case '7':
return Event{CtrlAltPageUp, 0, nil}
case '8':
return Event{CtrlAltShiftPageUp, 0, nil}
case '9':
return Event{AltPageUp, 0, nil}
}
}
return Event{Invalid, 0, nil}
case '6':
return Event{PageDown, 0, nil}
if r.buffer[3] == '~' {
return Event{PageDown, 0, nil}
}
if len(r.buffer) == 7 && r.buffer[6] == '~' && r.buffer[4] == '1' {
switch r.buffer[5] {
case '0':
return Event{AltShiftPageDown, 0, nil}
case '1':
return Event{AltPageDown, 0, nil}
case '2':
return Event{AltShiftPageDown, 0, nil}
case '3':
return Event{CtrlAltPageDown, 0, nil}
case '4':
return Event{CtrlAltShiftPageDown, 0, nil}
case '5':
return Event{CtrlAltPageDown, 0, nil}
case '6':
return Event{CtrlAltShiftPageDown, 0, nil}
}
}
if len(r.buffer) == 6 && r.buffer[5] == '~' {
*sz = 6
switch r.buffer[4] {
case '2':
return Event{ShiftPageDown, 0, nil}
case '3':
return Event{AltPageDown, 0, nil}
case '4':
return Event{AltShiftPageDown, 0, nil}
case '5':
return Event{CtrlPageDown, 0, nil}
case '6':
return Event{CtrlShiftPageDown, 0, nil}
case '7':
return Event{CtrlAltPageDown, 0, nil}
case '8':
return Event{CtrlAltShiftPageDown, 0, nil}
case '9':
return Event{AltPageDown, 0, nil}
}
}
return Event{Invalid, 0, nil}
case '7':
return Event{Home, 0, nil}
case '8':
@@ -526,63 +645,172 @@ func (r *LightRenderer) escSequence(sz *int) Event {
}
*sz = 6
switch r.buffer[4] {
case '1', '2', '3', '4', '5':
case '1', '2', '3', '4', '5', '6', '7', '8', '9':
// Kitty iTerm2 WezTerm
// SHIFT-ARROW "\e[1;2D"
// ALT-SHIFT-ARROW "\e[1;4D" "\e[1;10D" "\e[1;4D"
// CTRL-SHIFT-ARROW "\e[1;6D" N/A
// CMD-SHIFT-ARROW "\e[1;10D" N/A N/A ("\e[1;2D")
alt := r.buffer[4] == '3'
ctrl := bytes.IndexByte([]byte{'5', '6', '7', '8'}, r.buffer[4]) >= 0
alt := bytes.IndexByte([]byte{'3', '4', '7', '8'}, r.buffer[4]) >= 0
shift := bytes.IndexByte([]byte{'2', '4', '6', '8'}, r.buffer[4]) >= 0
char := r.buffer[5]
altShift := false
if r.buffer[4] == '1' && r.buffer[5] == '0' {
altShift = true
if len(r.buffer) < 7 {
return Event{Invalid, 0, nil}
}
*sz = 7
char = r.buffer[6]
} else if r.buffer[4] == '4' {
altShift = true
if r.buffer[4] == '9' {
ctrl = false
alt = true
shift = false
if len(r.buffer) < 6 {
return Event{Invalid, 0, nil}
}
*sz = 6
char = r.buffer[5]
} else if r.buffer[4] == '1' && bytes.IndexByte([]byte{'0', '1', '2', '3', '4', '5', '6'}, r.buffer[5]) >= 0 {
ctrl = bytes.IndexByte([]byte{'3', '4', '5', '6'}, r.buffer[5]) >= 0
alt = true
shift = bytes.IndexByte([]byte{'0', '2', '4', '6'}, r.buffer[5]) >= 0
if len(r.buffer) < 7 {
return Event{Invalid, 0, nil}
}
*sz = 7
char = r.buffer[6]
}
ctrlShift := ctrl && shift
ctrlAlt := ctrl && alt
altShift := alt && shift
ctrlAltShift := ctrl && alt && shift
switch char {
case 'A':
if alt {
return Event{AltUp, 0, nil}
if ctrlAltShift {
return Event{CtrlAltShiftUp, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltUp, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftUp, 0, nil}
}
if altShift {
return Event{AltShiftUp, 0, nil}
}
return Event{ShiftUp, 0, nil}
case 'B':
if ctrl {
return Event{CtrlUp, 0, nil}
}
if alt {
return Event{AltDown, 0, nil}
return Event{AltUp, 0, nil}
}
if shift {
return Event{ShiftUp, 0, nil}
}
case 'B':
if ctrlAltShift {
return Event{CtrlAltShiftDown, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltDown, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftDown, 0, nil}
}
if altShift {
return Event{AltShiftDown, 0, nil}
}
return Event{ShiftDown, 0, nil}
case 'C':
if ctrl {
return Event{CtrlDown, 0, nil}
}
if alt {
return Event{AltRight, 0, nil}
return Event{AltDown, 0, nil}
}
if shift {
return Event{ShiftDown, 0, nil}
}
case 'C':
if ctrlAltShift {
return Event{CtrlAltShiftRight, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltRight, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftRight, 0, nil}
}
if altShift {
return Event{AltShiftRight, 0, nil}
}
return Event{ShiftRight, 0, nil}
case 'D':
if ctrl {
return Event{CtrlRight, 0, nil}
}
if shift {
return Event{ShiftRight, 0, nil}
}
if alt {
return Event{AltLeft, 0, nil}
return Event{AltRight, 0, nil}
}
case 'D':
if ctrlAltShift {
return Event{CtrlAltShiftLeft, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltLeft, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftLeft, 0, nil}
}
if altShift {
return Event{AltShiftLeft, 0, nil}
}
return Event{ShiftLeft, 0, nil}
if ctrl {
return Event{CtrlLeft, 0, nil}
}
if alt {
return Event{AltLeft, 0, nil}
}
if shift {
return Event{ShiftLeft, 0, nil}
}
case 'H':
if ctrlAltShift {
return Event{CtrlAltShiftHome, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltHome, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftHome, 0, nil}
}
if altShift {
return Event{AltShiftHome, 0, nil}
}
if ctrl {
return Event{CtrlHome, 0, nil}
}
if alt {
return Event{AltHome, 0, nil}
}
if shift {
return Event{ShiftHome, 0, nil}
}
case 'F':
if ctrlAltShift {
return Event{CtrlAltShiftEnd, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltEnd, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftEnd, 0, nil}
}
if altShift {
return Event{AltShiftEnd, 0, nil}
}
if ctrl {
return Event{CtrlEnd, 0, nil}
}
if alt {
return Event{AltEnd, 0, nil}
}
if shift {
return Event{ShiftEnd, 0, nil}
}
}
} // r.buffer[4]
} // r.buffer[3]

335
src/tui/light_test.go Normal file
View File

@@ -0,0 +1,335 @@
package tui
import (
"fmt"
"os"
"testing"
"unicode"
)
func TestLightRenderer(t *testing.T) {
tty_file, _ := os.Open("")
renderer, _ := NewLightRenderer(
"", tty_file, &ColorTheme{}, true, false, 0, false, true,
func(h int) int { return h })
light_renderer := renderer.(*LightRenderer)
assertCharSequence := func(sequence string, name string) {
bytes := []byte(sequence)
light_renderer.buffer = bytes
event := light_renderer.GetChar()
if event.KeyName() != name {
t.Errorf(
"sequence: %q | %v | '%s' (%s) != %s",
string(bytes), bytes,
event.KeyName(), event.Type.String(), name)
}
}
assertEscSequence := func(sequence string, name string) {
bytes := []byte(sequence)
light_renderer.buffer = bytes
sz := 1
event := light_renderer.escSequence(&sz)
if fmt.Sprintf("!%s", event.Type.String()) == name {
// this is fine
} else if event.KeyName() != name {
t.Errorf(
"sequence: %q | %v | '%s' (%s) != %s",
string(bytes), bytes,
event.KeyName(), event.Type.String(), name)
}
}
// invalid
assertEscSequence("\x1b[<", "!Invalid")
assertEscSequence("\x1b[1;1R", "!Invalid")
assertEscSequence("\x1b[", "!Invalid")
assertEscSequence("\x1b[1", "!Invalid")
assertEscSequence("\x1b[3;3~1", "!Invalid")
assertEscSequence("\x1b[13", "!Invalid")
assertEscSequence("\x1b[1;3", "!Invalid")
assertEscSequence("\x1b[1;10", "!Invalid")
assertEscSequence("\x1b[220~", "!Invalid")
assertEscSequence("\x1b[5;30~", "!Invalid")
assertEscSequence("\x1b[6;30~", "!Invalid")
// general
for r := 'a'; r < 'z'; r++ {
lower_r := fmt.Sprintf("%c", r)
upper_r := fmt.Sprintf("%c", unicode.ToUpper(r))
assertCharSequence(lower_r, lower_r)
assertCharSequence(upper_r, upper_r)
}
assertCharSequence("\x01", "ctrl-a")
assertCharSequence("\x02", "ctrl-b")
assertCharSequence("\x03", "ctrl-c")
assertCharSequence("\x04", "ctrl-d")
assertCharSequence("\x05", "ctrl-e")
assertCharSequence("\x06", "ctrl-f")
assertCharSequence("\x07", "ctrl-g")
// ctrl-h is the same as ctrl-backspace
// ctrl-i is the same as tab
assertCharSequence("\n", "ctrl-j")
assertCharSequence("\x0b", "ctrl-k")
assertCharSequence("\x0c", "ctrl-l")
assertCharSequence("\r", "enter") // enter
assertCharSequence("\x0e", "ctrl-n")
assertCharSequence("\x0f", "ctrl-o")
assertCharSequence("\x10", "ctrl-p")
assertCharSequence("\x11", "ctrl-q")
assertCharSequence("\x12", "ctrl-r")
assertCharSequence("\x13", "ctrl-s")
assertCharSequence("\x14", "ctrl-t")
assertCharSequence("\x15", "ctrl-u")
assertCharSequence("\x16", "ctrl-v")
assertCharSequence("\x17", "ctrl-w")
assertCharSequence("\x18", "ctrl-x")
assertCharSequence("\x19", "ctrl-y")
assertCharSequence("\x1a", "ctrl-z")
assertCharSequence("\x00", "ctrl-space")
assertCharSequence("\x1c", "ctrl-\\")
assertCharSequence("\x1d", "ctrl-]")
assertCharSequence("\x1e", "ctrl-^")
assertCharSequence("\x1f", "ctrl-/")
assertEscSequence("\x1ba", "alt-a")
assertEscSequence("\x1bb", "alt-b")
assertEscSequence("\x1bc", "alt-c")
assertEscSequence("\x1bd", "alt-d")
assertEscSequence("\x1be", "alt-e")
assertEscSequence("\x1bf", "alt-f")
assertEscSequence("\x1bg", "alt-g")
assertEscSequence("\x1bh", "alt-h")
assertEscSequence("\x1bi", "alt-i")
assertEscSequence("\x1bj", "alt-j")
assertEscSequence("\x1bk", "alt-k")
assertEscSequence("\x1bl", "alt-l")
assertEscSequence("\x1bm", "alt-m")
assertEscSequence("\x1bn", "alt-n")
assertEscSequence("\x1bo", "alt-o")
assertEscSequence("\x1bp", "alt-p")
assertEscSequence("\x1bq", "alt-q")
assertEscSequence("\x1br", "alt-r")
assertEscSequence("\x1bs", "alt-s")
assertEscSequence("\x1bt", "alt-t")
assertEscSequence("\x1bu", "alt-u")
assertEscSequence("\x1bv", "alt-v")
assertEscSequence("\x1bw", "alt-w")
assertEscSequence("\x1bx", "alt-x")
assertEscSequence("\x1by", "alt-y")
assertEscSequence("\x1bz", "alt-z")
assertEscSequence("\x1bOP", "f1")
assertEscSequence("\x1bOQ", "f2")
assertEscSequence("\x1bOR", "f3")
assertEscSequence("\x1bOS", "f4")
assertEscSequence("\x1b[15~", "f5")
assertEscSequence("\x1b[17~", "f6")
assertEscSequence("\x1b[18~", "f7")
assertEscSequence("\x1b[19~", "f8")
assertEscSequence("\x1b[20~", "f9")
assertEscSequence("\x1b[21~", "f10")
assertEscSequence("\x1b[23~", "f11")
assertEscSequence("\x1b[24~", "f12")
assertEscSequence("\x1b", "esc")
assertCharSequence("\t", "tab")
assertEscSequence("\x1b[Z", "shift-tab")
assertCharSequence("\x7f", "backspace")
assertEscSequence("\x1b\x7f", "alt-backspace")
assertCharSequence("\b", "ctrl-backspace")
assertEscSequence("\x1b\b", "ctrl-alt-backspace")
assertEscSequence("\x1b[A", "up")
assertEscSequence("\x1b[B", "down")
assertEscSequence("\x1b[C", "right")
assertEscSequence("\x1b[D", "left")
assertEscSequence("\x1b[H", "home")
assertEscSequence("\x1b[F", "end")
assertEscSequence("\x1b[2~", "insert")
assertEscSequence("\x1b[3~", "delete")
assertEscSequence("\x1b[5~", "page-up")
assertEscSequence("\x1b[6~", "page-down")
assertEscSequence("\x1b[7~", "home")
assertEscSequence("\x1b[8~", "end")
assertEscSequence("\x1b[1;2A", "shift-up")
assertEscSequence("\x1b[1;2B", "shift-down")
assertEscSequence("\x1b[1;2C", "shift-right")
assertEscSequence("\x1b[1;2D", "shift-left")
assertEscSequence("\x1b[1;2H", "shift-home")
assertEscSequence("\x1b[1;2F", "shift-end")
assertEscSequence("\x1b[3;2~", "shift-delete")
assertEscSequence("\x1b[5;2~", "shift-page-up")
assertEscSequence("\x1b[6;2~", "shift-page-down")
assertEscSequence("\x1b\x1b", "esc")
assertEscSequence("\x1b\x1b[A", "alt-up")
assertEscSequence("\x1b\x1b[B", "alt-down")
assertEscSequence("\x1b\x1b[C", "alt-right")
assertEscSequence("\x1b\x1b[D", "alt-left")
assertEscSequence("\x1b[1;3A", "alt-up")
assertEscSequence("\x1b[1;3B", "alt-down")
assertEscSequence("\x1b[1;3C", "alt-right")
assertEscSequence("\x1b[1;3D", "alt-left")
assertEscSequence("\x1b[1;3H", "alt-home")
assertEscSequence("\x1b[1;3F", "alt-end")
assertEscSequence("\x1b[3;3~", "alt-delete")
assertEscSequence("\x1b[5;3~", "alt-page-up")
assertEscSequence("\x1b[6;3~", "alt-page-down")
assertEscSequence("\x1b[1;4A", "alt-shift-up")
assertEscSequence("\x1b[1;4B", "alt-shift-down")
assertEscSequence("\x1b[1;4C", "alt-shift-right")
assertEscSequence("\x1b[1;4D", "alt-shift-left")
assertEscSequence("\x1b[1;4H", "alt-shift-home")
assertEscSequence("\x1b[1;4F", "alt-shift-end")
assertEscSequence("\x1b[3;4~", "alt-shift-delete")
assertEscSequence("\x1b[5;4~", "alt-shift-page-up")
assertEscSequence("\x1b[6;4~", "alt-shift-page-down")
assertEscSequence("\x1b[1;5A", "ctrl-up")
assertEscSequence("\x1b[1;5B", "ctrl-down")
assertEscSequence("\x1b[1;5C", "ctrl-right")
assertEscSequence("\x1b[1;5D", "ctrl-left")
assertEscSequence("\x1b[1;5H", "ctrl-home")
assertEscSequence("\x1b[1;5F", "ctrl-end")
assertEscSequence("\x1b[3;5~", "ctrl-delete")
assertEscSequence("\x1b[5;5~", "ctrl-page-up")
assertEscSequence("\x1b[6;5~", "ctrl-page-down")
assertEscSequence("\x1b[1;7A", "ctrl-alt-up")
assertEscSequence("\x1b[1;7B", "ctrl-alt-down")
assertEscSequence("\x1b[1;7C", "ctrl-alt-right")
assertEscSequence("\x1b[1;7D", "ctrl-alt-left")
assertEscSequence("\x1b[1;7H", "ctrl-alt-home")
assertEscSequence("\x1b[1;7F", "ctrl-alt-end")
assertEscSequence("\x1b[3;7~", "ctrl-alt-delete")
assertEscSequence("\x1b[5;7~", "ctrl-alt-page-up")
assertEscSequence("\x1b[6;7~", "ctrl-alt-page-down")
assertEscSequence("\x1b[1;6A", "ctrl-shift-up")
assertEscSequence("\x1b[1;6B", "ctrl-shift-down")
assertEscSequence("\x1b[1;6C", "ctrl-shift-right")
assertEscSequence("\x1b[1;6D", "ctrl-shift-left")
assertEscSequence("\x1b[1;6H", "ctrl-shift-home")
assertEscSequence("\x1b[1;6F", "ctrl-shift-end")
assertEscSequence("\x1b[3;6~", "ctrl-shift-delete")
assertEscSequence("\x1b[5;6~", "ctrl-shift-page-up")
assertEscSequence("\x1b[6;6~", "ctrl-shift-page-down")
assertEscSequence("\x1b[1;8A", "ctrl-alt-shift-up")
assertEscSequence("\x1b[1;8B", "ctrl-alt-shift-down")
assertEscSequence("\x1b[1;8C", "ctrl-alt-shift-right")
assertEscSequence("\x1b[1;8D", "ctrl-alt-shift-left")
assertEscSequence("\x1b[1;8H", "ctrl-alt-shift-home")
assertEscSequence("\x1b[1;8F", "ctrl-alt-shift-end")
assertEscSequence("\x1b[3;8~", "ctrl-alt-shift-delete")
assertEscSequence("\x1b[5;8~", "ctrl-alt-shift-page-up")
assertEscSequence("\x1b[6;8~", "ctrl-alt-shift-page-down")
// xterm meta & mac
assertEscSequence("\x1b[1;9A", "alt-up")
assertEscSequence("\x1b[1;9B", "alt-down")
assertEscSequence("\x1b[1;9C", "alt-right")
assertEscSequence("\x1b[1;9D", "alt-left")
assertEscSequence("\x1b[1;9H", "alt-home")
assertEscSequence("\x1b[1;9F", "alt-end")
assertEscSequence("\x1b[3;9~", "alt-delete")
assertEscSequence("\x1b[5;9~", "alt-page-up")
assertEscSequence("\x1b[6;9~", "alt-page-down")
assertEscSequence("\x1b[1;10A", "alt-shift-up")
assertEscSequence("\x1b[1;10B", "alt-shift-down")
assertEscSequence("\x1b[1;10C", "alt-shift-right")
assertEscSequence("\x1b[1;10D", "alt-shift-left")
assertEscSequence("\x1b[1;10H", "alt-shift-home")
assertEscSequence("\x1b[1;10F", "alt-shift-end")
assertEscSequence("\x1b[3;10~", "alt-shift-delete")
assertEscSequence("\x1b[5;10~", "alt-shift-page-up")
assertEscSequence("\x1b[6;10~", "alt-shift-page-down")
assertEscSequence("\x1b[1;11A", "alt-up")
assertEscSequence("\x1b[1;11B", "alt-down")
assertEscSequence("\x1b[1;11C", "alt-right")
assertEscSequence("\x1b[1;11D", "alt-left")
assertEscSequence("\x1b[1;11H", "alt-home")
assertEscSequence("\x1b[1;11F", "alt-end")
assertEscSequence("\x1b[3;11~", "alt-delete")
assertEscSequence("\x1b[5;11~", "alt-page-up")
assertEscSequence("\x1b[6;11~", "alt-page-down")
assertEscSequence("\x1b[1;12A", "alt-shift-up")
assertEscSequence("\x1b[1;12B", "alt-shift-down")
assertEscSequence("\x1b[1;12C", "alt-shift-right")
assertEscSequence("\x1b[1;12D", "alt-shift-left")
assertEscSequence("\x1b[1;12H", "alt-shift-home")
assertEscSequence("\x1b[1;12F", "alt-shift-end")
assertEscSequence("\x1b[3;12~", "alt-shift-delete")
assertEscSequence("\x1b[5;12~", "alt-shift-page-up")
assertEscSequence("\x1b[6;12~", "alt-shift-page-down")
assertEscSequence("\x1b[1;13A", "ctrl-alt-up")
assertEscSequence("\x1b[1;13B", "ctrl-alt-down")
assertEscSequence("\x1b[1;13C", "ctrl-alt-right")
assertEscSequence("\x1b[1;13D", "ctrl-alt-left")
assertEscSequence("\x1b[1;13H", "ctrl-alt-home")
assertEscSequence("\x1b[1;13F", "ctrl-alt-end")
assertEscSequence("\x1b[3;13~", "ctrl-alt-delete")
assertEscSequence("\x1b[5;13~", "ctrl-alt-page-up")
assertEscSequence("\x1b[6;13~", "ctrl-alt-page-down")
assertEscSequence("\x1b[1;14A", "ctrl-alt-shift-up")
assertEscSequence("\x1b[1;14B", "ctrl-alt-shift-down")
assertEscSequence("\x1b[1;14C", "ctrl-alt-shift-right")
assertEscSequence("\x1b[1;14D", "ctrl-alt-shift-left")
assertEscSequence("\x1b[1;14H", "ctrl-alt-shift-home")
assertEscSequence("\x1b[1;14F", "ctrl-alt-shift-end")
assertEscSequence("\x1b[3;14~", "ctrl-alt-shift-delete")
assertEscSequence("\x1b[5;14~", "ctrl-alt-shift-page-up")
assertEscSequence("\x1b[6;14~", "ctrl-alt-shift-page-down")
assertEscSequence("\x1b[1;15A", "ctrl-alt-up")
assertEscSequence("\x1b[1;15B", "ctrl-alt-down")
assertEscSequence("\x1b[1;15C", "ctrl-alt-right")
assertEscSequence("\x1b[1;15D", "ctrl-alt-left")
assertEscSequence("\x1b[1;15H", "ctrl-alt-home")
assertEscSequence("\x1b[1;15F", "ctrl-alt-end")
assertEscSequence("\x1b[3;15~", "ctrl-alt-delete")
assertEscSequence("\x1b[5;15~", "ctrl-alt-page-up")
assertEscSequence("\x1b[6;15~", "ctrl-alt-page-down")
assertEscSequence("\x1b[1;16A", "ctrl-alt-shift-up")
assertEscSequence("\x1b[1;16B", "ctrl-alt-shift-down")
assertEscSequence("\x1b[1;16C", "ctrl-alt-shift-right")
assertEscSequence("\x1b[1;16D", "ctrl-alt-shift-left")
assertEscSequence("\x1b[1;16H", "ctrl-alt-shift-home")
assertEscSequence("\x1b[1;16F", "ctrl-alt-shift-end")
assertEscSequence("\x1b[3;16~", "ctrl-alt-shift-delete")
assertEscSequence("\x1b[5;16~", "ctrl-alt-shift-page-up")
assertEscSequence("\x1b[6;16~", "ctrl-alt-shift-page-down")
// tmux & emacs
assertEscSequence("\x1bOA", "up")
assertEscSequence("\x1bOB", "down")
assertEscSequence("\x1bOC", "right")
assertEscSequence("\x1bOD", "left")
assertEscSequence("\x1bOH", "home")
assertEscSequence("\x1bOF", "end")
// rrvt
assertEscSequence("\x1b[1~", "home")
assertEscSequence("\x1b[4~", "end")
assertEscSequence("\x1b[11~", "f1")
assertEscSequence("\x1b[12~", "f2")
assertEscSequence("\x1b[13~", "f3")
assertEscSequence("\x1b[14~", "f4")
}

View File

@@ -354,6 +354,8 @@ func (r *FullscreenRenderer) GetChar() Event {
shift := (mods & tcell.ModShift) > 0
ctrlAlt := ctrl && alt
altShift := alt && shift
ctrlShift := ctrl && shift
ctrlAltShift := ctrl && alt && shift
keyfn := func(r rune) Event {
if alt {
@@ -380,8 +382,11 @@ func (r *FullscreenRenderer) GetChar() Event {
case tcell.KeyCtrlH:
switch ev.Rune() {
case 0:
if ctrlAlt {
return Event{CtrlAltBackspace, 0, nil}
}
if ctrl {
return Event{Backspace, 0, nil}
return Event{CtrlBackspace, 0, nil}
}
case rune(tcell.KeyCtrlH):
switch {
@@ -442,6 +447,9 @@ func (r *FullscreenRenderer) GetChar() Event {
return Event{CtrlSlash, 0, nil}
// section 3: (Alt)+Backspace2
case tcell.KeyBackspace2:
if ctrl {
return Event{CtrlBackspace, 0, nil}
}
if alt {
return Event{AltBackspace, 0, nil}
}
@@ -449,9 +457,21 @@ func (r *FullscreenRenderer) GetChar() Event {
// section 4: (Alt+Shift)+Key(Up|Down|Left|Right)
case tcell.KeyUp:
if ctrlAltShift {
return Event{CtrlAltShiftUp, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltUp, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftUp, 0, nil}
}
if altShift {
return Event{AltShiftUp, 0, nil}
}
if ctrl {
return Event{CtrlUp, 0, nil}
}
if shift {
return Event{ShiftUp, 0, nil}
}
@@ -460,9 +480,21 @@ func (r *FullscreenRenderer) GetChar() Event {
}
return Event{Up, 0, nil}
case tcell.KeyDown:
if ctrlAltShift {
return Event{CtrlAltShiftDown, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltDown, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftDown, 0, nil}
}
if altShift {
return Event{AltShiftDown, 0, nil}
}
if ctrl {
return Event{CtrlDown, 0, nil}
}
if shift {
return Event{ShiftDown, 0, nil}
}
@@ -471,9 +503,21 @@ func (r *FullscreenRenderer) GetChar() Event {
}
return Event{Down, 0, nil}
case tcell.KeyLeft:
if ctrlAltShift {
return Event{CtrlAltShiftLeft, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltLeft, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftLeft, 0, nil}
}
if altShift {
return Event{AltShiftLeft, 0, nil}
}
if ctrl {
return Event{CtrlLeft, 0, nil}
}
if shift {
return Event{ShiftLeft, 0, nil}
}
@@ -482,9 +526,21 @@ func (r *FullscreenRenderer) GetChar() Event {
}
return Event{Left, 0, nil}
case tcell.KeyRight:
if ctrlAltShift {
return Event{CtrlAltShiftRight, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltRight, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftRight, 0, nil}
}
if altShift {
return Event{AltShiftRight, 0, nil}
}
if ctrl {
return Event{CtrlRight, 0, nil}
}
if shift {
return Event{ShiftRight, 0, nil}
}
@@ -497,20 +553,119 @@ func (r *FullscreenRenderer) GetChar() Event {
case tcell.KeyInsert:
return Event{Insert, 0, nil}
case tcell.KeyHome:
if ctrlAltShift {
return Event{CtrlAltShiftHome, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltHome, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftHome, 0, nil}
}
if altShift {
return Event{AltShiftHome, 0, nil}
}
if ctrl {
return Event{CtrlHome, 0, nil}
}
if shift {
return Event{ShiftHome, 0, nil}
}
if alt {
return Event{AltHome, 0, nil}
}
return Event{Home, 0, nil}
case tcell.KeyDelete:
if ctrlAltShift {
return Event{CtrlAltShiftDelete, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltDelete, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftDelete, 0, nil}
}
if altShift {
return Event{AltShiftDelete, 0, nil}
}
if ctrl {
return Event{CtrlDelete, 0, nil}
}
if alt {
return Event{AltDelete, 0, nil}
}
if shift {
return Event{ShiftDelete, 0, nil}
}
return Event{Delete, 0, nil}
case tcell.KeyEnd:
if ctrlAltShift {
return Event{CtrlAltShiftEnd, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltEnd, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftEnd, 0, nil}
}
if altShift {
return Event{AltShiftEnd, 0, nil}
}
if ctrl {
return Event{CtrlEnd, 0, nil}
}
if shift {
return Event{ShiftEnd, 0, nil}
}
if alt {
return Event{AltEnd, 0, nil}
}
return Event{End, 0, nil}
case tcell.KeyPgUp:
if ctrlAltShift {
return Event{CtrlAltShiftPageUp, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltPageUp, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftPageUp, 0, nil}
}
if altShift {
return Event{AltShiftPageUp, 0, nil}
}
if ctrl {
return Event{CtrlPageUp, 0, nil}
}
if shift {
return Event{ShiftPageUp, 0, nil}
}
if alt {
return Event{AltPageUp, 0, nil}
}
return Event{PageUp, 0, nil}
case tcell.KeyPgDn:
if ctrlAltShift {
return Event{CtrlAltShiftPageDown, 0, nil}
}
if ctrlAlt {
return Event{CtrlAltPageDown, 0, nil}
}
if ctrlShift {
return Event{CtrlShiftPageDown, 0, nil}
}
if altShift {
return Event{AltShiftPageDown, 0, nil}
}
if ctrl {
return Event{CtrlPageDown, 0, nil}
}
if shift {
return Event{ShiftPageDown, 0, nil}
}
if alt {
return Event{AltPageDown, 0, nil}
}
return Event{PageDown, 0, nil}
case tcell.KeyBacktab:
return Event{ShiftTab, 0, nil}

View File

@@ -107,18 +107,20 @@ func TestGetCharEventKey(t *testing.T) {
{giveKey{tcell.KeyBackspace2, 0, tcell.ModAlt}, wantKey{AltBackspace, 0, nil}}, // fabricated
{giveKey{tcell.KeyDEL, 0, tcell.ModNone}, wantKey{Backspace, 0, nil}}, // fabricated, unhandled
{giveKey{tcell.KeyDelete, 0, tcell.ModNone}, wantKey{Delete, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModAlt}, wantKey{Delete, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModAlt}, wantKey{AltDelete, 0, nil}},
{giveKey{tcell.KeyBackspace, 0, tcell.ModCtrl}, wantKey{CtrlBackspace, 0, nil}},
{giveKey{tcell.KeyBackspace, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltBackspace, 0, nil}},
{giveKey{tcell.KeyBackspace, 0, tcell.ModNone}, wantKey{Invalid, 0, nil}}, // fabricated, unhandled
{giveKey{tcell.KeyBS, 0, tcell.ModNone}, wantKey{Invalid, 0, nil}}, // fabricated, unhandled
{giveKey{tcell.KeyCtrlH, 0, tcell.ModNone}, wantKey{Invalid, 0, nil}}, // fabricated, unhandled
{giveKey{tcell.KeyCtrlH, rune(tcell.KeyCtrlH), tcell.ModNone}, wantKey{Backspace, 0, nil}}, // actual "Backspace" keystroke
{giveKey{tcell.KeyCtrlH, rune(tcell.KeyCtrlH), tcell.ModAlt}, wantKey{AltBackspace, 0, nil}}, // actual "Alt+Backspace" keystroke
{giveKey{tcell.KeyDEL, rune(tcell.KeyDEL), tcell.ModCtrl}, wantKey{Backspace, 0, nil}}, // actual "Ctrl+Backspace" keystroke
{giveKey{tcell.KeyDEL, rune(tcell.KeyDEL), tcell.ModCtrl}, wantKey{CtrlBackspace, 0, nil}}, // actual "Ctrl+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, rune(tcell.KeyCtrlH), tcell.ModShift}, wantKey{Backspace, 0, nil}}, // actual "Shift+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{Backspace, 0, nil}}, // actual "Ctrl+Alt+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{Backspace, 0, nil}}, // actual "Ctrl+Shift+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltBackspace, 0, nil}}, // actual "Ctrl+Alt+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlBackspace, 0, nil}}, // actual "Ctrl+Shift+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, rune(tcell.KeyCtrlH), tcell.ModShift | tcell.ModAlt}, wantKey{AltBackspace, 0, nil}}, // actual "Shift+Alt+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, 0, tcell.ModCtrl | tcell.ModAlt | tcell.ModShift}, wantKey{Backspace, 0, nil}}, // actual "Ctrl+Shift+Alt+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, 0, tcell.ModCtrl | tcell.ModAlt | tcell.ModShift}, wantKey{CtrlAltBackspace, 0, nil}}, // actual "Ctrl+Shift+Alt+Backspace" keystroke
{giveKey{tcell.KeyCtrlH, rune(tcell.KeyCtrlH), tcell.ModCtrl}, wantKey{CtrlH, 0, nil}}, // actual "Ctrl+H" keystroke
{giveKey{tcell.KeyCtrlH, rune(tcell.KeyCtrlH), tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAlt, 'h', nil}}, // fabricated "Ctrl+Alt+H" keystroke
{giveKey{tcell.KeyCtrlH, rune(tcell.KeyCtrlH), tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlH, 0, nil}}, // actual "Ctrl+Shift+H" keystroke
@@ -126,9 +128,41 @@ func TestGetCharEventKey(t *testing.T) {
// section 4: (Alt+Shift)+Key(Up|Down|Left|Right)
{giveKey{tcell.KeyUp, 0, tcell.ModNone}, wantKey{Up, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModAlt}, wantKey{AltDown, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModNone}, wantKey{Down, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModNone}, wantKey{Left, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModNone}, wantKey{Right, 0, nil}},
{giveKey{tcell.KeyUp, 0, tcell.ModNone}, wantKey{Up, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModNone}, wantKey{Down, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModNone}, wantKey{Right, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModNone}, wantKey{Left, 0, nil}},
{giveKey{tcell.KeyUp, 0, tcell.ModCtrl}, wantKey{CtrlUp, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModCtrl}, wantKey{CtrlDown, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModCtrl}, wantKey{CtrlRight, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModCtrl}, wantKey{CtrlLeft, 0, nil}},
{giveKey{tcell.KeyUp, 0, tcell.ModShift}, wantKey{ShiftUp, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModShift}, wantKey{ShiftDown, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModShift}, wantKey{ShiftRight, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModShift}, wantKey{ShiftLeft, 0, nil}},
{giveKey{tcell.KeyUp, 0, tcell.ModAlt}, wantKey{AltUp, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModAlt}, wantKey{AltDown, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModAlt}, wantKey{AltRight, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModAlt}, wantKey{AltLeft, 0, nil}},
{giveKey{tcell.KeyUp, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftUp, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftDown, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftRight, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftLeft, 0, nil}},
{giveKey{tcell.KeyUp, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltUp, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltDown, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltRight, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltLeft, 0, nil}},
{giveKey{tcell.KeyUp, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftUp, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftDown, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftRight, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftLeft, 0, nil}},
{giveKey{tcell.KeyUp, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftUp, 0, nil}},
{giveKey{tcell.KeyDown, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftDown, 0, nil}},
{giveKey{tcell.KeyRight, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftRight, 0, nil}},
{giveKey{tcell.KeyLeft, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftLeft, 0, nil}},
{giveKey{tcell.KeyUpLeft, 0, tcell.ModNone}, wantKey{Invalid, 0, nil}}, // fabricated, unhandled
{giveKey{tcell.KeyUpRight, 0, tcell.ModNone}, wantKey{Invalid, 0, nil}}, // fabricated, unhandled
{giveKey{tcell.KeyDownLeft, 0, tcell.ModNone}, wantKey{Invalid, 0, nil}}, // fabricated, unhandled
@@ -137,6 +171,46 @@ func TestGetCharEventKey(t *testing.T) {
// section 5: (Insert|Home|Delete|End|PgUp|PgDn|BackTab|F1-F12)
{giveKey{tcell.KeyInsert, 0, tcell.ModNone}, wantKey{Insert, 0, nil}},
{giveKey{tcell.KeyF1, 0, tcell.ModNone}, wantKey{F1, 0, nil}},
{giveKey{tcell.KeyHome, 0, tcell.ModNone}, wantKey{Home, 0, nil}},
{giveKey{tcell.KeyEnd, 0, tcell.ModNone}, wantKey{End, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModNone}, wantKey{Delete, 0, nil}},
{giveKey{tcell.KeyPgUp, 0, tcell.ModNone}, wantKey{PageUp, 0, nil}},
{giveKey{tcell.KeyPgDn, 0, tcell.ModNone}, wantKey{PageDown, 0, nil}},
{giveKey{tcell.KeyHome, 0, tcell.ModCtrl}, wantKey{CtrlHome, 0, nil}},
{giveKey{tcell.KeyEnd, 0, tcell.ModCtrl}, wantKey{CtrlEnd, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModCtrl}, wantKey{CtrlDelete, 0, nil}},
{giveKey{tcell.KeyPgUp, 0, tcell.ModCtrl}, wantKey{CtrlPageUp, 0, nil}},
{giveKey{tcell.KeyPgDn, 0, tcell.ModCtrl}, wantKey{CtrlPageDown, 0, nil}},
{giveKey{tcell.KeyHome, 0, tcell.ModShift}, wantKey{ShiftHome, 0, nil}},
{giveKey{tcell.KeyEnd, 0, tcell.ModShift}, wantKey{ShiftEnd, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModShift}, wantKey{ShiftDelete, 0, nil}},
{giveKey{tcell.KeyPgUp, 0, tcell.ModShift}, wantKey{ShiftPageUp, 0, nil}},
{giveKey{tcell.KeyPgDn, 0, tcell.ModShift}, wantKey{ShiftPageDown, 0, nil}},
{giveKey{tcell.KeyHome, 0, tcell.ModAlt}, wantKey{AltHome, 0, nil}},
{giveKey{tcell.KeyEnd, 0, tcell.ModAlt}, wantKey{AltEnd, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModAlt}, wantKey{AltDelete, 0, nil}},
{giveKey{tcell.KeyPgUp, 0, tcell.ModAlt}, wantKey{AltPageUp, 0, nil}},
{giveKey{tcell.KeyPgDn, 0, tcell.ModAlt}, wantKey{AltPageDown, 0, nil}},
{giveKey{tcell.KeyHome, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftHome, 0, nil}},
{giveKey{tcell.KeyEnd, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftEnd, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftDelete, 0, nil}},
{giveKey{tcell.KeyPgUp, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftPageUp, 0, nil}},
{giveKey{tcell.KeyPgDn, 0, tcell.ModCtrl | tcell.ModShift}, wantKey{CtrlShiftPageDown, 0, nil}},
{giveKey{tcell.KeyHome, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltHome, 0, nil}},
{giveKey{tcell.KeyEnd, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltEnd, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltDelete, 0, nil}},
{giveKey{tcell.KeyPgUp, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltPageUp, 0, nil}},
{giveKey{tcell.KeyPgDn, 0, tcell.ModCtrl | tcell.ModAlt}, wantKey{CtrlAltPageDown, 0, nil}},
{giveKey{tcell.KeyHome, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftHome, 0, nil}},
{giveKey{tcell.KeyEnd, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftEnd, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftDelete, 0, nil}},
{giveKey{tcell.KeyPgUp, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftPageUp, 0, nil}},
{giveKey{tcell.KeyPgDn, 0, tcell.ModShift | tcell.ModAlt}, wantKey{AltShiftPageDown, 0, nil}},
{giveKey{tcell.KeyHome, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftHome, 0, nil}},
{giveKey{tcell.KeyEnd, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftEnd, 0, nil}},
{giveKey{tcell.KeyDelete, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftDelete, 0, nil}},
{giveKey{tcell.KeyPgUp, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftPageUp, 0, nil}},
{giveKey{tcell.KeyPgDn, 0, tcell.ModCtrl | tcell.ModShift | tcell.ModAlt}, wantKey{CtrlAltShiftPageDown, 0, nil}},
// section 6: (Ctrl+Alt)+'rune'
{giveKey{tcell.KeyRune, 'a', tcell.ModNone}, wantKey{Rune, 'a', nil}},
{giveKey{tcell.KeyRune, 'a', tcell.ModCtrl}, wantKey{Rune, 'a', nil}}, // fabricated
@@ -198,6 +272,10 @@ func TestGetCharEventKey(t *testing.T) {
initialResizeAsInvalid = false
gotEvent = r.GetChar()
}
if gotEvent.Type == Resize {
t.Logf("Resize swallowed")
gotEvent = r.GetChar()
}
t.Logf("wantEvent = %T{Type: %v, Char: %q (%[3]v)}\n", test.wantKey, test.wantKey.Type, test.wantKey.Char)
t.Logf("gotEvent = %T{Type: %v, Char: %q (%[3]v)}\n", gotEvent, gotEvent.Type, gotEvent.Char)

View File

@@ -44,7 +44,6 @@ const (
CtrlZ
Esc
CtrlSpace
CtrlDelete
// https://apple.stackexchange.com/questions/24261/how-do-i-send-c-that-is-control-slash-to-the-terminal
CtrlBackSlash
@@ -72,6 +71,10 @@ const (
ShiftLeft
ShiftRight
ShiftDelete
ShiftHome
ShiftEnd
ShiftPageUp
ShiftPageDown
F1
F2
@@ -92,15 +95,67 @@ const (
AltDown
AltLeft
AltRight
AltDelete
AltHome
AltEnd
AltPageUp
AltPageDown
AltShiftUp
AltShiftDown
AltShiftLeft
AltShiftRight
AltShiftDelete
AltShiftHome
AltShiftEnd
AltShiftPageUp
AltShiftPageDown
CtrlUp
CtrlDown
CtrlLeft
CtrlRight
CtrlHome
CtrlEnd
CtrlBackspace
CtrlDelete
CtrlPageUp
CtrlPageDown
Alt
CtrlAlt
CtrlAltUp
CtrlAltDown
CtrlAltLeft
CtrlAltRight
CtrlAltHome
CtrlAltEnd
CtrlAltBackspace
CtrlAltDelete
CtrlAltPageUp
CtrlAltPageDown
CtrlShiftUp
CtrlShiftDown
CtrlShiftLeft
CtrlShiftRight
CtrlShiftHome
CtrlShiftEnd
CtrlShiftDelete
CtrlShiftPageUp
CtrlShiftPageDown
CtrlAltShiftUp
CtrlAltShiftDown
CtrlAltShiftLeft
CtrlAltShiftRight
CtrlAltShiftHome
CtrlAltShiftEnd
CtrlAltShiftDelete
CtrlAltShiftPageUp
CtrlAltShiftPageDown
Invalid
Fatal
BracketedPasteBegin