m/fzf
1
0
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:
Junegunn Choi
2015-05-31 16:46:54 +09:00
parent 446e822723
commit fdbfe36c0b
5 changed files with 257 additions and 90 deletions

View File

@@ -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 {