Skip to content

Commit

Permalink
Open the minibuffer if the user hits ":"
Browse files Browse the repository at this point in the history
Intended to mimic how you get to last-line mode in vim.
  • Loading branch information
gcla committed Jul 12, 2020
1 parent 2eda27c commit cf55f11
Show file tree
Hide file tree
Showing 4 changed files with 295 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ui/dialog.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/gcla/gowid/widgets/text"
"github.com/gcla/termshark/v2"
"github.com/gcla/termshark/v2/widgets/appkeys"
"github.com/gcla/termshark/v2/widgets/minibuffer"
)

//======================================================================
Expand All @@ -27,6 +28,7 @@ var (
hmiddle gowid.HAlignMiddle
vmiddle gowid.VAlignMiddle
YesNo *dialog.Widget
MiniBuffer *minibuffer.Widget
PleaseWait *dialog.Widget
)

Expand Down
223 changes: 223 additions & 0 deletions ui/lastline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
// Copyright 2019-2020 Graham Clark. All rights reserved. Use of this source
// code is governed by the MIT license that can be found in the LICENSE
// file.

// Package ui contains user-interface functions and helpers for termshark.
package ui

import (
"fmt"
"strconv"

"github.com/gcla/gowid"
"github.com/gcla/gowid/gwutil"
"github.com/gcla/termshark/v2"
"github.com/gcla/termshark/v2/widgets/minibuffer"
)

//======================================================================

var notEnoughArgumentsErr = fmt.Errorf("Not enough arguments provided")

type minibufferFn func(gowid.IApp, ...string) error

func (m minibufferFn) Run(app gowid.IApp, args ...string) error {
return m(app, args...)
}

func (m minibufferFn) OfferCompletion() bool {
return true
}

func (m minibufferFn) Arguments([]string) []minibuffer.IArg {
return nil
}

type quietMinibufferFn func(gowid.IApp, ...string) error

func (m quietMinibufferFn) Run(app gowid.IApp, args ...string) error {
return m(app, args...)
}

func (m quietMinibufferFn) OfferCompletion() bool {
return false
}

func (m quietMinibufferFn) Arguments([]string) []minibuffer.IArg {
return nil
}

//======================================================================

type boolArg struct {
arg string
}

var _ minibuffer.IArg = boolArg{}

func (s boolArg) OfferCompletion() bool {
return true
}

// return these in sorted order
func (s boolArg) Completions() []string {
return []string{"false", "true"}
}

//======================================================================

type onOffArg struct {
arg string
}

var _ minibuffer.IArg = onOffArg{}

func (s onOffArg) OfferCompletion() bool {
return true
}

// return these in sorted order
func (s onOffArg) Completions() []string {
return []string{"off", "on"}
}

//======================================================================

type unhelpfulArg struct {
arg string
}

var _ minibuffer.IArg = unhelpfulArg{}

func (s unhelpfulArg) OfferCompletion() bool {
return false
}

// return these in sorted order
func (s unhelpfulArg) Completions() []string {
return nil
}

//======================================================================

type setArg struct {
arg string
}

var _ minibuffer.IArg = setArg{}

func (s setArg) OfferCompletion() bool {
return true
}

// return these in sorted order
func (s setArg) Completions() []string {
return []string{
"auto-scroll",
"copy-command-timeout",
"dark-mode",
"disable-shark-fin",
"packet-colors",
}
}

//======================================================================

func stringIn(s string, a []string) bool {
for _, s2 := range a {
if s == s2 {
return true
}
}
return false
}

func parseOnOff(str string) (bool, error) {
switch str {
case "on", "ON", "On":
return true, nil
case "off", "OFF", "Off":
return false, nil
}
return false, strconv.ErrSyntax
}

type setCommand struct{}

var _ minibuffer.IAction = setCommand{}

func (d setCommand) Run(app gowid.IApp, args ...string) error {
var err error
var b bool
var i uint64
if len(args) == 3 {
switch args[1] {
case "auto-scroll":
if b, err = parseOnOff(args[2]); err == nil {
AutoScroll = b
termshark.SetConf("main.auto-scroll", AutoScroll)
OpenMessage(fmt.Sprintf("Packet auto-scroll is now %s", gwutil.If(b, "on", "off").(string)), appView, app)
}
case "copy-command-timeout":
if i, err = strconv.ParseUint(args[2], 10, 32); err == nil {
termshark.SetConf("main.copy-command-timeout", i)
OpenMessage(fmt.Sprintf("Copy command timeout is now %ds", i), appView, app)
}
case "dark-mode":
if b, err = parseOnOff(args[2]); err == nil {
DarkMode = b
termshark.SetConf("main.dark-mode", DarkMode)
}
case "disable-shark-fin":
if b, err = strconv.ParseBool(args[2]); err == nil {
termshark.SetConf("main.disable-shark-fin", DarkMode)
OpenMessage(fmt.Sprintf("Shark-saver is now %s", gwutil.If(b, "off", "on").(string)), appView, app)
}
case "packet-colors":
if b, err = parseOnOff(args[2]); err == nil {
PacketColors = b
termshark.SetConf("main.packet-colors", PacketColors)
OpenMessage(fmt.Sprintf("Packet colors are now %s", gwutil.If(b, "on", "off").(string)), appView, app)
}
}
} else {
err = notEnoughArgumentsErr
}

if err != nil {
OpenMessage(fmt.Sprintf("Error: %s", err), appView, app)
}

return err
}

func (d setCommand) OfferCompletion() bool {
return true
}

func (d setCommand) Arguments(toks []string) []minibuffer.IArg {
res := make([]minibuffer.IArg, 0)
res = append(res, setArg{})

if len(toks) > 0 {
onOffCmds := []string{"auto-scroll", "dark-mode", "packet-colors"}
boolCmds := []string{"disable-shark-fin"}
intCmds := []string{"disk-cache-size-mb", "copy-command-timeout"}

if stringIn(toks[0], boolCmds) {
res = append(res, boolArg{})
} else if stringIn(toks[0], intCmds) {
res = append(res, unhelpfulArg{})
} else if stringIn(toks[0], onOffCmds) {
res = append(res, onOffArg{})
}
}

return res
}

//======================================================================
// Local Variables:
// mode: Go
// fill-column: 110
// End:
1 change: 1 addition & 0 deletions ui/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ A wireshark-inspired tui for tshark. Analyze network traffic interactively from
't' - In bytes view, switch hex ⟷ ascii
'+/-' - Adjust horizontal split
'</>' - Adjust vertical split
':' - Last line mode (minibuffer)
'?' - Display help
In the filter, type a wireshark display filter expression.
Expand Down
69 changes: 69 additions & 0 deletions ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (
"github.com/gcla/termshark/v2/widgets/filter"
"github.com/gcla/termshark/v2/widgets/hexdumper2"
"github.com/gcla/termshark/v2/widgets/ifwidget"
"github.com/gcla/termshark/v2/widgets/minibuffer"
"github.com/gcla/termshark/v2/widgets/resizable"
"github.com/gcla/termshark/v2/widgets/rossshark"
"github.com/gcla/termshark/v2/widgets/withscrollbar"
Expand Down Expand Up @@ -938,6 +939,72 @@ func reallyQuit(app gowid.IApp) {
YesNo.Open(appView, units(len(msgt)+20), app)
}

func lastLineMode(app gowid.IApp) {
MiniBuffer = minibuffer.New()

MiniBuffer.Register("quit", minibufferFn(func(gowid.IApp, ...string) error {
// Delay because when control returns to the minibuffer, it closes itself
// if there is no error, but that has the side effect of closing this
// dialog too :-(
app.Run(gowid.RunFunction(func(app gowid.IApp) {
reallyQuit(app)
}))
return nil
}))

// force quit
MiniBuffer.Register("q!", quietMinibufferFn(func(gowid.IApp, ...string) error {
QuitRequestedChan <- struct{}{}
return nil
}))

MiniBuffer.Register("help", minibufferFn(func(gowid.IApp, ...string) error {
app.Run(gowid.RunFunction(func(app gowid.IApp) {
OpenTemplatedDialog(appView, "UIHelp", app)
}))
return nil
}))

MiniBuffer.Register("?", quietMinibufferFn(func(gowid.IApp, ...string) error {
app.Run(gowid.RunFunction(func(app gowid.IApp) {
OpenTemplatedDialog(appView, "UIHelp", app)
}))
return nil
}))

MiniBuffer.Register("convs", minibufferFn(func(gowid.IApp, ...string) error {
app.Run(gowid.RunFunction(func(app gowid.IApp) {
openConvsUi(app)
}))
return nil
}))

MiniBuffer.Register("streams", minibufferFn(func(gowid.IApp, ...string) error {
app.Run(gowid.RunFunction(func(app gowid.IApp) {
startStreamReassembly(app)
}))
return nil
}))

MiniBuffer.Register("capinfo", minibufferFn(func(gowid.IApp, ...string) error {
app.Run(gowid.RunFunction(func(app gowid.IApp) {
startCapinfo(app)
}))
return nil
}))

MiniBuffer.Register("clear", minibufferFn(func(gowid.IApp, ...string) error {
app.Run(gowid.RunFunction(func(app gowid.IApp) {
reallyClear(app)
}))
return nil
}))

MiniBuffer.Register("set", setCommand{})

minibuffer.Open(MiniBuffer, appView, ratio(1.0), flow, app)
}

//======================================================================

// getCurrentStructModel will return a termshark model of a packet section of PDML given a row number,
Expand Down Expand Up @@ -1404,6 +1471,8 @@ func appKeyPress(evk *tcell.EventKey, app gowid.IApp) bool {
app.Sync()
} else if evk.Rune() == 'q' || evk.Rune() == 'Q' {
reallyQuit(app)
} else if evk.Rune() == ':' {
lastLineMode(app)
} else if evk.Key() == tcell.KeyEscape {
gowid.SetFocusPath(mainview, menuPathMain, app)
gowid.SetFocusPath(altview1, menuPathAlt, app)
Expand Down

0 comments on commit cf55f11

Please sign in to comment.