aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2023-10-11 21:28:30 +0200
committerRobin Jarry <robin@jarry.cc>2023-10-28 19:24:52 +0200
commit591659b52867cb118d1f82d41693a02123935e0c (patch)
tree8cf2e5f16a7891f690bc07f83e35f27994cd2530
parente54486ee40c9cedde9d4dae3e89d8b5f932188ee (diff)
downloadaerc-591659b52867cb118d1f82d41693a02123935e0c.tar.gz
aerc-591659b52867cb118d1f82d41693a02123935e0c.zip
main: parse command line args with go-opt
Use get-opt to make argument parsing more explicit and have automatic usage generation. Update the man page to include missing details. Add a -h flag to display verbose usage and descriptions of options. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Koni Marti <koni.marti@gmail.com> Tested-by: Moritz Poldrack <moritz@poldrack.dev> Tested-by: Inwit <inwit@sindominio.net>
-rw-r--r--doc/aerc.1.scd22
-rw-r--r--main.go87
2 files changed, 73 insertions, 36 deletions
diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd
index 8443302c..2c49948f 100644
--- a/doc/aerc.1.scd
+++ b/doc/aerc.1.scd
@@ -6,23 +6,26 @@ aerc - a pretty good email client.
# SYNOPSIS
-*aerc* [*-v*] [*-a* _<account>_[,_<account>_]] [*mailto:*_..._]
+*aerc* [*-h*] [*-v*] [*-a* _<account>_] [*mailto:*_..._ | *:*_<command...>_ | *mbox:*_<file>_]
For a guided tutorial, use *:help tutorial* from aerc, or *man aerc-tutorial*
from your terminal.
# OPTIONS
+*-h*
+ Show aerc usage help and exit.
+
*-v*
- Prints the installed version of aerc and exits.
+ Print the installed version of aerc and exit.
-*-a* _<account>_[,_<account>_]
- Load only the named accounts, as opposed to all configured accounts.
- List must be comma separated, with no spaces. The account order will be
- preserved.
+*-a* _<account>_
+ Load only the named account, as opposed to all configured accounts. It
+ can also be a comma separated list of names. This option may be
+ specified multiple times. The account order will be preserved.
*mailto:*_address[,address][?query[&query]]_
- Opens the composer with the address(es) in the To field. These
+ Open the composer with the address(es) in the To field. These
addresses must not be percent encoded.
If aerc is already running, the composer is started in this instance,
otherwise aerc will be started.
@@ -47,10 +50,13 @@ from your terminal.
Note that reserved characters in the queries must be percent encoded.
-\:*command* [...]
+*:*_<command...>_
Run an aerc-internal command as you would in Ex-Mode. See *RUNTIME
COMMANDS* below.
+*mbox:*_<file>_
+ Open the specified mbox file as a virtual temporary account.
+
# RUNTIME COMMANDS
To execute a command, press *:* to bring up the command interface. Commands may
diff --git a/main.go b/main.go
index 2734164a..43e980e9 100644
--- a/main.go
+++ b/main.go
@@ -12,7 +12,7 @@ import (
"strings"
"time"
- "git.sr.ht/~sircmpwn/getopt"
+ "git.sr.ht/~rjarry/go-opt"
"github.com/mattn/go-isatty"
"github.com/xo/terminfo"
@@ -159,12 +159,6 @@ func buildInfo() string {
return info
}
-func usage(msg string) {
- fmt.Fprintln(os.Stderr, msg)
- fmt.Fprintln(os.Stderr, "usage: aerc [-v] [-a <account-name[,account-name>] [mailto:...]")
- os.Exit(1)
-}
-
func setWindowTitle() {
log.Tracef("Parsing terminfo")
ti, err := terminfo.LoadFromEnv()
@@ -186,28 +180,66 @@ func setWindowTitle() {
os.Stderr.Write(buf.Bytes())
}
+type Opts struct {
+ Help bool `opt:"-h" action:"ShowHelp"`
+ Version bool `opt:"-v" action:"ShowVersion"`
+ Accounts []string `opt:"-a" action:"ParseAccounts" metavar:"<account>"`
+ Command []string `opt:"..." required:"false" metavar:"mailto:<address> | mbox:<file> | :<command...>"`
+}
+
+func (o *Opts) ShowHelp(arg string) error {
+ fmt.Println("Usage: " + opt.NewCmdSpec(os.Args[0], o).Usage())
+ fmt.Print(`
+Aerc is an email client for your terminal.
+
+Options:
+
+ -h Show this help message and exit.
+ -v Print version information.
+ -a <account> Load only the named account, as opposed to all configured
+ accounts. It can also be a comma separated list of names.
+ This option may be specified multiple times. The account
+ order will be preserved.
+ mailto:<address> Open the composer with the address(es) in the To field.
+ If aerc is already running, the composer is started in
+ this instance, otherwise aerc will be started.
+ mbox:<file> Open the specified mbox file as a virtual temporary account.
+ :<command...> Run an aerc command as you would in Ex-Mode.
+`)
+ os.Exit(0)
+ return nil
+}
+
+func (o *Opts) ShowVersion(arg string) error {
+ fmt.Println(log.BuildInfo)
+ os.Exit(0)
+ return nil
+}
+
+func (o *Opts) ParseAccounts(arg string) error {
+ o.Accounts = append(o.Accounts, strings.Split(arg, ",")...)
+ return nil
+}
+
+func die(format string, args ...any) {
+ fmt.Fprintf(os.Stderr, "error: "+format+"\n", args...)
+ os.Exit(1)
+}
+
func main() {
defer log.PanicHandler()
- opts, optind, err := getopt.Getopts(os.Args, "va:")
- if err != nil {
- usage("error: " + err.Error())
- return
- }
log.BuildInfo = buildInfo()
- var accts []string
- for _, opt := range opts {
- if opt.Option == 'v' {
- fmt.Println("aerc " + log.BuildInfo)
- return
- }
- if opt.Option == 'a' {
- accts = strings.Split(opt.Value, ",")
- }
+
+ var opts Opts
+
+ args := opt.QuoteArgs(os.Args...)
+ err := opt.ArgsToStruct(args, &opts)
+ if err != nil {
+ die("%s", err)
}
retryExec := false
- args := os.Args[optind:]
- if len(args) > 0 {
- err := ipc.ConnectAndExec(args)
+ if len(opts.Command) > 0 {
+ err := ipc.ConnectAndExec(opts.Command)
if err == nil {
return // other aerc instance takes over
}
@@ -216,10 +248,9 @@ func main() {
retryExec = true
}
- err = config.LoadConfigFromFile(nil, accts)
+ err = config.LoadConfigFromFile(nil, opts.Accounts)
if err != nil {
- fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err)
- os.Exit(1) //nolint:gocritic // PanicHandler does not need to run as it's not a panic
+ die("failed to load config: %s", err)
}
log.Infof("Starting up version %s", log.BuildInfo)
@@ -261,7 +292,7 @@ func main() {
if retryExec {
// retry execution
- err := ipc.ConnectAndExec(args)
+ err := ipc.ConnectAndExec(opts.Command)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to communicate to aerc: %v\n", err)
err = app.CloseBackends()