aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--commands/compose/switch.go38
-rw-r--r--config/binds.conf2
-rw-r--r--doc/aerc.1.scd9
-rw-r--r--widgets/aerc.go36
5 files changed, 78 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f044039d..83e3eb2d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Cursor shape support in embedded terminals.
- Bracketed paste support.
- Display current directory in `status-line.render-format` with `%p`.
+- Change accounts while composing a message with `:switch-account`.
### Changed
diff --git a/commands/compose/switch.go b/commands/compose/switch.go
index 5109ee05..58702b5b 100644
--- a/commands/compose/switch.go
+++ b/commands/compose/switch.go
@@ -5,6 +5,7 @@ import (
"fmt"
"git.sr.ht/~rjarry/aerc/widgets"
+ "git.sr.ht/~sircmpwn/getopt"
)
type AccountSwitcher interface {
@@ -26,12 +27,29 @@ func (SwitchAccount) Complete(aerc *widgets.Aerc, args []string) []string {
}
func (SwitchAccount) Execute(aerc *widgets.Aerc, args []string) error {
- if len(args) != 2 {
+ opts, optind, err := getopt.Getopts(args, "np")
+ if err != nil {
+ return err
+ }
+ var next, prev bool
+ for _, opt := range opts {
+ switch opt.Option {
+ case 'n':
+ next = true
+ prev = false
+ case 'p':
+ next = false
+ prev = true
+ }
+ }
+ posargs := args[optind:]
+ // NOT ((prev || next) XOR (len(posargs) == 1))
+ if (prev || next) == (len(posargs) == 1) {
name := ""
if acct := aerc.SelectedAccount(); acct != nil {
name = fmt.Sprintf("Current account: %s. ", acct.Name())
}
- return errors.New(name + "Usage: switch-account <account-name>")
+ return errors.New(name + "Usage: switch-account [-np] <account-name>")
}
switcher, ok := aerc.SelectedTabContent().(AccountSwitcher)
@@ -39,9 +57,19 @@ func (SwitchAccount) Execute(aerc *widgets.Aerc, args []string) error {
return errors.New("this tab cannot switch accounts")
}
- if acct, err := aerc.Account(args[1]); err != nil {
+ var acct *widgets.AccountView
+
+ switch {
+ case prev:
+ acct, err = aerc.PrevAccount()
+ case next:
+ acct, err = aerc.NextAccount()
+ default:
+ acct, err = aerc.Account(posargs[0])
+ }
+ if err != nil {
return err
- } else {
- return switcher.SwitchAccount(acct)
}
+
+ return switcher.SwitchAccount(acct)
}
diff --git a/config/binds.conf b/config/binds.conf
index f46111b0..9e23ab91 100644
--- a/config/binds.conf
+++ b/config/binds.conf
@@ -94,6 +94,8 @@ $noinherit = true
$ex = <C-x>
<C-k> = :prev-field<Enter>
<C-j> = :next-field<Enter>
+<A-p> = :switch-account -p<Enter>
+<A-n> = :switch-account -n<Enter>
<tab> = :next-field<Enter>
<C-p> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>
diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd
index f0ca97e9..38862a53 100644
--- a/doc/aerc.1.scd
+++ b/doc/aerc.1.scd
@@ -476,9 +476,12 @@ message list, the message in the message viewer, etc).
configuration. For details on configuring outgoing mail delivery consult
*aerc-config*(5).
-*switch-account* <account-name>
- Switches the account. If run without arguments, the current account name
- is displayed.
+*switch-account* <-n|-p|account-name>
+ Switches the account. Can be used to switch to a specific account from
+ its name or to cycle through accounts using the -p and -n flags.
+
+ *-p*: switch to previous account
+ *-n*: switch to next account
*header* [-f] <field> [value]
Add a new email header. If the header already exists, -f must be
diff --git a/widgets/aerc.go b/widgets/aerc.go
index 656b25de..2b7a6d86 100644
--- a/widgets/aerc.go
+++ b/widgets/aerc.go
@@ -382,6 +382,42 @@ func (aerc *Aerc) Account(name string) (*AccountView, error) {
return nil, fmt.Errorf("account <%s> not found", name)
}
+func (aerc *Aerc) PrevAccount() (*AccountView, error) {
+ cur := aerc.SelectedAccount()
+ if cur == nil {
+ return nil, fmt.Errorf("no account selected, cannot get prev")
+ }
+ for i, conf := range aerc.conf.Accounts {
+ if conf.Name == cur.Name() {
+ i -= 1
+ if i == -1 {
+ i = len(aerc.conf.Accounts) - 1
+ }
+ conf = aerc.conf.Accounts[i]
+ return aerc.Account(conf.Name)
+ }
+ }
+ return nil, fmt.Errorf("no prev account")
+}
+
+func (aerc *Aerc) NextAccount() (*AccountView, error) {
+ cur := aerc.SelectedAccount()
+ if cur == nil {
+ return nil, fmt.Errorf("no account selected, cannot get next")
+ }
+ for i, conf := range aerc.conf.Accounts {
+ if conf.Name == cur.Name() {
+ i += 1
+ if i == len(aerc.conf.Accounts) {
+ i = 0
+ }
+ conf = aerc.conf.Accounts[i]
+ return aerc.Account(conf.Name)
+ }
+ }
+ return nil, fmt.Errorf("no next account")
+}
+
func (aerc *Aerc) AccountNames() []string {
results := make([]string, 0)
for name := range aerc.accounts {