mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-12-23 03:19:01 +00:00
Add rebind
action for restoring bindings after unbind
Fix #2752 Close #2564
This commit is contained in:
parent
f8b713f425
commit
d56f605b63
@ -12,6 +12,7 @@ CHANGELOG
|
||||
fzf --nth=-1 --no-hscroll --ellipsis='' |
|
||||
awk '{print $2}'
|
||||
```
|
||||
- Added `rebind` action for restoring bindings after `unbind`
|
||||
- Bug fixes and improvements
|
||||
|
||||
0.29.0
|
||||
|
@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
..
|
||||
.TH fzf-tmux 1 "Mar 2022" "fzf 0.30.0" "fzf-tmux - open fzf in tmux split pane"
|
||||
.TH fzf-tmux 1 "Apr 2022" "fzf 0.30.0" "fzf-tmux - open fzf in tmux split pane"
|
||||
|
||||
.SH NAME
|
||||
fzf-tmux - open fzf in tmux split pane
|
||||
|
@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
..
|
||||
.TH fzf 1 "Mar 2022" "fzf 0.30.0" "fzf - a command-line fuzzy finder"
|
||||
.TH fzf 1 "Apr 2022" "fzf 0.30.0" "fzf - a command-line fuzzy finder"
|
||||
|
||||
.SH NAME
|
||||
fzf - a command-line fuzzy finder
|
||||
@ -867,6 +867,7 @@ A key or an event can be bound to one or more of the following actions.
|
||||
\fBprint-query\fR (print query and exit)
|
||||
\fBput\fR (put the character to the prompt)
|
||||
\fBrefresh-preview\fR
|
||||
\fBrebind(...)\fR (rebind bindings after \fBunbind\fR)
|
||||
\fBreload(...)\fR (see below for the details)
|
||||
\fBreplace-query\fR (replace query string with the current selection)
|
||||
\fBselect\fR
|
||||
|
12
src/core.go
12
src/core.go
@ -242,9 +242,11 @@ func Run(opts *Options, version string, revision string) {
|
||||
for {
|
||||
delay := true
|
||||
ticks++
|
||||
input := func() []rune {
|
||||
input := func(reloaded bool) []rune {
|
||||
paused, input := terminal.Input()
|
||||
if !paused {
|
||||
if reloaded && paused {
|
||||
query = []rune{}
|
||||
} else if !paused {
|
||||
query = input
|
||||
}
|
||||
return query
|
||||
@ -274,7 +276,8 @@ func Run(opts *Options, version string, revision string) {
|
||||
opts.Sync = false
|
||||
terminal.UpdateList(PassMerger(&snapshot, opts.Tac), false)
|
||||
}
|
||||
matcher.Reset(snapshot, input(), false, !reading, sort, clearCache())
|
||||
reset := clearCache()
|
||||
matcher.Reset(snapshot, input(reset), false, !reading, sort, reset)
|
||||
|
||||
case EvtSearchNew:
|
||||
var command *string
|
||||
@ -293,7 +296,8 @@ func Run(opts *Options, version string, revision string) {
|
||||
break
|
||||
}
|
||||
snapshot, _ := chunkList.Snapshot()
|
||||
matcher.Reset(snapshot, input(), true, !reading, sort, clearCache())
|
||||
reset := clearCache()
|
||||
matcher.Reset(snapshot, input(reset), true, !reading, sort, reset)
|
||||
delay = false
|
||||
|
||||
case EvtSearchProgress:
|
||||
|
@ -798,7 +798,7 @@ func init() {
|
||||
// Backreferences are not supported.
|
||||
// "~!@#$%^&*;/|".each_char.map { |c| Regexp.escape(c) }.map { |c| "#{c}[^#{c}]*#{c}" }.join('|')
|
||||
executeRegexp = regexp.MustCompile(
|
||||
`(?si)[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt|change-preview-window|change-preview|unbind):.+|[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt|change-preview-window|change-preview|unbind)(\([^)]*\)|\[[^\]]*\]|~[^~]*~|![^!]*!|@[^@]*@|\#[^\#]*\#|\$[^\$]*\$|%[^%]*%|\^[^\^]*\^|&[^&]*&|\*[^\*]*\*|;[^;]*;|/[^/]*/|\|[^\|]*\|)`)
|
||||
`(?si)[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt|change-preview-window|change-preview|(?:re|un)bind):.+|[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt|change-preview-window|change-preview|(?:re|un)bind)(\([^)]*\)|\[[^\]]*\]|~[^~]*~|![^!]*!|@[^@]*@|\#[^\#]*\#|\$[^\$]*\$|%[^%]*%|\^[^\^]*\^|&[^&]*&|\*[^\*]*\*|;[^;]*;|/[^/]*/|\|[^\|]*\|)`)
|
||||
}
|
||||
|
||||
func parseKeymap(keymap map[tui.Event][]*action, str string) {
|
||||
@ -818,6 +818,8 @@ func parseKeymap(keymap map[tui.Event][]*action, str string) {
|
||||
prefix = symbol + "preview"
|
||||
} else if strings.HasPrefix(src[1:], "unbind") {
|
||||
prefix = symbol + "unbind"
|
||||
} else if strings.HasPrefix(src[1:], "rebind") {
|
||||
prefix = symbol + "rebind"
|
||||
} else if strings.HasPrefix(src[1:], "change-prompt") {
|
||||
prefix = symbol + "change-prompt"
|
||||
} else if src[len(prefix)] == '-' {
|
||||
@ -1025,6 +1027,8 @@ func parseKeymap(keymap map[tui.Event][]*action, str string) {
|
||||
offset = len("change-prompt")
|
||||
case actUnbind:
|
||||
offset = len("unbind")
|
||||
case actRebind:
|
||||
offset = len("rebind")
|
||||
case actExecuteSilent:
|
||||
offset = len("execute-silent")
|
||||
case actExecuteMulti:
|
||||
@ -1045,8 +1049,8 @@ func parseKeymap(keymap map[tui.Event][]*action, str string) {
|
||||
actionArg = spec[offset+1 : len(spec)-1]
|
||||
actions = append(actions, &action{t: t, a: actionArg})
|
||||
}
|
||||
if t == actUnbind {
|
||||
parseKeyChords(actionArg, "unbind target required")
|
||||
if t == actUnbind || t == actRebind {
|
||||
parseKeyChords(actionArg, spec[0:offset]+" target required")
|
||||
} else if t == actChangePreviewWindow {
|
||||
opts := previewOpts{}
|
||||
for _, arg := range strings.Split(actionArg, "|") {
|
||||
@ -1075,6 +1079,8 @@ func isExecuteAction(str string) actionType {
|
||||
return actReload
|
||||
case "unbind":
|
||||
return actUnbind
|
||||
case "rebind":
|
||||
return actRebind
|
||||
case "preview":
|
||||
return actPreview
|
||||
case "change-preview-window":
|
||||
|
@ -136,6 +136,7 @@ type Terminal struct {
|
||||
delimiter Delimiter
|
||||
expect map[tui.Event]string
|
||||
keymap map[tui.Event][]*action
|
||||
keymapOrg map[tui.Event][]*action
|
||||
pressed string
|
||||
printQuery bool
|
||||
history *History
|
||||
@ -313,6 +314,7 @@ const (
|
||||
actSelect
|
||||
actDeselect
|
||||
actUnbind
|
||||
actRebind
|
||||
)
|
||||
|
||||
type placeholderFlags struct {
|
||||
@ -501,6 +503,10 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
||||
wordRubout = fmt.Sprintf("%s[^%s]", sep, sep)
|
||||
wordNext = fmt.Sprintf("[^%s]%s|(.$)", sep, sep)
|
||||
}
|
||||
keymapCopy := make(map[tui.Event][]*action)
|
||||
for key, action := range opts.Keymap {
|
||||
keymapCopy[key] = action
|
||||
}
|
||||
t := Terminal{
|
||||
initDelay: delay,
|
||||
infoStyle: opts.InfoStyle,
|
||||
@ -526,6 +532,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
||||
delimiter: opts.Delimiter,
|
||||
expect: opts.Expect,
|
||||
keymap: opts.Keymap,
|
||||
keymapOrg: keymapCopy,
|
||||
pressed: "",
|
||||
printQuery: opts.PrintQuery,
|
||||
history: opts.History,
|
||||
@ -2734,6 +2741,13 @@ func (t *Terminal) Loop() {
|
||||
for key := range keys {
|
||||
delete(t.keymap, key)
|
||||
}
|
||||
case actRebind:
|
||||
keys := parseKeyChords(a.a, "PANIC")
|
||||
for key := range keys {
|
||||
if originalAction, found := t.keymapOrg[key]; found {
|
||||
t.keymap[key] = originalAction
|
||||
}
|
||||
}
|
||||
case actChangePreview:
|
||||
if t.previewOpts.command != a.a {
|
||||
togglePreview(len(a.a) > 0)
|
||||
|
@ -2043,8 +2043,8 @@ class TestGoFZF < TestBase
|
||||
tmux.until { |lines| assert_equal(%w[1 2 3 4 5], top5[lines]) }
|
||||
end
|
||||
|
||||
def test_unbind
|
||||
tmux.send_keys "seq 100 | #{FZF} --bind 'c:clear-query,d:unbind(c,d)'", :Enter
|
||||
def test_unbind_rebind
|
||||
tmux.send_keys "seq 100 | #{FZF} --bind 'c:clear-query,d:unbind(c,d),e:rebind(c,d)'", :Enter
|
||||
tmux.until { |lines| assert_equal 100, lines.item_count }
|
||||
tmux.send_keys 'ab'
|
||||
tmux.until { |lines| assert_equal '> ab', lines[-1] }
|
||||
@ -2052,6 +2052,8 @@ class TestGoFZF < TestBase
|
||||
tmux.until { |lines| assert_equal '>', lines[-1] }
|
||||
tmux.send_keys 'dabcd'
|
||||
tmux.until { |lines| assert_equal '> abcd', lines[-1] }
|
||||
tmux.send_keys 'ecabddc'
|
||||
tmux.until { |lines| assert_equal '> abdc', lines[-1] }
|
||||
end
|
||||
|
||||
def test_item_index_reset_on_reload
|
||||
|
Loading…
Reference in New Issue
Block a user