summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2015-06-15 23:00:38 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2015-06-15 23:00:38 +0900
commitfa5b58968e67a7f046d67554174a1923cfb30ea9 (patch)
tree41491a927baa168833a761b5a517b1b5d25e99d4
parente720f56ea8f01d17baa600e0f212cee8ba7cc53c (diff)
Add alternative execute notation that does not require closing char
This can be used to avoid parse errors that can happen when the command contains the closing character. Since the command does not finish at a certain character, the key binding should be the last one in the group. Suggested by @tiziano88. (#265) e.g. fzf --bind "ctrl-m:execute=COMMAND..." --bind ctrl-j:accept
-rw-r--r--src/options.go12
-rw-r--r--src/options_test.go4
2 files changed, 11 insertions, 5 deletions
diff --git a/src/options.go b/src/options.go
index 2bd013d0..25a87ac7 100644
--- a/src/options.go
+++ b/src/options.go
@@ -412,7 +412,7 @@ func parseKeymap(keymap map[int]actionType, execmap map[int]string, toggleSort b
// Backreferences are not supported.
// "~!@#$%^&*:;/|".each_char.map { |c| Regexp.escape(c) }.map { |c| "#{c}[^#{c}]*#{c}" }.join('|')
executeRegexp = regexp.MustCompile(
- ":execute(\\([^)]*\\)|\\[[^\\]]*\\]|~[^~]*~|![^!]*!|@[^@]*@|\\#[^\\#]*\\#|\\$[^\\$]*\\$|%[^%]*%|\\^[^\\^]*\\^|&[^&]*&|\\*[^\\*]*\\*|:[^:]*:|;[^;]*;|/[^/]*/|\\|[^\\|]*\\|)")
+ ":execute=.*|:execute(\\([^)]*\\)|\\[[^\\]]*\\]|~[^~]*~|![^!]*!|@[^@]*@|\\#[^\\#]*\\#|\\$[^\\$]*\\$|%[^%]*%|\\^[^\\^]*\\^|&[^&]*&|\\*[^\\*]*\\*|:[^:]*:|;[^;]*;|/[^/]*/|\\|[^\\|]*\\|)")
}
masked := executeRegexp.ReplaceAllStringFunc(str, func(src string) string {
return ":execute(" + strings.Repeat(" ", len(src)-10) + ")"
@@ -503,7 +503,11 @@ func parseKeymap(keymap map[int]actionType, execmap map[int]string, toggleSort b
default:
if isExecuteAction(act) {
keymap[key] = actExecute
- execmap[key] = pair[1][8 : len(act)-1]
+ if pair[1][7] == '=' {
+ execmap[key] = pair[1][8:]
+ } else {
+ execmap[key] = pair[1][8 : len(act)-1]
+ }
} else {
errorExit("unknown action: " + act)
}
@@ -518,8 +522,8 @@ func isExecuteAction(str string) bool {
}
b := str[7]
e := str[len(str)-1]
- if b == e && strings.ContainsAny(string(b), "~!@#$%^&*:;/|") ||
- b == '(' && e == ')' || b == '[' && e == ']' {
+ if b == '=' || b == '(' && e == ')' || b == '[' && e == ']' ||
+ b == e && strings.ContainsAny(string(b), "~!@#$%^&*:;/|") {
return true
}
return false
diff --git a/src/options_test.go b/src/options_test.go
index 630bde3b..162b8e48 100644
--- a/src/options_test.go
+++ b/src/options_test.go
@@ -163,7 +163,8 @@ func TestBind(t *testing.T) {
parseKeymap(keymap, execmap, false,
"ctrl-a:kill-line,ctrl-b:toggle-sort,c:page-up,alt-z:page-down,"+
"f1:execute(ls {}),f2:execute/echo {}, {}, {}/,f3:execute[echo '({})'],f4:execute:less {}:,"+
- "alt-a:execute@echo (,),[,],/,:,;,%,{}@,alt-b:execute;echo (,),[,],/,:,@,%,{};")
+ "alt-a:execute@echo (,),[,],/,:,;,%,{}@,alt-b:execute;echo (,),[,],/,:,@,%,{};"+
+ ",X:execute=foobar,Y:execute(baz)")
if !toggleSort {
t.Errorf("toggleSort not set")
}
@@ -181,6 +182,7 @@ func TestBind(t *testing.T) {
checkString("less {}", execmap[curses.F4])
checkString("echo (,),[,],/,:,;,%,{}", execmap[curses.AltA])
checkString("echo (,),[,],/,:,@,%,{}", execmap[curses.AltB])
+ checkString("foobar,Y:execute(baz)", execmap[curses.AltZ+'X'])
for idx, char := range []rune{'~', '!', '@', '#', '$', '%', '^', '&', '*', '|', ':', ';', '/'} {
keymap, execmap, toggleSort =