mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-06-03 07:50:49 +00:00
Add transform-prompt(...) action
This commit is contained in:
parent
e97176b1d7
commit
62c7f59b94
|
@ -56,6 +56,13 @@ CHANGELOG
|
||||||
```sh
|
```sh
|
||||||
curl localhost:6266 -d "change-query:$(date)"
|
curl localhost:6266 -d "change-query:$(date)"
|
||||||
```
|
```
|
||||||
|
- Added `transform-prompt(...)` action for transforming the prompt string
|
||||||
|
using an external command
|
||||||
|
```sh
|
||||||
|
# Press space to change the prompt string using an external command
|
||||||
|
# (only the first line of the output is taken)
|
||||||
|
fzf --bind 'space:reload(ls),load:transform-prompt(printf "%s> " "$(date)")'
|
||||||
|
```
|
||||||
- Added `transform-query(...)` action for transforming the query string using
|
- Added `transform-query(...)` action for transforming the query string using
|
||||||
an external command
|
an external command
|
||||||
```sh
|
```sh
|
||||||
|
|
|
@ -1034,6 +1034,7 @@ A key or an event can be bound to one or more of the following actions.
|
||||||
\fBtoggle-search\fR (toggle search functionality)
|
\fBtoggle-search\fR (toggle search functionality)
|
||||||
\fBtoggle-sort\fR
|
\fBtoggle-sort\fR
|
||||||
\fBtoggle+up\fR \fIbtab (shift-tab)\fR
|
\fBtoggle+up\fR \fIbtab (shift-tab)\fR
|
||||||
|
\fBtransform-prompt(...)\fR (transform prompt string using an external command)
|
||||||
\fBtransform-query(...)\fR (transform query string using an external command)
|
\fBtransform-query(...)\fR (transform query string using an external command)
|
||||||
\fBunbind(...)\fR (unbind bindings)
|
\fBunbind(...)\fR (unbind bindings)
|
||||||
\fBunix-line-discard\fR \fIctrl-u\fR
|
\fBunix-line-discard\fR \fIctrl-u\fR
|
||||||
|
|
|
@ -892,7 +892,7 @@ const (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
executeRegexp = regexp.MustCompile(
|
executeRegexp = regexp.MustCompile(
|
||||||
`(?si)[:+](execute(?:-multi|-silent)?|reload(?:-sync)?|preview|change-query|change-prompt|change-preview-window|change-preview|(?:re|un)bind|pos|put|transform-query)`)
|
`(?si)[:+](execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|transform)-(?:query|prompt)|change-preview-window|change-preview|(?:re|un)bind|pos|put)`)
|
||||||
splitRegexp = regexp.MustCompile("[,:]+")
|
splitRegexp = regexp.MustCompile("[,:]+")
|
||||||
actionNameRegexp = regexp.MustCompile("(?i)^[a-z-]+")
|
actionNameRegexp = regexp.MustCompile("(?i)^[a-z-]+")
|
||||||
}
|
}
|
||||||
|
@ -1211,6 +1211,8 @@ func isExecuteAction(str string) actionType {
|
||||||
return actExecuteMulti
|
return actExecuteMulti
|
||||||
case "put":
|
case "put":
|
||||||
return actPut
|
return actPut
|
||||||
|
case "transform-prompt":
|
||||||
|
return actTransformPrompt
|
||||||
case "transform-query":
|
case "transform-query":
|
||||||
return actTransformQuery
|
return actTransformQuery
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,6 +311,7 @@ const (
|
||||||
actToggleSort
|
actToggleSort
|
||||||
actTogglePreview
|
actTogglePreview
|
||||||
actTogglePreviewWrap
|
actTogglePreviewWrap
|
||||||
|
actTransformPrompt
|
||||||
actTransformQuery
|
actTransformQuery
|
||||||
actPreview
|
actPreview
|
||||||
actChangePreview
|
actChangePreview
|
||||||
|
@ -2034,8 +2035,10 @@ func (t *Terminal) redraw(clear bool) {
|
||||||
|
|
||||||
func (t *Terminal) executeCommand(template string, forcePlus bool, background bool, captureFirstLine bool) string {
|
func (t *Terminal) executeCommand(template string, forcePlus bool, background bool, captureFirstLine bool) string {
|
||||||
line := ""
|
line := ""
|
||||||
valid, list := t.buildPlusList(template, forcePlus)
|
valid, list := t.buildPlusList(template, forcePlus, false)
|
||||||
if !valid {
|
// captureFirstLine is used for transform-{prompt,query} and we don't want to
|
||||||
|
// return an empty string in those cases
|
||||||
|
if !valid && !captureFirstLine {
|
||||||
return line
|
return line
|
||||||
}
|
}
|
||||||
command := t.replacePlaceholder(template, forcePlus, string(t.input), list)
|
command := t.replacePlaceholder(template, forcePlus, string(t.input), list)
|
||||||
|
@ -2093,10 +2096,10 @@ func (t *Terminal) currentItem() *Item {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) buildPlusList(template string, forcePlus bool) (bool, []*Item) {
|
func (t *Terminal) buildPlusList(template string, forcePlus bool, forceEvaluation bool) (bool, []*Item) {
|
||||||
current := t.currentItem()
|
current := t.currentItem()
|
||||||
slot, plus, query := hasPreviewFlags(template)
|
slot, plus, query := hasPreviewFlags(template)
|
||||||
if !(!slot || query || (forcePlus || plus) && len(t.selected) > 0) {
|
if !forceEvaluation && !(!slot || query || (forcePlus || plus) && len(t.selected) > 0) {
|
||||||
return current != nil, []*Item{current, current}
|
return current != nil, []*Item{current, current}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2421,7 +2424,7 @@ func (t *Terminal) Loop() {
|
||||||
|
|
||||||
refreshPreview := func(command string) {
|
refreshPreview := func(command string) {
|
||||||
if len(command) > 0 && t.isPreviewEnabled() {
|
if len(command) > 0 && t.isPreviewEnabled() {
|
||||||
_, list := t.buildPlusList(command, false)
|
_, list := t.buildPlusList(command, false, false)
|
||||||
t.cancelPreview()
|
t.cancelPreview()
|
||||||
t.previewBox.Set(reqPreviewEnqueue, previewRequest{command, t.pwindow, t.evaluateScrollOffset(), list})
|
t.previewBox.Set(reqPreviewEnqueue, previewRequest{command, t.pwindow, t.evaluateScrollOffset(), list})
|
||||||
}
|
}
|
||||||
|
@ -2649,7 +2652,7 @@ func (t *Terminal) Loop() {
|
||||||
if t.hasPreviewer() {
|
if t.hasPreviewer() {
|
||||||
togglePreview(!t.previewer.enabled)
|
togglePreview(!t.previewer.enabled)
|
||||||
if t.previewer.enabled {
|
if t.previewer.enabled {
|
||||||
valid, list := t.buildPlusList(t.previewOpts.command, false)
|
valid, list := t.buildPlusList(t.previewOpts.command, false, false)
|
||||||
if valid {
|
if valid {
|
||||||
t.cancelPreview()
|
t.cancelPreview()
|
||||||
t.previewBox.Set(reqPreviewEnqueue,
|
t.previewBox.Set(reqPreviewEnqueue,
|
||||||
|
@ -2664,6 +2667,10 @@ func (t *Terminal) Loop() {
|
||||||
t.previewed.version = 0
|
t.previewed.version = 0
|
||||||
req(reqPreviewRefresh)
|
req(reqPreviewRefresh)
|
||||||
}
|
}
|
||||||
|
case actTransformPrompt:
|
||||||
|
prompt := t.executeCommand(a.a, false, true, true)
|
||||||
|
t.prompt, t.promptLen = t.parsePrompt(prompt)
|
||||||
|
req(reqPrompt)
|
||||||
case actTransformQuery:
|
case actTransformQuery:
|
||||||
query := t.executeCommand(a.a, false, true, true)
|
query := t.executeCommand(a.a, false, true, true)
|
||||||
t.input = []rune(query)
|
t.input = []rune(query)
|
||||||
|
@ -3036,7 +3043,7 @@ func (t *Terminal) Loop() {
|
||||||
case actReload, actReloadSync:
|
case actReload, actReloadSync:
|
||||||
t.failed = nil
|
t.failed = nil
|
||||||
|
|
||||||
valid, list := t.buildPlusList(a.a, false)
|
valid, list := t.buildPlusList(a.a, false, false)
|
||||||
if !valid {
|
if !valid {
|
||||||
// We run the command even when there's no match
|
// We run the command even when there's no match
|
||||||
// 1. If the template doesn't have any slots
|
// 1. If the template doesn't have any slots
|
||||||
|
|
|
@ -1806,6 +1806,15 @@ class TestGoFZF < TestBase
|
||||||
tmux.until { |lines| assert_equal '> RAB', lines[-1] }
|
tmux.until { |lines| assert_equal '> RAB', lines[-1] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_transform_prompt
|
||||||
|
tmux.send_keys %{#{FZF} --bind 'ctrl-r:transform-query(rev <<< {q}),ctrl-u:transform-query: tr "[:lower:]" "[:upper:]" <<< {q}' --query bar}, :Enter
|
||||||
|
tmux.until { |lines| assert_equal '> bar', lines[-1] }
|
||||||
|
tmux.send_keys 'C-r'
|
||||||
|
tmux.until { |lines| assert_equal '> rab', lines[-1] }
|
||||||
|
tmux.send_keys 'C-u'
|
||||||
|
tmux.until { |lines| assert_equal '> RAB', lines[-1] }
|
||||||
|
end
|
||||||
|
|
||||||
def test_clear_selection
|
def test_clear_selection
|
||||||
tmux.send_keys %(seq 100 | #{FZF} --multi --bind space:clear-selection), :Enter
|
tmux.send_keys %(seq 100 | #{FZF} --multi --bind space:clear-selection), :Enter
|
||||||
tmux.until { |lines| assert_equal 100, lines.match_count }
|
tmux.until { |lines| assert_equal 100, lines.match_count }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user