mirror of
https://github.com/junegunn/fzf.git
synced 2025-11-14 22:33:47 -05:00
Add 'click-footer' event
This commit is contained in:
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,6 +1,27 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
0.65.0
|
||||||
|
------
|
||||||
|
- Added `click-footer` event that is triggered when the footer section is clicked. When the event is triggered, the following environment variables are set:
|
||||||
|
- `$FZF_CLICK_FOOTER_COLUMN` - clicked column (1-based)
|
||||||
|
- `$FZF_CLICK_FOOTER_LINE` - clicked line (1-based)
|
||||||
|
- `$FZF_CLICK_FOOTER_WORD` - the word under the cursor
|
||||||
|
```sh
|
||||||
|
fzf --footer $'[Edit] [View]\n[Copy to clipboard]' \
|
||||||
|
--with-shell 'bash -c' \
|
||||||
|
--bind 'click-footer:transform:
|
||||||
|
[[ $FZF_CLICK_FOOTER_WORD =~ Edit ]] && echo "execute:vim \{}"
|
||||||
|
[[ $FZF_CLICK_FOOTER_WORD =~ View ]] && echo "execute:view \{}"
|
||||||
|
(( FZF_CLICK_FOOTER_LINE == 2 )) && (( FZF_CLICK_FOOTER_COLUMN < 20 )) &&
|
||||||
|
echo "execute-silent(echo -n \{} | pbcopy)+bell"
|
||||||
|
'
|
||||||
|
```
|
||||||
|
- Added support for `{*n}` and `{*nf}` placeholder.
|
||||||
|
- `{*n}` evaluates to the zero-based ordinal index of all matched items.
|
||||||
|
- `{*nf}` evaluates to the temporary file containing that.
|
||||||
|
- Bug fixes
|
||||||
|
|
||||||
0.64.0
|
0.64.0
|
||||||
------
|
------
|
||||||
- Added `multi` event that is triggered when the multi-selection has changed.
|
- Added `multi` event that is triggered when the multi-selection has changed.
|
||||||
|
|||||||
@@ -1682,6 +1682,14 @@ e.g.
|
|||||||
)'\fR
|
)'\fR
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
\fIclick\-footer\fR
|
||||||
|
.RS
|
||||||
|
Triggered when a mouse click occurs within the footer. Sets
|
||||||
|
\fBFZF_CLICK_FOOTER_LINE\fR and \fBFZF_CLICK_FOOTER_COLUMN\fR environment
|
||||||
|
variables starting from 1. It optionally sets \fBFZF_CLICK_FOOTER_WORD\fR
|
||||||
|
if clicked on a word.
|
||||||
|
.RE
|
||||||
|
|
||||||
.SS AVAILABLE ACTIONS:
|
.SS AVAILABLE ACTIONS:
|
||||||
A key or an event can be bound to one or more of the following actions.
|
A key or an event can be bound to one or more of the following actions.
|
||||||
|
|
||||||
|
|||||||
@@ -1008,6 +1008,8 @@ func parseKeyChordsImpl(str string, message string) (map[tui.Event]string, error
|
|||||||
add(tui.JumpCancel)
|
add(tui.JumpCancel)
|
||||||
case "click-header":
|
case "click-header":
|
||||||
add(tui.ClickHeader)
|
add(tui.ClickHeader)
|
||||||
|
case "click-footer":
|
||||||
|
add(tui.ClickFooter)
|
||||||
case "multi":
|
case "multi":
|
||||||
add(tui.Multi)
|
add(tui.Multi)
|
||||||
case "alt-enter", "alt-return":
|
case "alt-enter", "alt-return":
|
||||||
|
|||||||
@@ -422,6 +422,8 @@ type Terminal struct {
|
|||||||
forcePreview bool
|
forcePreview bool
|
||||||
clickHeaderLine int
|
clickHeaderLine int
|
||||||
clickHeaderColumn int
|
clickHeaderColumn int
|
||||||
|
clickFooterLine int
|
||||||
|
clickFooterColumn int
|
||||||
proxyScript string
|
proxyScript string
|
||||||
numLinesCache map[int32]numLinesCacheValue
|
numLinesCache map[int32]numLinesCacheValue
|
||||||
}
|
}
|
||||||
@@ -1259,7 +1261,10 @@ func (t *Terminal) environImpl(forPreview bool) []string {
|
|||||||
env = append(env, fmt.Sprintf("FZF_POS=%d", util.Min(t.merger.Length(), t.cy+1)))
|
env = append(env, fmt.Sprintf("FZF_POS=%d", util.Min(t.merger.Length(), t.cy+1)))
|
||||||
env = append(env, fmt.Sprintf("FZF_CLICK_HEADER_LINE=%d", t.clickHeaderLine))
|
env = append(env, fmt.Sprintf("FZF_CLICK_HEADER_LINE=%d", t.clickHeaderLine))
|
||||||
env = append(env, fmt.Sprintf("FZF_CLICK_HEADER_COLUMN=%d", t.clickHeaderColumn))
|
env = append(env, fmt.Sprintf("FZF_CLICK_HEADER_COLUMN=%d", t.clickHeaderColumn))
|
||||||
|
env = append(env, fmt.Sprintf("FZF_CLICK_FOOTER_LINE=%d", t.clickFooterLine))
|
||||||
|
env = append(env, fmt.Sprintf("FZF_CLICK_FOOTER_COLUMN=%d", t.clickFooterColumn))
|
||||||
env = t.addClickHeaderWord(env)
|
env = t.addClickHeaderWord(env)
|
||||||
|
env = t.addClickFooterWord(env)
|
||||||
|
|
||||||
// Add preview environment variables if preview is enabled
|
// Add preview environment variables if preview is enabled
|
||||||
pwindowSize := t.pwindowSize()
|
pwindowSize := t.pwindowSize()
|
||||||
@@ -1634,6 +1639,8 @@ func (t *Terminal) changeFooter(footer string) {
|
|||||||
lines = strings.Split(strings.TrimSuffix(footer, "\n"), "\n")
|
lines = strings.Split(strings.TrimSuffix(footer, "\n"), "\n")
|
||||||
}
|
}
|
||||||
t.footer = lines
|
t.footer = lines
|
||||||
|
t.clickFooterLine = 0
|
||||||
|
t.clickFooterColumn = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateHeader updates the header
|
// UpdateHeader updates the header
|
||||||
@@ -4803,6 +4810,35 @@ func (t *Terminal) addClickHeaderWord(env []string) []string {
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Terminal) addClickFooterWord(env []string) []string {
|
||||||
|
clickFooterLine := t.clickFooterLine - 1
|
||||||
|
if clickFooterLine < 0 || clickFooterLine >= len(t.footer) {
|
||||||
|
// Never clicked on the footer
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Unlike in click-header, we don't use --delimiter here, since we're
|
||||||
|
// only interested in the word, not nth. Does this make sense?
|
||||||
|
words := Tokenize(t.footer[clickFooterLine], Delimiter{})
|
||||||
|
colNum := t.clickFooterColumn - 1
|
||||||
|
for _, token := range words {
|
||||||
|
prefixWidth := int(token.prefixLength)
|
||||||
|
word := token.text.ToString()
|
||||||
|
trimmed := strings.TrimRightFunc(word, unicode.IsSpace)
|
||||||
|
trimWidth, _ := util.RunesWidth([]rune(trimmed), prefixWidth, t.tabstop, math.MaxInt32)
|
||||||
|
|
||||||
|
// Find the position of the first non-space character in the word
|
||||||
|
minPos := strings.IndexFunc(trimmed, func(r rune) bool {
|
||||||
|
return !unicode.IsSpace(r)
|
||||||
|
})
|
||||||
|
if colNum >= minPos && colNum >= prefixWidth && colNum < prefixWidth+trimWidth {
|
||||||
|
env = append(env, fmt.Sprintf("FZF_CLICK_FOOTER_WORD=%s", trimmed))
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
||||||
// Loop is called to start Terminal I/O
|
// Loop is called to start Terminal I/O
|
||||||
func (t *Terminal) Loop() error {
|
func (t *Terminal) Loop() error {
|
||||||
// prof := profile.Start(profile.ProfilePath("/tmp/"))
|
// prof := profile.Start(profile.ProfilePath("/tmp/"))
|
||||||
@@ -6380,6 +6416,18 @@ func (t *Terminal) Loop() error {
|
|||||||
return doActions(actionsFor(tui.ClickHeader))
|
return doActions(actionsFor(tui.ClickHeader))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inside the footer window
|
||||||
|
if clicked && t.footerWindow != nil && t.footerWindow.Enclose(my, mx) {
|
||||||
|
mx -= t.footerWindow.Left() + t.headerIndent(t.footerBorderShape)
|
||||||
|
my -= t.footerWindow.Top()
|
||||||
|
if mx < 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
t.clickFooterLine = my + 1
|
||||||
|
t.clickFooterColumn = mx + 1
|
||||||
|
return doActions(actionsFor(tui.ClickFooter))
|
||||||
|
}
|
||||||
|
|
||||||
// Ignored
|
// Ignored
|
||||||
if !t.window.Enclose(my, mx) && !barDragging {
|
if !t.window.Enclose(my, mx) && !barDragging {
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -110,12 +110,13 @@ func _() {
|
|||||||
_ = x[Jump-99]
|
_ = x[Jump-99]
|
||||||
_ = x[JumpCancel-100]
|
_ = x[JumpCancel-100]
|
||||||
_ = x[ClickHeader-101]
|
_ = x[ClickHeader-101]
|
||||||
_ = x[Multi-102]
|
_ = x[ClickFooter-102]
|
||||||
|
_ = x[Multi-103]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _EventType_name = "RuneCtrlACtrlBCtrlCCtrlDCtrlECtrlFCtrlGCtrlHTabCtrlJCtrlKCtrlLEnterCtrlNCtrlOCtrlPCtrlQCtrlRCtrlSCtrlTCtrlUCtrlVCtrlWCtrlXCtrlYCtrlZEscCtrlSpaceCtrlDeleteCtrlBackSlashCtrlRightBracketCtrlCaretCtrlSlashShiftTabBackspaceDeletePageUpPageDownUpDownLeftRightHomeEndInsertShiftUpShiftDownShiftLeftShiftRightShiftDeleteF1F2F3F4F5F6F7F8F9F10F11F12AltBackspaceAltUpAltDownAltLeftAltRightAltShiftUpAltShiftDownAltShiftLeftAltShiftRightAltCtrlAltInvalidFatalBracketedPasteBeginBracketedPasteEndMouseDoubleClickLeftClickRightClickSLeftClickSRightClickScrollUpScrollDownSScrollUpSScrollDownPreviewScrollUpPreviewScrollDownResizeChangeBackwardEOFStartLoadFocusOneZeroResultJumpJumpCancelClickHeaderMulti"
|
const _EventType_name = "RuneCtrlACtrlBCtrlCCtrlDCtrlECtrlFCtrlGCtrlHTabCtrlJCtrlKCtrlLEnterCtrlNCtrlOCtrlPCtrlQCtrlRCtrlSCtrlTCtrlUCtrlVCtrlWCtrlXCtrlYCtrlZEscCtrlSpaceCtrlDeleteCtrlBackSlashCtrlRightBracketCtrlCaretCtrlSlashShiftTabBackspaceDeletePageUpPageDownUpDownLeftRightHomeEndInsertShiftUpShiftDownShiftLeftShiftRightShiftDeleteF1F2F3F4F5F6F7F8F9F10F11F12AltBackspaceAltUpAltDownAltLeftAltRightAltShiftUpAltShiftDownAltShiftLeftAltShiftRightAltCtrlAltInvalidFatalBracketedPasteBeginBracketedPasteEndMouseDoubleClickLeftClickRightClickSLeftClickSRightClickScrollUpScrollDownSScrollUpSScrollDownPreviewScrollUpPreviewScrollDownResizeChangeBackwardEOFStartLoadFocusOneZeroResultJumpJumpCancelClickHeaderClickFooterMulti"
|
||||||
|
|
||||||
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, 689}
|
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}
|
||||||
|
|
||||||
func (i EventType) String() string {
|
func (i EventType) String() string {
|
||||||
if i < 0 || i >= EventType(len(_EventType_index)-1) {
|
if i < 0 || i >= EventType(len(_EventType_index)-1) {
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ const (
|
|||||||
Jump
|
Jump
|
||||||
JumpCancel
|
JumpCancel
|
||||||
ClickHeader
|
ClickHeader
|
||||||
|
ClickFooter
|
||||||
Multi
|
Multi
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user