mirror of
https://github.com/junegunn/fzf.git
synced 2025-11-14 22:33:47 -05:00
Color customization (#245)
This commit is contained in:
111
src/options.go
111
src/options.go
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
@@ -35,8 +36,7 @@ const usage = `usage: fzf [options]
|
||||
-m, --multi Enable multi-select with tab/shift-tab
|
||||
--ansi Enable processing of ANSI color codes
|
||||
--no-mouse Disable mouse
|
||||
--color=COL Color scheme; [dark|light|16|bw]
|
||||
(default: dark on 256-color terminal, otherwise 16)
|
||||
--color=COLSPEC Base scheme (dark|light|16|bw) and/or custom colors
|
||||
--black Use black background
|
||||
--reverse Reverse orientation
|
||||
--no-hscroll Disable horizontal scroll
|
||||
@@ -121,14 +121,14 @@ type Options struct {
|
||||
Version bool
|
||||
}
|
||||
|
||||
func defaultOptions() *Options {
|
||||
var defaultTheme *curses.ColorTheme
|
||||
func defaultTheme() *curses.ColorTheme {
|
||||
if strings.Contains(os.Getenv("TERM"), "256") {
|
||||
defaultTheme = curses.Dark256
|
||||
} else {
|
||||
defaultTheme = curses.Default16
|
||||
return curses.Dark256
|
||||
}
|
||||
return curses.Default16
|
||||
}
|
||||
|
||||
func defaultOptions() *Options {
|
||||
return &Options{
|
||||
Mode: ModeFuzzy,
|
||||
Case: CaseSmart,
|
||||
@@ -141,7 +141,7 @@ func defaultOptions() *Options {
|
||||
Multi: false,
|
||||
Ansi: false,
|
||||
Mouse: true,
|
||||
Theme: defaultTheme,
|
||||
Theme: defaultTheme(),
|
||||
Black: false,
|
||||
Reverse: false,
|
||||
Hscroll: true,
|
||||
@@ -187,6 +187,14 @@ func nextString(args []string, i *int, message string) string {
|
||||
return args[*i]
|
||||
}
|
||||
|
||||
func optionalNextString(args []string, i *int) string {
|
||||
if len(args) > *i+1 {
|
||||
*i++
|
||||
return args[*i]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func optionalNumeric(args []string, i *int) int {
|
||||
if len(args) > *i+1 {
|
||||
if strings.IndexAny(args[*i+1], "0123456789") == 0 {
|
||||
@@ -277,20 +285,72 @@ func parseTiebreak(str string) tiebreak {
|
||||
return byLength
|
||||
}
|
||||
|
||||
func parseTheme(str string) *curses.ColorTheme {
|
||||
switch strings.ToLower(str) {
|
||||
case "dark":
|
||||
return curses.Dark256
|
||||
case "light":
|
||||
return curses.Light256
|
||||
case "16":
|
||||
return curses.Default16
|
||||
case "bw", "no":
|
||||
return nil
|
||||
default:
|
||||
errorExit("invalid color scheme: " + str)
|
||||
func dupeTheme(theme *curses.ColorTheme) *curses.ColorTheme {
|
||||
dupe := *theme
|
||||
return &dupe
|
||||
}
|
||||
|
||||
func parseTheme(defaultTheme *curses.ColorTheme, str string) *curses.ColorTheme {
|
||||
theme := dupeTheme(defaultTheme)
|
||||
for _, str := range strings.Split(strings.ToLower(str), ",") {
|
||||
switch str {
|
||||
case "dark":
|
||||
theme = dupeTheme(curses.Dark256)
|
||||
case "light":
|
||||
theme = dupeTheme(curses.Light256)
|
||||
case "16":
|
||||
theme = dupeTheme(curses.Default16)
|
||||
case "bw", "no":
|
||||
theme = nil
|
||||
default:
|
||||
fail := func() {
|
||||
errorExit("invalid color specification: " + str)
|
||||
}
|
||||
// Color is disabled
|
||||
if theme == nil {
|
||||
errorExit("colors disabled; cannot customize colors")
|
||||
}
|
||||
|
||||
pair := strings.Split(str, ":")
|
||||
if len(pair) != 2 {
|
||||
fail()
|
||||
}
|
||||
ansi32, err := strconv.Atoi(pair[1])
|
||||
if err != nil || ansi32 < -1 || ansi32 > 255 {
|
||||
fail()
|
||||
}
|
||||
ansi := int16(ansi32)
|
||||
switch pair[0] {
|
||||
case "fg":
|
||||
theme.Fg = ansi
|
||||
theme.UseDefault = theme.UseDefault && ansi < 0
|
||||
case "bg":
|
||||
theme.Bg = ansi
|
||||
theme.UseDefault = theme.UseDefault && ansi < 0
|
||||
case "fg+":
|
||||
theme.Current = ansi
|
||||
case "bg+":
|
||||
theme.DarkBg = ansi
|
||||
case "hl":
|
||||
theme.Match = ansi
|
||||
case "hl+":
|
||||
theme.CurrentMatch = ansi
|
||||
case "prompt":
|
||||
theme.Prompt = ansi
|
||||
case "spinner":
|
||||
theme.Spinner = ansi
|
||||
case "info":
|
||||
theme.Info = ansi
|
||||
case "pointer":
|
||||
theme.Cursor = ansi
|
||||
case "marker":
|
||||
theme.Selected = ansi
|
||||
default:
|
||||
fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return theme
|
||||
}
|
||||
|
||||
func parseKeymap(keymap map[int]actionType, toggleSort bool, str string) (map[int]actionType, bool) {
|
||||
@@ -400,7 +460,12 @@ func parseOptions(opts *Options, allArgs []string) {
|
||||
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"))
|
||||
spec := optionalNextString(allArgs, &i)
|
||||
if len(spec) == 0 {
|
||||
opts.Theme = defaultTheme()
|
||||
} else {
|
||||
opts.Theme = parseTheme(opts.Theme, spec)
|
||||
}
|
||||
case "--toggle-sort":
|
||||
opts.Keymap = checkToggleSort(opts.Keymap, nextString(allArgs, &i, "key name required"))
|
||||
opts.ToggleSort = true
|
||||
@@ -497,7 +562,7 @@ func parseOptions(opts *Options, allArgs []string) {
|
||||
} else if match, value := optString(arg, "--tiebreak="); match {
|
||||
opts.Tiebreak = parseTiebreak(value)
|
||||
} else if match, value := optString(arg, "--color="); match {
|
||||
opts.Theme = parseTheme(value)
|
||||
opts.Theme = parseTheme(opts.Theme, value)
|
||||
} else if match, value := optString(arg, "--bind="); match {
|
||||
opts.Keymap, opts.ToggleSort = parseKeymap(opts.Keymap, opts.ToggleSort, value)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user