summaryrefslogtreecommitdiff
path: root/src/tui/tcell.go
diff options
context:
space:
mode:
authorMassimo Mund <masmu@users.noreply.github.com>2025-09-05 07:56:51 +0200
committerGitHub <noreply@github.com>2025-09-05 14:56:51 +0900
commit9ed971cc90c9d65def3c52178578e43f29b68f9f (patch)
tree3a25368d44d6091c83e21623b313886bdfa1700b /src/tui/tcell.go
parent129cb230781d0258cd837486e436ba9ad471bc89 (diff)
downloadfzf-9ed971cc90c9d65def3c52178578e43f29b68f9f.tar.gz
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 https://github.com/joejulian/xterm/blob/defc6dd5684a12dc8e56cb6973ef973e7a32caa3/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.
Diffstat (limited to 'src/tui/tcell.go')
-rw-r--r--src/tui/tcell.go157
1 files changed, 156 insertions, 1 deletions
diff --git a/src/tui/tcell.go b/src/tui/tcell.go
index 0f80882e..3bf28797 100644
--- a/src/tui/tcell.go
+++ b/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}