diff options
| author | Junegunn Choi <junegunn.c@gmail.com> | 2015-04-18 02:52:30 +0900 |
|---|---|---|
| committer | Junegunn Choi <junegunn.c@gmail.com> | 2015-04-18 02:55:17 +0900 |
| commit | f66d94c6b06c58141c40935bfb18a45858cf79da (patch) | |
| tree | bf33ee2c91769984d59d2fd0fb479bdeda5f80a1 /src | |
| parent | 2fe1e28220c543ddbf4e12ee7396e44ee85ad8e0 (diff) | |
| download | fzf-f66d94c6b06c58141c40935bfb18a45858cf79da.tar.gz | |
Add `--color=[dark|light|16|bw]` option
- dark: the current default for 256-color terminal
- light: color scheme for 256-color terminal with light background
- 16: the default color scheme for 16-color terminal (`+2`)
- bw: no colors (`+c`)
Diffstat (limited to 'src')
| -rw-r--r-- | src/core.go | 2 | ||||
| -rw-r--r-- | src/curses/curses.go | 98 | ||||
| -rw-r--r-- | src/options.go | 41 | ||||
| -rw-r--r-- | src/terminal.go | 2 |
4 files changed, 103 insertions, 40 deletions
diff --git a/src/core.go b/src/core.go index 7230cffd..d7a6a0bb 100644 --- a/src/core.go +++ b/src/core.go @@ -68,7 +68,7 @@ func Run(options *Options) { return data, nil } if opts.Ansi { - if opts.Color { + if opts.Theme != nil { ansiProcessor = func(data *string) (*string, []ansiOffset) { return extractColor(data) } diff --git a/src/curses/curses.go b/src/curses/curses.go index 3340a5c3..f3263615 100644 --- a/src/curses/curses.go +++ b/src/curses/curses.go @@ -95,6 +95,18 @@ const ( doubleClickDuration = 500 * time.Millisecond ) +type ColorTheme struct { + darkBg C.short + prompt C.short + match C.short + current C.short + currentMatch C.short + spinner C.short + info C.short + cursor C.short + selected C.short +} + type Event struct { Type int Char rune @@ -117,6 +129,9 @@ var ( _colorMap map[int]int _prevDownTime time.Time _clickY []int + Default16 *ColorTheme + Dark256 *ColorTheme + Light256 *ColorTheme DarkBG C.short ) @@ -124,6 +139,36 @@ func init() { _prevDownTime = time.Unix(0, 0) _clickY = []int{} _colorMap = make(map[int]int) + Default16 = &ColorTheme{ + darkBg: C.COLOR_BLACK, + prompt: C.COLOR_BLUE, + match: C.COLOR_GREEN, + current: C.COLOR_YELLOW, + currentMatch: C.COLOR_GREEN, + spinner: C.COLOR_GREEN, + info: C.COLOR_WHITE, + cursor: C.COLOR_RED, + selected: C.COLOR_MAGENTA} + Dark256 = &ColorTheme{ + darkBg: 236, + prompt: 110, + match: 108, + current: 254, + currentMatch: 151, + spinner: 148, + info: 144, + cursor: 161, + selected: 168} + Light256 = &ColorTheme{ + darkBg: 251, + prompt: 25, + match: 66, + current: 237, + currentMatch: 23, + spinner: 65, + info: 101, + cursor: 161, + selected: 168} } func attrColored(pair int, bold bool) C.int { @@ -173,7 +218,7 @@ func getch(nonblock bool) int { return int(b[0]) } -func Init(color bool, color256 bool, black bool, mouse bool) { +func Init(theme *ColorTheme, black bool, mouse bool) { { in, err := os.OpenFile("/dev/tty", syscall.O_RDONLY, 0) if err != nil { @@ -203,42 +248,35 @@ func Init(color bool, color256 bool, black bool, mouse bool) { os.Exit(1) }() - if color { + if theme != nil { C.start_color() - var bg C.short - if black { - bg = C.COLOR_BLACK - } else { - C.use_default_colors() - bg = -1 - } - if color256 { - DarkBG = 236 - C.init_pair(ColPrompt, 110, bg) - C.init_pair(ColMatch, 108, bg) - C.init_pair(ColCurrent, 254, DarkBG) - C.init_pair(ColCurrentMatch, 151, DarkBG) - C.init_pair(ColSpinner, 148, bg) - C.init_pair(ColInfo, 144, bg) - C.init_pair(ColCursor, 161, DarkBG) - C.init_pair(ColSelected, 168, DarkBG) - } else { - DarkBG = C.COLOR_BLACK - C.init_pair(ColPrompt, C.COLOR_BLUE, bg) - C.init_pair(ColMatch, C.COLOR_GREEN, bg) - C.init_pair(ColCurrent, C.COLOR_YELLOW, DarkBG) - C.init_pair(ColCurrentMatch, C.COLOR_GREEN, DarkBG) - C.init_pair(ColSpinner, C.COLOR_GREEN, bg) - C.init_pair(ColInfo, C.COLOR_WHITE, bg) - C.init_pair(ColCursor, C.COLOR_RED, DarkBG) - C.init_pair(ColSelected, C.COLOR_MAGENTA, DarkBG) - } + initPairs(theme, black) _color = attrColored } else { _color = attrMono } } +func initPairs(theme *ColorTheme, black bool) { + var bg C.short + if black { + bg = C.COLOR_BLACK + } else { + C.use_default_colors() + bg = -1 + } + + DarkBG = theme.darkBg + C.init_pair(ColPrompt, theme.prompt, bg) + C.init_pair(ColMatch, theme.match, bg) + C.init_pair(ColCurrent, theme.current, DarkBG) + C.init_pair(ColCurrentMatch, theme.currentMatch, DarkBG) + C.init_pair(ColSpinner, theme.spinner, bg) + C.init_pair(ColInfo, theme.info, bg) + C.init_pair(ColCursor, theme.cursor, DarkBG) + C.init_pair(ColSelected, theme.selected, DarkBG) +} + func Close() { C.endwin() C.swapOutput() diff --git a/src/options.go b/src/options.go index d13a53b8..173dee91 100644 --- a/src/options.go +++ b/src/options.go @@ -35,8 +35,8 @@ 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 - +c, --no-color Disable colors - +2, --no-256 Disable 256-color + --color=COL Color scheme [dark|light|16|bw] + (default: dark on 256-color terminal, otherwise 16) --black Use black background --reverse Reverse orientation --no-hscroll Disable horizontal scroll @@ -101,8 +101,7 @@ type Options struct { Multi bool Ansi bool Mouse bool - Color bool - Color256 bool + Theme *curses.ColorTheme Black bool Reverse bool Hscroll bool @@ -119,6 +118,13 @@ type Options struct { } func defaultOptions() *Options { + var defaultTheme *curses.ColorTheme + if strings.Contains(os.Getenv("TERM"), "256") { + defaultTheme = curses.Dark256 + } else { + defaultTheme = curses.Default16 + } + return &Options{ Mode: ModeFuzzy, Case: CaseSmart, @@ -131,8 +137,7 @@ func defaultOptions() *Options { Multi: false, Ansi: false, Mouse: true, - Color: true, - Color256: strings.Contains(os.Getenv("TERM"), "256"), + Theme: defaultTheme, Black: false, Reverse: false, Hscroll: true, @@ -266,6 +271,22 @@ 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", "off", "no", "none": + return nil + default: + errorExit("invalid color scheme: " + str) + } + return nil +} + func checkToggleSort(str string) int { keys := parseKeyChords(str, "key name required") if len(keys) != 1 { @@ -295,6 +316,8 @@ 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 "--color": + opts.Theme = parseTheme(nextString(allArgs, &i, "color scheme name required")) case "--toggle-sort": opts.ToggleSort = checkToggleSort(nextString(allArgs, &i, "key name required")) case "-d", "--delimiter": @@ -326,9 +349,9 @@ func parseOptions(opts *Options, allArgs []string) { case "--no-mouse": opts.Mouse = false case "+c", "--no-color": - opts.Color = false + opts.Theme = nil case "+2", "--no-256": - opts.Color256 = false + opts.Theme = curses.Default16 case "--black": opts.Black = true case "--no-black": @@ -384,6 +407,8 @@ func parseOptions(opts *Options, allArgs []string) { 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 { errorExit("unknown option: " + arg) } diff --git a/src/terminal.go b/src/terminal.go index eaec9a3f..959c84d9 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -105,7 +105,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { suppress: true, startChan: make(chan bool, 1), initFunc: func() { - C.Init(opts.Color, opts.Color256, opts.Black, opts.Mouse) + C.Init(opts.Theme, opts.Black, opts.Mouse) }} } |
