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:
112
man/man1/fzf.1
112
man/man1/fzf.1
@@ -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
|
||||
|
||||
106
src/options.go
106
src/options.go
@@ -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":
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
284
src/tui/light.go
284
src/tui/light.go
@@ -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
335
src/tui/light_test.go
Normal 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")
|
||||
|
||||
}
|
||||
157
src/tui/tcell.go
157
src/tui/tcell.go
@@ -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}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user