mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-08 16:12:09 -07:00
Custom key binding support (#238)
This commit is contained in:
@@ -51,6 +51,7 @@ const usage = `usage: fzf [options]
|
||||
--print-query Print query as the first line
|
||||
--expect=KEYS Comma-separated list of keys to complete fzf
|
||||
--toggle-sort=KEY Key to toggle sort
|
||||
--bind=KEYBINDS Custom key bindings. Refer to the man page.
|
||||
--sync Synchronous search for multi-staged filtering
|
||||
|
||||
Environment variables
|
||||
@@ -112,8 +113,9 @@ type Options struct {
|
||||
Select1 bool
|
||||
Exit0 bool
|
||||
Filter *string
|
||||
ToggleSort int
|
||||
ToggleSort bool
|
||||
Expect []int
|
||||
Keymap map[int]actionType
|
||||
PrintQuery bool
|
||||
Sync bool
|
||||
Version bool
|
||||
@@ -149,8 +151,9 @@ func defaultOptions() *Options {
|
||||
Select1: false,
|
||||
Exit0: false,
|
||||
Filter: nil,
|
||||
ToggleSort: 0,
|
||||
ToggleSort: false,
|
||||
Expect: []int{},
|
||||
Keymap: defaultKeymap(),
|
||||
PrintQuery: false,
|
||||
Sync: false,
|
||||
Version: false}
|
||||
@@ -290,12 +293,82 @@ func parseTheme(str string) *curses.ColorTheme {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkToggleSort(str string) int {
|
||||
func parseKeymap(keymap map[int]actionType, toggleSort bool, str string) (map[int]actionType, bool) {
|
||||
for _, pairStr := range strings.Split(str, ",") {
|
||||
pair := strings.Split(pairStr, ":")
|
||||
if len(pair) != 2 {
|
||||
errorExit("invalid key binding: " + pairStr)
|
||||
}
|
||||
keys := parseKeyChords(pair[0], "key name required")
|
||||
if len(keys) != 1 {
|
||||
errorExit("invalid key binding: " + pairStr)
|
||||
}
|
||||
key := keys[0]
|
||||
act := strings.ToLower(pair[1])
|
||||
switch strings.ToLower(pair[1]) {
|
||||
case "beginning-of-line":
|
||||
keymap[key] = actBeginningOfLine
|
||||
case "abort":
|
||||
keymap[key] = actAbort
|
||||
case "accept":
|
||||
keymap[key] = actAccept
|
||||
case "backward-char":
|
||||
keymap[key] = actBackwardChar
|
||||
case "backward-delete-char":
|
||||
keymap[key] = actBackwardDeleteChar
|
||||
case "backward-word":
|
||||
keymap[key] = actBackwardWord
|
||||
case "clear-screen":
|
||||
keymap[key] = actClearScreen
|
||||
case "delete-char":
|
||||
keymap[key] = actDeleteChar
|
||||
case "end-of-line":
|
||||
keymap[key] = actEndOfLine
|
||||
case "forward-char":
|
||||
keymap[key] = actForwardChar
|
||||
case "forward-word":
|
||||
keymap[key] = actForwardWord
|
||||
case "kill-line":
|
||||
keymap[key] = actKillLine
|
||||
case "kill-word":
|
||||
keymap[key] = actKillWord
|
||||
case "unix-line-discard", "line-discard":
|
||||
keymap[key] = actUnixLineDiscard
|
||||
case "unix-word-rubout", "word-rubout":
|
||||
keymap[key] = actUnixWordRubout
|
||||
case "yank":
|
||||
keymap[key] = actYank
|
||||
case "backward-kill-word":
|
||||
keymap[key] = actBackwardKillWord
|
||||
case "toggle-down":
|
||||
keymap[key] = actToggleDown
|
||||
case "toggle-up":
|
||||
keymap[key] = actToggleUp
|
||||
case "down":
|
||||
keymap[key] = actDown
|
||||
case "up":
|
||||
keymap[key] = actUp
|
||||
case "page-up":
|
||||
keymap[key] = actPageUp
|
||||
case "page-down":
|
||||
keymap[key] = actPageDown
|
||||
case "toggle-sort":
|
||||
keymap[key] = actToggleSort
|
||||
toggleSort = true
|
||||
default:
|
||||
errorExit("unknown action: " + act)
|
||||
}
|
||||
}
|
||||
return keymap, toggleSort
|
||||
}
|
||||
|
||||
func checkToggleSort(keymap map[int]actionType, str string) map[int]actionType {
|
||||
keys := parseKeyChords(str, "key name required")
|
||||
if len(keys) != 1 {
|
||||
errorExit("multiple keys specified")
|
||||
}
|
||||
return keys[0]
|
||||
keymap[keys[0]] = actToggleSort
|
||||
return keymap
|
||||
}
|
||||
|
||||
func parseOptions(opts *Options, allArgs []string) {
|
||||
@@ -319,10 +392,13 @@ func parseOptions(opts *Options, allArgs []string) {
|
||||
opts.Expect = parseKeyChords(nextString(allArgs, &i, "key names required"), "key names required")
|
||||
case "--tiebreak":
|
||||
opts.Tiebreak = parseTiebreak(nextString(allArgs, &i, "sort criterion required"))
|
||||
case "--bind":
|
||||
opts.Keymap, opts.ToggleSort = parseKeymap(opts.Keymap, opts.ToggleSort, nextString(allArgs, &i, "bind expression required"))
|
||||
case "--color":
|
||||
opts.Theme = parseTheme(nextString(allArgs, &i, "color scheme name required"))
|
||||
case "--toggle-sort":
|
||||
opts.ToggleSort = checkToggleSort(nextString(allArgs, &i, "key name required"))
|
||||
opts.Keymap = checkToggleSort(opts.Keymap, nextString(allArgs, &i, "key name required"))
|
||||
opts.ToggleSort = true
|
||||
case "-d", "--delimiter":
|
||||
opts.Delimiter = delimiterRegexp(nextString(allArgs, &i, "delimiter required"))
|
||||
case "-n", "--nth":
|
||||
@@ -409,13 +485,16 @@ func parseOptions(opts *Options, allArgs []string) {
|
||||
} else if match, _ := optString(arg, "-s|--sort="); match {
|
||||
opts.Sort = 1 // Don't care
|
||||
} else if match, value := optString(arg, "--toggle-sort="); match {
|
||||
opts.ToggleSort = checkToggleSort(value)
|
||||
opts.Keymap = checkToggleSort(opts.Keymap, value)
|
||||
opts.ToggleSort = true
|
||||
} else if match, value := optString(arg, "--expect="); match {
|
||||
opts.Expect = parseKeyChords(value, "key names required")
|
||||
} else if match, value := optString(arg, "--tiebreak="); match {
|
||||
opts.Tiebreak = parseTiebreak(value)
|
||||
} else if match, value := optString(arg, "--color="); match {
|
||||
opts.Theme = parseTheme(value)
|
||||
} else if match, value := optString(arg, "--bind="); match {
|
||||
opts.Keymap, opts.ToggleSort = parseKeymap(opts.Keymap, opts.ToggleSort, value)
|
||||
} else {
|
||||
errorExit("unknown option: " + arg)
|
||||
}
|
||||
|
Reference in New Issue
Block a user