260602.1 · ae78a5c56d6586589f9587902f437385c176eddc
Allow bare put action in transform output
transform/bg-transform now permit bare `put`, inserting the key that triggered the action (`a:transform:echo put` puts `a`).
reading declarations
@@ -10,7 +10,6 @@ import ( "strconv" "strings" "time"- "unicode" "github.com/junegunn/fzf/src/algo" "github.com/junegunn/fzf/src/tui"@@ -1734,10 +1733,10 @@ Loop: return masked } -func parseSingleActionList(str string) ([]*action, error) {+func parseSingleActionList(str string, putAllowed bool) ([]*action, error) { // We prepend a colon to satisfy argActionRegexp and remove it later masked := maskActionContents(":" + str)[1:]- return parseActionList(masked, str, []*action{}, false)+ return parseActionList(masked, str, []*action{}, putAllowed) } func parseActionList(masked string, original string, prevActions []*action, putAllowed bool) ([]*action, error) {@@ -2043,8 +2042,7 @@ func parseKeymap(keymap map[tui.Event][]*action, str string) error { } key = firstKey(keys) }- putAllowed := key.Type == tui.Rune && unicode.IsGraphic(key.Char)- keymap[key], err = parseActionList(pair[1], origPairStr[len(pair[0])+1:], keymap[key], putAllowed)+ keymap[key], err = parseActionList(pair[1], origPairStr[len(pair[0])+1:], keymap[key], key.Printable()) if err != nil { return err }
@@ -572,7 +572,7 @@ func TestValidateSign(t *testing.T) { } func TestParseSingleActionList(t *testing.T) {- actions, _ := parseSingleActionList("Execute@foo+bar,baz@+up+up+reload:down+down")+ actions, _ := parseSingleActionList("Execute@foo+bar,baz@+up+up+reload:down+down", false) if len(actions) != 4 { t.Errorf("Invalid number of actions parsed:%d", len(actions)) }@@ -588,7 +588,7 @@ func TestParseSingleActionList(t *testing.T) { } func TestParseSingleActionListError(t *testing.T) {- _, err := parseSingleActionList("change-query(foobar)baz")+ _, err := parseSingleActionList("change-query(foobar)baz", false) if err == nil { t.Errorf("Failed to detect error") }
@@ -240,7 +240,7 @@ Loop: } body = body[:contentLength] - actions, err := parseSingleActionList(strings.Trim(string(body), "\r\n"))+ actions, err := parseSingleActionList(strings.Trim(string(body), "\r\n"), false) if err != nil { return bad(err.Error()) }
@@ -6973,7 +6973,8 @@ func (t *Terminal) Loop() error { }) case actTransform, actBgTransform: capture(false, func(body string) {- if actions, err := parseSingleActionList(strings.Trim(body, "\r\n")); err == nil {+ // Allow 'put' if the triggering key is a printable character+ if actions, err := parseSingleActionList(strings.Trim(body, "\r\n"), event.Printable()); err == nil { // NOTE: We're not properly passing the return value here doActions(actions) }
@@ -4,6 +4,7 @@ import ( "strconv" "strings" "time"+ "unicode" "github.com/junegunn/fzf/src/util" "github.com/rivo/uniseg"@@ -252,6 +253,12 @@ func (e Event) Comparable() Event { return Event{e.Type, e.Char, nil} } +// Printable returns true if the event is a printable character that can be+// inserted into the query (e.g. via the 'put' action).+func (e Event) Printable() bool {+ return e.Type == Rune && unicode.IsGraphic(e.Char)+}+ func (e Event) KeyName() string { if me := e.MouseEvent; me != nil { return me.Name()
@@ -971,6 +971,24 @@ class TestCore < TestInteractive tmux.until { |lines| assert_includes lines[1], ' aabravo/aabravo' } end + def test_transform_put+ tmux.send_keys %(seq 1000 | #{FZF} --bind 'a:transform:echo put'), :Enter+ tmux.until { |lines| assert_equal 1000, lines.match_count }+ tmux.send_keys :a+ tmux.until { |lines| assert_equal '> a', lines.last }+ tmux.send_keys :b+ tmux.until { |lines| assert_equal '> ab', lines.last }+ end++ # The async callback runs in a later iteration, but 'put' must still insert+ # the key that triggered the bg-transform (snapshot of the scheduling event).+ def test_bg_transform_put+ tmux.send_keys %(seq 1000 | #{FZF} --bind 'a:bg-transform:sleep 0.5; echo put'), :Enter+ tmux.until { |lines| assert_equal 1000, lines.match_count }+ tmux.send_keys 'ab'+ tmux.until { |lines| assert_equal '> ba', lines.last }+ end+ def test_accept_non_empty tmux.send_keys %(seq 1000 | #{fzf('--print-query --bind enter:accept-non-empty')}), :Enter tmux.until { |lines| assert_equal 1000, lines.match_count }