Skip to content

Commit

Permalink
Merge remote-tracking branch 'rephorm/filter'
Browse files Browse the repository at this point in the history
  • Loading branch information
xxxserxxx committed Feb 14, 2020
2 parents 64d4a81 + 246ebfb commit f850a47
Show file tree
Hide file tree
Showing 12 changed files with 266 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Bug fixes & pull requests
- Merged pull request for README clean-ups (theverything:add-missing-option-to-readme)
- Merge Nord color scheme (jrswab:nordColorScheme)
- Merge support for multiple (and filtering) network interfaces (mattLLVW:feature/network_interface_list)
- Merge filtering subprocesses by substring (rephorm:filter)

## [3.1.0] - 2020-02-13

Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ Unzip it and then move `gotop` into your `$PATH` somewhere. If you're on a Debi
### Keybinds

- Quit: `q` or `<C-c>`
- Process navigation
- Process navigation:
- `k` and `<Up>`: up
- `j` and `<Down`: down
- `j` and `<Down>`: down
- `<C-u>`: half page up
- `<C-d>`: half page down
- `<C-b>`: full page up
Expand All @@ -55,6 +55,11 @@ Unzip it and then move `gotop` into your `$PATH` somewhere. If you're on a Debi
- `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
Expand Down
9 changes: 9 additions & 0 deletions cmd/gotop/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ func eventLoop(c gotop.Config, grid *layout.MyGrid) {
}
}
case e := <-uiEvents:
if grid.Proc != nil && grid.Proc.HandleEvent(e) {
ui.Render(grid.Proc)
break
}
switch e.ID {
case "q", "<C-c>":
return
Expand Down Expand Up @@ -354,6 +358,11 @@ func eventLoop(c gotop.Config, grid *layout.MyGrid) {
grid.Proc.ChangeProcSortMethod(w.ProcSortMethod(e.ID))
ui.Render(grid.Proc)
}
case "/":
if grid.Proc != nil {
grid.Proc.SetEditingFilter(true)
ui.Render(grid.Proc)
}
}

if previousKey == e.ID {
Expand Down
1 change: 0 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
// TODO: Merge #167 configuration file (jrswab:configFile111)
// TODO: Merge #157 FreeBSD fixes & Nvidia GPU support (kraust:master)
// TODO: Merge #156 Added temperatures for NVidia GPUs (azak-azkaran:master)
// TODO: Merge #147 filtering subprocesses by substring (rephorm:filter)
// TODO: Merge #140 color-related fix (Tazer:master)
// TODO: Merge #135 linux console font (cmatsuoka:console-font)
type Config struct {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/docopt/docopt.go v0.0.0-20180111231733-ee0de3bc6815
github.com/gizak/termui/v3 v3.0.0
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/mattn/go-runewidth v0.0.4
github.com/shirou/gopsutil v2.18.11+incompatible
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
github.com/stretchr/testify v1.4.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
Expand Down
113 changes: 113 additions & 0 deletions termui/entry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package termui

import (
"image"
"strings"
"unicode/utf8"

. "github.com/gizak/termui/v3"
rw "github.com/mattn/go-runewidth"
"github.com/xxxserxxx/gotop/utils"
)

const (
ELLIPSIS = "…"
CURSOR = " "
)

type Entry struct {
Block

Style Style

Label string
Value string
ShowWhenEmpty bool
UpdateCallback func(string)

editing bool
}

func (self *Entry) SetEditing(editing bool) {
self.editing = editing
}

func (self *Entry) update() {
if self.UpdateCallback != nil {
self.UpdateCallback(self.Value)
}
}

// HandleEvent handles input events if the entry is being edited.
// Returns true if the event was handled.
func (self *Entry) HandleEvent(e Event) bool {
if !self.editing {
return false
}
if utf8.RuneCountInString(e.ID) == 1 {
self.Value += e.ID
self.update()
return true
}
switch e.ID {
case "<C-c>", "<Escape>":
self.Value = ""
self.editing = false
self.update()
case "<Enter>":
self.editing = false
case "<Backspace>":
if self.Value != "" {
r := []rune(self.Value)
self.Value = string(r[:len(r)-1])
self.update()
}
case "<Space>":
self.Value += " "
self.update()
default:
return false
}
return true
}

func (self *Entry) Draw(buf *Buffer) {
if self.Value == "" && !self.editing && !self.ShowWhenEmpty {
return
}

style := self.Style
label := self.Label
if self.editing {
label += "["
style = NewStyle(style.Fg, style.Bg, ModifierBold)
}
cursorStyle := NewStyle(style.Bg, style.Fg, ModifierClear)

p := image.Pt(self.Min.X, self.Min.Y)
buf.SetString(label, style, p)
p.X += rw.StringWidth(label)

tail := " "
if self.editing {
tail = "] "
}

maxLen := self.Max.X - p.X - rw.StringWidth(tail)
if self.editing {
maxLen -= 1 // for cursor
}
value := utils.TruncateFront(self.Value, maxLen, ELLIPSIS)
buf.SetString(value, self.Style, p)
p.X += rw.StringWidth(value)

if self.editing {
buf.SetString(CURSOR, cursorStyle, p)
p.X += rw.StringWidth(CURSOR)
if remaining := maxLen - rw.StringWidth(value); remaining > 0 {
buf.SetString(strings.Repeat(" ", remaining), self.TitleStyle, p)
p.X += remaining
}
}
buf.SetString(tail, style, p)
}
3 changes: 3 additions & 0 deletions termui/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ func (self *Table) Draw(buf *Buffer) {
func (self *Table) drawLocation(buf *Buffer) {
total := len(self.Rows)
topRow := self.TopRow + 1
if topRow > total {
topRow = total
}
bottomRow := self.TopRow + self.Inner.Dy() - 1
if bottomRow > total {
bottomRow = total
Expand Down
24 changes: 24 additions & 0 deletions utils/runes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package utils

import (
rw "github.com/mattn/go-runewidth"
)

func TruncateFront(s string, w int, prefix string) string {
if rw.StringWidth(s) <= w {
return s
}
r := []rune(s)
pw := rw.StringWidth(prefix)
w -= pw
width := 0
i := len(r) - 1
for ; i >= 0; i-- {
cw := rw.RuneWidth(r[i])
width += cw
if width > w {
break
}
}
return prefix + string(r[i+1:len(r)])
}
50 changes: 50 additions & 0 deletions utils/runes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package utils

import "testing"

const (
ELLIPSIS = "…"
)

func TestTruncateFront(t *testing.T) {
tests := []struct {
s string
w int
prefix string
want string
}{
{"", 0, ELLIPSIS, ""},
{"", 1, ELLIPSIS, ""},
{"", 10, ELLIPSIS, ""},

{"abcdef", 0, ELLIPSIS, ELLIPSIS},
{"abcdef", 1, ELLIPSIS, ELLIPSIS},
{"abcdef", 2, ELLIPSIS, ELLIPSIS + "f"},
{"abcdef", 5, ELLIPSIS, ELLIPSIS + "cdef"},
{"abcdef", 6, ELLIPSIS, "abcdef"},
{"abcdef", 10, ELLIPSIS, "abcdef"},

{"abcdef", 0, "...", "..."},
{"abcdef", 1, "...", "..."},
{"abcdef", 3, "...", "..."},
{"abcdef", 4, "...", "...f"},
{"abcdef", 5, "...", "...ef"},
{"abcdef", 6, "...", "abcdef"},
{"abcdef", 10, "...", "abcdef"},

{"⦅full~width⦆", 15, ".", "⦅full~width⦆"},
{"⦅full~width⦆", 14, ".", ".full~width⦆"},
{"⦅full~width⦆", 13, ".", ".ull~width⦆"},
{"⦅full~width⦆", 10, ".", ".~width⦆"},
{"⦅full~width⦆", 9, ".", ".width⦆"},
{"⦅full~width⦆", 8, ".", ".width⦆"},
{"⦅full~width⦆", 3, ".", ".⦆"},
{"⦅full~width⦆", 2, ".", "."},
}

for _, test := range tests {
if got := TruncateFront(test.s, test.w, test.prefix); got != test.want {
t.Errorf("TruncateFront(%q, %d, %q) = %q; want %q", test.s, test.w, test.prefix, got, test.want)
}
}
}
18 changes: 10 additions & 8 deletions widgets/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
const KEYBINDS = `
Quit: q or <C-c>
Process navigation
Process navigation:
- k and <Up>: up
- j and <Down>: down
- <C-u>: half page up
Expand All @@ -26,11 +26,17 @@ Process actions:
- d3: kill selected process or group of processes with SIGQUIT (3)
- d9: kill selected process or group of processes with SIGKILL (9)
Process sorting
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
Expand All @@ -47,12 +53,8 @@ func NewHelpMenu() *HelpMenu {
}

func (self *HelpMenu) Resize(termWidth, termHeight int) {
var textWidth = 0
for _, line := range strings.Split(KEYBINDS, "\n") {
textWidth = maxInt(len(line), textWidth)
}
textWidth += 2
textHeight := 28
textWidth := 53
textHeight := strings.Count(KEYBINDS, "\n") + 1
x := (termWidth - textWidth) / 2
y := (termHeight - textHeight) / 2

Expand Down
Loading

0 comments on commit f850a47

Please sign in to comment.