mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2025-01-15 11:46:58 +00:00
Merge 6783417504
into a30181e240
This commit is contained in:
commit
2324ed28f9
529
src/options.go
529
src/options.go
@ -700,54 +700,11 @@ func defaultOptions() *Options {
|
||||
Version: false}
|
||||
}
|
||||
|
||||
func optString(arg string, prefixes ...string) (bool, string) {
|
||||
for _, prefix := range prefixes {
|
||||
if strings.HasPrefix(arg, prefix) {
|
||||
return true, arg[len(prefix):]
|
||||
}
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func nextString(args []string, i *int, message string) (string, error) {
|
||||
if len(args) > *i+1 {
|
||||
*i++
|
||||
} else {
|
||||
return "", errors.New(message)
|
||||
}
|
||||
return args[*i], nil
|
||||
}
|
||||
|
||||
func optionalNextString(args []string, i *int) (bool, string) {
|
||||
if len(args) > *i+1 && !strings.HasPrefix(args[*i+1], "-") && !strings.HasPrefix(args[*i+1], "+") {
|
||||
*i++
|
||||
return true, args[*i]
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func isDir(path string) bool {
|
||||
stat, err := os.Stat(path)
|
||||
return err == nil && stat.IsDir()
|
||||
}
|
||||
|
||||
func nextDirs(args []string, i *int) ([]string, error) {
|
||||
dirs := []string{}
|
||||
for *i < len(args)-1 {
|
||||
arg := args[*i+1]
|
||||
if isDir(arg) {
|
||||
dirs = append(dirs, arg)
|
||||
*i++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(dirs) == 0 {
|
||||
return nil, errors.New("no directory specified")
|
||||
}
|
||||
return dirs, nil
|
||||
}
|
||||
|
||||
func atoi(str string) (int, error) {
|
||||
num, err := strconv.Atoi(str)
|
||||
if err != nil {
|
||||
@ -764,33 +721,6 @@ func atof(str string) (float64, error) {
|
||||
return num, nil
|
||||
}
|
||||
|
||||
func nextInt(args []string, i *int, message string) (int, error) {
|
||||
if len(args) > *i+1 {
|
||||
*i++
|
||||
} else {
|
||||
return 0, errors.New(message)
|
||||
}
|
||||
n, err := atoi(args[*i])
|
||||
if err != nil {
|
||||
return 0, errors.New(message)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func optionalNumeric(args []string, i *int, defaultValue int) (int, error) {
|
||||
if len(args) > *i+1 {
|
||||
if strings.IndexAny(args[*i+1], "0123456789") == 0 {
|
||||
*i++
|
||||
n, err := atoi(args[*i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
}
|
||||
return defaultValue, nil
|
||||
}
|
||||
|
||||
func splitNth(str string) ([]Range, error) {
|
||||
if match, _ := regexp.MatchString("^[0-9,-.]+$", str); !match {
|
||||
return nil, errors.New("invalid format: " + str)
|
||||
@ -2077,6 +2007,13 @@ func parseMarkerMultiLine(str string) (*[3]string, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func optString(arg string, prefix string) (bool, string) {
|
||||
if strings.HasPrefix(arg, prefix) {
|
||||
return true, arg[len(prefix):]
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
var err error
|
||||
var historyMax int
|
||||
@ -2113,10 +2050,101 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
opts.Version = false
|
||||
opts.Man = false
|
||||
}
|
||||
|
||||
startIndex := *index
|
||||
for i := 0; i < len(allArgs); i++ {
|
||||
|
||||
var i int
|
||||
var val *string = nil
|
||||
nextString := func(message string) (string, error) {
|
||||
defer func() { val = nil }()
|
||||
if val != nil {
|
||||
return *val, nil
|
||||
}
|
||||
if len(allArgs) > i+1 {
|
||||
i++
|
||||
} else {
|
||||
return "", errors.New(message)
|
||||
}
|
||||
return allArgs[i], nil
|
||||
}
|
||||
|
||||
optionalNextString := func() (bool, string) {
|
||||
defer func() { val = nil }()
|
||||
if val != nil {
|
||||
return true, *val
|
||||
}
|
||||
if len(allArgs) > i+1 && !strings.HasPrefix(allArgs[i+1], "-") && !strings.HasPrefix(allArgs[i+1], "+") {
|
||||
i++
|
||||
return true, allArgs[i]
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
nextDirs := func() ([]string, error) {
|
||||
defer func() { val = nil }()
|
||||
dirs := []string{}
|
||||
if val != nil {
|
||||
dirs = append(dirs, *val)
|
||||
}
|
||||
for i < len(allArgs)-1 {
|
||||
arg := allArgs[i+1]
|
||||
if isDir(arg) {
|
||||
dirs = append(dirs, arg)
|
||||
i++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(dirs) == 0 {
|
||||
return nil, errors.New("no directory specified")
|
||||
}
|
||||
return dirs, nil
|
||||
}
|
||||
|
||||
nextInt := func(message string) (int, error) {
|
||||
defer func() { val = nil }()
|
||||
var str string
|
||||
if val != nil {
|
||||
str = *val
|
||||
} else if len(allArgs) > i+1 {
|
||||
i++
|
||||
str = allArgs[i]
|
||||
} else {
|
||||
return 0, errors.New(message)
|
||||
}
|
||||
n, err := atoi(str)
|
||||
if err != nil {
|
||||
return 0, errors.New(message)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
optionalNumeric := func(defaultValue int) (int, error) {
|
||||
defer func() { val = nil }()
|
||||
var str string
|
||||
if val != nil {
|
||||
str = *val
|
||||
} else if len(allArgs) > i+1 && strings.IndexAny(allArgs[i+1], "0123456789") == 0 {
|
||||
i++
|
||||
str = allArgs[i]
|
||||
} else {
|
||||
return defaultValue, nil
|
||||
}
|
||||
n, err := atoi(str)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
for ; i < len(allArgs); i++ {
|
||||
arg := allArgs[i]
|
||||
index := i + startIndex
|
||||
if strings.HasPrefix(arg, "--") && strings.IndexRune(arg, '=') > 0 {
|
||||
tokens := strings.SplitN(arg, "=", 2)
|
||||
arg = tokens[0]
|
||||
val = &tokens[1]
|
||||
}
|
||||
switch arg {
|
||||
case "--man":
|
||||
clearExitingOpts()
|
||||
@ -2139,7 +2167,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-winpty":
|
||||
opts.NoWinpty = true
|
||||
case "--tmux":
|
||||
given, str := optionalNextString(allArgs, &i)
|
||||
given, str := optionalNextString()
|
||||
if given {
|
||||
if opts.Tmux, err = parseTmuxOptions(str, index); err != nil {
|
||||
return err
|
||||
@ -2156,7 +2184,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-force-tty-in":
|
||||
opts.ForceTtyIn = false
|
||||
case "--proxy-script":
|
||||
if opts.ProxyScript, err = nextString(allArgs, &i, ""); err != nil {
|
||||
if opts.ProxyScript, err = nextString(""); err != nil {
|
||||
return err
|
||||
}
|
||||
case "-x", "--extended":
|
||||
@ -2172,11 +2200,11 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "+e", "--no-exact":
|
||||
opts.Fuzzy = true
|
||||
case "-q", "--query":
|
||||
if opts.Query, err = nextString(allArgs, &i, "query string required"); err != nil {
|
||||
if opts.Query, err = nextString("query string required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "-f", "--filter":
|
||||
filter, err := nextString(allArgs, &i, "query string required")
|
||||
filter, err := nextString("query string required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2186,7 +2214,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-literal":
|
||||
opts.Normalize = true
|
||||
case "--algo":
|
||||
str, err := nextString(allArgs, &i, "algorithm required (v1|v2)")
|
||||
str, err := nextString("algorithm required (v1|v2)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2194,13 +2222,13 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--scheme":
|
||||
str, err := nextString(allArgs, &i, "scoring scheme required (default|path|history)")
|
||||
str, err := nextString("scoring scheme required (default|path|history)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.Scheme = strings.ToLower(str)
|
||||
case "--expect":
|
||||
str, err := nextString(allArgs, &i, "key names required")
|
||||
str, err := nextString("key names required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2218,7 +2246,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--disabled", "--phony":
|
||||
opts.Phony = true
|
||||
case "--tiebreak":
|
||||
str, err := nextString(allArgs, &i, "sort criterion required")
|
||||
str, err := nextString("sort criterion required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2226,7 +2254,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--bind":
|
||||
str, err := nextString(allArgs, &i, "bind expression required")
|
||||
str, err := nextString("bind expression required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2234,7 +2262,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--color":
|
||||
_, spec := optionalNextString(allArgs, &i)
|
||||
_, spec := optionalNextString()
|
||||
if len(spec) == 0 {
|
||||
opts.Theme = tui.EmptyTheme()
|
||||
} else {
|
||||
@ -2243,7 +2271,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
}
|
||||
}
|
||||
case "--toggle-sort":
|
||||
str, err := nextString(allArgs, &i, "key name required")
|
||||
str, err := nextString("key name required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2251,13 +2279,13 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "-d", "--delimiter":
|
||||
str, err := nextString(allArgs, &i, "delimiter required")
|
||||
str, err := nextString("delimiter required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.Delimiter = delimiterRegexp(str)
|
||||
case "-n", "--nth":
|
||||
str, err := nextString(allArgs, &i, "nth expression required")
|
||||
str, err := nextString("nth expression required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2265,7 +2293,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--with-nth":
|
||||
str, err := nextString(allArgs, &i, "nth expression required")
|
||||
str, err := nextString("nth expression required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2273,7 +2301,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "-s", "--sort":
|
||||
if opts.Sort, err = optionalNumeric(allArgs, &i, 1); err != nil {
|
||||
if opts.Sort, err = optionalNumeric(1); err != nil {
|
||||
return err
|
||||
}
|
||||
case "+s", "--no-sort":
|
||||
@ -2287,7 +2315,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-tac":
|
||||
opts.Tac = false
|
||||
case "--tail":
|
||||
if opts.Tail, err = nextInt(allArgs, &i, "number of items to keep required"); err != nil {
|
||||
if opts.Tail, err = nextInt("number of items to keep required"); err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.Tail <= 0 {
|
||||
@ -2302,7 +2330,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "+i", "--no-ignore-case":
|
||||
opts.Case = CaseRespect
|
||||
case "-m", "--multi":
|
||||
if opts.Multi, err = optionalNumeric(allArgs, &i, maxMulti); err != nil {
|
||||
if opts.Multi, err = optionalNumeric(maxMulti); err != nil {
|
||||
return err
|
||||
}
|
||||
case "+m", "--no-multi":
|
||||
@ -2326,7 +2354,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-bold":
|
||||
opts.Bold = false
|
||||
case "--layout":
|
||||
str, err := nextString(allArgs, &i, "layout required (default / reverse / reverse-list)")
|
||||
str, err := nextString("layout required (default / reverse / reverse-list)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2350,7 +2378,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-wrap":
|
||||
opts.Wrap = false
|
||||
case "--wrap-sign":
|
||||
str, err := nextString(allArgs, &i, "wrap sign required")
|
||||
str, err := nextString("wrap sign required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2368,11 +2396,11 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-hscroll":
|
||||
opts.Hscroll = false
|
||||
case "--hscroll-off":
|
||||
if opts.HscrollOff, err = nextInt(allArgs, &i, "hscroll offset required"); err != nil {
|
||||
if opts.HscrollOff, err = nextInt("hscroll offset required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--scroll-off":
|
||||
if opts.ScrollOff, err = nextInt(allArgs, &i, "scroll offset required"); err != nil {
|
||||
if opts.ScrollOff, err = nextInt("scroll offset required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--filepath-word":
|
||||
@ -2380,7 +2408,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-filepath-word":
|
||||
opts.FileWord = false
|
||||
case "--info":
|
||||
str, err := nextString(allArgs, &i, "info style required")
|
||||
str, err := nextString("info style required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2388,7 +2416,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--info-command":
|
||||
if opts.InfoCommand, err = nextString(allArgs, &i, "info command required"); err != nil {
|
||||
if opts.InfoCommand, err = nextString("info command required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--no-info-command":
|
||||
@ -2401,7 +2429,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-inline-info":
|
||||
opts.InfoStyle = infoDefault
|
||||
case "--separator":
|
||||
separator, err := nextString(allArgs, &i, "separator character required")
|
||||
separator, err := nextString("separator character required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2410,7 +2438,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
nosep := ""
|
||||
opts.Separator = &nosep
|
||||
case "--scrollbar":
|
||||
given, bar := optionalNextString(allArgs, &i)
|
||||
given, bar := optionalNextString()
|
||||
if given {
|
||||
opts.Scrollbar = &bar
|
||||
} else {
|
||||
@ -2420,7 +2448,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
noBar := ""
|
||||
opts.Scrollbar = &noBar
|
||||
case "--jump-labels":
|
||||
if opts.JumpLabels, err = nextString(allArgs, &i, "label characters required"); err != nil {
|
||||
if opts.JumpLabels, err = nextString("label characters required"); err != nil {
|
||||
return err
|
||||
}
|
||||
validateJumpLabels = true
|
||||
@ -2447,26 +2475,26 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-print-query":
|
||||
opts.PrintQuery = false
|
||||
case "--prompt":
|
||||
opts.Prompt, err = nextString(allArgs, &i, "prompt string required")
|
||||
opts.Prompt, err = nextString("prompt string required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "--pointer":
|
||||
str, err := nextString(allArgs, &i, "pointer sign required")
|
||||
str, err := nextString("pointer sign required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
str = firstLine(str)
|
||||
opts.Pointer = &str
|
||||
case "--marker":
|
||||
str, err := nextString(allArgs, &i, "marker sign required")
|
||||
str, err := nextString("marker sign required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
str = firstLine(str)
|
||||
opts.Marker = &str
|
||||
case "--marker-multi-line":
|
||||
str, err := nextString(allArgs, &i, "marker sign for multi-line entries required")
|
||||
str, err := nextString("marker sign for multi-line entries required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2480,7 +2508,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-history":
|
||||
opts.History = nil
|
||||
case "--history":
|
||||
str, err := nextString(allArgs, &i, "history file path required")
|
||||
str, err := nextString("history file path required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2488,7 +2516,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--history-size":
|
||||
n, err := nextInt(allArgs, &i, "history max size required")
|
||||
n, err := nextInt("history max size required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2500,13 +2528,13 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-header-lines":
|
||||
opts.HeaderLines = 0
|
||||
case "--header":
|
||||
str, err := nextString(allArgs, &i, "header string required")
|
||||
str, err := nextString("header string required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.Header = strLines(str)
|
||||
case "--header-lines":
|
||||
if opts.HeaderLines, err = nextInt(allArgs, &i, "number of header lines required"); err != nil {
|
||||
if opts.HeaderLines, err = nextInt("number of header lines required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--header-first":
|
||||
@ -2514,26 +2542,26 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-header-first":
|
||||
opts.HeaderFirst = false
|
||||
case "--gap":
|
||||
if opts.Gap, err = optionalNumeric(allArgs, &i, 1); err != nil {
|
||||
if opts.Gap, err = optionalNumeric(1); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--no-gap":
|
||||
opts.Gap = 0
|
||||
case "--ellipsis":
|
||||
str, err := nextString(allArgs, &i, "ellipsis string required")
|
||||
str, err := nextString("ellipsis string required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
str = firstLine(str)
|
||||
opts.Ellipsis = &str
|
||||
case "--preview":
|
||||
if opts.Preview.command, err = nextString(allArgs, &i, "preview command required"); err != nil {
|
||||
if opts.Preview.command, err = nextString("preview command required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--no-preview":
|
||||
opts.Preview.command = ""
|
||||
case "--preview-window":
|
||||
str, err := nextString(allArgs, &i, "preview window layout required: [up|down|left|right][,SIZE[%]][,border-STYLE][,wrap][,cycle][,hidden][,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES][,default]")
|
||||
str, err := nextString("preview window layout required: [up|down|left|right][,SIZE[%]][,border-STYLE][,wrap][,cycle][,hidden][,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES][,default]")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2543,12 +2571,12 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-preview-border":
|
||||
opts.Preview.border = tui.BorderNone
|
||||
case "--preview-border":
|
||||
hasArg, arg := optionalNextString(allArgs, &i)
|
||||
hasArg, arg := optionalNextString()
|
||||
if opts.Preview.border, err = parseBorder(arg, !hasArg, true); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--height":
|
||||
str, err := nextString(allArgs, &i, "height required: [~]HEIGHT[%]")
|
||||
str, err := nextString("height required: [~]HEIGHT[%]")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2556,7 +2584,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--min-height":
|
||||
if opts.MinHeight, err = nextInt(allArgs, &i, "height required: HEIGHT"); err != nil {
|
||||
if opts.MinHeight, err = nextInt("height required: HEIGHT"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--no-height":
|
||||
@ -2568,12 +2596,12 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-border":
|
||||
opts.BorderShape = tui.BorderNone
|
||||
case "--border":
|
||||
hasArg, arg := optionalNextString(allArgs, &i)
|
||||
hasArg, arg := optionalNextString()
|
||||
if opts.BorderShape, err = parseBorder(arg, !hasArg, false); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--list-border":
|
||||
hasArg, arg := optionalNextString(allArgs, &i)
|
||||
hasArg, arg := optionalNextString()
|
||||
if opts.ListBorderShape, err = parseBorder(arg, !hasArg, false); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2582,12 +2610,12 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-list-label":
|
||||
opts.ListLabel.label = ""
|
||||
case "--list-label":
|
||||
opts.ListLabel.label, err = nextString(allArgs, &i, "label required")
|
||||
opts.ListLabel.label, err = nextString("label required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "--list-label-pos":
|
||||
pos, err := nextString(allArgs, &i, "label position required (positive or negative integer or 'center')")
|
||||
pos, err := nextString("label position required (positive or negative integer or 'center')")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2597,18 +2625,18 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-header-border":
|
||||
opts.HeaderBorderShape = tui.BorderNone
|
||||
case "--header-border":
|
||||
hasArg, arg := optionalNextString(allArgs, &i)
|
||||
hasArg, arg := optionalNextString()
|
||||
if opts.HeaderBorderShape, err = parseBorder(arg, !hasArg, false); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--no-header-label":
|
||||
opts.HeaderLabel.label = ""
|
||||
case "--header-label":
|
||||
if opts.HeaderLabel.label, err = nextString(allArgs, &i, "header label required"); err != nil {
|
||||
if opts.HeaderLabel.label, err = nextString("header label required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--header-label-pos":
|
||||
pos, err := nextString(allArgs, &i, "header label position required (positive or negative integer or 'center')")
|
||||
pos, err := nextString("header label position required (positive or negative integer or 'center')")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2618,18 +2646,18 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-input-border":
|
||||
opts.InputBorderShape = tui.BorderNone
|
||||
case "--input-border":
|
||||
hasArg, arg := optionalNextString(allArgs, &i)
|
||||
hasArg, arg := optionalNextString()
|
||||
if opts.InputBorderShape, err = parseBorder(arg, !hasArg, false); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--no-input-label":
|
||||
opts.InputLabel.label = ""
|
||||
case "--input-label":
|
||||
if opts.InputLabel.label, err = nextString(allArgs, &i, "input label required"); err != nil {
|
||||
if opts.InputLabel.label, err = nextString("input label required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--input-label-pos":
|
||||
pos, err := nextString(allArgs, &i, "input label position required (positive or negative integer or 'center')")
|
||||
pos, err := nextString("input label position required (positive or negative integer or 'center')")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2639,12 +2667,12 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-border-label":
|
||||
opts.BorderLabel.label = ""
|
||||
case "--border-label":
|
||||
opts.BorderLabel.label, err = nextString(allArgs, &i, "label required")
|
||||
opts.BorderLabel.label, err = nextString("label required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "--border-label-pos":
|
||||
pos, err := nextString(allArgs, &i, "label position required (positive or negative integer or 'center')")
|
||||
pos, err := nextString("label position required (positive or negative integer or 'center')")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2654,11 +2682,11 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-preview-label":
|
||||
opts.PreviewLabel.label = ""
|
||||
case "--preview-label":
|
||||
if opts.PreviewLabel.label, err = nextString(allArgs, &i, "preview label required"); err != nil {
|
||||
if opts.PreviewLabel.label, err = nextString("preview label required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--preview-label-pos":
|
||||
pos, err := nextString(allArgs, &i, "preview label position required (positive or negative integer or 'center')")
|
||||
pos, err := nextString("preview label position required (positive or negative integer or 'center')")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2666,7 +2694,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--style":
|
||||
preset, err := nextString(allArgs, &i, "preset name required: [default|minimal|full]")
|
||||
preset, err := nextString("preset name required: [default|minimal|full]")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2682,7 +2710,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-ambidouble":
|
||||
opts.Ambidouble = false
|
||||
case "--margin":
|
||||
str, err := nextString(allArgs, &i, "margin required (TRBL / TB,RL / T,RL,B / T,R,B,L)")
|
||||
str, err := nextString("margin required (TRBL / TB,RL / T,RL,B / T,R,B,L)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2690,7 +2718,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--padding":
|
||||
str, err := nextString(allArgs, &i, "padding required (TRBL / TB,RL / T,RL,B / T,R,B,L)")
|
||||
str, err := nextString("padding required (TRBL / TB,RL / T,RL,B / T,R,B,L)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2698,15 +2726,15 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--tabstop":
|
||||
if opts.Tabstop, err = nextInt(allArgs, &i, "tab stop required"); err != nil {
|
||||
if opts.Tabstop, err = nextInt("tab stop required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--with-shell":
|
||||
if opts.WithShell, err = nextString(allArgs, &i, "shell command and flags required"); err != nil {
|
||||
if opts.WithShell, err = nextString("shell command and flags required"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--listen", "--listen-unsafe":
|
||||
given, str := optionalNextString(allArgs, &i)
|
||||
given, str := optionalNextString()
|
||||
addr := defaultListenAddr
|
||||
if given {
|
||||
var err error
|
||||
@ -2725,7 +2753,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
case "--no-clear":
|
||||
opts.ClearOnExit = false
|
||||
case "--walker":
|
||||
str, err := nextString(allArgs, &i, "walker options required [file][,dir][,follow][,hidden]")
|
||||
str, err := nextString("walker options required [file][,dir][,follow][,hidden]")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2733,261 +2761,58 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
||||
return err
|
||||
}
|
||||
case "--walker-root":
|
||||
if opts.WalkerRoot, err = nextDirs(allArgs, &i); err != nil {
|
||||
if opts.WalkerRoot, err = nextDirs(); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--walker-skip":
|
||||
str, err := nextString(allArgs, &i, "directory names to ignore required")
|
||||
str, err := nextString("directory names to ignore required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.WalkerSkip = filterNonEmpty(strings.Split(str, ","))
|
||||
case "--profile-cpu":
|
||||
if opts.CPUProfile, err = nextString(allArgs, &i, "file path required: cpu"); err != nil {
|
||||
if opts.CPUProfile, err = nextString("file path required: cpu"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--profile-mem":
|
||||
if opts.MEMProfile, err = nextString(allArgs, &i, "file path required: mem"); err != nil {
|
||||
if opts.MEMProfile, err = nextString("file path required: mem"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--profile-block":
|
||||
if opts.BlockProfile, err = nextString(allArgs, &i, "file path required: block"); err != nil {
|
||||
if opts.BlockProfile, err = nextString("file path required: block"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--profile-mutex":
|
||||
if opts.MutexProfile, err = nextString(allArgs, &i, "file path required: mutex"); err != nil {
|
||||
if opts.MutexProfile, err = nextString("file path required: mutex"); err != nil {
|
||||
return err
|
||||
}
|
||||
case "--":
|
||||
// Ignored
|
||||
default:
|
||||
if match, value := optString(arg, "--algo="); match {
|
||||
if opts.FuzzyAlgo, err = parseAlgo(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--tmux="); match {
|
||||
if opts.Tmux, err = parseTmuxOptions(value, index); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--style="); match {
|
||||
if err := applyPreset(opts, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--scheme="); match {
|
||||
opts.Scheme = strings.ToLower(value)
|
||||
} else if match, value := optString(arg, "-q", "--query="); match {
|
||||
if match, value := optString(arg, "-q"); match {
|
||||
opts.Query = value
|
||||
} else if match, value := optString(arg, "-f", "--filter="); match {
|
||||
} else if match, value := optString(arg, "-f"); match {
|
||||
opts.Filter = &value
|
||||
} else if match, value := optString(arg, "-d", "--delimiter="); match {
|
||||
} else if match, value := optString(arg, "-d"); match {
|
||||
opts.Delimiter = delimiterRegexp(value)
|
||||
} else if match, value := optString(arg, "--border="); match {
|
||||
if opts.BorderShape, err = parseBorder(value, false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--preview-border="); match {
|
||||
if opts.Preview.border, err = parseBorder(value, false, true); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--list-border="); match {
|
||||
if opts.ListBorderShape, err = parseBorder(value, false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--list-label="); match {
|
||||
opts.ListLabel.label = value
|
||||
} else if match, value := optString(arg, "--list-label-pos="); match {
|
||||
if err := parseLabelPosition(&opts.ListLabel, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--input-border="); match {
|
||||
if opts.InputBorderShape, err = parseBorder(value, false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--input-label="); match {
|
||||
opts.InputLabel.label = value
|
||||
} else if match, value := optString(arg, "--input-label-pos="); match {
|
||||
if err := parseLabelPosition(&opts.InputLabel, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--border-label="); match {
|
||||
opts.BorderLabel.label = value
|
||||
} else if match, value := optString(arg, "--border-label-pos="); match {
|
||||
if err := parseLabelPosition(&opts.BorderLabel, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--preview-label="); match {
|
||||
opts.PreviewLabel.label = value
|
||||
} else if match, value := optString(arg, "--preview-label-pos="); match {
|
||||
if err := parseLabelPosition(&opts.PreviewLabel, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--wrap-sign="); match {
|
||||
opts.WrapSign = &value
|
||||
} else if match, value := optString(arg, "--prompt="); match {
|
||||
opts.Prompt = value
|
||||
} else if match, value := optString(arg, "--pointer="); match {
|
||||
str := firstLine(value)
|
||||
opts.Pointer = &str
|
||||
} else if match, value := optString(arg, "--marker="); match {
|
||||
str := firstLine(value)
|
||||
opts.Marker = &str
|
||||
} else if match, value := optString(arg, "--marker-multi-line="); match {
|
||||
if opts.MarkerMulti, err = parseMarkerMultiLine(firstLine(value)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "-n", "--nth="); match {
|
||||
} else if match, value := optString(arg, "-n"); match {
|
||||
if opts.Nth, err = splitNth(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--with-nth="); match {
|
||||
if opts.WithNth, err = splitNth(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, _ := optString(arg, "-s", "--sort="); match {
|
||||
} else if match, _ := optString(arg, "-s"); match {
|
||||
opts.Sort = 1 // Don't care
|
||||
} else if match, value := optString(arg, "-m", "--multi="); match {
|
||||
} else if match, value := optString(arg, "-m"); match {
|
||||
if opts.Multi, err = atoi(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--height="); match {
|
||||
if opts.Height, err = parseHeight(value, index); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--min-height="); match {
|
||||
if opts.MinHeight, err = atoi(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--layout="); match {
|
||||
if opts.Layout, err = parseLayout(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--info="); match {
|
||||
if opts.InfoStyle, opts.InfoPrefix, err = parseInfoStyle(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--info-command="); match {
|
||||
opts.InfoCommand = value
|
||||
} else if match, value := optString(arg, "--separator="); match {
|
||||
opts.Separator = &value
|
||||
} else if match, value := optString(arg, "--scrollbar="); match {
|
||||
opts.Scrollbar = &value
|
||||
} else if match, value := optString(arg, "--toggle-sort="); match {
|
||||
if err := parseToggleSort(opts.Keymap, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--expect="); match {
|
||||
chords, err := parseKeyChords(value, "key names required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range chords {
|
||||
opts.Expect[k] = v
|
||||
}
|
||||
} else if match, value := optString(arg, "--tiebreak="); match {
|
||||
if opts.Criteria, err = parseTiebreak(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--color="); match {
|
||||
if opts.Theme, err = parseTheme(opts.Theme, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--bind="); match {
|
||||
if err := parseKeymap(opts.Keymap, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--history="); match {
|
||||
if err := setHistory(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--history-size="); match {
|
||||
n, err := atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setHistoryMax(n); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--header="); match {
|
||||
opts.Header = strLines(value)
|
||||
} else if match, value := optString(arg, "--header-lines="); match {
|
||||
if opts.HeaderLines, err = atoi(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--gap="); match {
|
||||
if opts.Gap, err = atoi(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--ellipsis="); match {
|
||||
str := firstLine(value)
|
||||
opts.Ellipsis = &str
|
||||
} else if match, value := optString(arg, "--preview="); match {
|
||||
opts.Preview.command = value
|
||||
} else if match, value := optString(arg, "--preview-window="); match {
|
||||
if err := parsePreviewWindow(&opts.Preview, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--margin="); match {
|
||||
if opts.Margin, err = parseMargin("margin", value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--padding="); match {
|
||||
if opts.Padding, err = parseMargin("padding", value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--tabstop="); match {
|
||||
if opts.Tabstop, err = atoi(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--with-shell="); match {
|
||||
opts.WithShell = value
|
||||
} else if match, value := optString(arg, "--listen="); match {
|
||||
addr, err := parseListenAddress(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.ListenAddr = &addr
|
||||
opts.Unsafe = false
|
||||
} else if match, value := optString(arg, "--listen-unsafe="); match {
|
||||
addr, err := parseListenAddress(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.ListenAddr = &addr
|
||||
opts.Unsafe = true
|
||||
} else if match, value := optString(arg, "--walker="); match {
|
||||
if opts.WalkerOpts, err = parseWalkerOpts(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--walker-root="); match {
|
||||
if !isDir(value) {
|
||||
return errors.New("not a directory: " + value)
|
||||
}
|
||||
dirs, _ := nextDirs(allArgs, &i)
|
||||
opts.WalkerRoot = append([]string{value}, dirs...)
|
||||
} else if match, value := optString(arg, "--walker-skip="); match {
|
||||
opts.WalkerSkip = filterNonEmpty(strings.Split(value, ","))
|
||||
} else if match, value := optString(arg, "--hscroll-off="); match {
|
||||
if opts.HscrollOff, err = atoi(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--scroll-off="); match {
|
||||
if opts.ScrollOff, err = atoi(value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if match, value := optString(arg, "--jump-labels="); match {
|
||||
opts.JumpLabels = value
|
||||
validateJumpLabels = true
|
||||
} else if match, value := optString(arg, "--tail="); match {
|
||||
if opts.Tail, err = atoi(value); err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.Tail <= 0 {
|
||||
return errors.New("number of items to keep must be a positive integer")
|
||||
}
|
||||
} else {
|
||||
return errors.New("unknown option: " + arg)
|
||||
}
|
||||
}
|
||||
|
||||
if val != nil {
|
||||
return errors.New("unexpected value for " + arg + ": " + *val)
|
||||
}
|
||||
}
|
||||
*index += len(allArgs)
|
||||
|
||||
|
@ -1012,6 +1012,14 @@ func (t *Terminal) deferActivation() bool {
|
||||
}
|
||||
|
||||
func (t *Terminal) environ() []string {
|
||||
return t.environImpl(false)
|
||||
}
|
||||
|
||||
func (t *Terminal) environForPreview() []string {
|
||||
return t.environImpl(true)
|
||||
}
|
||||
|
||||
func (t *Terminal) environImpl(forPreview bool) []string {
|
||||
env := os.Environ()
|
||||
if t.listenPort != nil {
|
||||
env = append(env, fmt.Sprintf("FZF_PORT=%d", *t.listenPort))
|
||||
@ -1037,9 +1045,11 @@ func (t *Terminal) environ() []string {
|
||||
if pwindowSize.Lines > 0 {
|
||||
lines := fmt.Sprintf("LINES=%d", pwindowSize.Lines)
|
||||
columns := fmt.Sprintf("COLUMNS=%d", pwindowSize.Columns)
|
||||
if forPreview {
|
||||
env = append(env, lines)
|
||||
env = append(env, "FZF_PREVIEW_"+lines)
|
||||
env = append(env, columns)
|
||||
}
|
||||
env = append(env, "FZF_PREVIEW_"+lines)
|
||||
env = append(env, "FZF_PREVIEW_"+columns)
|
||||
env = append(env, fmt.Sprintf("FZF_PREVIEW_TOP=%d", t.tui.Top()+t.pwindow.Top()))
|
||||
env = append(env, fmt.Sprintf("FZF_PREVIEW_LEFT=%d", t.pwindow.Left()))
|
||||
@ -1093,6 +1103,9 @@ func (t *Terminal) extraLines() int {
|
||||
if t.listBorderShape.Visible() {
|
||||
extra += borderLines(t.listBorderShape)
|
||||
}
|
||||
if t.headerBorderShape.Visible() {
|
||||
extra += borderLines(t.headerBorderShape)
|
||||
}
|
||||
if !t.noSeparatorLine() {
|
||||
extra++
|
||||
}
|
||||
@ -4129,7 +4142,7 @@ func (t *Terminal) Loop() error {
|
||||
if len(command) > 0 && t.canPreview() {
|
||||
_, list := t.buildPlusList(command, false)
|
||||
t.cancelPreview()
|
||||
t.previewBox.Set(reqPreviewEnqueue, previewRequest{command, t.evaluateScrollOffset(), list, t.environ()})
|
||||
t.previewBox.Set(reqPreviewEnqueue, previewRequest{command, t.evaluateScrollOffset(), list, t.environForPreview()})
|
||||
}
|
||||
}
|
||||
|
||||
@ -4521,7 +4534,7 @@ func (t *Terminal) Loop() error {
|
||||
if valid {
|
||||
t.cancelPreview()
|
||||
t.previewBox.Set(reqPreviewEnqueue,
|
||||
previewRequest{t.previewOpts.command, t.evaluateScrollOffset(), list, t.environ()})
|
||||
previewRequest{t.previewOpts.command, t.evaluateScrollOffset(), list, t.environForPreview()})
|
||||
}
|
||||
} else {
|
||||
// Discard the preview content so that it won't accidentally appear
|
||||
|
@ -3702,6 +3702,22 @@ class TestGoFZF < TestBase
|
||||
BLOCK
|
||||
tmux.until { assert_block(block, _1) }
|
||||
end
|
||||
|
||||
def test_style_full_adaptive_height
|
||||
tmux.send_keys %(seq 1| #{FZF} --style=full --height=~100% --header-lines=1 --info=default), :Enter
|
||||
block = <<~BLOCK
|
||||
╭────────
|
||||
╰────────
|
||||
╭────────
|
||||
│ 1
|
||||
╰────────
|
||||
╭────────
|
||||
│ 0/0
|
||||
│ >
|
||||
╰────────
|
||||
BLOCK
|
||||
tmux.until { assert_block(block, _1) }
|
||||
end
|
||||
end
|
||||
|
||||
module TestShell
|
||||
|
Loading…
Reference in New Issue
Block a user