Go vet/lint cleanups

This commit is contained in:
Sean E. Russell 2020-04-27 20:33:41 -05:00
parent 1e78e6faa0
commit 285d4d0297
19 changed files with 271 additions and 295 deletions

View File

@ -25,6 +25,7 @@ import (
"github.com/xxxserxxx/gotop/v4/devices" "github.com/xxxserxxx/gotop/v4/devices"
"github.com/xxxserxxx/gotop/v4/layout" "github.com/xxxserxxx/gotop/v4/layout"
"github.com/xxxserxxx/gotop/v4/logging" "github.com/xxxserxxx/gotop/v4/logging"
"github.com/xxxserxxx/gotop/v4/widgets"
w "github.com/xxxserxxx/gotop/v4/widgets" w "github.com/xxxserxxx/gotop/v4/widgets"
) )
@ -38,7 +39,9 @@ const (
) )
var ( var (
Version = "0.0.0" // Version of the program; set during build from git tags
Version = "0.0.0"
// BuildDate when the program was compiled; set during build
BuildDate = "Hadean" BuildDate = "Hadean"
conf gotop.Config conf gotop.Config
help *w.HelpMenu help *w.HelpMenu
@ -104,9 +107,9 @@ func parseArgs(conf *gotop.Config) error {
if *list != "" { if *list != "" {
switch *list { switch *list {
case "layouts": case "layouts":
fmt.Println(LAYOUTS) fmt.Println(_layouts)
case "colorschemes": case "colorschemes":
fmt.Println(COLORSCHEMES) fmt.Println(_colorschemes)
case "paths": case "paths":
fmt.Println("Loadable colorschemes & layouts, and the config file, are searched for, in order:") fmt.Println("Loadable colorschemes & layouts, and the config file, are searched for, in order:")
paths := make([]string, 0) paths := make([]string, 0)
@ -118,7 +121,7 @@ func parseArgs(conf *gotop.Config) error {
case "devices": case "devices":
listDevices() listDevices()
case "keys": case "keys":
fmt.Println(KEYS) fmt.Println(widgets.KEYBINDS)
default: default:
fmt.Printf("Unknown option \"%s\"; try layouts, colorschemes, keys, paths, or devices\n", *list) fmt.Printf("Unknown option \"%s\"; try layouts, colorschemes, keys, paths, or devices\n", *list)
os.Exit(1) os.Exit(1)
@ -391,7 +394,7 @@ func run() int {
} }
return 1 return 1
} }
if err := ui.Init(); err != nil { if err = ui.Init(); err != nil {
stderrLogger.Print(err) stderrLogger.Print(err)
return 1 return 1
} }
@ -481,40 +484,12 @@ func listDevices() {
} }
} }
const KEYS = `Quit: q or <C-c> const _layouts = `Built-in layouts:
Process navigation:
k and <Up>: up
j and <Down>: down
<C-u>: half page up
<C-d>: half page down
<C-b>: full page up
<C-f>: full page down
gg and <Home>: jump to top
G and <End>: jump to bottom
Process actions:
<Tab>: toggle process grouping
dd: kill selected process or group of processes with SIGTERM
d3: kill selected process or group of processes with SIGQUIT
d9: kill selected process or group of processes with SIGKILL
Process sorting
c: CPU
m: Mem
p: PID
Process filtering:
/: start editing filter
(while editing):
<Enter> accept filter
<C-c> and <Escape>: clear filter
CPU and Mem graph scaling:
h: scale in
l: scale out
?: toggles keybind help menu`
const LAYOUTS = `Built-in layouts:
default default
minimal minimal
battery battery
kitchensink` kitchensink`
const COLORSCHEMES = `Built-in colorschemes: const _colorschemes = `Built-in colorschemes:
default default
default-dark (for white background) default-dark (for white background)
solarized solarized

View File

@ -1,6 +1,8 @@
package colorschemes package colorschemes
import ( import (
"github.com/shibukawa/configdir"
"path/filepath"
"reflect" "reflect"
"testing" "testing"
) )
@ -8,8 +10,10 @@ import (
func TestColorRegistry(t *testing.T) { func TestColorRegistry(t *testing.T) {
colors := []string{"default", "default-dark", "solarized", "solarized16-dark", "solarized16-light", "monokai", "vice"} colors := []string{"default", "default-dark", "solarized", "solarized16-dark", "solarized16-light", "monokai", "vice"}
zeroCS := Colorscheme{} zeroCS := Colorscheme{}
cd := configdir.New("", "gotop")
cd.LocalPath, _ = filepath.Abs(".")
for _, cn := range colors { for _, cn := range colors {
c, e := FromName("", cn) c, e := FromName(cd, cn)
if e != nil { if e != nil {
t.Errorf("unexpected error fetching built-in color %s: %s", cn, e) t.Errorf("unexpected error fetching built-in color %s: %s", cn, e)
} }

View File

@ -48,7 +48,7 @@ func NewConfig() Config {
PercpuLoad: true, PercpuLoad: true,
TempScale: widgets.Celsius, TempScale: widgets.Celsius,
Statusbar: false, Statusbar: false,
NetInterface: widgets.NET_INTERFACE_ALL, NetInterface: widgets.NetInterfaceAll,
MaxLogSize: 5000000, MaxLogSize: 5000000,
Layout: "default", Layout: "default",
ExtensionVars: make(map[string]string), ExtensionVars: make(map[string]string),
@ -169,16 +169,16 @@ func load(in io.Reader, conf *Config) error {
return nil return nil
} }
func (c *Config) Write() (string, error) { func (conf *Config) Write() (string, error) {
cfn := "gotop.conf" cfn := "gotop.conf"
ds := c.ConfigDir.QueryFolders(configdir.Global) ds := conf.ConfigDir.QueryFolders(configdir.Global)
if len(ds) == 0 { if len(ds) == 0 {
ds = c.ConfigDir.QueryFolders(configdir.Local) ds = conf.ConfigDir.QueryFolders(configdir.Local)
if len(ds) == 0 { if len(ds) == 0 {
return "", fmt.Errorf("error locating config folders") return "", fmt.Errorf("error locating config folders")
} }
} }
marshalled := marshal(c) marshalled := marshal(conf)
err := ds[0].WriteFile(cfn, marshalled) err := ds[0].WriteFile(cfn, marshalled)
if err != nil { if err != nil {
return "", err return "", err

View File

@ -78,7 +78,6 @@ func RegisterDeviceList(typ string, all func() []string, def func() []string) {
func Devices(domain string, all bool) []string { func Devices(domain string, all bool) []string {
if all { if all {
return _devs[domain] return _devs[domain]
} else {
return _defaults[domain]
} }
return _defaults[domain]
} }

View File

@ -1,4 +1,3 @@
// Copyright 2020 The gotop Authors Licensed under terms of the LICENSE file in this repository.
package layout package layout
import ( import (
@ -165,7 +164,7 @@ func makeWidget(c gotop.Config, widRule widgetRule) interface{} {
dw := widgets.NewDiskWidget() dw := widgets.NewDiskWidget()
w = dw w = dw
case "cpu": case "cpu":
cpu := widgets.NewCpuWidget(c.UpdateInterval, c.GraphHorizontalScale, c.AverageLoad, c.PercpuLoad) cpu := widgets.NewCPUWidget(c.UpdateInterval, c.GraphHorizontalScale, c.AverageLoad, c.PercpuLoad)
assignColors(cpu.Data, c.Colorscheme.CPULines, cpu.LineColors) assignColors(cpu.Data, c.Colorscheme.CPULines, cpu.LineColors)
w = cpu w = cpu
case "mem": case "mem":
@ -228,7 +227,7 @@ func assignColors(data map[string][]float64, colors []int, assign map[string]ui.
func countNumRows(rs [][]widgetRule) int { func countNumRows(rs [][]widgetRule) int {
var ttl int var ttl int
for len(rs) > 0 { for len(rs) > 0 {
ttl += 1 ttl++
line := rs[0] line := rs[0]
h := 1 h := 1
for _, c := range line { for _, c := range line {

View File

@ -111,7 +111,7 @@ func ParseLayout(i io.Reader) layout {
} }
weightTotal += weight weightTotal += weight
} else { } else {
weightTotal += 1 weightTotal++
} }
row = append(row, wr) row = append(row, wr)
} }

View File

@ -17,8 +17,6 @@ func TestLogging(t *testing.T) {
defer os.RemoveAll(path) defer os.RemoveAll(path)
c := gotop.Config{ c := gotop.Config{
MaxLogSize: 300, MaxLogSize: 300,
LogDir: path,
LogFile: "errors.log",
} }
wc, err := New(c) wc, err := New(c)
assert.NoError(t, err) assert.NoError(t, err)
@ -27,7 +25,7 @@ func TestLogging(t *testing.T) {
} }
defer wc.Close() defer wc.Close()
ds := make([]byte, 100) ds := make([]byte, 100)
for i, _ := range ds { for i := range ds {
ds[i] = 'x' ds[i] = 'x'
} }

View File

@ -7,7 +7,6 @@ import (
func ConvertLocalizedString(s string) string { func ConvertLocalizedString(s string) string {
if strings.ContainsAny(s, ",") { if strings.ContainsAny(s, ",") {
return strings.Replace(s, ",", ".", 1) return strings.Replace(s, ",", ".", 1)
} else {
return s
} }
return s
} }

View File

@ -62,7 +62,7 @@ func (b *BatteryWidget) EnableMetric() {
} }
} }
func makeId(i int) string { func makeID(i int) string {
return "Batt" + strconv.Itoa(i) return "Batt" + strconv.Itoa(i)
} }
@ -70,7 +70,7 @@ func (b *BatteryWidget) Scale(i int) {
b.LineGraph.HorizontalScale = i b.LineGraph.HorizontalScale = i
} }
func (self *BatteryWidget) update() { func (b *BatteryWidget) update() {
batteries, err := battery.GetAll() batteries, err := battery.GetAll()
if err != nil { if err != nil {
switch errt := err.(type) { switch errt := err.(type) {
@ -94,13 +94,13 @@ func (self *BatteryWidget) update() {
} }
} }
for i, battery := range batteries { for i, battery := range batteries {
id := makeId(i) id := makeID(i)
perc := battery.Current / battery.Full perc := battery.Current / battery.Full
percentFull := math.Abs(perc) * 100.0 percentFull := math.Abs(perc) * 100.0
self.Data[id] = append(self.Data[id], percentFull) b.Data[id] = append(b.Data[id], percentFull)
self.Labels[id] = fmt.Sprintf("%3.0f%% %.0f/%.0f", percentFull, math.Abs(battery.Current), math.Abs(battery.Full)) b.Labels[id] = fmt.Sprintf("%3.0f%% %.0f/%.0f", percentFull, math.Abs(battery.Current), math.Abs(battery.Full))
if self.metric != nil { if b.metric != nil {
self.metric[i].Set(perc) b.metric[i].Set(perc)
} }
} }
} }

View File

@ -9,16 +9,16 @@ import (
"github.com/distatus/battery" "github.com/distatus/battery"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
. "github.com/xxxserxxx/gotop/v4/termui" "github.com/xxxserxxx/gotop/v4/termui"
) )
type BatteryGauge struct { type BatteryGauge struct {
*Gauge *termui.Gauge
metric prometheus.Gauge metric prometheus.Gauge
} }
func NewBatteryGauge() *BatteryGauge { func NewBatteryGauge() *BatteryGauge {
self := &BatteryGauge{Gauge: NewGauge()} self := &BatteryGauge{Gauge: termui.NewGauge()}
self.Title = " Power Level " self.Title = " Power Level "
self.update() self.update()
@ -56,7 +56,7 @@ func (b *BatteryGauge) EnableMetric() {
} }
} }
func (self *BatteryGauge) update() { func (b *BatteryGauge) update() {
bats, err := battery.GetAll() bats, err := battery.GetAll()
if err != nil { if err != nil {
log.Printf("error setting up batteries: %v", err) log.Printf("error setting up batteries: %v", err)
@ -78,9 +78,9 @@ func (self *BatteryGauge) update() {
} }
tn := (mx - cu) / rate tn := (mx - cu) / rate
d, _ := time.ParseDuration(fmt.Sprintf("%fh", tn)) d, _ := time.ParseDuration(fmt.Sprintf("%fh", tn))
self.Percent = int((cu / mx) * 100.0) b.Percent = int((cu / mx) * 100.0)
self.Label = fmt.Sprintf(charging, self.Percent, d.Truncate(time.Minute)) b.Label = fmt.Sprintf(charging, b.Percent, d.Truncate(time.Minute))
if self.metric != nil { if b.metric != nil {
self.metric.Set(cu / mx) b.metric.Set(cu / mx)
} }
} }

View File

@ -12,11 +12,11 @@ import (
ui "github.com/xxxserxxx/gotop/v4/termui" ui "github.com/xxxserxxx/gotop/v4/termui"
) )
type CpuWidget struct { type CPUWidget struct {
*ui.LineGraph *ui.LineGraph
CpuCount int CPUCount int
ShowAverageLoad bool ShowAverageLoad bool
ShowPerCpuLoad bool ShowPerCPULoad bool
updateInterval time.Duration updateInterval time.Duration
updateLock sync.Mutex updateLock sync.Mutex
metric map[string]prometheus.Gauge metric map[string]prometheus.Gauge
@ -24,20 +24,20 @@ type CpuWidget struct {
var cpuLabels []string var cpuLabels []string
func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverageLoad bool, showPerCpuLoad bool) *CpuWidget { func NewCPUWidget(updateInterval time.Duration, horizontalScale int, showAverageLoad bool, showPerCPULoad bool) *CPUWidget {
self := &CpuWidget{ self := &CPUWidget{
LineGraph: ui.NewLineGraph(), LineGraph: ui.NewLineGraph(),
CpuCount: len(cpuLabels), CPUCount: len(cpuLabels),
updateInterval: updateInterval, updateInterval: updateInterval,
ShowAverageLoad: showAverageLoad, ShowAverageLoad: showAverageLoad,
ShowPerCpuLoad: showPerCpuLoad, ShowPerCPULoad: showPerCPULoad,
} }
self.Title = " CPU Usage " self.Title = " CPU Usage "
self.HorizontalScale = horizontalScale self.HorizontalScale = horizontalScale
if !(self.ShowAverageLoad || self.ShowPerCpuLoad) { if !(self.ShowAverageLoad || self.ShowPerCPULoad) {
if self.CpuCount <= 8 { if self.CPUCount <= 8 {
self.ShowPerCpuLoad = true self.ShowPerCPULoad = true
} else { } else {
self.ShowAverageLoad = true self.ShowAverageLoad = true
} }
@ -47,9 +47,9 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage
self.Data["AVRG"] = []float64{0} self.Data["AVRG"] = []float64{0}
} }
if self.ShowPerCpuLoad { if self.ShowPerCPULoad {
cpus := make(map[string]int) cpus := make(map[string]int)
devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad) devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCPULoad)
for k, v := range cpus { for k, v := range cpus {
self.Data[k] = []float64{float64(v)} self.Data[k] = []float64{float64(v)}
} }
@ -66,17 +66,17 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage
return self return self
} }
func (self *CpuWidget) EnableMetric() { func (cpu *CPUWidget) EnableMetric() {
if self.ShowAverageLoad { if cpu.ShowAverageLoad {
self.metric = make(map[string]prometheus.Gauge) cpu.metric = make(map[string]prometheus.Gauge)
self.metric["AVRG"] = prometheus.NewGauge(prometheus.GaugeOpts{ cpu.metric["AVRG"] = prometheus.NewGauge(prometheus.GaugeOpts{
Subsystem: "cpu", Subsystem: "cpu",
Name: "avg", Name: "avg",
}) })
} else { } else {
cpus := make(map[string]int) cpus := make(map[string]int)
devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad) devices.UpdateCPU(cpus, cpu.updateInterval, cpu.ShowPerCPULoad)
self.metric = make(map[string]prometheus.Gauge) cpu.metric = make(map[string]prometheus.Gauge)
for key, perc := range cpus { for key, perc := range cpus {
gauge := prometheus.NewGauge(prometheus.GaugeOpts{ gauge := prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: "gotop", Namespace: "gotop",
@ -85,53 +85,53 @@ func (self *CpuWidget) EnableMetric() {
}) })
gauge.Set(float64(perc)) gauge.Set(float64(perc))
prometheus.MustRegister(gauge) prometheus.MustRegister(gauge)
self.metric[key] = gauge cpu.metric[key] = gauge
} }
} }
} }
func (b *CpuWidget) Scale(i int) { func (cpu *CPUWidget) Scale(i int) {
b.LineGraph.HorizontalScale = i cpu.LineGraph.HorizontalScale = i
} }
func (self *CpuWidget) update() { func (cpu *CPUWidget) update() {
if self.ShowAverageLoad { if cpu.ShowAverageLoad {
go func() { go func() {
cpus := make(map[string]int) cpus := make(map[string]int)
devices.UpdateCPU(cpus, self.updateInterval, false) devices.UpdateCPU(cpus, cpu.updateInterval, false)
self.Lock() cpu.Lock()
defer self.Unlock() defer cpu.Unlock()
self.updateLock.Lock() cpu.updateLock.Lock()
defer self.updateLock.Unlock() defer cpu.updateLock.Unlock()
var val float64 var val float64
for _, v := range cpus { for _, v := range cpus {
val = float64(v) val = float64(v)
break break
} }
self.Data["AVRG"] = append(self.Data["AVRG"], val) cpu.Data["AVRG"] = append(cpu.Data["AVRG"], val)
self.Labels["AVRG"] = fmt.Sprintf("%3.0f%%", val) cpu.Labels["AVRG"] = fmt.Sprintf("%3.0f%%", val)
if self.metric != nil { if cpu.metric != nil {
self.metric["AVRG"].Set(val) cpu.metric["AVRG"].Set(val)
} }
}() }()
} }
if self.ShowPerCpuLoad { if cpu.ShowPerCPULoad {
go func() { go func() {
cpus := make(map[string]int) cpus := make(map[string]int)
devices.UpdateCPU(cpus, self.updateInterval, true) devices.UpdateCPU(cpus, cpu.updateInterval, true)
self.Lock() cpu.Lock()
defer self.Unlock() defer cpu.Unlock()
self.updateLock.Lock() cpu.updateLock.Lock()
defer self.updateLock.Unlock() defer cpu.updateLock.Unlock()
for key, percent := range cpus { for key, percent := range cpus {
self.Data[key] = append(self.Data[key], float64(percent)) cpu.Data[key] = append(cpu.Data[key], float64(percent))
self.Labels[key] = fmt.Sprintf("%d%%", percent) cpu.Labels[key] = fmt.Sprintf("%d%%", percent)
if self.metric != nil { if cpu.metric != nil {
if self.metric[key] == nil { if cpu.metric[key] == nil {
log.Printf("no metrics for %s", key) log.Printf("no metrics for %s", key)
} else { } else {
self.metric[key].Set(float64(percent)) cpu.metric[key].Set(float64(percent))
} }
} }
} }

View File

@ -64,9 +64,9 @@ func NewDiskWidget() *DiskWidget {
return self return self
} }
func (self *DiskWidget) EnableMetric() { func (disk *DiskWidget) EnableMetric() {
self.metric = make(map[string]prometheus.Gauge) disk.metric = make(map[string]prometheus.Gauge)
for key, part := range self.Partitions { for key, part := range disk.Partitions {
gauge := prometheus.NewGauge(prometheus.GaugeOpts{ gauge := prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: "gotop", Namespace: "gotop",
Subsystem: "disk", Subsystem: "disk",
@ -75,11 +75,11 @@ func (self *DiskWidget) EnableMetric() {
}) })
gauge.Set(float64(part.UsedPercent) / 100.0) gauge.Set(float64(part.UsedPercent) / 100.0)
prometheus.MustRegister(gauge) prometheus.MustRegister(gauge)
self.metric[key] = gauge disk.metric[key] = gauge
} }
} }
func (self *DiskWidget) update() { func (disk *DiskWidget) update() {
partitions, err := psDisk.Partitions(false) partitions, err := psDisk.Partitions(false)
if err != nil { if err != nil {
log.Printf("failed to get disk partitions from gopsutil: %v", err) log.Printf("failed to get disk partitions from gopsutil: %v", err)
@ -97,8 +97,8 @@ func (self *DiskWidget) update() {
continue continue
} }
// check if partition doesn't already exist in our list // check if partition doesn't already exist in our list
if _, ok := self.Partitions[partition.Device]; !ok { if _, ok := disk.Partitions[partition.Device]; !ok {
self.Partitions[partition.Device] = &Partition{ disk.Partitions[partition.Device] = &Partition{
Device: partition.Device, Device: partition.Device,
MountPoint: partition.Mountpoint, MountPoint: partition.Mountpoint,
} }
@ -107,7 +107,7 @@ func (self *DiskWidget) update() {
// delete a partition if it no longer exists // delete a partition if it no longer exists
toDelete := []string{} toDelete := []string{}
for device := range self.Partitions { for device := range disk.Partitions {
exists := false exists := false
for _, partition := range partitions { for _, partition := range partitions {
if device == partition.Device { if device == partition.Device {
@ -120,11 +120,11 @@ func (self *DiskWidget) update() {
} }
} }
for _, device := range toDelete { for _, device := range toDelete {
delete(self.Partitions, device) delete(disk.Partitions, device)
} }
// updates partition info. We add 0.5 to all values to make sure the truncation rounds // updates partition info. We add 0.5 to all values to make sure the truncation rounds
for _, partition := range self.Partitions { for _, partition := range disk.Partitions {
usage, err := psDisk.Usage(partition.MountPoint) usage, err := psDisk.Usage(partition.MountPoint)
if err != nil { if err != nil {
log.Printf("failed to get partition usage statistics from gopsutil: %v. partition: %v", err, partition) log.Printf("failed to get partition usage statistics from gopsutil: %v. partition: %v", err, partition)
@ -160,27 +160,27 @@ func (self *DiskWidget) update() {
// converts self.Partitions into self.Rows which is a [][]String // converts self.Partitions into self.Rows which is a [][]String
sortedPartitions := []string{} sortedPartitions := []string{}
for seriesName := range self.Partitions { for seriesName := range disk.Partitions {
sortedPartitions = append(sortedPartitions, seriesName) sortedPartitions = append(sortedPartitions, seriesName)
} }
sort.Strings(sortedPartitions) sort.Strings(sortedPartitions)
self.Rows = make([][]string, len(self.Partitions)) disk.Rows = make([][]string, len(disk.Partitions))
for i, key := range sortedPartitions { for i, key := range sortedPartitions {
partition := self.Partitions[key] partition := disk.Partitions[key]
self.Rows[i] = make([]string, 6) disk.Rows[i] = make([]string, 6)
self.Rows[i][0] = strings.Replace(strings.Replace(partition.Device, "/dev/", "", -1), "mapper/", "", -1) disk.Rows[i][0] = strings.Replace(strings.Replace(partition.Device, "/dev/", "", -1), "mapper/", "", -1)
self.Rows[i][1] = partition.MountPoint disk.Rows[i][1] = partition.MountPoint
self.Rows[i][2] = fmt.Sprintf("%d%%", partition.UsedPercent) disk.Rows[i][2] = fmt.Sprintf("%d%%", partition.UsedPercent)
self.Rows[i][3] = partition.Free disk.Rows[i][3] = partition.Free
self.Rows[i][4] = partition.BytesReadRecently disk.Rows[i][4] = partition.BytesReadRecently
self.Rows[i][5] = partition.BytesWrittenRecently disk.Rows[i][5] = partition.BytesWrittenRecently
if self.metric != nil { if disk.metric != nil {
if self.metric[key] == nil { if disk.metric[key] == nil {
log.Printf("ERROR: missing metric %s", key) log.Printf("ERROR: missing metric %s", key)
} else { } else {
self.metric[key].Set(float64(partition.UsedPercent) / 100.0) disk.metric[key].Set(float64(partition.UsedPercent) / 100.0)
} }
} }
} }

View File

@ -7,6 +7,7 @@ import (
ui "github.com/gizak/termui/v3" ui "github.com/gizak/termui/v3"
) )
// KEYBINDS is the help text for the in-program shortcuts
const KEYBINDS = ` const KEYBINDS = `
Quit: q or <C-c> Quit: q or <C-c>
@ -55,7 +56,7 @@ func NewHelpMenu() *HelpMenu {
} }
} }
func (self *HelpMenu) Resize(termWidth, termHeight int) { func (help *HelpMenu) Resize(termWidth, termHeight int) {
textWidth := 53 textWidth := 53
for _, line := range strings.Split(KEYBINDS, "\n") { for _, line := range strings.Split(KEYBINDS, "\n") {
if textWidth < len(line) { if textWidth < len(line) {
@ -66,17 +67,17 @@ func (self *HelpMenu) Resize(termWidth, termHeight int) {
x := (termWidth - textWidth) / 2 x := (termWidth - textWidth) / 2
y := (termHeight - textHeight) / 2 y := (termHeight - textHeight) / 2
self.Block.SetRect(x, y, textWidth+x, textHeight+y) help.Block.SetRect(x, y, textWidth+x, textHeight+y)
} }
func (self *HelpMenu) Draw(buf *ui.Buffer) { func (help *HelpMenu) Draw(buf *ui.Buffer) {
self.Block.Draw(buf) help.Block.Draw(buf)
for y, line := range strings.Split(KEYBINDS, "\n") { for y, line := range strings.Split(KEYBINDS, "\n") {
for x, rune := range line { for x, rune := range line {
buf.SetCell( buf.SetCell(
ui.NewCell(rune, ui.Theme.Default), ui.NewCell(rune, ui.Theme.Default),
image.Pt(self.Inner.Min.X+x, self.Inner.Min.Y+y-1), image.Pt(help.Inner.Min.X+x, help.Inner.Min.Y+y-1),
) )
} }
} }

View File

@ -48,30 +48,30 @@ func NewMemWidget(updateInterval time.Duration, horizontalScale int) *MemWidget
return self return self
} }
func (b *MemWidget) EnableMetric() { func (mem *MemWidget) EnableMetric() {
b.metrics = make(map[string]prometheus.Gauge) mem.metrics = make(map[string]prometheus.Gauge)
mems := make(map[string]devices.MemoryInfo) mems := make(map[string]devices.MemoryInfo)
devices.UpdateMem(mems) devices.UpdateMem(mems)
for l, mem := range mems { for l, m := range mems {
b.metrics[l] = prometheus.NewGauge(prometheus.GaugeOpts{ mem.metrics[l] = prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: "gotop", Namespace: "gotop",
Subsystem: "memory", Subsystem: "memory",
Name: l, Name: l,
}) })
b.metrics[l].Set(mem.UsedPercent) mem.metrics[l].Set(m.UsedPercent)
prometheus.MustRegister(b.metrics[l]) prometheus.MustRegister(mem.metrics[l])
} }
} }
func (b *MemWidget) Scale(i int) { func (mem *MemWidget) Scale(i int) {
b.LineGraph.HorizontalScale = i mem.LineGraph.HorizontalScale = i
} }
func (self *MemWidget) renderMemInfo(line string, memoryInfo devices.MemoryInfo) { func (mem *MemWidget) renderMemInfo(line string, memoryInfo devices.MemoryInfo) {
self.Data[line] = append(self.Data[line], memoryInfo.UsedPercent) mem.Data[line] = append(mem.Data[line], memoryInfo.UsedPercent)
memoryTotalBytes, memoryTotalMagnitude := utils.ConvertBytes(memoryInfo.Total) memoryTotalBytes, memoryTotalMagnitude := utils.ConvertBytes(memoryInfo.Total)
memoryUsedBytes, memoryUsedMagnitude := utils.ConvertBytes(memoryInfo.Used) memoryUsedBytes, memoryUsedMagnitude := utils.ConvertBytes(memoryInfo.Used)
self.Labels[line] = fmt.Sprintf("%3.0f%% %5.1f%s/%.0f%s", mem.Labels[line] = fmt.Sprintf("%3.0f%% %5.1f%s/%.0f%s",
memoryInfo.UsedPercent, memoryInfo.UsedPercent,
memoryUsedBytes, memoryUsedBytes,
memoryUsedMagnitude, memoryUsedMagnitude,

View File

@ -14,8 +14,10 @@ import (
) )
const ( const (
NET_INTERFACE_ALL = "all" // NetInterfaceAll enables all network interfaces
NET_INTERFACE_VPN = "tun0" NetInterfaceAll = "all"
// NetInterfaceVpn is the VPN interface
NetInterfaceVpn = "tun0"
) )
type NetWidget struct { type NetWidget struct {
@ -63,23 +65,23 @@ func NewNetWidget(netInterface string) *NetWidget {
return self return self
} }
func (b *NetWidget) EnableMetric() { func (net *NetWidget) EnableMetric() {
b.recvMetric = prometheus.NewCounter(prometheus.CounterOpts{ net.recvMetric = prometheus.NewCounter(prometheus.CounterOpts{
Namespace: "gotop", Namespace: "gotop",
Subsystem: "net", Subsystem: "net",
Name: "recv", Name: "recv",
}) })
prometheus.MustRegister(b.recvMetric) prometheus.MustRegister(net.recvMetric)
b.sentMetric = prometheus.NewCounter(prometheus.CounterOpts{ net.sentMetric = prometheus.NewCounter(prometheus.CounterOpts{
Namespace: "gotop", Namespace: "gotop",
Subsystem: "net", Subsystem: "net",
Name: "sent", Name: "sent",
}) })
prometheus.MustRegister(b.sentMetric) prometheus.MustRegister(net.sentMetric)
} }
func (self *NetWidget) update() { func (net *NetWidget) update() {
interfaces, err := psNet.IOCounters(true) interfaces, err := psNet.IOCounters(true)
if err != nil { if err != nil {
log.Printf("failed to get network activity from gopsutil: %v", err) log.Printf("failed to get network activity from gopsutil: %v", err)
@ -90,15 +92,15 @@ func (self *NetWidget) update() {
var totalBytesSent uint64 var totalBytesSent uint64
interfaceMap := make(map[string]bool) interfaceMap := make(map[string]bool)
// Default behaviour // Default behaviour
interfaceMap[NET_INTERFACE_ALL] = true interfaceMap[NetInterfaceAll] = true
interfaceMap[NET_INTERFACE_VPN] = false interfaceMap[NetInterfaceVpn] = false
// Build a map with wanted status for each interfaces. // Build a map with wanted status for each interfaces.
for _, iface := range self.NetInterface { for _, iface := range net.NetInterface {
if strings.HasPrefix(iface, "!") { if strings.HasPrefix(iface, "!") {
interfaceMap[strings.TrimPrefix(iface, "!")] = false interfaceMap[strings.TrimPrefix(iface, "!")] = false
} else { } else {
// if we specify a wanted interface, remove capture on all. // if we specify a wanted interface, remove capture on all.
delete(interfaceMap, NET_INTERFACE_ALL) delete(interfaceMap, NetInterfaceAll)
interfaceMap[iface] = true interfaceMap[iface] = true
} }
} }
@ -109,7 +111,7 @@ func (self *NetWidget) update() {
totalBytesSent += _interface.BytesSent totalBytesSent += _interface.BytesSent
} else if ok { // Present but unwanted } else if ok { // Present but unwanted
continue continue
} else if interfaceMap[NET_INTERFACE_ALL] { // Capture other } else if interfaceMap[NetInterfaceAll] { // Capture other
totalBytesRecv += _interface.BytesRecv totalBytesRecv += _interface.BytesRecv
totalBytesSent += _interface.BytesSent totalBytesSent += _interface.BytesSent
} }
@ -118,9 +120,9 @@ func (self *NetWidget) update() {
var recentBytesRecv uint64 var recentBytesRecv uint64
var recentBytesSent uint64 var recentBytesSent uint64
if self.totalBytesRecv != 0 { // if this isn't the first update if net.totalBytesRecv != 0 { // if this isn't the first update
recentBytesRecv = totalBytesRecv - self.totalBytesRecv recentBytesRecv = totalBytesRecv - net.totalBytesRecv
recentBytesSent = totalBytesSent - self.totalBytesSent recentBytesSent = totalBytesSent - net.totalBytesSent
if int(recentBytesRecv) < 0 { if int(recentBytesRecv) < 0 {
log.Printf("error: negative value for recently received network data from gopsutil. recentBytesRecv: %v", recentBytesRecv) log.Printf("error: negative value for recently received network data from gopsutil. recentBytesRecv: %v", recentBytesRecv)
@ -133,20 +135,20 @@ func (self *NetWidget) update() {
recentBytesSent = 0 recentBytesSent = 0
} }
self.Lines[0].Data = append(self.Lines[0].Data, int(recentBytesRecv)) net.Lines[0].Data = append(net.Lines[0].Data, int(recentBytesRecv))
self.Lines[1].Data = append(self.Lines[1].Data, int(recentBytesSent)) net.Lines[1].Data = append(net.Lines[1].Data, int(recentBytesSent))
if self.sentMetric != nil { if net.sentMetric != nil {
self.sentMetric.Add(float64(recentBytesSent)) net.sentMetric.Add(float64(recentBytesSent))
self.recvMetric.Add(float64(recentBytesRecv)) net.recvMetric.Add(float64(recentBytesRecv))
} }
} }
// used in later calls to update // used in later calls to update
self.totalBytesRecv = totalBytesRecv net.totalBytesRecv = totalBytesRecv
self.totalBytesSent = totalBytesSent net.totalBytesSent = totalBytesSent
rx, tx := "RX/s", "TX/s" rx, tx := "RX/s", "TX/s"
if self.Mbps { if net.Mbps {
rx, tx = "mbps", "mbps" rx, tx = "mbps", "mbps"
} }
format := " %s: %9.1f %2s/s" format := " %s: %9.1f %2s/s"
@ -163,13 +165,13 @@ func (self *NetWidget) update() {
} }
totalConverted, unitTotal := utils.ConvertBytes(total) totalConverted, unitTotal := utils.ConvertBytes(total)
if self.Mbps { if net.Mbps {
recentConverted, unitRecent, format = float64(recent)*0.000008, "", " %s: %11.3f %2s" recentConverted, unitRecent, format = float64(recent)*0.000008, "", " %s: %11.3f %2s"
} else { } else {
recentConverted, unitRecent = utils.ConvertBytes(recent) recentConverted, unitRecent = utils.ConvertBytes(recent)
} }
self.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", label, totalConverted, unitTotal) net.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", label, totalConverted, unitTotal)
self.Lines[i].Title2 = fmt.Sprintf(format, rate, recentConverted, unitRecent) net.Lines[i].Title2 = fmt.Sprintf(format, rate, recentConverted, unitRecent)
} }
} }

View File

@ -17,14 +17,13 @@ import (
) )
const ( const (
UP_ARROW = "▲" _downArrow = "▼"
DOWN_ARROW = "▼"
) )
type ProcSortMethod string type ProcSortMethod string
const ( const (
ProcSortCpu ProcSortMethod = "c" ProcSortCPU ProcSortMethod = "c"
ProcSortMem = "m" ProcSortMem = "m"
ProcSortPid = "p" ProcSortPid = "p"
) )
@ -33,7 +32,7 @@ type Proc struct {
Pid int Pid int
CommandName string CommandName string
FullCommand string FullCommand string
Cpu float64 CPU float64
Mem float64 Mem float64
} }
@ -58,7 +57,7 @@ func NewProcWidget() *ProcWidget {
Table: ui.NewTable(), Table: ui.NewTable(),
updateInterval: time.Second, updateInterval: time.Second,
cpuCount: cpuCount, cpuCount: cpuCount,
sortMethod: ProcSortCpu, sortMethod: ProcSortCPU,
showGroupedProcs: true, showGroupedProcs: true,
filter: "", filter: "",
} }
@ -100,42 +99,42 @@ func NewProcWidget() *ProcWidget {
return self return self
} }
func (p *ProcWidget) EnableMetric() { func (proc *ProcWidget) EnableMetric() {
// There's (currently) no metric for this // There's (currently) no metric for this
} }
func (self *ProcWidget) SetEditingFilter(editing bool) { func (proc *ProcWidget) SetEditingFilter(editing bool) {
self.entry.SetEditing(editing) proc.entry.SetEditing(editing)
} }
func (self *ProcWidget) HandleEvent(e tui.Event) bool { func (proc *ProcWidget) HandleEvent(e tui.Event) bool {
return self.entry.HandleEvent(e) return proc.entry.HandleEvent(e)
} }
func (self *ProcWidget) SetRect(x1, y1, x2, y2 int) { func (proc *ProcWidget) SetRect(x1, y1, x2, y2 int) {
self.Table.SetRect(x1, y1, x2, y2) proc.Table.SetRect(x1, y1, x2, y2)
self.entry.SetRect(x1+2, y2-1, x2-2, y2) proc.entry.SetRect(x1+2, y2-1, x2-2, y2)
} }
func (self *ProcWidget) Draw(buf *tui.Buffer) { func (proc *ProcWidget) Draw(buf *tui.Buffer) {
self.Table.Draw(buf) proc.Table.Draw(buf)
self.entry.Draw(buf) proc.entry.Draw(buf)
} }
func (self *ProcWidget) filterProcs(procs []Proc) []Proc { func (proc *ProcWidget) filterProcs(procs []Proc) []Proc {
if self.filter == "" { if proc.filter == "" {
return procs return procs
} }
var filtered []Proc var filtered []Proc
for _, proc := range procs { for _, p := range procs {
if strings.Contains(proc.FullCommand, self.filter) || strings.Contains(fmt.Sprintf("%d", proc.Pid), self.filter) { if strings.Contains(p.FullCommand, proc.filter) || strings.Contains(fmt.Sprintf("%d", p.Pid), proc.filter) {
filtered = append(filtered, proc) filtered = append(filtered, p)
} }
} }
return filtered return filtered
} }
func (self *ProcWidget) update() { func (proc *ProcWidget) update() {
procs, err := getProcs() procs, err := getProcs()
if err != nil { if err != nil {
log.Printf("failed to retrieve processes: %v", err) log.Printf("failed to retrieve processes: %v", err)
@ -144,103 +143,103 @@ func (self *ProcWidget) update() {
// have to iterate over the entry number in order to modify the array in place // have to iterate over the entry number in order to modify the array in place
for i := range procs { for i := range procs {
procs[i].Cpu /= float64(self.cpuCount) procs[i].CPU /= float64(proc.cpuCount)
} }
procs = self.filterProcs(procs) procs = proc.filterProcs(procs)
self.ungroupedProcs = procs proc.ungroupedProcs = procs
self.groupedProcs = groupProcs(procs) proc.groupedProcs = groupProcs(procs)
self.sortProcs() proc.sortProcs()
self.convertProcsToTableRows() proc.convertProcsToTableRows()
} }
// sortProcs sorts either the grouped or ungrouped []Process based on the sortMethod. // sortProcs sorts either the grouped or ungrouped []Process based on the sortMethod.
// Called with every update, when the sort method is changed, and when processes are grouped and ungrouped. // Called with every update, when the sort method is changed, and when processes are grouped and ungrouped.
func (self *ProcWidget) sortProcs() { func (proc *ProcWidget) sortProcs() {
self.Header = []string{"Count", "Command", "CPU%", "Mem%"} proc.Header = []string{"Count", "Command", "CPU%", "Mem%"}
if !self.showGroupedProcs { if !proc.showGroupedProcs {
self.Header[0] = "PID" proc.Header[0] = "PID"
} }
var procs *[]Proc var procs *[]Proc
if self.showGroupedProcs { if proc.showGroupedProcs {
procs = &self.groupedProcs procs = &proc.groupedProcs
} else { } else {
procs = &self.ungroupedProcs procs = &proc.ungroupedProcs
} }
switch self.sortMethod { switch proc.sortMethod {
case ProcSortCpu: case ProcSortCPU:
sort.Sort(sort.Reverse(SortProcsByCpu(*procs))) sort.Sort(sort.Reverse(SortProcsByCPU(*procs)))
self.Header[2] += DOWN_ARROW proc.Header[2] += _downArrow
case ProcSortPid: case ProcSortPid:
if self.showGroupedProcs { if proc.showGroupedProcs {
sort.Sort(sort.Reverse(SortProcsByPid(*procs))) sort.Sort(sort.Reverse(SortProcsByPid(*procs)))
} else { } else {
sort.Sort(SortProcsByPid(*procs)) sort.Sort(SortProcsByPid(*procs))
} }
self.Header[0] += DOWN_ARROW proc.Header[0] += _downArrow
case ProcSortMem: case ProcSortMem:
sort.Sort(sort.Reverse(SortProcsByMem(*procs))) sort.Sort(sort.Reverse(SortProcsByMem(*procs)))
self.Header[3] += DOWN_ARROW proc.Header[3] += _downArrow
} }
} }
// convertProcsToTableRows converts a []Proc to a [][]string and sets it to the table Rows // convertProcsToTableRows converts a []Proc to a [][]string and sets it to the table Rows
func (self *ProcWidget) convertProcsToTableRows() { func (proc *ProcWidget) convertProcsToTableRows() {
var procs *[]Proc var procs *[]Proc
if self.showGroupedProcs { if proc.showGroupedProcs {
procs = &self.groupedProcs procs = &proc.groupedProcs
} else { } else {
procs = &self.ungroupedProcs procs = &proc.ungroupedProcs
} }
strings := make([][]string, len(*procs)) strings := make([][]string, len(*procs))
for i := range *procs { for i := range *procs {
strings[i] = make([]string, 4) strings[i] = make([]string, 4)
strings[i][0] = strconv.Itoa(int((*procs)[i].Pid)) strings[i][0] = strconv.Itoa(int((*procs)[i].Pid))
if self.showGroupedProcs { if proc.showGroupedProcs {
strings[i][1] = (*procs)[i].CommandName strings[i][1] = (*procs)[i].CommandName
} else { } else {
strings[i][1] = (*procs)[i].FullCommand strings[i][1] = (*procs)[i].FullCommand
} }
strings[i][2] = fmt.Sprintf("%4s", strconv.FormatFloat((*procs)[i].Cpu, 'f', 1, 64)) strings[i][2] = fmt.Sprintf("%4s", strconv.FormatFloat((*procs)[i].CPU, 'f', 1, 64))
strings[i][3] = fmt.Sprintf("%4s", strconv.FormatFloat(float64((*procs)[i].Mem), 'f', 1, 64)) strings[i][3] = fmt.Sprintf("%4s", strconv.FormatFloat(float64((*procs)[i].Mem), 'f', 1, 64))
} }
self.Rows = strings proc.Rows = strings
} }
func (self *ProcWidget) ChangeProcSortMethod(method ProcSortMethod) { func (proc *ProcWidget) ChangeProcSortMethod(method ProcSortMethod) {
if self.sortMethod != method { if proc.sortMethod != method {
self.sortMethod = method proc.sortMethod = method
self.ScrollTop() proc.ScrollTop()
self.sortProcs() proc.sortProcs()
self.convertProcsToTableRows() proc.convertProcsToTableRows()
} }
} }
func (self *ProcWidget) ToggleShowingGroupedProcs() { func (proc *ProcWidget) ToggleShowingGroupedProcs() {
self.showGroupedProcs = !self.showGroupedProcs proc.showGroupedProcs = !proc.showGroupedProcs
if self.showGroupedProcs { if proc.showGroupedProcs {
self.UniqueCol = 1 proc.UniqueCol = 1
} else { } else {
self.UniqueCol = 0 proc.UniqueCol = 0
} }
self.ScrollTop() proc.ScrollTop()
self.sortProcs() proc.sortProcs()
self.convertProcsToTableRows() proc.convertProcsToTableRows()
} }
// KillProc kills a process or group of processes depending on if we're // KillProc kills a process or group of processes depending on if we're
// displaying the processes grouped or not. // displaying the processes grouped or not.
func (self *ProcWidget) KillProc(sigName string) { func (proc *ProcWidget) KillProc(sigName string) {
self.SelectedItem = "" proc.SelectedItem = ""
command := "kill" command := "kill"
if self.UniqueCol == 1 { if proc.UniqueCol == 1 {
command = "pkill" command = "pkill"
} }
cmd := exec.Command(command, "--signal", sigName, self.Rows[self.SelectedRow][self.UniqueCol]) cmd := exec.Command(command, "--signal", sigName, proc.Rows[proc.SelectedRow][proc.UniqueCol])
cmd.Start() cmd.Start()
cmd.Wait() cmd.Wait()
} }
@ -257,7 +256,7 @@ func groupProcs(procs []Proc) []Proc {
val.Pid + 1, val.Pid + 1,
val.CommandName, val.CommandName,
"", "",
val.Cpu + proc.Cpu, val.CPU + proc.CPU,
val.Mem + proc.Mem, val.Mem + proc.Mem,
} }
} else { } else {
@ -265,7 +264,7 @@ func groupProcs(procs []Proc) []Proc {
1, 1,
proc.CommandName, proc.CommandName,
"", "",
proc.Cpu, proc.CPU,
proc.Mem, proc.Mem,
} }
} }
@ -283,53 +282,53 @@ func groupProcs(procs []Proc) []Proc {
// []Proc Sorting ////////////////////////////////////////////////////////////// // []Proc Sorting //////////////////////////////////////////////////////////////
type SortProcsByCpu []Proc type SortProcsByCPU []Proc
// Len implements Sort interface // Len implements Sort interface
func (self SortProcsByCpu) Len() int { func (procs SortProcsByCPU) Len() int {
return len(self) return len(procs)
} }
// Swap implements Sort interface // Swap implements Sort interface
func (self SortProcsByCpu) Swap(i, j int) { func (procs SortProcsByCPU) Swap(i, j int) {
self[i], self[j] = self[j], self[i] procs[i], procs[j] = procs[j], procs[i]
} }
// Less implements Sort interface // Less implements Sort interface
func (self SortProcsByCpu) Less(i, j int) bool { func (procs SortProcsByCPU) Less(i, j int) bool {
return self[i].Cpu < self[j].Cpu return procs[i].CPU < procs[j].CPU
} }
type SortProcsByPid []Proc type SortProcsByPid []Proc
// Len implements Sort interface // Len implements Sort interface
func (self SortProcsByPid) Len() int { func (procs SortProcsByPid) Len() int {
return len(self) return len(procs)
} }
// Swap implements Sort interface // Swap implements Sort interface
func (self SortProcsByPid) Swap(i, j int) { func (procs SortProcsByPid) Swap(i, j int) {
self[i], self[j] = self[j], self[i] procs[i], procs[j] = procs[j], procs[i]
} }
// Less implements Sort interface // Less implements Sort interface
func (self SortProcsByPid) Less(i, j int) bool { func (procs SortProcsByPid) Less(i, j int) bool {
return self[i].Pid < self[j].Pid return procs[i].Pid < procs[j].Pid
} }
type SortProcsByMem []Proc type SortProcsByMem []Proc
// Len implements Sort interface // Len implements Sort interface
func (self SortProcsByMem) Len() int { func (procs SortProcsByMem) Len() int {
return len(self) return len(procs)
} }
// Swap implements Sort interface // Swap implements Sort interface
func (self SortProcsByMem) Swap(i, j int) { func (procs SortProcsByMem) Swap(i, j int) {
self[i], self[j] = self[j], self[i] procs[i], procs[j] = procs[j], procs[i]
} }
// Less implements Sort interface // Less implements Sort interface
func (self SortProcsByMem) Less(i, j int) bool { func (procs SortProcsByMem) Less(i, j int) bool {
return self[i].Mem < self[j].Mem return procs[i].Mem < procs[j].Mem
} }

View File

@ -35,7 +35,7 @@ func getProcs() ([]Proc, error) {
Pid: pid, Pid: pid,
CommandName: strings.TrimSpace(line[11:61]), CommandName: strings.TrimSpace(line[11:61]),
FullCommand: line[74:], FullCommand: line[74:],
Cpu: cpu, CPU: cpu,
Mem: mem, Mem: mem,
} }
procs = append(procs, proc) procs = append(procs, proc)

View File

@ -19,8 +19,8 @@ func NewStatusBar() *StatusBar {
return self return self
} }
func (self *StatusBar) Draw(buf *ui.Buffer) { func (sb *StatusBar) Draw(buf *ui.Buffer) {
self.Block.Draw(buf) sb.Block.Draw(buf)
hostname, err := os.Hostname() hostname, err := os.Hostname()
if err != nil { if err != nil {
@ -30,7 +30,7 @@ func (self *StatusBar) Draw(buf *ui.Buffer) {
buf.SetString( buf.SetString(
hostname, hostname,
ui.Theme.Default, ui.Theme.Default,
image.Pt(self.Inner.Min.X, self.Inner.Min.Y+(self.Inner.Dy()/2)), image.Pt(sb.Inner.Min.X, sb.Inner.Min.Y+(sb.Inner.Dy()/2)),
) )
currentTime := time.Now() currentTime := time.Now()
@ -39,8 +39,8 @@ func (self *StatusBar) Draw(buf *ui.Buffer) {
formattedTime, formattedTime,
ui.Theme.Default, ui.Theme.Default,
image.Pt( image.Pt(
self.Inner.Min.X+(self.Inner.Dx()/2)-len(formattedTime)/2, sb.Inner.Min.X+(sb.Inner.Dx()/2)-len(formattedTime)/2,
self.Inner.Min.Y+(self.Inner.Dy()/2), sb.Inner.Min.Y+(sb.Inner.Dy()/2),
), ),
) )
@ -48,8 +48,8 @@ func (self *StatusBar) Draw(buf *ui.Buffer) {
"gotop", "gotop",
ui.Theme.Default, ui.Theme.Default,
image.Pt( image.Pt(
self.Inner.Max.X-6, sb.Inner.Max.X-6,
self.Inner.Min.Y+(self.Inner.Dy()/2), sb.Inner.Min.Y+(sb.Inner.Dy()/2),
), ),
) )
} }

View File

@ -68,9 +68,9 @@ func NewTempWidget(tempScale TempScale, filter []string) *TempWidget {
return self return self
} }
func (self *TempWidget) EnableMetric() { func (temp *TempWidget) EnableMetric() {
self.tempsMetric = make(map[string]prometheus.Gauge) temp.tempsMetric = make(map[string]prometheus.Gauge)
for k, v := range self.Data { for k, v := range temp.Data {
gauge := prometheus.NewGauge(prometheus.GaugeOpts{ gauge := prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: "gotop", Namespace: "gotop",
Subsystem: "temp", Subsystem: "temp",
@ -78,58 +78,58 @@ func (self *TempWidget) EnableMetric() {
}) })
gauge.Set(float64(v)) gauge.Set(float64(v))
prometheus.MustRegister(gauge) prometheus.MustRegister(gauge)
self.tempsMetric[k] = gauge temp.tempsMetric[k] = gauge
} }
} }
// Custom Draw method instead of inheriting from a generic Widget. // Custom Draw method instead of inheriting from a generic Widget.
func (self *TempWidget) Draw(buf *ui.Buffer) { func (temp *TempWidget) Draw(buf *ui.Buffer) {
self.Block.Draw(buf) temp.Block.Draw(buf)
var keys []string var keys []string
for key := range self.Data { for key := range temp.Data {
keys = append(keys, key) keys = append(keys, key)
} }
sort.Strings(keys) sort.Strings(keys)
for y, key := range keys { for y, key := range keys {
if y+1 > self.Inner.Dy() { if y+1 > temp.Inner.Dy() {
break break
} }
var fg ui.Color var fg ui.Color
if self.Data[key] < self.TempThreshold { if temp.Data[key] < temp.TempThreshold {
fg = self.TempLowColor fg = temp.TempLowColor
} else { } else {
fg = self.TempHighColor fg = temp.TempHighColor
} }
s := ui.TrimString(key, (self.Inner.Dx() - 4)) s := ui.TrimString(key, (temp.Inner.Dx() - 4))
buf.SetString(s, buf.SetString(s,
ui.Theme.Default, ui.Theme.Default,
image.Pt(self.Inner.Min.X, self.Inner.Min.Y+y), image.Pt(temp.Inner.Min.X, temp.Inner.Min.Y+y),
) )
if self.tempsMetric != nil { if temp.tempsMetric != nil {
self.tempsMetric[key].Set(float64(self.Data[key])) temp.tempsMetric[key].Set(float64(temp.Data[key]))
} }
temperature := fmt.Sprintf("%3d°%c", self.Data[key], self.TempScale) temperature := fmt.Sprintf("%3d°%c", temp.Data[key], temp.TempScale)
buf.SetString( buf.SetString(
temperature, temperature,
ui.NewStyle(fg), ui.NewStyle(fg),
image.Pt(self.Inner.Max.X-(len(temperature)-1), self.Inner.Min.Y+y), image.Pt(temp.Inner.Max.X-(len(temperature)-1), temp.Inner.Min.Y+y),
) )
} }
} }
func (self *TempWidget) update() { func (temp *TempWidget) update() {
devices.UpdateTemps(self.Data) devices.UpdateTemps(temp.Data)
for name, val := range self.Data { for name, val := range temp.Data {
if self.TempScale == Fahrenheit { if temp.TempScale == Fahrenheit {
self.Data[name] = utils.CelsiusToFahrenheit(val) temp.Data[name] = utils.CelsiusToFahrenheit(val)
} else { } else {
self.Data[name] = val temp.Data[name] = val
} }
} }
} }