mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2025-01-11 18:38:45 +00:00
parent
cfdb00b971
commit
0a8d2996dc
@ -113,7 +113,8 @@ const (
|
|||||||
|
|
||||||
// Pallete
|
// Pallete
|
||||||
const (
|
const (
|
||||||
ColNormal = iota
|
_ = iota
|
||||||
|
ColNormal
|
||||||
ColPrompt
|
ColPrompt
|
||||||
ColMatch
|
ColMatch
|
||||||
ColCurrent
|
ColCurrent
|
||||||
@ -134,7 +135,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ColorTheme struct {
|
type ColorTheme struct {
|
||||||
UseDefault bool
|
|
||||||
Fg int16
|
Fg int16
|
||||||
Bg int16
|
Bg int16
|
||||||
DarkBg int16
|
DarkBg int16
|
||||||
@ -168,7 +168,8 @@ type MouseEvent struct {
|
|||||||
var (
|
var (
|
||||||
_buf []byte
|
_buf []byte
|
||||||
_in *os.File
|
_in *os.File
|
||||||
_color func(int, Attr) C.int
|
_color bool
|
||||||
|
_colorFn func(int, Attr) C.int
|
||||||
_colorMap map[int]int
|
_colorMap map[int]int
|
||||||
_prevDownTime time.Time
|
_prevDownTime time.Time
|
||||||
_clickY []int
|
_clickY []int
|
||||||
@ -176,10 +177,6 @@ var (
|
|||||||
Default16 *ColorTheme
|
Default16 *ColorTheme
|
||||||
Dark256 *ColorTheme
|
Dark256 *ColorTheme
|
||||||
Light256 *ColorTheme
|
Light256 *ColorTheme
|
||||||
FG int
|
|
||||||
CurrentFG int
|
|
||||||
BG int
|
|
||||||
DarkBG int
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Window struct {
|
type Window struct {
|
||||||
@ -192,12 +189,16 @@ type Window struct {
|
|||||||
|
|
||||||
func NewWindow(top int, left int, width int, height int, border bool) *Window {
|
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))
|
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 {
|
if border {
|
||||||
attr := _color(ColBorder, 0)
|
attr := _colorFn(ColBorder, 0)
|
||||||
C.wattron(win, attr)
|
C.wattron(win, attr)
|
||||||
C.box(win, 0, 0)
|
C.box(win, 0, 0)
|
||||||
C.wattroff(win, attr)
|
C.wattroff(win, attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Window{
|
return &Window{
|
||||||
win: win,
|
win: win,
|
||||||
Top: top,
|
Top: top,
|
||||||
@ -209,7 +210,6 @@ func NewWindow(top int, left int, width int, height int, border bool) *Window {
|
|||||||
|
|
||||||
func EmptyTheme() *ColorTheme {
|
func EmptyTheme() *ColorTheme {
|
||||||
return &ColorTheme{
|
return &ColorTheme{
|
||||||
UseDefault: true,
|
|
||||||
Fg: colUndefined,
|
Fg: colUndefined,
|
||||||
Bg: colUndefined,
|
Bg: colUndefined,
|
||||||
DarkBg: colUndefined,
|
DarkBg: colUndefined,
|
||||||
@ -230,9 +230,8 @@ func init() {
|
|||||||
_clickY = []int{}
|
_clickY = []int{}
|
||||||
_colorMap = make(map[int]int)
|
_colorMap = make(map[int]int)
|
||||||
Default16 = &ColorTheme{
|
Default16 = &ColorTheme{
|
||||||
UseDefault: true,
|
Fg: colDefault,
|
||||||
Fg: 15,
|
Bg: colDefault,
|
||||||
Bg: 0,
|
|
||||||
DarkBg: C.COLOR_BLACK,
|
DarkBg: C.COLOR_BLACK,
|
||||||
Prompt: C.COLOR_BLUE,
|
Prompt: C.COLOR_BLUE,
|
||||||
Match: C.COLOR_GREEN,
|
Match: C.COLOR_GREEN,
|
||||||
@ -245,9 +244,8 @@ func init() {
|
|||||||
Header: C.COLOR_CYAN,
|
Header: C.COLOR_CYAN,
|
||||||
Border: C.COLOR_BLACK}
|
Border: C.COLOR_BLACK}
|
||||||
Dark256 = &ColorTheme{
|
Dark256 = &ColorTheme{
|
||||||
UseDefault: true,
|
Fg: colDefault,
|
||||||
Fg: 15,
|
Bg: colDefault,
|
||||||
Bg: 0,
|
|
||||||
DarkBg: 236,
|
DarkBg: 236,
|
||||||
Prompt: 110,
|
Prompt: 110,
|
||||||
Match: 108,
|
Match: 108,
|
||||||
@ -260,9 +258,8 @@ func init() {
|
|||||||
Header: 109,
|
Header: 109,
|
||||||
Border: 59}
|
Border: 59}
|
||||||
Light256 = &ColorTheme{
|
Light256 = &ColorTheme{
|
||||||
UseDefault: true,
|
Fg: colDefault,
|
||||||
Fg: 15,
|
Bg: colDefault,
|
||||||
Bg: 0,
|
|
||||||
DarkBg: 251,
|
DarkBg: 251,
|
||||||
Prompt: 25,
|
Prompt: 25,
|
||||||
Match: 66,
|
Match: 66,
|
||||||
@ -278,7 +275,7 @@ func init() {
|
|||||||
|
|
||||||
func attrColored(pair int, a Attr) C.int {
|
func attrColored(pair int, a Attr) C.int {
|
||||||
var attr C.int
|
var attr C.int
|
||||||
if pair > ColNormal {
|
if pair > 0 {
|
||||||
attr = C.COLOR_PAIR(C.int(pair))
|
attr = C.COLOR_PAIR(C.int(pair))
|
||||||
}
|
}
|
||||||
return attr | C.int(a)
|
return attr | C.int(a)
|
||||||
@ -344,7 +341,8 @@ func Init(theme *ColorTheme, black bool, mouse bool) {
|
|||||||
C.noecho()
|
C.noecho()
|
||||||
C.raw() // stty dsusp undef
|
C.raw() // stty dsusp undef
|
||||||
|
|
||||||
if theme != nil {
|
_color = theme != nil
|
||||||
|
if _color {
|
||||||
C.start_color()
|
C.start_color()
|
||||||
var baseTheme *ColorTheme
|
var baseTheme *ColorTheme
|
||||||
if C.tigetnum(C.CString("colors")) >= 256 {
|
if C.tigetnum(C.CString("colors")) >= 256 {
|
||||||
@ -353,52 +351,57 @@ func Init(theme *ColorTheme, black bool, mouse bool) {
|
|||||||
baseTheme = Default16
|
baseTheme = Default16
|
||||||
}
|
}
|
||||||
initPairs(baseTheme, theme, black)
|
initPairs(baseTheme, theme, black)
|
||||||
_color = attrColored
|
C.bkgd(C.chtype(C.COLOR_PAIR(ColNormal)))
|
||||||
|
_colorFn = attrColored
|
||||||
} else {
|
} else {
|
||||||
_color = attrMono
|
_colorFn = attrMono
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func override(a int16, b int16) C.short {
|
func override(baseTheme *ColorTheme, theme *ColorTheme) {
|
||||||
if b == colUndefined {
|
o := func(a int16, b int16) int16 {
|
||||||
return C.short(a)
|
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) {
|
func initPairs(baseTheme *ColorTheme, theme *ColorTheme, black bool) {
|
||||||
fg := override(baseTheme.Fg, theme.Fg)
|
|
||||||
bg := override(baseTheme.Bg, theme.Bg)
|
|
||||||
if black {
|
if black {
|
||||||
bg = C.COLOR_BLACK
|
theme.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))
|
|
||||||
}
|
}
|
||||||
|
// Updates theme
|
||||||
|
override(baseTheme, theme)
|
||||||
|
|
||||||
currentFG := override(baseTheme.Current, theme.Current)
|
C.assume_default_colors(C.int(theme.Fg), C.int(theme.Bg))
|
||||||
darkBG := override(baseTheme.DarkBg, theme.DarkBg)
|
initPair := func(group C.short, fg int16, bg int16) {
|
||||||
CurrentFG = int(currentFG)
|
C.init_pair(group, C.short(fg), C.short(bg))
|
||||||
DarkBG = int(darkBG)
|
}
|
||||||
C.init_pair(ColPrompt, override(baseTheme.Prompt, theme.Prompt), bg)
|
initPair(ColNormal, theme.Fg, theme.Bg)
|
||||||
C.init_pair(ColMatch, override(baseTheme.Match, theme.Match), bg)
|
initPair(ColPrompt, theme.Prompt, theme.Bg)
|
||||||
C.init_pair(ColCurrent, currentFG, darkBG)
|
initPair(ColMatch, theme.Match, theme.Bg)
|
||||||
C.init_pair(ColCurrentMatch, override(baseTheme.CurrentMatch, theme.CurrentMatch), darkBG)
|
initPair(ColCurrent, theme.Current, theme.DarkBg)
|
||||||
C.init_pair(ColSpinner, override(baseTheme.Spinner, theme.Spinner), bg)
|
initPair(ColCurrentMatch, theme.CurrentMatch, theme.DarkBg)
|
||||||
C.init_pair(ColInfo, override(baseTheme.Info, theme.Info), bg)
|
initPair(ColSpinner, theme.Spinner, theme.Bg)
|
||||||
C.init_pair(ColCursor, override(baseTheme.Cursor, theme.Cursor), darkBG)
|
initPair(ColInfo, theme.Info, theme.Bg)
|
||||||
C.init_pair(ColSelected, override(baseTheme.Selected, theme.Selected), darkBG)
|
initPair(ColCursor, theme.Cursor, theme.DarkBg)
|
||||||
C.init_pair(ColHeader, override(baseTheme.Header, theme.Header), bg)
|
initPair(ColSelected, theme.Selected, theme.DarkBg)
|
||||||
C.init_pair(ColBorder, override(baseTheme.Border, theme.Border), bg)
|
initPair(ColHeader, theme.Header, theme.Bg)
|
||||||
|
initPair(ColBorder, theme.Border, theme.Bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Close() {
|
func Close() {
|
||||||
@ -656,7 +659,7 @@ func (w *Window) Print(text string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) CPrint(pair int, a Attr, 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)
|
C.wattron(w.win, attr)
|
||||||
w.Print(text)
|
w.Print(text)
|
||||||
C.wattroff(w.win, attr)
|
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 {
|
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)
|
C.wattron(w.win, attr)
|
||||||
ret := w.Fill(str)
|
ret := w.Fill(str)
|
||||||
C.wattroff(w.win, attr)
|
C.wattroff(w.win, attr)
|
||||||
|
@ -499,10 +499,8 @@ func parseTheme(defaultTheme *curses.ColorTheme, str string) *curses.ColorTheme
|
|||||||
switch pair[0] {
|
switch pair[0] {
|
||||||
case "fg":
|
case "fg":
|
||||||
theme.Fg = ansi
|
theme.Fg = ansi
|
||||||
theme.UseDefault = theme.UseDefault && ansi < 0
|
|
||||||
case "bg":
|
case "bg":
|
||||||
theme.Bg = ansi
|
theme.Bg = ansi
|
||||||
theme.UseDefault = theme.UseDefault && ansi < 0
|
|
||||||
case "fg+":
|
case "fg+":
|
||||||
theme.Current = ansi
|
theme.Current = ansi
|
||||||
case "bg+":
|
case "bg+":
|
||||||
|
@ -299,20 +299,14 @@ func TestColorSpec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
customized.Fg = curses.Dark256.Fg
|
customized.Fg = curses.Dark256.Fg
|
||||||
customized.Bg = curses.Dark256.Bg
|
customized.Bg = curses.Dark256.Bg
|
||||||
if *curses.Dark256 == *customized {
|
if *curses.Dark256 != *customized {
|
||||||
t.Errorf("colors should now be equivalent")
|
t.Errorf("colors should now be equivalent: %v, %v", curses.Dark256, customized)
|
||||||
}
|
}
|
||||||
|
|
||||||
customized = parseTheme(theme, "fg:231,dark,bg:232")
|
customized = parseTheme(theme, "fg:231,dark,bg:232")
|
||||||
if customized.Fg != curses.Dark256.Fg || customized.Bg == curses.Dark256.Bg {
|
if customized.Fg != curses.Dark256.Fg || customized.Bg == curses.Dark256.Bg {
|
||||||
t.Errorf("color not customized")
|
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) {
|
func TestParseNilTheme(t *testing.T) {
|
||||||
|
@ -92,13 +92,13 @@ func minRank() rank {
|
|||||||
return rank{index: 0, points: [4]uint16{math.MaxUint16, 0, 0, 0}}
|
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()
|
itemColors := result.item.Colors()
|
||||||
|
|
||||||
|
// No ANSI code, or --color=no
|
||||||
if len(itemColors) == 0 {
|
if len(itemColors) == 0 {
|
||||||
var offsets []colorOffset
|
var offsets []colorOffset
|
||||||
for _, off := range matchOffsets {
|
for _, off := range matchOffsets {
|
||||||
|
|
||||||
offsets = append(offsets, colorOffset{offset: [2]int32{off[0], off[1]}, color: color, attr: attr})
|
offsets = append(offsets, colorOffset{offset: [2]int32{off[0], off[1]}, color: color, attr: attr})
|
||||||
}
|
}
|
||||||
return offsets
|
return offsets
|
||||||
@ -149,17 +149,17 @@ func (result *Result) colorOffsets(matchOffsets []Offset, color int, attr curses
|
|||||||
fg := ansi.color.fg
|
fg := ansi.color.fg
|
||||||
if fg == -1 {
|
if fg == -1 {
|
||||||
if current {
|
if current {
|
||||||
fg = curses.CurrentFG
|
fg = int(theme.Current)
|
||||||
} else {
|
} else {
|
||||||
fg = curses.FG
|
fg = int(theme.Fg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bg := ansi.color.bg
|
bg := ansi.color.bg
|
||||||
if bg == -1 {
|
if bg == -1 {
|
||||||
if current {
|
if current {
|
||||||
bg = curses.DarkBG
|
bg = int(theme.DarkBg)
|
||||||
} else {
|
} else {
|
||||||
bg = curses.BG
|
bg = int(theme.Bg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
colors = append(colors, colorOffset{
|
colors = append(colors, colorOffset{
|
||||||
|
@ -103,7 +103,7 @@ func TestColorOffset(t *testing.T) {
|
|||||||
ansiOffset{[2]int32{33, 40}, ansiState{4, 8, curses.Bold}}}}}
|
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}]
|
// [{[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) {
|
assert := func(idx int, b int32, e int32, c int, bold bool) {
|
||||||
var attr curses.Attr
|
var attr curses.Attr
|
||||||
if bold {
|
if bold {
|
||||||
|
@ -90,6 +90,7 @@ type Terminal struct {
|
|||||||
suppress bool
|
suppress bool
|
||||||
startChan chan bool
|
startChan chan bool
|
||||||
slab *util.Slab
|
slab *util.Slab
|
||||||
|
theme *C.ColorTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
type selectedItem struct {
|
type selectedItem struct {
|
||||||
@ -295,6 +296,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
|||||||
mutex: sync.Mutex{},
|
mutex: sync.Mutex{},
|
||||||
suppress: true,
|
suppress: true,
|
||||||
slab: util.MakeSlab(slab16Size, slab32Size),
|
slab: util.MakeSlab(slab16Size, slab32Size),
|
||||||
|
theme: opts.Theme,
|
||||||
startChan: make(chan bool, 1),
|
startChan: make(chan bool, 1),
|
||||||
initFunc: func() {
|
initFunc: func() {
|
||||||
C.Init(opts.Theme, opts.Black, opts.Mouse)
|
C.Init(opts.Theme, opts.Black, opts.Mouse)
|
||||||
@ -637,7 +639,7 @@ func (t *Terminal) printItem(result *Result, i int, current bool) {
|
|||||||
} else {
|
} else {
|
||||||
t.window.Print(" ")
|
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]))
|
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
|
maxWidth := t.window.Width - 3
|
||||||
maxe = util.Constrain(maxe+util.Min(maxWidth/2-2, t.hscrollOff), 0, len(text))
|
maxe = util.Constrain(maxe+util.Min(maxWidth/2-2, t.hscrollOff), 0, len(text))
|
||||||
if overflow(text, maxWidth) {
|
if overflow(text, maxWidth) {
|
||||||
|
Loading…
Reference in New Issue
Block a user