Moar code cleanup
This commit is contained in:
11
README.md
11
README.md
@ -75,15 +75,12 @@ Feel free to add a new one. You can use 256 colors, bold, underline, and reverse
|
|||||||
- zooming in and out of graphs
|
- zooming in and out of graphs
|
||||||
- gopsutil issue for darwin i386
|
- gopsutil issue for darwin i386
|
||||||
* cleaning up code
|
* cleaning up code
|
||||||
- termui Blocks should ignore writing to the outside area
|
- termui buffers should ignore setting characters outside the widget area
|
||||||
- Ignore writes to outside of inner area, or give error?
|
- ignore writes or give an error?
|
||||||
- termui Blocks should be indexed at 0, and maybe change X and Y variables too
|
- termui Blocks should be indexed at 0, and maybe change their X and Y variables too
|
||||||
- remove gotop unique logic from list and table
|
- remove gotop unique logic from list and table
|
||||||
- turn column width logic into a function
|
- turn column width logic into a function
|
||||||
- try to get drawille fork merged upstream
|
- try to get drawille fork merged upstream
|
||||||
- more documentation
|
- more documentation
|
||||||
- Draw borders and label after other stuff
|
- Draw borders and label after other stuff
|
||||||
- Only merge stuff in the range
|
- Only merge stuff in the buffer's area?
|
||||||
- Merge should include offset
|
|
||||||
- Remove merge from grid buffer function, just render
|
|
||||||
- Remove merge altogether
|
|
||||||
|
|||||||
21
gotop.go
21
gotop.go
@ -16,12 +16,17 @@ import (
|
|||||||
const VERSION = "1.0.1"
|
const VERSION = "1.0.1"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// for when terminal is resized
|
||||||
resized = make(chan bool, 1)
|
resized = make(chan bool, 1)
|
||||||
|
|
||||||
|
// for when help menu is toggled
|
||||||
helpToggled = make(chan bool, 1)
|
helpToggled = make(chan bool, 1)
|
||||||
helpStatus = false
|
// whether help menu is toggled
|
||||||
|
helpStatus = false
|
||||||
|
|
||||||
|
// proc widget takes longer to load, wait to render until it loads data
|
||||||
procLoaded = make(chan bool, 1)
|
procLoaded = make(chan bool, 1)
|
||||||
|
// used to render the proc widget whenever a key is pressed for it
|
||||||
keyPressed = make(chan bool, 1)
|
keyPressed = make(chan bool, 1)
|
||||||
|
|
||||||
colorscheme = colorschemes.Default
|
colorscheme = colorschemes.Default
|
||||||
@ -37,7 +42,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Sets up docopt which is a command line argument parser
|
// Sets up docopt which is a command line argument parser
|
||||||
func arguments() {
|
func cliArguments() {
|
||||||
usage := `
|
usage := `
|
||||||
Usage: gotop [options]
|
Usage: gotop [options]
|
||||||
|
|
||||||
@ -123,9 +128,11 @@ func termuiColors() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func widgetColors() {
|
func widgetColors() {
|
||||||
|
// memory widget colors
|
||||||
mem.LineColor["Main"] = ui.Color(colorscheme.MainMem)
|
mem.LineColor["Main"] = ui.Color(colorscheme.MainMem)
|
||||||
mem.LineColor["Swap"] = ui.Color(colorscheme.SwapMem)
|
mem.LineColor["Swap"] = ui.Color(colorscheme.SwapMem)
|
||||||
|
|
||||||
|
// cpu widget colors
|
||||||
LineColor := make(map[string]ui.Color)
|
LineColor := make(map[string]ui.Color)
|
||||||
for i := 0; i < len(cpu.Data); i++ {
|
for i := 0; i < len(cpu.Data); i++ {
|
||||||
LineColor[fmt.Sprintf("CPU%d", i+1)] = ui.Color(colorscheme.CPULines[i])
|
LineColor[fmt.Sprintf("CPU%d", i+1)] = ui.Color(colorscheme.CPULines[i])
|
||||||
@ -134,12 +141,13 @@ func widgetColors() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
arguments()
|
cliArguments()
|
||||||
|
|
||||||
termuiColors()
|
|
||||||
|
|
||||||
keyBinds()
|
keyBinds()
|
||||||
|
|
||||||
|
// need to do this before initializing widgets so that they can inherit the colors
|
||||||
|
termuiColors()
|
||||||
|
|
||||||
cpu = w.NewCPU()
|
cpu = w.NewCPU()
|
||||||
mem = w.NewMem()
|
mem = w.NewMem()
|
||||||
proc = w.NewProc(procLoaded, keyPressed)
|
proc = w.NewProc(procLoaded, keyPressed)
|
||||||
@ -149,8 +157,10 @@ func main() {
|
|||||||
|
|
||||||
widgetColors()
|
widgetColors()
|
||||||
|
|
||||||
|
// blocks till loaded
|
||||||
<-procLoaded
|
<-procLoaded
|
||||||
|
|
||||||
|
// inits termui
|
||||||
err := ui.Init()
|
err := ui.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -159,6 +169,7 @@ func main() {
|
|||||||
|
|
||||||
setupGrid()
|
setupGrid()
|
||||||
|
|
||||||
|
// load help widget after init termui/termbox so that it has access to terminal size
|
||||||
help = w.NewHelpMenu()
|
help = w.NewHelpMenu()
|
||||||
|
|
||||||
ui.On("resize", func(e ui.Event) {
|
ui.On("resize", func(e ui.Event) {
|
||||||
|
|||||||
@ -36,8 +36,9 @@ func (g *Gauge) Buffer() *Buffer {
|
|||||||
|
|
||||||
// plot percentage
|
// plot percentage
|
||||||
s := strconv.Itoa(g.Percent) + "%" + g.Description
|
s := strconv.Itoa(g.Percent) + "%" + g.Description
|
||||||
y := (g.Y + 1) / 2
|
|
||||||
s = MaxString(s, g.X)
|
s = MaxString(s, g.X)
|
||||||
|
|
||||||
|
y := (g.Y + 1) / 2
|
||||||
x := ((g.X - len(s)) + 1) / 2
|
x := ((g.X - len(s)) + 1) / 2
|
||||||
|
|
||||||
for i, char := range s {
|
for i, char := range s {
|
||||||
|
|||||||
@ -31,6 +31,7 @@ func NewLineGraph() *LineGraph {
|
|||||||
func (lc *LineGraph) Buffer() *Buffer {
|
func (lc *LineGraph) Buffer() *Buffer {
|
||||||
buf := lc.Block.Buffer()
|
buf := lc.Block.Buffer()
|
||||||
c := drawille.NewCanvas()
|
c := drawille.NewCanvas()
|
||||||
|
// used to keep track of colors but not write them to the buffer until the end
|
||||||
colors := make([][]Color, lc.X+2)
|
colors := make([][]Color, lc.X+2)
|
||||||
for i := range colors {
|
for i := range colors {
|
||||||
colors[i] = make([]Color, lc.Y+2)
|
colors[i] = make([]Color, lc.Y+2)
|
||||||
@ -52,6 +53,7 @@ func (lc *LineGraph) Buffer() *Buffer {
|
|||||||
seriesLineColor = lc.DefaultLineColor
|
seriesLineColor = lc.DefaultLineColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// coordinates of last point
|
||||||
lastY, lastX := -1, -1
|
lastY, lastX := -1, -1
|
||||||
// assign colors to `colors` and lines/points to the canvas
|
// assign colors to `colors` and lines/points to the canvas
|
||||||
for i := len(seriesData) - 1; i >= 0; i-- {
|
for i := len(seriesData) - 1; i >= 0; i-- {
|
||||||
@ -63,7 +65,7 @@ func (lc *LineGraph) Buffer() *Buffer {
|
|||||||
}
|
}
|
||||||
if lastY == -1 { // if this is the first point
|
if lastY == -1 { // if this is the first point
|
||||||
c.Set(x, y)
|
c.Set(x, y)
|
||||||
colors[x/2][y/4] = seriesLineColor
|
colors[x/2][y/4] = seriesLineColor // divide by 2 and 4 due to 2x4 dots in braille characters
|
||||||
} else {
|
} else {
|
||||||
c.DrawLine(lastX, lastY, x, y)
|
c.DrawLine(lastX, lastY, x, y)
|
||||||
for _, p := range drawille.Line(lastX, lastY, x, y) {
|
for _, p := range drawille.Line(lastX, lastY, x, y) {
|
||||||
@ -73,20 +75,20 @@ func (lc *LineGraph) Buffer() *Buffer {
|
|||||||
lastX, lastY = x, y
|
lastX, lastY = x, y
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy drawille and colors to buffer
|
// copy braille and colors to buffer
|
||||||
for y, line := range c.Rows(c.MinX(), c.MinY(), c.MaxX(), c.MaxY()) {
|
for y, line := range c.Rows(c.MinX(), c.MinY(), c.MaxX(), c.MaxY()) {
|
||||||
for x, char := range line {
|
for x, char := range line {
|
||||||
x /= 3
|
x /= 3 // idk why but it works
|
||||||
if x == 0 {
|
if x == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if char != 10240 {
|
if char != 10240 { // empty braille character
|
||||||
buf.SetCell(x, y, Cell{char, colors[x][y], lc.Bg})
|
buf.SetCell(x, y, Cell{char, colors[x][y], lc.Bg})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render key
|
// Render key ontop, but let braille be drawn between words
|
||||||
str := fmt.Sprintf("%s %3.0f%%", seriesName, seriesData[len(seriesData)-1])
|
str := fmt.Sprintf("%s %3.0f%%", seriesName, seriesData[len(seriesData)-1])
|
||||||
for k, char := range str {
|
for k, char := range str {
|
||||||
if char != ' ' {
|
if char != ' ' {
|
||||||
|
|||||||
@ -29,12 +29,14 @@ func (bc *List) Buffer() *Buffer {
|
|||||||
if y+1 > bc.Y {
|
if y+1 > bc.Y {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
fg := Theme.TempLow
|
fg := Theme.TempLow
|
||||||
if bc.Data[y] >= bc.Threshold {
|
if bc.Data[y] >= bc.Threshold {
|
||||||
fg = Theme.TempHigh
|
fg = Theme.TempHigh
|
||||||
}
|
}
|
||||||
r := MaxString(text, (bc.X - 4))
|
|
||||||
buf.SetString(1, y+1, r, Theme.Fg, bc.Bg)
|
s := MaxString(text, (bc.X - 4))
|
||||||
|
buf.SetString(1, y+1, s, Theme.Fg, bc.Bg)
|
||||||
buf.SetString(bc.X-2, y+1, fmt.Sprintf("%dC", bc.Data[y]), fg, bc.Bg)
|
buf.SetString(bc.X-2, y+1, fmt.Sprintf("%dC", bc.Data[y]), fg, bc.Bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,9 +56,9 @@ func (sl *Sparklines) Buffer() *Buffer {
|
|||||||
buf.SetString(1, title1Y, title1, line.TitleColor|AttrBold, sl.Bg)
|
buf.SetString(1, title1Y, title1, line.TitleColor|AttrBold, sl.Bg)
|
||||||
buf.SetString(1, title2Y, title2, line.TitleColor|AttrBold, sl.Bg)
|
buf.SetString(1, title2Y, title2, line.TitleColor|AttrBold, sl.Bg)
|
||||||
|
|
||||||
// sparkline
|
|
||||||
sparkY := (sl.Y / lc) * (i + 1)
|
sparkY := (sl.Y / lc) * (i + 1)
|
||||||
// finds max used for relative heights
|
|
||||||
|
// finds max data in current view used for relative heights
|
||||||
max := 1
|
max := 1
|
||||||
for i := len(line.Data) - 1; i >= 0 && sl.X-((len(line.Data)-1)-i) >= 1; i-- {
|
for i := len(line.Data) - 1; i >= 0 && sl.X-((len(line.Data)-1)-i) >= 1; i-- {
|
||||||
if line.Data[i] > max {
|
if line.Data[i] > max {
|
||||||
|
|||||||
@ -8,15 +8,17 @@ import (
|
|||||||
// Table tracks all the attributes of a Table instance
|
// Table tracks all the attributes of a Table instance
|
||||||
type Table struct {
|
type Table struct {
|
||||||
*Block
|
*Block
|
||||||
Header []string
|
Header []string
|
||||||
Rows [][]string
|
Rows [][]string
|
||||||
Fg Color
|
Fg Color
|
||||||
Bg Color
|
Bg Color
|
||||||
Cursor Color
|
Cursor Color
|
||||||
|
// the unique column used to keep track of which process we're one
|
||||||
|
// either the PID column or Command column depending on if processes are grouped
|
||||||
UniqueCol int
|
UniqueCol int
|
||||||
pid string
|
pid string // used to keep the cursor on the correct process after each update
|
||||||
selected int
|
selected int // selected row
|
||||||
topRow int
|
topRow int // top process in current view
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTable returns a new Table instance
|
// NewTable returns a new Table instance
|
||||||
@ -32,7 +34,7 @@ func NewTable() *Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer ...
|
// Buffer implements the Bufferer interface.
|
||||||
func (t *Table) Buffer() *Buffer {
|
func (t *Table) Buffer() *Buffer {
|
||||||
buf := t.Block.Buffer()
|
buf := t.Block.Buffer()
|
||||||
|
|
||||||
@ -58,9 +60,9 @@ func (t *Table) Buffer() *Buffer {
|
|||||||
|
|
||||||
// total width requires by all 4 columns
|
// total width requires by all 4 columns
|
||||||
contentWidth := gap + cw[0] + gap + cw[1] + gap + cw[2] + gap + cw[3] + gap
|
contentWidth := gap + cw[0] + gap + cw[1] + gap + cw[2] + gap + cw[3] + gap
|
||||||
render := 4 // number of columns to iterate through
|
render := 4 // number of columns to render based on the terminal width
|
||||||
|
|
||||||
// removes CPU and MEM if there isn't enough room
|
// removes CPU and MEM columns if there isn't enough room
|
||||||
if t.X < (contentWidth - gap - cw[3]) {
|
if t.X < (contentWidth - gap - cw[3]) {
|
||||||
render = 2
|
render = 2
|
||||||
} else if t.X < contentWidth {
|
} else if t.X < contentWidth {
|
||||||
@ -75,8 +77,6 @@ func (t *Table) Buffer() *Buffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prints each row
|
// prints each row
|
||||||
// for y, row := range t.Rows {
|
|
||||||
// for y := t.topRow; y <= t.topRow+t.Y; y++ {
|
|
||||||
for rowNum := t.topRow; rowNum < t.topRow+t.Y-1 && rowNum < len(t.Rows); rowNum++ {
|
for rowNum := t.topRow; rowNum < t.topRow+t.Y-1 && rowNum < len(t.Rows); rowNum++ {
|
||||||
row := t.Rows[rowNum]
|
row := t.Rows[rowNum]
|
||||||
y := (rowNum + 2) - t.topRow
|
y := (rowNum + 2) - t.topRow
|
||||||
@ -92,7 +92,7 @@ func (t *Table) Buffer() *Buffer {
|
|||||||
t.selected = rowNum
|
t.selected = rowNum
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints each string
|
// prints each col of the row
|
||||||
for i := 0; i < render; i++ {
|
for i := 0; i < render; i++ {
|
||||||
r := MaxString(row[i], t.X-6)
|
r := MaxString(row[i], t.X-6)
|
||||||
buf.SetString(cp[i], y, r, t.Fg, bg)
|
buf.SetString(cp[i], y, r, t.Fg, bg)
|
||||||
@ -104,6 +104,7 @@ func (t *Table) Buffer() *Buffer {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// calcPos is used to calculate the cursor position and where in the process list we are located.
|
||||||
func (t *Table) calcPos() {
|
func (t *Table) calcPos() {
|
||||||
t.pid = ""
|
t.pid = ""
|
||||||
|
|
||||||
@ -171,6 +172,7 @@ func (t *Table) Click(x, y int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Kill kills process or group of processes.
|
||||||
func (t *Table) Kill() {
|
func (t *Table) Kill() {
|
||||||
t.pid = ""
|
t.pid = ""
|
||||||
command := "kill"
|
command := "kill"
|
||||||
|
|||||||
@ -25,11 +25,11 @@ Process Sorting:
|
|||||||
`
|
`
|
||||||
|
|
||||||
type HelpMenu struct {
|
type HelpMenu struct {
|
||||||
ui.Block
|
*ui.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHelpMenu() *HelpMenu {
|
func NewHelpMenu() *HelpMenu {
|
||||||
block := *ui.NewBlock()
|
block := ui.NewBlock()
|
||||||
block.X = 48 // width
|
block.X = 48 // width
|
||||||
block.Y = 15 // height
|
block.Y = 15 // height
|
||||||
block.XOffset = (ui.Body.Width - block.X) / 2 // X coordinate
|
block.XOffset = (ui.Body.Width - block.X) / 2 // X coordinate
|
||||||
|
|||||||
@ -57,8 +57,9 @@ func (n *Net) update() {
|
|||||||
n.recvTotal = recv
|
n.recvTotal = recv
|
||||||
n.sentTotal = sent
|
n.sentTotal = sent
|
||||||
|
|
||||||
|
// renders net widget titles
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
var method string
|
var method string // either 'Rx' or 'Tx'
|
||||||
var total uint64
|
var total uint64
|
||||||
cur := n.Lines[i].Data[len(n.Lines[i].Data)-1]
|
cur := n.Lines[i].Data[len(n.Lines[i].Data)-1]
|
||||||
totalUnit := "B"
|
totalUnit := "B"
|
||||||
|
|||||||
@ -15,7 +15,7 @@ const (
|
|||||||
UP = "▲"
|
UP = "▲"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Process represents each process
|
// Process represents each process.
|
||||||
type Process struct {
|
type Process struct {
|
||||||
PID int32
|
PID int32
|
||||||
Command string
|
Command string
|
||||||
@ -23,7 +23,7 @@ type Process struct {
|
|||||||
Mem float32
|
Mem float32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proc is the widget
|
// Proc widget.
|
||||||
type Proc struct {
|
type Proc struct {
|
||||||
*ui.Table
|
*ui.Table
|
||||||
cpuCount int
|
cpuCount int
|
||||||
@ -35,7 +35,7 @@ type Proc struct {
|
|||||||
KeyPressed chan bool
|
KeyPressed chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new Proc widget
|
// NewProc creates a new Proc widget.
|
||||||
func NewProc(loaded, keyPressed chan bool) *Proc {
|
func NewProc(loaded, keyPressed chan bool) *Proc {
|
||||||
cpuCount, _ := cpu.Counts(false)
|
cpuCount, _ := cpu.Counts(false)
|
||||||
p := &Proc{
|
p := &Proc{
|
||||||
@ -70,6 +70,7 @@ func NewProc(loaded, keyPressed chan bool) *Proc {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update updates proc widget.
|
||||||
func (p *Proc) update() {
|
func (p *Proc) update() {
|
||||||
psProcs, _ := proc.Processes()
|
psProcs, _ := proc.Processes()
|
||||||
processes := make([]Process, len(psProcs))
|
processes := make([]Process, len(psProcs))
|
||||||
@ -92,7 +93,8 @@ func (p *Proc) update() {
|
|||||||
p.Sort()
|
p.Sort()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort sorts either the grouped or ungrouped []Process based on the sortMethod
|
// Sort 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.
|
||||||
func (p *Proc) Sort() {
|
func (p *Proc) Sort() {
|
||||||
p.Header = []string{"Count", "Command", "CPU%", "Mem%"}
|
p.Header = []string{"Count", "Command", "CPU%", "Mem%"}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user