summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2024-04-13 14:00:16 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2024-04-13 14:00:16 +0900
commitfd1ba46f77532b4bc9b6af00db9dc8ecdf6e2b3f (patch)
treec284b39e0b6948e0ce12d2cacf830d586582d201
parenta4745626dd5c5f697dbbc5e3aa1796d5016c1faf (diff)
Export $FZF_KEY environment variable to child processes
It's the name of the last key pressed. Related #3412
-rw-r--r--CHANGELOG.md22
-rw-r--r--man/man1/fzf.129
-rw-r--r--src/options.go40
-rw-r--r--src/terminal.go36
-rw-r--r--src/tui/eventtype_string.go120
-rw-r--r--src/tui/light.go65
-rw-r--r--src/tui/tui.go112
-rw-r--r--src/util/util.go12
8 files changed, 315 insertions, 121 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d6c9fb1..dffc16c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,28 @@
CHANGELOG
=========
+0.50.0
+------
+- Added `jump` and `jump-cancel` events that are triggered when leaving `jump` mode
+ ```sh
+ # Default behavior
+ fzf --bind space:jump
+
+ # Same as jump-accept action
+ fzf --bind space:jump,jump:accept
+
+ # Accept on jump, abort on cancel
+ fzf --bind space:jump,jump:accept,jump-cancel:abort
+
+ # Change header on jump-cancel
+ fzf --bind 'space:change-header(Type jump label)+jump,jump-cancel:change-header:Jump cancelled'
+ ```
+- Added a new environment variable `$FZF_KEY` exported to the child processes. It's the name of the last key pressed.
+ ```sh
+ fzf --bind 'space:jump,jump:accept,jump-cancel:transform:[[ $FZF_KEY =~ ctrl-c ]] && echo abort'
+ ```
+- Bug fixes
+
0.49.0
------
- Ingestion performance improved by around 40% (more or less depending on options)
diff --git a/man/man1/fzf.1 b/man/man1/fzf.1
index 24048e77..fc621c3e 100644
--- a/man/man1/fzf.1
+++ b/man/man1/fzf.1
@@ -191,7 +191,7 @@ actions are affected:
\fBkill-word\fR
.TP
.BI "--jump-labels=" "CHARS"
-Label characters for \fBjump\fR and \fBjump-accept\fR
+Label characters for \fBjump\fR mode.
.SS Layout
.TP
.BI "--height=" "[~]HEIGHT[%]"
@@ -982,6 +982,8 @@ fzf exports the following environment variables to its child processes.
.br
.BR FZF_ACTION " The name of the last action performed"
.br
+.BR FZF_KEY " The name of the last key pressed"
+.br
.BR FZF_PORT " Port number when --listen option is used"
.br
@@ -1052,21 +1054,21 @@ e.g.
.br
\fIctrl-]\fR
.br
-\fIctrl-^\fR (\fIctrl-6\fR)
+\fIctrl-^\fR (\fIctrl-6\fR)
.br
-\fIctrl-/\fR (\fIctrl-_\fR)
+\fIctrl-/\fR (\fIctrl-_\fR)
.br
\fIctrl-alt-[a-z]\fR
.br
-\fIalt-[*]\fR (Any case-sensitive single character is allowed)
+\fIalt-[*]\fR (Any case-sensitive single character is allowed)
.br
\fIf[1-12]\fR
.br
-\fIenter\fR (\fIreturn\fR \fIctrl-m\fR)
+\fIenter\fR (\fIreturn\fR \fIctrl-m\fR)
.br
\fIspace\fR
.br
-\fIbspace\fR (\fIbs\fR)
+\fIbackspace\fR (\fIbspace\fR \fIbs\fR)
.br
\fIalt-up\fR
.br
@@ -1080,15 +1082,15 @@ e.g.
.br
\fIalt-space\fR
.br
-\fIalt-bspace\fR (\fIalt-bs\fR)
+\fIalt-backspace\fR (\fIalt-bspace\fR \fIalt-bs\fR)
.br
\fItab\fR
.br
-\fIbtab\fR (\fIshift-tab\fR)
+\fIshift-tab\fR (\fIbtab\fR)
.br
\fIesc\fR
.br
-\fIdel\fR
+\fIdelete\fR (\fIdel\fR)
.br
\fIup\fR
.br
@@ -1104,9 +1106,9 @@ e.g.
.br
\fIinsert\fR
.br
-\fIpgup\fR (\fIpage-up\fR)
+\fIpage-up\fR (\fIpgup\fR)
.br
-\fIpgdn\fR (\fIpage-down\fR)
+\fIpage-down\fR (\fIpgdn\fR)
.br
\fIshift-up\fR
.br
@@ -1248,7 +1250,7 @@ e.g.
\fIjump\fR
.RS
-Triggered when successfully jumped to the target item in \fB--jump\fR mode.
+Triggered when successfully jumped to the target item in \fBjump\fR mode.
e.g.
\fBfzf --bind space:jump,jump:accept\fR
@@ -1256,7 +1258,7 @@ e.g.
\fIjump-cancel\fR
.RS
-Triggered when \fB--jump\fR mode is cancelled.
+Triggered when \fBjump\fR mode is cancelled.
e.g.
\fBfzf --bind space:jump,jump:accept,jump-cancel:abort\fR
@@ -1304,7 +1306,6 @@ A key or an event can be bound to one or more of the following actions.
\fBforward-word\fR \fIalt-f shift-right\fR
\fBignore\fR
\fBjump\fR (EasyMotion-like 2-keystroke movement)
- \fBjump-accept\fR (jump and accept)
\fBkill-line\fR
\fBkill-word\fR \fIalt-d\fR
\fBlast\fR (move to the last match; same as \fBpos(-1)\fR)
diff --git a/src/options.go b/src/options.go
index ffa3878f..c4006df2 100644
--- a/src/options.go
+++ b/src/options.go
@@ -52,7 +52,7 @@ const usage = `usage: fzf [options]
--hscroll-off=COLS Number of screen columns to keep to the right of the
highlighted substring (default: 10)
--filepath-word Make word-wise movements respect path separators
- --jump-labels=CHARS Label characters for jump and jump-accept
+ --jump-labels=CHARS Label characters for jump mode
Layout
--height=[~]HEIGHT[%] Display fzf window below the cursor with the given
@@ -666,8 +666,8 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E
add(tui.CtrlM)
case "space":
chords[tui.Key(' ')] = key
- case "bspace", "bs":
- add(tui.BSpace)
+ case "backspace", "bspace", "bs":
+ add(tui.Backspace)
case "ctrl-space":
add(tui.CtrlSpace)
case "ctrl-delete":
@@ -706,8 +706,8 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E
chords[tui.CtrlAltKey('m')] = key
case "alt-space":
chords[tui.AltKey(' ')] = key
- case "alt-bs", "alt-bspace":
- add(tui.AltBS)
+ case "alt-bs", "alt-bspace", "alt-backspace":
+ add(tui.AltBackspace)
case "alt-up":
add(tui.AltUp)
case "alt-down":
@@ -719,11 +719,11 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E
case "tab":
add(tui.Tab)
case "btab", "shift-tab":
- add(tui.BTab)
+ add(tui.ShiftTab)
case "esc":
- add(tui.ESC)
- case "del":
- add(tui.Del)
+ add(tui.Esc)
+ case "delete", "del":
+ add(tui.Delete)
case "home":
add(tui.Home)
case "end":
@@ -731,27 +731,27 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E
case "insert":
add(tui.Insert)
case "pgup", "page-up":
- add(tui.PgUp)
+ add(tui.PageUp)
case "pgdn", "page-down":
- add(tui.PgDn)
+ add(tui.PageDown)
case "alt-shift-up", "shift-alt-up":
- add(tui.AltSUp)
+ add(tui.AltShiftUp)
case "alt-shift-down", "shift-alt-down":
- add(tui.AltSDown)
+ add(tui.AltShiftDown)
case "alt-shift-left", "shift-alt-left":
- add(tui.AltSLeft)
+ add(tui.AltShiftLeft)
case "alt-shift-right", "shift-alt-right":
- add(tui.AltSRight)
+ add(tui.AltShiftRight)
case "shift-up":
- add(tui.SUp)
+ add(tui.ShiftUp)
case "shift-down":
- add(tui.SDown)
+ add(tui.ShiftDown)
case "shift-left":
- add(tui.SLeft)
+ add(tui.ShiftLeft)
case "shift-right":
- add(tui.SRight)
+ add(tui.ShiftRight)
case "shift-delete":
- add(tui.SDelete)
+ add(tui.ShiftDelete)
case "left-click":
add(tui.LeftClick)
case "right-click":
diff --git a/src/terminal.go b/src/terminal.go
index 5057e931..0519836f 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -293,6 +293,7 @@ type Terminal struct {
executing *util.AtomicBool
termSize tui.TermSize
lastAction actionType
+ lastKey string
lastFocus int32
areaLines int
areaColumns int
@@ -408,7 +409,7 @@ const (
actOffsetUp
actOffsetDown
actJump
- actJumpAccept
+ actJumpAccept // XXX Deprecated in favor of jump:accept binding
actPrintQuery
actRefreshPreview
actReplaceQuery
@@ -460,14 +461,7 @@ const (
)
func (a actionType) Name() string {
- name := ""
- for i, r := range a.String()[3:] {
- if i > 0 && r >= 'A' && r <= 'Z' {
- name += "-"
- }
- name += string(r)
- }
- return strings.ToLower(name)
+ return util.ToKebabCase(a.String()[3:])
}
func processExecution(action actionType) bool {
@@ -546,14 +540,14 @@ func defaultKeymap() map[tui.Event][]*action {
add(tui.CtrlC, actAbort)
add(tui.CtrlG, actAbort)
add(tui.CtrlQ, actAbort)
- add(tui.ESC, actAbort)
+ add(tui.Esc, actAbort)
add(tui.CtrlD, actDeleteCharEof)
add(tui.CtrlE, actEndOfLine)
add(tui.CtrlF, actForwardChar)
add(tui.CtrlH, actBackwardDeleteChar)
- add(tui.BSpace, actBackwardDeleteChar)
+ add(tui.Backspace, actBackwardDeleteChar)
add(tui.Tab, actToggleDown)
- add(tui.BTab, actToggleUp)
+ add(tui.ShiftTab, actToggleUp)
add(tui.CtrlJ, actDown)
add(tui.CtrlK, actUp)
add(tui.CtrlL, actClearScreen)
@@ -568,11 +562,11 @@ func defaultKeymap() map[tui.Event][]*action {
}
addEvent(tui.AltKey('b'), actBackwardWord)
- add(tui.SLeft, actBackwardWord)
+ add(tui.ShiftLeft, actBackwardWord)
addEvent(tui.AltKey('f'), actForwardWord)
- add(tui.SRight, actForwardWord)
+ add(tui.ShiftRight, actForwardWord)
addEvent(tui.AltKey('d'), actKillWord)
- add(tui.AltBS, actBackwardKillWord)
+ add(tui.AltBackspace, actBackwardKillWord)
add(tui.Up, actUp)
add(tui.Down, actDown)
@@ -581,12 +575,12 @@ func defaultKeymap() map[tui.Event][]*action {
add(tui.Home, actBeginningOfLine)
add(tui.End, actEndOfLine)
- add(tui.Del, actDeleteChar)
- add(tui.PgUp, actPageUp)
- add(tui.PgDn, actPageDown)
+ add(tui.Delete, actDeleteChar)
+ add(tui.PageUp, actPageUp)
+ add(tui.PageDown, actPageDown)
- add(tui.SUp, actPreviewUp)
- add(tui.SDown, actPreviewDown)
+ add(tui.ShiftUp, actPreviewUp)
+ add(tui.ShiftDown, actPreviewDown)
add(tui.Mouse, actMouse)
add(tui.LeftClick, actClick)
@@ -851,6 +845,7 @@ func (t *Terminal) environ() []string {
}
env = append(env, "FZF_QUERY="+string(t.input))
env = append(env, "FZF_ACTION="+t.lastAction.Name())
+ env = append(env, "FZF_KEY="+t.lastKey)
env = append(env, "FZF_PROMPT="+string(t.promptString))
env = append(env, "FZF_PREVIEW_LABEL="+t.previewLabelOpts.label)
env = append(env, "FZF_BORDER_LABEL="+t.borderLabelOpts.label)
@@ -3290,6 +3285,7 @@ func (t *Terminal) Loop() {
t.mutex.Lock()
previousInput := t.input
previousCx := t.cx
+ t.lastKey = event.KeyName()
events := []util.EventType{}
req := func(evts ...util.EventType) {
for _, event := range evts {
diff --git a/src/tui/eventtype_string.go b/src/tui/eventtype_string.go
new file mode 100644
index 00000000..ce34d36e
--- /dev/null
+++ b/src/tui/eventtype_string.go
@@ -0,0 +1,120 @@
+// Code generated by "stringer -type=EventType"; DO NOT EDIT.
+
+package tui
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[Rune-0]
+ _ = x[CtrlA-1]
+ _ = x[CtrlB-2]
+ _ = x[CtrlC-3]
+ _ = x[CtrlD-4]
+ _ = x[CtrlE-5]
+ _ = x[CtrlF-6]
+ _ = x[CtrlG-7]
+ _ = x[CtrlH-8]
+ _ = x[Tab-9]
+ _ = x[CtrlJ-10]
+ _ = x[CtrlK-11]
+ _ = x[CtrlL-12]
+ _ = x[CtrlM-13]
+ _ = x[CtrlN-14]
+ _ = x[CtrlO-15]
+ _ = x[CtrlP-16]
+ _ = x[CtrlQ-17]
+ _ = x[CtrlR-18]
+ _ = x[CtrlS-19]
+ _ = x[CtrlT-20]
+ _ = x[CtrlU-21]
+ _ = x[CtrlV-22]
+ _ = x[CtrlW-23]
+ _ = x[CtrlX-24]
+ _ = x[CtrlY-25]
+ _ = 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[Mouse-75]
+ _ = x[DoubleClick-76]
+ _ = x[LeftClick-77]
+ _ = x[RightClick-78]
+ _ = x[SLeftClick-79]
+ _ = x[SRightClick-80]
+ _ = x[ScrollUp-81]
+ _ = x[ScrollDown-82]
+ _ = x[SScrollUp-83]
+ _ = x[SScrollDown-84]
+ _ = x[PreviewScrollUp-85]
+ _ = x[PreviewScrollDown-86]
+ _ = x[Resize-87]
+ _ = x[Change-88]
+ _ = x[BackwardEOF-89]
+ _ = x[Start-90]
+ _ = x[Load-91]
+ _ = x[Focus-92]
+ _ = x[One-93]
+ _ = x[Zero-94]
+ _ = x[Result-95]
+ _ = x[Jump-96]
+ _ = x[JumpCancel-97]
+}
+
+const _EventType_name = "RuneCtrlACtrlBCtrlCCtrlDCtrlECtrlFCtrlGCtrlHTabCtrlJCtrlKCtrlLCtrlMCtrlNCtrlOCtrlPCtrlQCtrlRCtrlSCtrlTCtrlUCtrlVCtrlWCtrlXCtrlYCtrlZEscCtrlSpaceCtrlDeleteCtrlBackSlashCtrlRightBracketCtrlCaretCtrlSlashShiftTabBackspaceDeletePageUpPageDownUpDownLeftRightHomeEndInsertShiftUpShiftDownShiftLeftShiftRightShiftDeleteF1F2F3F4F5F6F7F8F9F10F11F12AltBackspaceAltUpAltDownAltLeftAltRightAltShiftUpAltShiftDownAltShiftLeftAltShiftRightAltCtrlAltInvalidMouseDoubleClickLeftClickRightClickSLeftClickSRightClickScrollUpScrollDownSScrollUpSScrollDownPreviewScrollUpPreviewScrollDownResizeChangeBackwardEOFStartLoadFocusOneZeroResultJumpJumpCancel"
+
+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, 458, 467, 477, 487, 498, 506, 516, 525, 536, 551, 568, 574, 580, 591, 596, 600, 605, 608, 612, 618, 622, 632}
+
+func (i EventType) String() string {
+ if i < 0 || i >= EventType(len(_EventType_index)-1) {
+ return "EventType(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _EventType_name[_EventType_index[i]:_EventType_index[i+1]]
+}
diff --git a/src/tui/light.go b/src/tui/light.go
index e42d398b..244891a9 100644
--- a/src/tui/light.go
+++ b/src/tui/light.go
@@ -245,7 +245,7 @@ func (r *LightRenderer) getBytesInternal(buffer []byte, nonblock bool) []byte {
}
retries := 0
- if c == ESC.Int() || nonblock {
+ if c == Esc.Int() || nonblock {
retries = r.escDelay / escPollInterval
}
buffer = append(buffer, byte(c))
@@ -260,7 +260,7 @@ func (r *LightRenderer) getBytesInternal(buffer []byte, nonblock bool) []byte {
continue
}
break
- } else if c == ESC.Int() && pc != c {
+ } else if c == Esc.Int() && pc != c {
retries = r.escDelay / escPollInterval
} else {
retries = 0
@@ -300,7 +300,7 @@ func (r *LightRenderer) GetChar() Event {
case CtrlQ.Byte():
return Event{CtrlQ, 0, nil}
case 127:
- return Event{BSpace, 0, nil}
+ return Event{Backspace, 0, nil}
case 0:
return Event{CtrlSpace, 0, nil}
case 28:
@@ -311,7 +311,7 @@ func (r *LightRenderer) GetChar() Event {
return Event{CtrlCaret, 0, nil}
case 31:
return Event{CtrlSlash, 0, nil}
- case ESC.Byte():
+ case Esc.Byte():
ev := r.escSequence(&sz)
// Second chance
if ev.Type == Invalid {
@@ -327,7 +327,7 @@ func (r *LightRenderer) GetChar() Event {
}
char, rsz := utf8.DecodeRune(r.buffer)
if char == utf8.RuneError {
- return Event{ESC, 0, nil}
+ return Event{Esc, 0, nil}
}
sz = rsz
return Event{Rune, char, nil}
@@ -335,7 +335,7 @@ func (r *LightRenderer) GetChar() Event {
func (r *LightRenderer) escSequence(sz *int) Event {
if len(r.buffer) < 2 {
- return Event{ESC, 0, nil}
+ return Event{Esc, 0, nil}
}
loc := offsetRegexpBegin.FindIndex(r.buffer)
@@ -349,15 +349,15 @@ func (r *LightRenderer) escSequence(sz *int) Event {
return CtrlAltKey(rune(r.buffer[1] + 'a' - 1))
}
alt := false
- if len(r.buffer) > 2 && r.buffer[1] == ESC.Byte() {
+ if len(r.buffer) > 2 && r.buffer[1] == Esc.Byte() {
r.buffer = r.buffer[1:]
alt = true
}
switch r.buffer[1] {
- case ESC.Byte():
- return Event{ESC, 0, nil}
+ case Esc.Byte():
+ return Event{Esc, 0, nil}
case 127:
- return Event{AltBS, 0, nil}
+ return Event{AltBackspace, 0, nil}
case '[', 'O':
if len(r.buffer) < 3 {
return Event{Invalid, 0, nil}
@@ -386,7 +386,7 @@ func (r *LightRenderer) escSequence(sz *int) Event {
}
return Event{Up, 0, nil}
case 'Z':
- return Event{BTab, 0, nil}
+ return Event{ShiftTab, 0, nil}
case 'H':
return Event{Home, 0, nil}
case 'F':
@@ -434,7 +434,7 @@ func (r *LightRenderer) escSequence(sz *int) Event {
return Event{Invalid, 0, nil} // INS
case '3':
if r.buffer[3] == '~' {
- return Event{Del, 0, nil}
+ return Event{Delete, 0, nil}
}
if len(r.buffer) == 6 && r.buffer[5] == '~' {
*sz = 6
@@ -442,16 +442,16 @@ func (r *LightRenderer) escSequence(sz *int) Event {
case '5':
return Event{CtrlDelete, 0, nil}
case '2':
- return Event{SDelete, 0, nil}
+ return Event{ShiftDelete, 0, nil}
}
}
return Event{Invalid, 0, nil}
case '4':
return Event{End, 0, nil}
case '5':
- return Event{PgUp, 0, nil}
+ return Event{PageUp, 0, nil}
case '6':
- return Event{PgDn, 0, nil}
+ return Event{PageDown, 0, nil}
case '7':
return Event{Home, 0, nil}
case '8':
@@ -489,16 +489,29 @@ func (r *LightRenderer) escSequence(sz *int) Event {
}
*sz = 6
switch r.buffer[4] {
- case '1', '2', '3', '5':
+ case '1', '2', '3', '4', '5':
+ // 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'
- altShift := r.buffer[4] == '1' && r.buffer[5] == '0'
char := r.buffer[5]
- if altShift {
+ 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 len(r.buffer) < 6 {
+ return Event{Invalid, 0, nil}
+ }
+ *sz = 6
+ char = r.buffer[5]
}
switch char {
case 'A':
@@ -506,33 +519,33 @@ func (r *LightRenderer) escSequence(sz *int) Event {
return Event{AltUp, 0, nil}
}
if altShift {
- return Event{AltSUp, 0, nil}
+ return Event{AltShiftUp, 0, nil}
}
- return Event{SUp, 0, nil}
+ return Event{ShiftUp, 0, nil}
case 'B':
if alt {
return Event{AltDown, 0, nil}
}
if altShift {
- return Event{AltSDown, 0, nil}
+ return Event{AltShiftDown, 0, nil}
}
- return Event{SDown, 0, nil}
+ return Event{ShiftDown, 0, nil}
case 'C':
if alt {
return Event{AltRight, 0, nil}
}
if altShift {
- return Event{AltSRight, 0, nil}
+ return Event{AltShiftRight, 0, nil}
}
- return Event{SRight, 0, nil}
+ return Event{ShiftRight, 0, nil}
case 'D':
if alt {
return Event{AltLeft, 0, nil}
}
if altShift {
- return Event{AltSLeft, 0, nil}
+ return Event{AltShiftLeft, 0, nil}
}
- return Event{SLeft, 0, nil}
+ return Event{ShiftLeft, 0, nil}
}
} // r.buffer[4]
} // r.buffer[3]
diff --git a/src/tui/tui.go b/src/tui/tui.go
index 729146cc..ad65e92f 100644
--- a/src/tui/tui.go
+++ b/src/tui/tui.go
@@ -6,10 +6,13 @@ import (
"strconv"
"time"
+ "github.com/junegunn/fzf/src/util"
"github.com/rivo/uniseg"
)
// Types of user action
+//
+//go:generate stringer -type=EventType
type EventType int
const (
@@ -41,7 +44,7 @@ const (
CtrlX
CtrlY
CtrlZ
- ESC
+ Esc
CtrlSpace
CtrlDelete
@@ -51,27 +54,12 @@ const (
CtrlCaret
CtrlSlash
- Invalid
- Resize
- Mouse
- DoubleClick
- LeftClick
- RightClick
- SLeftClick
- SRightClick
- ScrollUp
- ScrollDown
- SScrollUp
- SScrollDown
- PreviewScrollUp
- PreviewScrollDown
-
- BTab
- BSpace
+ ShiftTab
+ Backspace
- Del
- PgUp
- PgDn
+ Delete
+ PageUp
+ PageDown
Up
Down
@@ -81,11 +69,11 @@ const (
End
Insert
- SUp
- SDown
- SLeft
- SRight
- SDelete
+ ShiftUp
+ ShiftDown
+ ShiftLeft
+ ShiftRight
+ ShiftDelete
F1
F2
@@ -100,6 +88,38 @@ const (
F11
F12
+ AltBackspace
+
+ AltUp
+ AltDown
+ AltLeft
+ AltRight
+
+ AltShiftUp
+ AltShiftDown
+ AltShiftLeft
+ AltShiftRight
+
+ Alt
+ CtrlAlt
+
+ Invalid
+
+ Mouse
+ DoubleClick
+ LeftClick
+ RightClick
+ SLeftClick
+ SRightClick
+ ScrollUp
+ ScrollDown
+ SScrollUp
+ SScrollDown
+ PreviewScrollUp
+ PreviewScrollDown
+
+ // Events
+ Resize
Change
BackwardEOF
Start
@@ -110,21 +130,6 @@ const (
Result
Jump
JumpCancel
-
- AltBS
-
- AltUp
- AltDown
- AltLeft
- AltRight
-
- AltSUp
- AltSDown
- AltSLeft
- AltSRight
-
- Alt
- CtrlAlt
)
func (t EventType) AsEvent() Event {
@@ -144,6 +149,31 @@ func (e Event) Comparable() Event {
return Event{e.Type, e.Char, nil}
}
+func (e Event) KeyName() string {
+ if e.Type >= Invalid {
+ return ""
+ }
+
+ switch e.Type {
+ case Rune:
+ return string(e.Char)
+ case Alt:
+ return "alt-" + string(e.Char)
+ case CtrlAlt:
+ return "ctrl-alt-" + string(e.Char)
+ case CtrlBackSlash:
+ return "ctrl-\\"
+ case CtrlRightBracket:
+ return "ctrl-]"
+ case CtrlCaret:
+ return "ctrl-^"
+ case CtrlSlash:
+ return "ctrl-/"
+ }
+
+ return util.ToKebabCase(e.Type.String())
+}
+
func Key(r rune) Event {
return Event{Rune, r, nil}
}
diff --git a/src/util/util.go b/src/util/util.go
index 190d34d5..f6e00e9c 100644
--- a/src/util/util.go
+++ b/src/util/util.go
@@ -176,3 +176,15 @@ func RepeatToFill(str string, length int, limit int) string {
}
return output
}
+
+// ToKebabCase converts the given CamelCase string to kebab-case
+func ToKebabCase(s string) string {
+ name := ""
+ for i, r := range s {
+ if i > 0 && r >= 'A' && r <= 'Z' {
+ name += "-"
+ }
+ name += string(r)
+ }
+ return strings.ToLower(name)
+}