Add context-specific commands

This commit is contained in:
Drew DeVault 2019-03-21 16:30:23 -04:00
parent fe79a9a587
commit 8126d82956
14 changed files with 103 additions and 35 deletions

36
aerc.go
View file

@ -11,10 +11,23 @@ import (
"git.sr.ht/~sircmpwn/aerc2/config" "git.sr.ht/~sircmpwn/aerc2/config"
"git.sr.ht/~sircmpwn/aerc2/commands" "git.sr.ht/~sircmpwn/aerc2/commands"
"git.sr.ht/~sircmpwn/aerc2/commands/account"
libui "git.sr.ht/~sircmpwn/aerc2/lib/ui" libui "git.sr.ht/~sircmpwn/aerc2/lib/ui"
"git.sr.ht/~sircmpwn/aerc2/widgets" "git.sr.ht/~sircmpwn/aerc2/widgets"
) )
func getCommands(selected libui.Drawable) []*commands.Commands {
switch selected.(type) {
case *widgets.AccountView:
return []*commands.Commands{
commands.GlobalCommands,
account.AccountCommands,
}
default:
return []*commands.Commands{commands.GlobalCommands}
}
}
func main() { func main() {
var ( var (
logOut io.Writer logOut io.Writer
@ -38,12 +51,25 @@ func main() {
ui *libui.UI ui *libui.UI
) )
aerc = widgets.NewAerc(conf, logger, func(cmd string) error { aerc = widgets.NewAerc(conf, logger, func(cmd string) error {
err = commands.ExecuteCommand(aerc, cmd) cmds := getCommands(aerc.SelectedTab())
if _, ok := err.(commands.ErrorExit); ok { for i, set := range cmds {
ui.Exit = true err := set.ExecuteCommand(aerc, cmd)
return nil if _, ok := err.(commands.NoSuchCommand); ok {
if i == len(cmds) - 1 {
return err
} else {
continue
}
} else if _, ok := err.(commands.ErrorExit); ok {
ui.Exit = true
return nil
} else if err != nil {
return err
} else {
break
}
} }
return err return nil
}) })
ui, err = libui.Initialize(conf, aerc) ui, err = libui.Initialize(conf, aerc)

View file

@ -0,0 +1,16 @@
package account
import (
"git.sr.ht/~sircmpwn/aerc2/commands"
)
var (
AccountCommands *commands.Commands
)
func register(name string, cmd commands.AercCommand) {
if AccountCommands == nil {
AccountCommands = commands.NewCommands()
}
AccountCommands.Register(name, cmd)
}

View file

@ -1,4 +1,4 @@
package commands package account
import ( import (
"errors" "errors"
@ -12,7 +12,7 @@ var (
func init() { func init() {
history = make(map[string]string) history = make(map[string]string)
Register("cf", ChangeFolder) register("cf", ChangeFolder)
} }
func ChangeFolder(aerc *widgets.Aerc, args []string) error { func ChangeFolder(aerc *widgets.Aerc, args []string) error {

View file

@ -1,4 +1,4 @@
package commands package account
import ( import (
"errors" "errors"
@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
Register("delete-message", DeleteMessage) register("delete-message", DeleteMessage)
} }
func DeleteMessage(aerc *widgets.Aerc, args []string) error { func DeleteMessage(aerc *widgets.Aerc, args []string) error {

View file

@ -1,4 +1,4 @@
package commands package account
import ( import (
"errors" "errors"
@ -9,8 +9,8 @@ import (
) )
func init() { func init() {
Register("next-folder", NextPrevFolder) register("next-folder", NextPrevFolder)
Register("prev-folder", NextPrevFolder) register("prev-folder", NextPrevFolder)
} }
func nextPrevFolderUsage(cmd string) error { func nextPrevFolderUsage(cmd string) error {

View file

@ -1,4 +1,4 @@
package commands package account
import ( import (
"errors" "errors"
@ -10,8 +10,8 @@ import (
) )
func init() { func init() {
Register("next-message", NextPrevMessage) register("next-message", NextPrevMessage)
Register("prev-message", NextPrevMessage) register("prev-message", NextPrevMessage)
} }
func nextPrevMessageUsage(cmd string) error { func nextPrevMessageUsage(cmd string) error {

View file

@ -1,4 +1,4 @@
package commands package account
import ( import (
"errors" "errors"
@ -8,7 +8,7 @@ import (
) )
func init() { func init() {
Register("select-message", SelectMessage) register("select-message", SelectMessage)
} }
func SelectMessage(aerc *widgets.Aerc, args []string) error { func SelectMessage(aerc *widgets.Aerc, args []string) error {

View file

@ -13,7 +13,7 @@ var (
) )
func init() { func init() {
Register("cd", ChangeDirectory) register("cd", ChangeDirectory)
} }
func ChangeDirectory(aerc *widgets.Aerc, args []string) error { func ChangeDirectory(aerc *widgets.Aerc, args []string) error {

View file

@ -10,18 +10,32 @@ import (
type AercCommand func(aerc *widgets.Aerc, args []string) error type AercCommand func(aerc *widgets.Aerc, args []string) error
var ( type Commands map[string]AercCommand
commands map[string]AercCommand
)
func Register(name string, cmd AercCommand) { func NewCommands() *Commands {
if commands == nil { cmds := Commands(make(map[string]AercCommand))
commands = make(map[string]AercCommand) return &cmds
}
commands[name] = cmd
} }
func ExecuteCommand(aerc *widgets.Aerc, cmd string) error { func (cmds *Commands) dict() map[string]AercCommand {
return map[string]AercCommand(*cmds)
}
func (cmds *Commands) Register(name string, cmd AercCommand) {
cmds.dict()[name] = cmd
}
type NoSuchCommand string
func (err NoSuchCommand) Error() string {
return "Unknown command " + string(err)
}
type CommandSource interface {
Commands() *Commands
}
func (cmds *Commands) ExecuteCommand(aerc *widgets.Aerc, cmd string) error {
args, err := shlex.Split(cmd) args, err := shlex.Split(cmd)
if err != nil { if err != nil {
return err return err
@ -29,8 +43,8 @@ func ExecuteCommand(aerc *widgets.Aerc, cmd string) error {
if len(args) == 0 { if len(args) == 0 {
return errors.New("Expected a command.") return errors.New("Expected a command.")
} }
if fn, ok := commands[args[0]]; ok { if fn, ok := cmds.dict()[args[0]]; ok {
return fn(aerc, args) return fn(aerc, args)
} }
return errors.New("Unknown command " + args[0]) return NoSuchCommand(args[0])
} }

12
commands/global.go Normal file
View file

@ -0,0 +1,12 @@
package commands
var (
GlobalCommands *Commands
)
func register(name string, cmd AercCommand) {
if GlobalCommands == nil {
GlobalCommands = NewCommands()
}
GlobalCommands.Register(name, cmd)
}

View file

@ -9,8 +9,8 @@ import (
) )
func init() { func init() {
Register("next-tab", NextPrevTab) register("next-tab", NextPrevTab)
Register("prev-tab", NextPrevTab) register("prev-tab", NextPrevTab)
} }
func nextPrevTabUsage(cmd string) error { func nextPrevTabUsage(cmd string) error {

View file

@ -7,7 +7,7 @@ import (
) )
func init() { func init() {
Register("quit", ChangeQuit) register("quit", CommandQuit)
} }
type ErrorExit int type ErrorExit int
@ -16,7 +16,7 @@ func (err ErrorExit) Error() string {
return "exit" return "exit"
} }
func ChangeQuit(aerc *widgets.Aerc, args []string) error { func CommandQuit(aerc *widgets.Aerc, args []string) error {
if len(args) != 1 { if len(args) != 1 {
return errors.New("Usage: quit") return errors.New("Usage: quit")
} }

View file

@ -8,7 +8,7 @@ import (
func init() { func init() {
// TODO: Move this command into a terminal-specific command set // TODO: Move this command into a terminal-specific command set
Register("close", TermClose) register("close", TermClose)
} }
func TermClose(aerc *widgets.Aerc, args []string) error { func TermClose(aerc *widgets.Aerc, args []string) error {

View file

@ -11,7 +11,7 @@ import (
) )
func init() { func init() {
Register("term", Term) register("term", Term)
} }
func Term(aerc *widgets.Aerc, args []string) error { func Term(aerc *widgets.Aerc, args []string) error {