mirror of
https://github.com/rocky-linux/peridot.git
synced 2024-10-19 07:55:07 +00:00
108 lines
2.4 KiB
Go
108 lines
2.4 KiB
Go
|
package decor
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
|
||
|
"github.com/acarl005/stripansi"
|
||
|
"github.com/mattn/go-runewidth"
|
||
|
)
|
||
|
|
||
|
// Merge wraps its decorator argument with intention to sync width
|
||
|
// with several decorators of another bar. Visual example:
|
||
|
//
|
||
|
// +----+--------+---------+--------+
|
||
|
// | B1 | MERGE(D, P1, Pn) |
|
||
|
// +----+--------+---------+--------+
|
||
|
// | B2 | D0 | D1 | Dn |
|
||
|
// +----+--------+---------+--------+
|
||
|
//
|
||
|
func Merge(decorator Decorator, placeholders ...WC) Decorator {
|
||
|
if _, ok := decorator.Sync(); !ok || len(placeholders) == 0 {
|
||
|
return decorator
|
||
|
}
|
||
|
md := &mergeDecorator{
|
||
|
Decorator: decorator,
|
||
|
wc: decorator.GetConf(),
|
||
|
placeHolders: make([]*placeHolderDecorator, len(placeholders)),
|
||
|
}
|
||
|
decorator.SetConf(WC{})
|
||
|
for i, wc := range placeholders {
|
||
|
if (wc.C & DSyncWidth) == 0 {
|
||
|
return decorator
|
||
|
}
|
||
|
md.placeHolders[i] = &placeHolderDecorator{wc.Init()}
|
||
|
}
|
||
|
return md
|
||
|
}
|
||
|
|
||
|
type mergeDecorator struct {
|
||
|
Decorator
|
||
|
wc WC
|
||
|
placeHolders []*placeHolderDecorator
|
||
|
}
|
||
|
|
||
|
func (d *mergeDecorator) GetConf() WC {
|
||
|
return d.wc
|
||
|
}
|
||
|
|
||
|
func (d *mergeDecorator) SetConf(conf WC) {
|
||
|
d.wc = conf.Init()
|
||
|
}
|
||
|
|
||
|
func (d *mergeDecorator) MergeUnwrap() []Decorator {
|
||
|
decorators := make([]Decorator, len(d.placeHolders))
|
||
|
for i, ph := range d.placeHolders {
|
||
|
decorators[i] = ph
|
||
|
}
|
||
|
return decorators
|
||
|
}
|
||
|
|
||
|
func (d *mergeDecorator) Sync() (chan int, bool) {
|
||
|
return d.wc.Sync()
|
||
|
}
|
||
|
|
||
|
func (d *mergeDecorator) Base() Decorator {
|
||
|
return d.Decorator
|
||
|
}
|
||
|
|
||
|
func (d *mergeDecorator) Decor(s Statistics) string {
|
||
|
msg := d.Decorator.Decor(s)
|
||
|
pureWidth := runewidth.StringWidth(msg)
|
||
|
stripWidth := runewidth.StringWidth(stripansi.Strip(msg))
|
||
|
cellCount := stripWidth
|
||
|
if (d.wc.C & DextraSpace) != 0 {
|
||
|
cellCount++
|
||
|
}
|
||
|
|
||
|
total := runewidth.StringWidth(d.placeHolders[0].FormatMsg(""))
|
||
|
pw := (cellCount - total) / len(d.placeHolders)
|
||
|
rem := (cellCount - total) % len(d.placeHolders)
|
||
|
|
||
|
var diff int
|
||
|
for i := 1; i < len(d.placeHolders); i++ {
|
||
|
ph := d.placeHolders[i]
|
||
|
width := pw - diff
|
||
|
if (ph.WC.C & DextraSpace) != 0 {
|
||
|
width--
|
||
|
if width < 0 {
|
||
|
width = 0
|
||
|
}
|
||
|
}
|
||
|
max := runewidth.StringWidth(ph.FormatMsg(strings.Repeat(" ", width)))
|
||
|
total += max
|
||
|
diff = max - pw
|
||
|
}
|
||
|
|
||
|
d.wc.wsync <- pw + rem
|
||
|
max := <-d.wc.wsync
|
||
|
return d.wc.fill(msg, max+total+(pureWidth-stripWidth))
|
||
|
}
|
||
|
|
||
|
type placeHolderDecorator struct {
|
||
|
WC
|
||
|
}
|
||
|
|
||
|
func (d *placeHolderDecorator) Decor(Statistics) string {
|
||
|
return ""
|
||
|
}
|