Fix #292 - Allow binding of colon and comma

This commit is contained in:
Junegunn Choi 2015-07-16 19:18:23 +09:00
parent b0f491d3c3
commit a0e6147bb5
2 changed files with 30 additions and 12 deletions

View File

@ -430,6 +430,11 @@ func firstKey(keymap map[int]string) int {
return 0 return 0
} }
const (
escapedColon = 0
escapedComma = 1
)
func parseKeymap(keymap map[int]actionType, execmap map[int]string, toggleSort bool, str string) (map[int]actionType, map[int]string, bool) { func parseKeymap(keymap map[int]actionType, execmap map[int]string, toggleSort bool, str string) (map[int]actionType, map[int]string, bool) {
if executeRegexp == nil { if executeRegexp == nil {
// Backreferences are not supported. // Backreferences are not supported.
@ -440,10 +445,12 @@ func parseKeymap(keymap map[int]actionType, execmap map[int]string, toggleSort b
masked := executeRegexp.ReplaceAllStringFunc(str, func(src string) string { masked := executeRegexp.ReplaceAllStringFunc(str, func(src string) string {
return ":execute(" + strings.Repeat(" ", len(src)-10) + ")" return ":execute(" + strings.Repeat(" ", len(src)-10) + ")"
}) })
masked = strings.Replace(masked, "::", string([]rune{escapedColon, ':'}), -1)
masked = strings.Replace(masked, ",:", string([]rune{escapedComma, ':'}), -1)
idx := 0 idx := 0
for _, pairStr := range strings.Split(masked, ",") { for _, pairStr := range strings.Split(masked, ",") {
pairStr = str[idx : idx+len(pairStr)] origPairStr := str[idx : idx+len(pairStr)]
idx += len(pairStr) + 1 idx += len(pairStr) + 1
fail := func() { fail := func() {
@ -453,13 +460,22 @@ func parseKeymap(keymap map[int]actionType, execmap map[int]string, toggleSort b
if len(pair) != 2 { if len(pair) != 2 {
fail() fail()
} }
keys := parseKeyChords(pair[0], "key name required") var key int
if len(keys) != 1 { if len(pair[0]) == 1 && pair[0][0] == escapedColon {
fail() key = ':' + curses.AltZ
} else if len(pair[0]) == 1 && pair[0][0] == escapedComma {
key = ',' + curses.AltZ
} else {
keys := parseKeyChords(pair[0], "key name required")
if len(keys) != 1 {
fail()
}
key = firstKey(keys)
} }
key := firstKey(keys)
act := strings.ToLower(pair[1]) act := origPairStr[len(pair[0])+1 : len(origPairStr)]
switch act { actLower := strings.ToLower(act)
switch actLower {
case "ignore": case "ignore":
keymap[key] = actIgnore keymap[key] = actIgnore
case "beginning-of-line": case "beginning-of-line":
@ -524,12 +540,12 @@ func parseKeymap(keymap map[int]actionType, execmap map[int]string, toggleSort b
keymap[key] = actToggleSort keymap[key] = actToggleSort
toggleSort = true toggleSort = true
default: default:
if isExecuteAction(act) { if isExecuteAction(actLower) {
keymap[key] = actExecute keymap[key] = actExecute
if pair[1][7] == ':' { if act[7] == ':' {
execmap[key] = pair[1][8:] execmap[key] = act[8:]
} else { } else {
execmap[key] = pair[1][8 : len(act)-1] execmap[key] = act[8 : len(act)-1]
} }
} else { } else {
errorExit("unknown action: " + act) errorExit("unknown action: " + act)

View File

@ -188,13 +188,15 @@ func TestBind(t *testing.T) {
"ctrl-a:kill-line,ctrl-b:toggle-sort,c:page-up,alt-z:page-down,"+ "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 {};,"+ "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:\nfoobar,Y:execute(baz)") ",,:abort,::accept,X:execute:\nfoobar,Y:execute(baz)")
if !toggleSort { if !toggleSort {
t.Errorf("toggleSort not set") t.Errorf("toggleSort not set")
} }
check(actKillLine, keymap[curses.CtrlA]) check(actKillLine, keymap[curses.CtrlA])
check(actToggleSort, keymap[curses.CtrlB]) check(actToggleSort, keymap[curses.CtrlB])
check(actPageUp, keymap[curses.AltZ+'c']) check(actPageUp, keymap[curses.AltZ+'c'])
check(actAbort, keymap[curses.AltZ+','])
check(actAccept, keymap[curses.AltZ+':'])
check(actPageDown, keymap[curses.AltZ]) check(actPageDown, keymap[curses.AltZ])
check(actExecute, keymap[curses.F1]) check(actExecute, keymap[curses.F1])
check(actExecute, keymap[curses.F2]) check(actExecute, keymap[curses.F2])