Skip to content
This repository has been archived by the owner on Aug 29, 2020. It is now read-only.

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
Updated event management based on changes to termui
  • Loading branch information
cjbassi committed Nov 30, 2018
1 parent ce5342c commit 8ee8950
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 229 deletions.
27 changes: 17 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ git clone --depth 1 https://github.com/cjbassi/gotop /tmp/gotop
/tmp/gotop/scripts/download.sh
```

Then move `gotop` into your $PATH somewhere.
Then move `gotop` into your \$PATH somewhere.

### Arch Linux

Expand All @@ -47,18 +47,25 @@ go get github.com/cjbassi/gotop
### Keybinds

- Quit: `q` or `<C-c>`
- Process Navigation:
- `<up>`/`<down>` and `j`/`k`: up and down
- `<C-d>` and `<C-u>`: up and down half a page
- `<C-f>` and `<C-b>`: up and down a full page
- `gg` and `G`: jump to top and bottom
- Process Sorting:
- 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
- Process sorting
- `c`: CPU
- `m`: Mem
- `p`: PID
- `<tab>`: toggle process grouping
- `dd`: kill the selected process or process group
- `h` and `l`: zoom in and out of CPU and Mem graphs
- CPU and Mem graph scaling:
- `h`: scale in
- `l`: scale out
- `?`: toggles keybind help menu

### Mouse
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/cjbassi/gotop
require (
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/cjbassi/drawille-go v0.0.0-20180329221028-ad535d0f92cd // indirect
github.com/cjbassi/termui v0.0.0-20180823181054-5edfcb3a441f
github.com/cjbassi/termui v0.0.0-20181129231847-3a3db079d9dd
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
github.com/go-ole/go-ole v1.2.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ github.com/cjbassi/drawille-go v0.0.0-20180329221028-ad535d0f92cd h1:nSJpATLVvFa
github.com/cjbassi/drawille-go v0.0.0-20180329221028-ad535d0f92cd/go.mod h1:vjcQJUZJYD3MeVGhtZXSMnCHfUNZxsyYzJt90eCYxK4=
github.com/cjbassi/termui v0.0.0-20180823181054-5edfcb3a441f h1:t8d9FIPBeDHClPJBkB8yJyIBcMIxzdMAY2xB1vWHi48=
github.com/cjbassi/termui v0.0.0-20180823181054-5edfcb3a441f/go.mod h1:rqXckrwz+i0fH/zNwU6AdBNULHwmZsgehnSlhKP5i2Q=
github.com/cjbassi/termui v0.0.0-20181129202454-e08bceac6d82 h1:Nohf7C2tEJfEtfJ2mAF244MPJUj6JT9Quzf4ZrkmEfE=
github.com/cjbassi/termui v0.0.0-20181129202454-e08bceac6d82/go.mod h1:rqXckrwz+i0fH/zNwU6AdBNULHwmZsgehnSlhKP5i2Q=
github.com/cjbassi/termui v0.0.0-20181129231847-3a3db079d9dd h1:12/9RCEyFB4mnNlafhySzhfPgFIfTxbjHrkhEX0SgDQ=
github.com/cjbassi/termui v0.0.0-20181129231847-3a3db079d9dd/go.mod h1:rqXckrwz+i0fH/zNwU6AdBNULHwmZsgehnSlhKP5i2Q=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
Expand Down
236 changes: 122 additions & 114 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,22 @@ import (
var version = "1.5.1"

var (
termResized = make(chan bool, 1)

helpToggled = make(chan bool, 1)
helpVisible = false

wg sync.WaitGroup
// used to render the proc widget whenever a key is pressed for it
keyPressed = make(chan bool, 1)
// used to render cpu and mem when zoom has changed
zoomed = make(chan bool, 1)

colorscheme = colorschemes.Default

colorscheme = colorschemes.Default
minimal = false
widgetCount = 6
interval = time.Second
zoom = 7
zoomInterval = 3

averageLoad = false
percpuLoad = false
helpVisible = false
averageLoad = false
percpuLoad = false
widgetCount = 6

cpu *w.CPU
mem *w.Mem
proc *w.Proc
net *w.Net
disk *w.Disk
temp *w.Temp

help *w.HelpMenu
)

Expand Down Expand Up @@ -78,6 +65,8 @@ Colorschemes:
if val, _ := args["--color"]; val != nil {
handleColorscheme(val.(string))
}
averageLoad, _ = args["--averagecpu"].(bool)
percpuLoad, _ = args["--percpu"].(bool)

minimal, _ = args["--minimal"].(bool)
if minimal {
Expand All @@ -91,9 +80,6 @@ Colorschemes:
} else {
interval = time.Second / time.Duration(rate)
}

averageLoad, _ = args["--averagecpu"].(bool)
percpuLoad, _ = args["--percpu"].(bool)
}

func handleColorscheme(cs string) {
Expand Down Expand Up @@ -153,41 +139,6 @@ func setupGrid() {
}
}

func keyBinds() {
// quits
ui.On("q", "<C-c>", func(e ui.Event) {
ui.StopLoop()
})

// toggles help menu
ui.On("?", func(e ui.Event) {
helpToggled <- true
helpVisible = !helpVisible
})
// hides help menu
ui.On("<escape>", func(e ui.Event) {
if helpVisible {
helpToggled <- true
helpVisible = false
}
})

ui.On("h", func(e ui.Event) {
zoom += zoomInterval
cpu.Zoom = zoom
mem.Zoom = zoom
zoomed <- true
})
ui.On("l", func(e ui.Event) {
if zoom > zoomInterval {
zoom -= zoomInterval
cpu.Zoom = zoom
mem.Zoom = zoom
zoomed <- true
}
})
}

func termuiColors() {
ui.Theme.Fg = ui.Color(colorscheme.Fg)
ui.Theme.Bg = ui.Color(colorscheme.Bg)
Expand Down Expand Up @@ -227,8 +178,8 @@ func widgetColors() {
}
}

// load widgets asynchronously but wait till they are all finished
func initWidgets() {
var wg sync.WaitGroup
wg.Add(widgetCount)

go func() {
Expand All @@ -240,7 +191,7 @@ func initWidgets() {
wg.Done()
}()
go func() {
proc = w.NewProc(keyPressed)
proc = w.NewProc()
wg.Done()
}()
if !minimal {
Expand All @@ -261,75 +212,132 @@ func initWidgets() {
wg.Wait()
}

func main() {
cliArguments()

keyBinds()

// need to do this before initializing widgets so that they can inherit the colors
termuiColors()

initWidgets()

widgetColors()

help = w.NewHelpMenu()

// inits termui
err := ui.Init()
if err != nil {
panic(err)
}
defer ui.Close()
func eventLoop() {
drawTicker := time.NewTicker(interval).C

setupGrid()
// handles kill signal sent to gotop
sigTerm := make(chan os.Signal, 2)
signal.Notify(sigTerm, os.Interrupt, syscall.SIGTERM)

ui.On("<resize>", func(e ui.Event) {
ui.Body.Width, ui.Body.Height = e.Width, e.Height
ui.Body.Resize()
uiEvents := ui.PollEvents()

termResized <- true
})
previousKey := ""

// all rendering done here
go func() {
ui.Render(ui.Body)
drawTick := time.NewTicker(interval)
for {
if helpVisible {
select {
case <-helpToggled:
ui.Render(ui.Body)
case <-termResized:
for {
select {
case <-sigTerm:
return
case <-drawTicker:
if !helpVisible {
ui.Render(ui.Body)
}
case e := <-uiEvents:
switch e.ID {
case "q", "<C-c>":
return
case "?":
helpVisible = !helpVisible
if helpVisible {
ui.Clear()
ui.Render(help)
} else {
ui.Render(ui.Body)
}
} else {
select {
case <-helpToggled:
ui.Clear()
case "h":
if !helpVisible {
zoom += zoomInterval
cpu.Zoom = zoom
mem.Zoom = zoom
ui.Render(cpu, mem)
}
case "l":
if !helpVisible {
if zoom > zoomInterval {
zoom -= zoomInterval
cpu.Zoom = zoom
mem.Zoom = zoom
ui.Render(cpu, mem)
}
}
case "<Escape>":
if helpVisible {
helpVisible = false
ui.Render(ui.Body)
}
case "<Resize>":
payload := e.Payload.(ui.Resize)
ui.Body.Width, ui.Body.Height = payload.Width, payload.Height
ui.Body.Resize()
ui.Clear()
if helpVisible {
ui.Render(help)
case <-termResized:
ui.Clear()
} else {
ui.Render(ui.Body)
case <-keyPressed:
}

case "<MouseLeft>":
payload := e.Payload.(ui.Mouse)
proc.Click(payload.X, payload.Y)
ui.Render(proc)
case "<MouseWheelUp>", "<Up>", "k":
proc.Up()
ui.Render(proc)
case "<MouseWheelDown>", "<Down>", "j":
proc.Down()
ui.Render(proc)
case "g", "<Home>":
if previousKey == "g" {
proc.Top()
ui.Render(proc)
case <-zoomed:
ui.Render(cpu, mem)
case <-drawTick.C:
ui.Render(ui.Body)
previousKey = ""
}
case "G", "<End>":
proc.Bottom()
ui.Render(proc)
case "<C-d>":
proc.HalfPageDown()
ui.Render(proc)
case "<C-u>":
proc.HalfPageUp()
ui.Render(proc)
case "<C-f>":
proc.PageDown()
ui.Render(proc)
case "<C-b>":
proc.PageUp()
ui.Render(proc)
case "d":
if previousKey == "d" {
proc.Kill()
previousKey = ""
}
case "<Tab>":
proc.Tab()
ui.Render(proc)
case "m", "c", "p":
proc.ChangeSort(e)
ui.Render(proc)
}
previousKey = e.ID
}
}()
}
}

// handles kill signal sent to gotop
c := make(chan os.Signal, 2)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
ui.StopLoop()
}()
func main() {
cliArguments()
termuiColors() // need to do this before initializing widgets so that they can inherit the colors
initWidgets()
widgetColors()
help = w.NewHelpMenu()

ui.Loop()
// inits termui
err := ui.Init()
if err != nil {
panic(err)
}
defer ui.Close()

setupGrid()
ui.Render(ui.Body)
eventLoop()
}
6 changes: 3 additions & 3 deletions src/widgets/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ func NewCPU(interval time.Duration, zoom int, average bool, percpu bool) *CPU {
}
}

ticker := time.NewTicker(self.interval)
go self.update() // update asynchronously because of 1 second blocking period

go func() {
// update asynchronously because of 1 second blocking period
go self.update()
ticker := time.NewTicker(self.interval)
for range ticker.C {
self.update()
}
Expand Down
2 changes: 1 addition & 1 deletion src/widgets/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ func NewDisk() *Disk {

self.update()

ticker := time.NewTicker(self.interval)
go func() {
ticker := time.NewTicker(self.interval)
for range ticker.C {
self.update()
}
Expand Down
Loading

0 comments on commit 8ee8950

Please sign in to comment.