summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2016-10-21 19:35:59 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2016-10-21 19:35:59 +0900
commit0a8d2996dcb3cd3ebf55b783b08667fa3740433b (patch)
tree62b1268f394dfd5bed28398fbd3ca379b8c87953
parentcfdb00b9718822b6ab2018a47288d5be3a32d07c (diff)
Set foreground color without affecting background
Close #712
-rw-r--r--src/curses/curses.go117
-rw-r--r--src/options.go2
-rw-r--r--src/options_test.go10
-rw-r--r--src/result.go12
-rw-r--r--src/result_test.go2
-rw-r--r--src/terminal.go6
6 files changed, 73 insertions, 76 deletions
diff --git a/src/curses/curses.go b/src/curses/curses.go
index 700e6670..638a8629 100644
--- a/src/curses/curses.go
+++ b/src/curses/curses.go
@@ -113,7 +113,8 @@ const (
// Pallete
const (
- ColNormal = iota
+ _ = iota
+ ColNormal
ColPrompt
ColMatch
ColCurrent
@@ -134,7 +135,6 @@ const (
)
type ColorTheme struct {
- UseDefault bool
Fg int16
Bg int16
DarkBg int16
@@ -168,7 +168,8 @@ type MouseEvent struct {
var (
_buf []byte
_in *os.File
- _color func(int, Attr) C.int
+ _color bool
+ _colorFn func(int, Attr) C.int
_colorMap map[int]int
_prevDownTime time.Time
_clickY []int
@@ -176,10 +177,6 @@ var (
Default16 *ColorTheme
Dark256 *ColorTheme
Light256 *ColorTheme
- FG int
- CurrentFG int
- BG int
- DarkBG int
)
type Window struct {
@@ -192,12 +189,16 @@ type Window struct {
func NewWindow(top int, left int, width int, height int, border bool) *Window {
win := C.newwin(C.int(height), C.int(width), C.int(top), C.int(left))
+ if _color {
+ C.wbkgd(win, C.chtype(C.COLOR_PAIR(ColNormal)))
+ }
if border {
- attr := _color(ColBorder, 0)
+ attr := _colorFn(ColBorder, 0)
C.wattron(win, attr)
C.box(win, 0, 0)
C.wattroff(win, attr)
}
+
return &Window{
win: win,
Top: top,
@@ -209,7 +210,6 @@ func NewWindow(top int, left int, width int, height int, border bool) *Window {
func EmptyTheme() *ColorTheme {
return &ColorTheme{
- UseDefault: true,
Fg: colUndefined,
Bg: colUndefined,
DarkBg: colUndefined,
@@ -230,9 +230,8 @@ func init() {
_clickY = []int{}
_colorMap = make(map[int]int)
Default16 = &ColorTheme{
- UseDefault: true,
- Fg: 15,
- Bg: 0,
+ Fg: colDefault,
+ Bg: colDefault,
DarkBg: C.COLOR_BLACK,
Prompt: C.COLOR_BLUE,
Match: C.COLOR_GREEN,
@@ -245,9 +244,8 @@ func init() {
Header: C.COLOR_CYAN,
Border: C.COLOR_BLACK}
Dark256 = &ColorTheme{
- UseDefault: true,
- Fg: 15,
- Bg: 0,
+ Fg: colDefault,
+ Bg: colDefault,
DarkBg: 236,
Prompt: 110,
Match: 108,
@@ -260,9 +258,8 @@ func init() {
Header: 109,
Border: 59}
Light256 = &ColorTheme{
- UseDefault: true,
- Fg: 15,
- Bg: 0,
+ Fg: colDefault,
+ Bg: colDefault,
DarkBg: 251,
Prompt: 25,
Match: 66,
@@ -278,7 +275,7 @@ func init() {
func attrColored(pair int, a Attr) C.int {
var attr C.int
- if pair > ColNormal {
+ if pair > 0 {
attr = C.COLOR_PAIR(C.int(pair))
}
return attr | C.int(a)
@@ -344,7 +341,8 @@ func Init(theme *ColorTheme, black bool, mouse bool) {
C.noecho()
C.raw() // stty dsusp undef
- if theme != nil {
+ _color = theme != nil
+ if _color {
C.start_color()
var baseTheme *ColorTheme
if C.tigetnum(C.CString("colors")) >= 256 {
@@ -353,52 +351,57 @@ func Init(theme *ColorTheme, black bool, mouse bool) {
baseTheme = Default16
}
initPairs(baseTheme, theme, black)
- _color = attrColored
+ C.bkgd(C.chtype(C.COLOR_PAIR(ColNormal)))
+ _colorFn = attrColored
} else {
- _color = attrMono
+ _colorFn = attrMono
}
}
-func override(a int16, b int16) C.short {
- if b == colUndefined {
- return C.short(a)
+func override(baseTheme *ColorTheme, theme *ColorTheme) {
+ o := func(a int16, b int16) int16 {
+ if b == colUndefined {
+ return a
+ }
+ return b
}
- return C.short(b)
+ theme.Fg = o(baseTheme.Fg, theme.Fg)
+ theme.Bg = o(baseTheme.Bg, theme.Bg)
+ theme.DarkBg = o(baseTheme.DarkBg, theme.DarkBg)
+ theme.Prompt = o(baseTheme.Prompt, theme.Prompt)
+ theme.Match = o(baseTheme.Match, theme.Match)
+ theme.Current = o(baseTheme.Current, theme.Current)
+ theme.CurrentMatch = o(baseTheme.CurrentMatch, theme.CurrentMatch)
+ theme.Spinner = o(baseTheme.Spinner, theme.Spinner)
+ theme.Info = o(baseTheme.Info, theme.Info)
+ theme.Cursor = o(baseTheme.Cursor, theme.Cursor)
+ theme.Selected = o(baseTheme.Selected, theme.Selected)
+ theme.Header = o(baseTheme.Header, theme.Header)
+ theme.Border = o(baseTheme.Border, theme.Border)
}
func initPairs(baseTheme *ColorTheme, theme *ColorTheme, black bool) {
- fg := override(baseTheme.Fg, theme.Fg)
- bg := override(baseTheme.Bg, theme.Bg)
if black {
- bg = C.COLOR_BLACK
- } else if theme.UseDefault {
- fg = colDefault
- bg = colDefault
- C.use_default_colors()
- }
- if theme.UseDefault {
- FG = colDefault
- BG = colDefault
- } else {
- FG = int(fg)
- BG = int(bg)
- C.assume_default_colors(C.int(override(baseTheme.Fg, theme.Fg)), C.int(bg))
+ theme.Bg = C.COLOR_BLACK
}
+ // Updates theme
+ override(baseTheme, theme)
- currentFG := override(baseTheme.Current, theme.Current)
- darkBG := override(baseTheme.DarkBg, theme.DarkBg)
- CurrentFG = int(currentFG)
- DarkBG = int(darkBG)
- C.init_pair(ColPrompt, override(baseTheme.Prompt, theme.Prompt), bg)
- C.init_pair(ColMatch, override(baseTheme.Match, theme.Match), bg)
- C.init_pair(ColCurrent, currentFG, darkBG)
- C.init_pair(ColCurrentMatch, override(baseTheme.CurrentMatch, theme.CurrentMatch), darkBG)
- C.init_pair(ColSpinner, override(baseTheme.Spinner, theme.Spinner), bg)
- C.init_pair(ColInfo, override(baseTheme.Info, theme.Info), bg)
- C.init_pair(ColCursor, override(baseTheme.Cursor, theme.Cursor), darkBG)
- C.init_pair(ColSelected, override(baseTheme.Selected, theme.Selected), darkBG)
- C.init_pair(ColHeader, override(baseTheme.Header, theme.Header), bg)
- C.init_pair(ColBorder, override(baseTheme.Border, theme.Border), bg)
+ C.assume_default_colors(C.int(theme.Fg), C.int(theme.Bg))
+ initPair := func(group C.short, fg int16, bg int16) {
+ C.init_pair(group, C.short(fg), C.short(bg))
+ }
+ initPair(ColNormal, theme.Fg, theme.Bg)
+ initPair(ColPrompt, theme.Prompt, theme.Bg)
+ initPair(ColMatch, theme.Match, theme.Bg)
+ initPair(ColCurrent, theme.Current, theme.DarkBg)
+ initPair(ColCurrentMatch, theme.CurrentMatch, theme.DarkBg)
+ initPair(ColSpinner, theme.Spinner, theme.Bg)
+ initPair(ColInfo, theme.Info, theme.Bg)
+ initPair(ColCursor, theme.Cursor, theme.DarkBg)
+ initPair(ColSelected, theme.Selected, theme.DarkBg)
+ initPair(ColHeader, theme.Header, theme.Bg)
+ initPair(ColBorder, theme.Border, theme.Bg)
}
func Close() {
@@ -656,7 +659,7 @@ func (w *Window) Print(text string) {
}
func (w *Window) CPrint(pair int, a Attr, text string) {
- attr := _color(pair, a)
+ attr := _colorFn(pair, a)
C.wattron(w.win, attr)
w.Print(text)
C.wattroff(w.win, attr)
@@ -683,7 +686,7 @@ func (w *Window) Fill(str string) bool {
}
func (w *Window) CFill(str string, fg int, bg int, a Attr) bool {
- attr := _color(PairFor(fg, bg), a)
+ attr := _colorFn(PairFor(fg, bg), a)
C.wattron(w.win, attr)
ret := w.Fill(str)
C.wattroff(w.win, attr)
diff --git a/src/options.go b/src/options.go
index a7f01887..c5e6d7b7 100644
--- a/src/options.go
+++ b/src/options.go
@@ -499,10 +499,8 @@ func parseTheme(defaultTheme *curses.ColorTheme, str string) *curses.ColorTheme
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+":
diff --git a/src/options_test.go b/src/options_test.go
index cc4d07c5..60136173 100644
--- a/src/options_test.go
+++ b/src/options_test.go
@@ -299,20 +299,14 @@ func TestColorSpec(t *testing.T) {
}
customized.Fg = curses.Dark256.Fg
customized.Bg = curses.Dark256.Bg
- if *curses.Dark256 == *customized {
- t.Errorf("colors should now be equivalent")
+ if *curses.Dark256 != *customized {
+ t.Errorf("colors should now be equivalent: %v, %v", curses.Dark256, customized)
}
customized = parseTheme(theme, "fg:231,dark,bg:232")
if customized.Fg != curses.Dark256.Fg || customized.Bg == curses.Dark256.Bg {
t.Errorf("color not customized")
}
- if customized.UseDefault {
- t.Errorf("not using default colors")
- }
- if !curses.Dark256.UseDefault {
- t.Errorf("using default colors")
- }
}
func TestParseNilTheme(t *testing.T) {
diff --git a/src/result.go b/src/result.go
index 347cf599..69e83f85 100644
--- a/src/result.go
+++ b/src/result.go
@@ -92,13 +92,13 @@ func minRank() rank {
return rank{index: 0, points: [4]uint16{math.MaxUint16, 0, 0, 0}}
}
-func (result *Result) colorOffsets(matchOffsets []Offset, color int, attr curses.Attr, current bool) []colorOffset {
+func (result *Result) colorOffsets(matchOffsets []Offset, theme *curses.ColorTheme, color int, attr curses.Attr, current bool) []colorOffset {
itemColors := result.item.Colors()
+ // No ANSI code, or --color=no
if len(itemColors) == 0 {
var offsets []colorOffset
for _, off := range matchOffsets {
-
offsets = append(offsets, colorOffset{offset: [2]int32{off[0], off[1]}, color: color, attr: attr})
}
return offsets
@@ -149,17 +149,17 @@ func (result *Result) colorOffsets(matchOffsets []Offset, color int, attr curses
fg := ansi.color.fg
if fg == -1 {
if current {
- fg = curses.CurrentFG
+ fg = int(theme.Current)
} else {
- fg = curses.FG
+ fg = int(theme.Fg)
}
}
bg := ansi.color.bg
if bg == -1 {
if current {
- bg = curses.DarkBG
+ bg = int(theme.DarkBg)
} else {
- bg = curses.BG
+ bg = int(theme.Bg)
}
}
colors = append(colors, colorOffset{
diff --git a/src/result_test.go b/src/result_test.go
index 46c20fd9..645684dd 100644
--- a/src/result_test.go
+++ b/src/result_test.go
@@ -103,7 +103,7 @@ func TestColorOffset(t *testing.T) {
ansiOffset{[2]int32{33, 40}, ansiState{4, 8, curses.Bold}}}}}
// [{[0 5] 9 false} {[5 15] 99 false} {[15 20] 9 false} {[22 25] 10 true} {[25 35] 99 false} {[35 40] 11 true}]
- colors := item.colorOffsets(offsets, 99, 0, true)
+ colors := item.colorOffsets(offsets, curses.Dark256, 99, 0, true)
assert := func(idx int, b int32, e int32, c int, bold bool) {
var attr curses.Attr
if bold {
diff --git a/src/terminal.go b/src/terminal.go
index e07eb3ce..2abe62ee 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -90,6 +90,7 @@ type Terminal struct {
suppress bool
startChan chan bool
slab *util.Slab
+ theme *C.ColorTheme
}
type selectedItem struct {
@@ -295,6 +296,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
mutex: sync.Mutex{},
suppress: true,
slab: util.MakeSlab(slab16Size, slab32Size),
+ theme: opts.Theme,
startChan: make(chan bool, 1),
initFunc: func() {
C.Init(opts.Theme, opts.Black, opts.Mouse)
@@ -637,7 +639,7 @@ func (t *Terminal) printItem(result *Result, i int, current bool) {
} else {
t.window.Print(" ")
}
- t.printHighlighted(result, 0, 0, C.ColMatch, false)
+ t.printHighlighted(result, 0, C.ColNormal, C.ColMatch, false)
}
}
@@ -718,7 +720,7 @@ func (t *Terminal) printHighlighted(result *Result, attr C.Attr, col1 int, col2
maxe = util.Max(maxe, int(offset[1]))
}
- offsets := result.colorOffsets(charOffsets, col2, attr, current)
+ offsets := result.colorOffsets(charOffsets, t.theme, col2, attr, current)
maxWidth := t.window.Width - 3
maxe = util.Constrain(maxe+util.Min(maxWidth/2-2, t.hscrollOff), 0, len(text))
if overflow(text, maxWidth) {