diff options
author | Robin Jarry <robin@jarry.cc> | 2022-12-12 15:03:30 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-12-14 11:22:58 +0100 |
commit | c05c2ffe0424b048b10e7dd1aca59ae9cf631f12 (patch) | |
tree | 13a3a84eb74fdea77996161f01bec5596f67f39f | |
parent | 9d0297e9d913a92b2d7ae02692e83f0f4093a766 (diff) | |
download | aerc-c05c2ffe0424b048b10e7dd1aca59ae9cf631f12.tar.gz |
config: make various sections accessible via global vars
There is only one instance of AercConfig which is associated to the Aerc
widget. Everywhere we need to access configuration options, we need
somehow to get a reference either to the Aerc widget or to a pointer to
the AercConfig instance. This makes the code cluttered.
Remove the AercConfig structure and every place where it is referenced.
Instead, declare global variables for every configuration section and
access them directly from the `config` module.
Since bindings and ui sections can be "contextual" (i.e. per account,
per folder or per subject), leave most local references intact.
Replacing them with config.{Ui,Binds}.For{Account,Folder,Subject} would
make this patch even more unreadable. This is something that may be
addressed in the future.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
47 files changed, 395 insertions, 423 deletions
@@ -167,7 +167,7 @@ func main() { retryExec = true } - conf, err := config.LoadConfigFromFile(nil, accts) + err = config.LoadConfigFromFile(nil, accts) 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 @@ -182,14 +182,14 @@ func main() { deferLoop := make(chan struct{}) - c := crypto.New(conf.General.PgpProvider) + c := crypto.New() err = c.Init() if err != nil { log.Warnf("failed to initialise crypto interface: %v", err) } defer c.Close() - aerc = widgets.NewAerc(conf, c, func(cmd []string) error { + aerc = widgets.NewAerc(c, func(cmd []string) error { return execCommand(aerc, ui, cmd) }, func(cmd string) []string { return getCompletions(aerc, cmd) @@ -205,7 +205,7 @@ func main() { } close(deferLoop) - if conf.Ui.MouseEnabled { + if config.Ui.MouseEnabled { ui.EnableMouse() } diff --git a/commands/account/compose.go b/commands/account/compose.go index 3d3d9afb..fb37b231 100644 --- a/commands/account/compose.go +++ b/commands/account/compose.go @@ -10,6 +10,7 @@ import ( "github.com/emersion/go-message/mail" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib/ui" "git.sr.ht/~rjarry/aerc/log" "git.sr.ht/~rjarry/aerc/models" @@ -41,7 +42,7 @@ func (Compose) Execute(aerc *widgets.Aerc, args []string) error { return errors.New("No account selected") } if template == "" { - template = aerc.Config().Templates.NewMessage + template = config.Templates.NewMessage } msg, err := gomail.ReadMessage(strings.NewReader(body)) @@ -53,7 +54,7 @@ func (Compose) Execute(aerc *widgets.Aerc, args []string) error { headers := mail.HeaderFromMap(msg.Header) composer, err := widgets.NewComposer(aerc, acct, - aerc.Config(), acct.AccountConfig(), acct.Worker(), + acct.AccountConfig(), acct.Worker(), template, &headers, models.OriginalMail{}) if err != nil { return err diff --git a/commands/account/recover.go b/commands/account/recover.go index 9bb73316..8ce878ee 100644 --- a/commands/account/recover.go +++ b/commands/account/recover.go @@ -102,7 +102,7 @@ func (Recover) Execute(aerc *widgets.Aerc, args []string) error { } composer, err := widgets.NewComposer(aerc, acct, - aerc.Config(), acct.AccountConfig(), acct.Worker(), + acct.AccountConfig(), acct.Worker(), "", nil, models.OriginalMail{}) if err != nil { return err diff --git a/commands/account/view.go b/commands/account/view.go index f30ac61b..f48d3bc3 100644 --- a/commands/account/view.go +++ b/commands/account/view.go @@ -65,7 +65,7 @@ func (ViewMessage) Execute(aerc *widgets.Aerc, args []string) error { aerc.PushError(err.Error()) return } - viewer := widgets.NewMessageViewer(acct, aerc.Config(), view) + viewer := widgets.NewMessageViewer(acct, view) aerc.NewTab(viewer, msg.Envelope.Subject) }) return nil diff --git a/commands/compose/attach.go b/commands/compose/attach.go index 62ae0291..7e50ea85 100644 --- a/commands/compose/attach.go +++ b/commands/compose/attach.go @@ -11,6 +11,7 @@ import ( "strings" "git.sr.ht/~rjarry/aerc/commands" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib/ui" "git.sr.ht/~rjarry/aerc/log" "git.sr.ht/~rjarry/aerc/widgets" @@ -85,7 +86,7 @@ func (a Attach) addPath(aerc *widgets.Aerc, path string) error { } func (a Attach) openMenu(aerc *widgets.Aerc, args []string) error { - filePickerCmd := aerc.Config().Compose.FilePickerCmd + filePickerCmd := config.Compose.FilePickerCmd if filePickerCmd == "" { return fmt.Errorf("no file-picker-cmd defined") } diff --git a/commands/compose/multipart.go b/commands/compose/multipart.go index 5a6dd770..32801965 100644 --- a/commands/compose/multipart.go +++ b/commands/compose/multipart.go @@ -5,6 +5,7 @@ import ( "fmt" "git.sr.ht/~rjarry/aerc/commands" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/widgets" "git.sr.ht/~sircmpwn/getopt" ) @@ -22,7 +23,7 @@ func (Multipart) Aliases() []string { func (Multipart) Complete(aerc *widgets.Aerc, args []string) []string { var completions []string completions = append(completions, "-d") - for mime := range aerc.Config().Converters { + for mime := range config.Converters { completions = append(completions, mime) } return commands.CompletionFromList(aerc, completions, args) @@ -53,7 +54,7 @@ func (a Multipart) Execute(aerc *widgets.Aerc, args []string) error { if remove { return composer.RemovePart(mime) } else { - _, found := aerc.Config().Converters[mime] + _, found := config.Converters[mime] if !found { return fmt.Errorf("no command defined for MIME type: %s", mime) } diff --git a/commands/compose/send.go b/commands/compose/send.go index 6d9bfe25..7306bef8 100644 --- a/commands/compose/send.go +++ b/commands/compose/send.go @@ -108,7 +108,7 @@ func (Send) Execute(aerc *widgets.Aerc, args []string) error { msg = "Failed to check for a forgotten attachment." } - prompt := widgets.NewPrompt(aerc.Config(), + prompt := widgets.NewPrompt( msg+" Abort send? [Y/n] ", func(text string) { if text == "n" || text == "N" { diff --git a/commands/eml.go b/commands/eml.go index 864145ce..00380763 100644 --- a/commands/eml.go +++ b/commands/eml.go @@ -43,8 +43,7 @@ func (Eml) Execute(aerc *widgets.Aerc, args []string) error { aerc.PushError(err.Error()) return } - msgView := widgets.NewMessageViewer(acct, - aerc.Config(), view) + msgView := widgets.NewMessageViewer(acct, view) aerc.NewTab(msgView, view.MessageInfo().Envelope.Subject) }) diff --git a/commands/msg/delete.go b/commands/msg/delete.go index 066476d8..6c786257 100644 --- a/commands/msg/delete.go +++ b/commands/msg/delete.go @@ -4,6 +4,7 @@ import ( "errors" "time" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/ui" "git.sr.ht/~rjarry/aerc/models" @@ -54,7 +55,7 @@ func (Delete) Execute(aerc *widgets.Aerc, args []string) error { aerc.PushStatus("Messages deleted.", 10*time.Second) mv, isMsgView := h.msgProvider.(*widgets.MessageViewer) if isMsgView { - if !aerc.Config().Ui.NextMessageOnDelete { + if !config.Ui.NextMessageOnDelete { aerc.RemoveTab(h.msgProvider) } else { // no more messages in the list @@ -71,7 +72,7 @@ func (Delete) Execute(aerc *widgets.Aerc, args []string) error { aerc.PushError(err.Error()) return } - nextMv := widgets.NewMessageViewer(acct, aerc.Config(), view) + nextMv := widgets.NewMessageViewer(acct, view) aerc.ReplaceTab(mv, nextMv, next.Envelope.Subject) }) } diff --git a/commands/msg/forward.go b/commands/msg/forward.go index c0215aee..9a4f3d41 100644 --- a/commands/msg/forward.go +++ b/commands/msg/forward.go @@ -12,6 +12,7 @@ import ( "strings" "sync" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/format" "git.sr.ht/~rjarry/aerc/lib/ui" @@ -99,7 +100,7 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error { } addTab := func() (*widgets.Composer, error) { - composer, err := widgets.NewComposer(aerc, acct, aerc.Config(), + composer, err := widgets.NewComposer(aerc, acct, acct.AccountConfig(), acct.Worker(), template, h, original) if err != nil { aerc.PushError("Error: " + err.Error()) @@ -158,7 +159,7 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error { }) } else { if template == "" { - template = aerc.Config().Templates.Forwards + template = config.Templates.Forwards } part := lib.FindPlaintext(msg.BodyStructure, nil) diff --git a/commands/msg/invite.go b/commands/msg/invite.go index 32251643..2dca259b 100644 --- a/commands/msg/invite.go +++ b/commands/msg/invite.go @@ -5,6 +5,7 @@ import ( "fmt" "io" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/calendar" "git.sr.ht/~rjarry/aerc/lib/format" @@ -99,7 +100,7 @@ func (invite) Execute(aerc *widgets.Aerc, args []string) error { to = msg.Envelope.From } - if !aerc.Config().Compose.ReplyToSelf { + if !config.Compose.ReplyToSelf { for i, v := range to { if v.Address == from.Address { to = append(to[:i], to[i+1:]...) @@ -147,7 +148,7 @@ func (invite) Execute(aerc *widgets.Aerc, args []string) error { } addTab := func(cr *calendar.Reply) error { - composer, err := widgets.NewComposer(aerc, acct, aerc.Config(), + composer, err := widgets.NewComposer(aerc, acct, acct.AccountConfig(), acct.Worker(), "", h, original) if err != nil { aerc.PushError("Error: " + err.Error()) diff --git a/commands/msg/move.go b/commands/msg/move.go index 15494364..6e77a88c 100644 --- a/commands/msg/move.go +++ b/commands/msg/move.go @@ -6,6 +6,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/commands" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/ui" "git.sr.ht/~rjarry/aerc/models" @@ -91,7 +92,7 @@ func handleDone( aerc.PushStatus(message, 10*time.Second) mv, isMsgView := h.msgProvider.(*widgets.MessageViewer) switch { - case isMsgView && !aerc.Config().Ui.NextMessageOnDelete: + case isMsgView && !config.Ui.NextMessageOnDelete: aerc.RemoveTab(h.msgProvider) case isMsgView: if next == nil { @@ -107,7 +108,7 @@ func handleDone( aerc.PushError(err.Error()) return } - nextMv := widgets.NewMessageViewer(acct, aerc.Config(), view) + nextMv := widgets.NewMessageViewer(acct, view) aerc.ReplaceTab(mv, nextMv, next.Envelope.Subject) }) default: diff --git a/commands/msg/recall.go b/commands/msg/recall.go index d39f4daf..f106e8bd 100644 --- a/commands/msg/recall.go +++ b/commands/msg/recall.go @@ -72,7 +72,7 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error { } log.Debugf("Recalling message <%s>", msgInfo.Envelope.MessageId) - composer, err := widgets.NewComposer(aerc, acct, aerc.Config(), + composer, err := widgets.NewComposer(aerc, acct, acct.AccountConfig(), acct.Worker(), "", msgInfo.RFC822Headers, models.OriginalMail{}) if err != nil { diff --git a/commands/msg/reply.go b/commands/msg/reply.go index 12eba928..5aad4fc9 100644 --- a/commands/msg/reply.go +++ b/commands/msg/reply.go @@ -11,6 +11,7 @@ import ( "git.sr.ht/~sircmpwn/getopt" "git.sr.ht/~rjarry/aerc/commands/account" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/crypto" "git.sr.ht/~rjarry/aerc/lib/format" @@ -118,7 +119,7 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error { to = msg.Envelope.From } - if !aerc.Config().Compose.ReplyToSelf { + if !config.Compose.ReplyToSelf { for i, v := range to { if v.Address == from.Address { to = append(to[:i], to[i+1:]...) @@ -179,13 +180,13 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error { mv, _ := aerc.SelectedTabContent().(*widgets.MessageViewer) addTab := func() error { - composer, err := widgets.NewComposer(aerc, acct, aerc.Config(), + composer, err := widgets.NewComposer(aerc, acct, acct.AccountConfig(), acct.Worker(), template, h, original) if err != nil { aerc.PushError("Error: " + err.Error()) return err } - if (mv != nil) && aerc.Config().Viewer.CloseOnReply { + if (mv != nil) && config.Viewer.CloseOnReply { mv.Close() aerc.RemoveTab(mv) } @@ -208,7 +209,7 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error { switch { case c.Sent(): store.Answered([]uint32{msg.Uid}, true, nil) - case mv != nil && aerc.Config().Viewer.CloseOnReply: + case mv != nil && config.Viewer.CloseOnReply: //nolint:errcheck // who cares? account.ViewMessage{}.Execute(aerc, []string{"-p"}) } @@ -219,7 +220,7 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error { if quote { if template == "" { - template = aerc.Config().Templates.QuotedReply + template = config.Templates.QuotedReply } if crypto.IsEncrypted(msg.BodyStructure) { @@ -275,7 +276,7 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error { return nil } else { if template == "" { - template = aerc.Config().Templates.NewMessage + template = config.Templates.NewMessage } return addTab() } diff --git a/commands/msg/unsubscribe.go b/commands/msg/unsubscribe.go index 0538b2f2..a334e827 100644 --- a/commands/msg/unsubscribe.go +++ b/commands/msg/unsubscribe.go @@ -151,7 +151,6 @@ func unsubscribeMailto(aerc *widgets.Aerc, u *url.URL) error { composer, err := widgets.NewComposer( aerc, acct, - aerc.Config(), acct.AccountConfig(), acct.Worker(), "", diff --git a/commands/msgview/next.go b/commands/msgview/next.go index a32e358f..d4c02123 100644 --- a/commands/msgview/next.go +++ b/commands/msgview/next.go @@ -51,8 +51,7 @@ func (NextPrevMsg) Execute(aerc *widgets.Aerc, args []string) error { aerc.PushError(err.Error()) return } - nextMv := widgets.NewMessageViewer(acct, - aerc.Config(), view) + nextMv := widgets.NewMessageViewer(acct, view) aerc.ReplaceTab(mv, nextMv, nextMsg.Envelope.Subject) }) diff --git a/commands/msgview/open.go b/commands/msgview/open.go index 637fceeb..1b9efb38 100644 --- a/commands/msgview/open.go +++ b/commands/msgview/open.go @@ -57,8 +57,7 @@ func (Open) Execute(aerc *widgets.Aerc, args []string) error { } go func() { - openers := aerc.Config().Openers - err = lib.XDGOpenMime(tmpFile.Name(), mimeType, openers, args[1:]) + err = lib.XDGOpenMime(tmpFile.Name(), mimeType, args[1:]) if err != nil { aerc.PushError("open: " + err.Error()) } diff --git a/commands/msgview/save.go b/commands/msgview/save.go index 3cb48c2b..ef31988b 100644 --- a/commands/msgview/save.go +++ b/commands/msgview/save.go @@ -13,6 +13,7 @@ import ( "github.com/mitchellh/go-homedir" "git.sr.ht/~rjarry/aerc/commands" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/log" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/widgets" @@ -34,7 +35,7 @@ func (Save) Complete(aerc *widgets.Aerc, args []string) []string { args = args[optind:] } path := strings.Join(args, " ") - defaultPath := aerc.Config().General.DefaultSavePath + defaultPath := config.General.DefaultSavePath if defaultPath != "" && !isAbsPath(path) { path = filepath.Join(defaultPath, path) } @@ -68,7 +69,7 @@ func (Save) Execute(aerc *widgets.Aerc, args []string) error { } } - defaultPath := aerc.Config().General.DefaultSavePath + defaultPath := config.General.DefaultSavePath // we either need a path or a defaultPath if defaultPath == "" && len(args) == optind { return errors.New("Usage: :save [-fpa] <path>") diff --git a/commands/new-account.go b/commands/new-account.go index 2b28a1b1..2747b159 100644 --- a/commands/new-account.go +++ b/commands/new-account.go @@ -26,7 +26,7 @@ func (NewAccount) Execute(aerc *widgets.Aerc, args []string) error { if err != nil { return errors.New("Usage: new-account [-t]") } - wizard := widgets.NewAccountWizard(aerc.Config(), aerc) + wizard := widgets.NewAccountWizard(aerc) for _, opt := range opts { if opt.Option == 't' { wizard.ConfigureTemporaryAccount(true) diff --git a/config/accounts.go b/config/accounts.go index 61f0e282..54c6556f 100644 --- a/config/accounts.go +++ b/config/accounts.go @@ -104,9 +104,11 @@ type AccountConfig struct { TrustedAuthRes []string `ini:"trusted-authres" delim:","` } -func (config *AercConfig) parseAccounts(root string, accts []string) error { +var Accounts []*AccountConfig + +func parseAccounts(root string, accts []string) error { filename := path.Join(root, "accounts.conf") - if !config.General.UnsafeAccountsConf { + if !General.UnsafeAccountsConf { if err := checkConfigPerms(filename); err != nil { return err } @@ -217,15 +219,15 @@ func (config *AercConfig) parseAccounts(root string, accts []string) error { } log.Debugf("accounts.conf: [%s] from = %s", account.Name, account.From) - config.Accounts = append(config.Accounts, account) + Accounts = append(Accounts, &account) } if len(accts) > 0 { // Sort accounts struct to match the specified order, if we // have one - if len(config.Accounts) != len(accts) { + if len(Accounts) != len(accts) { return errors.New("account(s) not found") } - sort.Slice(config.Accounts, func(i, j int) bool { + sort.Slice(Accounts, func(i, j int) bool { return strings.ToLower(accts[i]) < strings.ToLower(accts[j]) }) } diff --git a/config/binds.go b/config/binds.go index abaff78c..60e3a854 100644 --- a/config/binds.go +++ b/config/binds.go @@ -77,14 +77,28 @@ const ( type BindingSearchResult int -func (config *AercConfig) parseBinds(root string) error { +func defaultBindsConfig() *BindingConfig { // These bindings are not configurable - config.Bindings.AccountWizard.ExKey = KeyStroke{ - Key: tcell.KeyCtrlE, - } + wizard := NewKeyBindings() + wizard.ExKey = KeyStroke{Key: tcell.KeyCtrlE} quit, _ := ParseBinding("<C-q>", ":quit<Enter>") - config.Bindings.AccountWizard.Add(quit) + wizard.Add(quit) + return &BindingConfig{ + Global: NewKeyBindings(), + AccountWizard: wizard, + Compose: NewKeyBindings(), + ComposeEditor: NewKeyBindings(), + ComposeReview: NewKeyBindings(), + MessageList: NewKeyBindings(), + MessageView: NewKeyBindings(), + MessageViewPassthrough: NewKeyBindings(), + Terminal: NewKeyBindings(), + } +} + +var Binds = defaultBindsConfig() +func parseBinds(root string) error { filename := path.Join(root, "binds.conf") if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) { fmt.Printf("%s not found, installing the system default", filename) @@ -99,14 +113,14 @@ func (config *AercConfig) parseBinds(root string) error { } baseGroups := map[string]**KeyBindings{ - "default": &config.Bindings.Global, - "compose": &config.Bindings.Compose, - "messages": &config.Bindings.MessageList, - "terminal": &config.Bindings.Terminal, - "view": &config.Bindings.MessageView, - "view::passthrough": &config.Bindings.MessageViewPassthrough, - "compose::editor": &config.Bindings.ComposeEditor, - "compose::review": &config.Bindings.ComposeReview, + "default": &Binds.Global, + "compose": &Binds.Compose, + "messages": &Binds.MessageList, + "terminal": &Binds.Terminal, + "view": &Binds.MessageView, + "view::passthrough": &Binds.MessageViewPassthrough, + "compose::editor": &Binds.ComposeEditor, + "compose::review": &Binds.ComposeReview, } // Base Bindings @@ -123,14 +137,14 @@ func (config *AercConfig) parseBinds(root string) error { } if baseOnly { - err = config.LoadBinds(binds, baseSectionName, group) + err = LoadBinds(binds, baseSectionName, group) if err != nil { return err } } } - log.Debugf("binds.conf: %#v", config.Bindings) + log.Debugf("binds.conf: %#v", Binds) return nil } @@ -167,7 +181,7 @@ func LoadBindingSection(sec *ini.Section) (*KeyBindings, error) { return bindings, nil } -func (config *AercConfig) LoadBinds(binds *ini.File, baseName string, baseGroup **KeyBindings) error { +func LoadBinds(binds *ini.File, baseName string, baseGroup **KeyBindings) error { if sec, err := binds.GetSection(baseName); err == nil { binds, err := LoadBindingSection(sec) if err != nil { @@ -221,7 +235,7 @@ func (config *AercConfig) LoadBinds(binds *ini.File, baseName string, baseGroup case "account": acctName := sectionName[index+1:] valid := false - for _, acctConf := range config.Accounts { + for _, acctConf := range Accounts { matches := contextualBind.Regex.FindString(acctConf.Name) if matches != "" { valid = true @@ -246,20 +260,6 @@ func (config *AercConfig) LoadBinds(binds *ini.File, baseName string, baseGroup return nil } -func defaultBindsConfig() BindingConfig { - return BindingConfig{ - Global: NewKeyBindings(), - AccountWizard: NewKeyBindings(), - Compose: NewKeyBindings(), - ComposeEditor: NewKeyBindings(), - ComposeReview: NewKeyBindings(), - MessageList: NewKeyBindings(), - MessageView: NewKeyBindings(), - MessageViewPassthrough: NewKeyBindings(), - Terminal: NewKeyBindings(), - } -} - func NewKeyBindings() *KeyBindings { return &KeyBindings{ ExKey: KeyStroke{tcell.ModNone, tcell.KeyRune, ':'}, diff --git a/config/compose.go b/config/compose.go index cf9c9b58..80d93204 100644 --- a/config/compose.go +++ b/config/compose.go @@ -17,8 +17,8 @@ type ComposeConfig struct { FilePickerCmd string `ini:"file-picker-cmd"` } -func defaultComposeConfig() ComposeConfig { - return ComposeConfig{ +func defaultComposeConfig() *ComposeConfig { + return &ComposeConfig{ HeaderLayout: [][]string{ {"To", "From"}, {"Subject"}, @@ -27,18 +27,20 @@ func defaultComposeConfig() ComposeConfig { } } -func (config *AercConfig) parseCompose(file *ini.File) error { +var Compose = defaultComposeConfig() + +func parseCompose(file *ini.File) error { compose, err := file.GetSection("compose") if err != nil { goto end } - if err := compose.MapTo(&config.Compose); err != nil { + if err := compose.MapTo(&Compose); err != nil { return err } for key, val := range compose.KeysHash() { if key == "header-layout" { - config.Compose.HeaderLayout = parseLayout(val) + Compose.HeaderLayout = parseLayout(val) } if key == "no-attachment-warning" && len(val) > 0 { @@ -50,11 +52,11 @@ func (config *AercConfig) parseCompose(file *ini.File) error { ) } - config.Compose.NoAttachmentWarning = re + Compose.NoAttachmentWarning = re } } end: - log.Debugf("aerc.conf: [compose] %#v", config.Compose) + log.Debugf("aerc.conf: [compose] %#v", Compose) return nil } diff --git a/config/config.go b/config/config.go index 90951985..09fb5efc 100644 --- a/config/config.go +++ b/config/config.go @@ -14,21 +14,6 @@ import ( "github.com/mitchellh/go-homedir" ) -type AercConfig struct { - Bindings BindingConfig - Compose ComposeConfig - Converters map[string]string - Accounts []AccountConfig `ini:"-"` - Filters []FilterConfig `ini:"-"` - Viewer ViewerConfig `ini:"-"` - Statusline StatuslineConfig `ini:"-"` - Triggers TriggersConfig `ini:"-"` - Ui UIConfig - General GeneralConfig - Templates TemplateConfig - Openers map[string][]string -} - // Input: TimestampFormat // Output: timestamp-format func mapName(raw string) string { @@ -108,7 +93,7 @@ func installTemplate(root, name string) error { return nil } -func LoadConfigFromFile(root *string, accts []string) (*AercConfig, error) { +func LoadConfigFromFile(root *string, accts []string) error { if root == nil { _root := path.Join(xdg.ConfigHome(), "aerc") root = &_root @@ -119,7 +104,7 @@ func LoadConfigFromFile(root *string, accts []string) (*AercConfig, error) { if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) { fmt.Printf("%s not found, installing the system default", filename) if err := installTemplate(*root, "aerc.conf"); err != nil { - return nil, err + return err } } @@ -127,59 +112,48 @@ func LoadConfigFromFile(root *string, accts []string) (*AercConfig, error) { KeyValueDelimiters: "=", }, filename) if err != nil { - return nil, err + return err } file.NameMapper = mapName - config := &AercConfig{ - Bindings: defaultBindsConfig(), - General: defaultGeneralConfig(), - Ui: defaultUiConfig(), - Viewer: defaultViewerConfig(), - Statusline: defaultStatuslineConfig(), - Compose: defaultComposeConfig(), - Converters: make(map[string]string), - Templates: defaultTemplatesConfig(), - Openers: make(map[string][]string), - } - if err := config.parseGeneral(file); err != nil { - return nil, err + if err := parseGeneral(file); err != nil { + return err } - if err := config.parseFilters(file); err != nil { - return nil, err + if err := parseFilters(file); err != nil { + return err } - if err := config.parseCompose(file); err != nil { - return nil, err + if err := parseCompose(file); err != nil { + return err } - if err := config.parseConverters(file); err != nil { - return nil, err + if err := parseConverters(file); err != nil { + return err } - if err := config.parseViewer(file); err != nil { - return nil, err + if err := parseViewer(file); err != nil { + return err } - if err := config.parseStatusline(file); err != nil { - return nil, err + if err := parseStatusline(file); err != nil { + return err } - if err := config.parseOpeners(file); err != nil { - return nil, err + if err := parseOpeners(file); err != nil { + return err } - if err := config.parseTriggers(file); err != nil { - return nil, err + if err := parseTriggers(file); err != nil { + return err } - if err := config.parseUi(file); err != nil { - return nil, err + if err := parseUi(file); err != nil { + return err } - if err := config.parseTemplates(file); err != nil { - return nil, err + if err := parseTemplates(file); err != nil { + return err } - if err := config.parseAccounts(*root, accts); err != nil { - return nil, err + if err := parseAccounts(*root, accts); err != nil { + return err } - if err := config.parseBinds(*root); err != nil { - return nil, err + if err := parseBinds(*root); err != nil { + return err } - return config, nil + return nil } func parseLayout(layout string) [][]string { diff --git a/config/converters.go b/config/converters.go index 8c6b88df..72c1cbd4 100644 --- a/config/converters.go +++ b/config/converters.go @@ -8,7 +8,9 @@ import ( "github.com/go-ini/ini" ) -func (config *AercConfig) parseConverters(file *ini.File) error { +var Converters = make(map[string]string) + +func parseConverters(file *ini.File) error { converters, err := file.GetSection("multipart-converters") if err != nil { goto out @@ -25,10 +27,10 @@ func (config *AercConfig) parseConverters(file *ini.File) error { "multipart-converters: %q: only text/* MIME types are supported", mimeType) } - config.Converters[mimeType] = command + Converters[mimeType] = command } out: - log.Debugf("aerc.conf: [multipart-converters] %#v", config.Converters) + log.Debugf("aerc.conf: [multipart-converters] %#v", Converters) return nil } diff --git a/config/filters.go b/config/filters.go index 2b5a0c84..0b7a1cb2 100644 --- a/config/filters.go +++ b/config/filters.go @@ -23,7 +23,9 @@ type FilterConfig struct { Regex *regexp.Regexp } -func (config *AercConfig) parseFilters(file *ini.File) error { +var Filters []*FilterConfig + +func parseFilters(file *ini.File) error { filters, err := file.GetSection("filters") if err != nil { goto end @@ -58,10 +60,10 @@ func (config *AercConfig) parseFilters(file *ini.File) error { default: filter.Type = FILTER_MIMETYPE } - config.Filters = append(config.Filters, filter) + Filters = append(Filters, &filter) } end: - log.Debugf("aerc.conf: [filters] %#v", config.Filters) + log.Debugf("aerc.conf: [filters] %#v", Filters) return nil } diff --git a/config/general.go b/config/general.go index 2c09a14e..2921fdf5 100644 --- a/config/general.go +++ b/config/general.go @@ -18,15 +18,17 @@ type GeneralConfig struct { LogLevel log.LogLevel `ini:"-"` } -func defaultGeneralConfig() GeneralConfig { - return GeneralConfig{ +func defaultGeneralConfig() *GeneralConfig { + return &GeneralConfig{ PgpProvider: "auto", UnsafeAccountsConf: false, LogLevel: log.INFO, } } -func (config *AercConfig) parseGeneral(file *ini.File) error { +var General = defaultGeneralConfig() + +func parseGeneral(file *ini.File) error { var level *ini.Key var logFile *os.File @@ -34,7 +36,7 @@ func (config *AercConfig) parseGeneral(file *ini.File) error { if err != nil { goto end } - if err := gen.MapTo(&config.General); err != nil { + if err := gen.MapTo(&General); err != nil { return err } level, err = gen.GetKey("log-level") @@ -43,18 +45,18 @@ func (config *AercConfig) parseGeneral(file *ini.File) error { if err != nil { return err } - config.General.LogLevel = l + General.LogLevel = l } - if err := config.General.validatePgpProvider(); err != nil { + if err := General.validatePgpProvider(); err != nil { return err } end: if !isatty.IsTerminal(os.Stdout.Fd()) { logFile = os.Stdout // redirected to file, force TRACE level - config.General.LogLevel = log.TRACE - } else if config.General.LogFile != "" { - path, err := homedir.Expand(config.General.LogFile) + General.LogLevel = log.TRACE + } else if General.LogFile != "" { + path, err := homedir.Expand(General.LogFile) if err != nil { return fmt.Errorf("log-file: %w", err) } @@ -64,8 +66,8 @@ end: return fmt.Errorf("log-file: %w", err) } } - log.Init(logFile, config.General.LogLevel) - log.Debugf("aerc.conf: [general] %#v", config.General) + log.Init(logFile, General.LogLevel) + log.Debugf("aerc.conf: [general] %#v", General) return nil } diff --git a/config/openers.go b/config/openers.go index c62ec974..181536f5 100644 --- a/config/openers.go +++ b/config/openers.go @@ -8,7 +8,9 @@ import ( "github.com/google/shlex" ) -func (config *AercConfig) parseOpeners(file *ini.File) error { +var Openers = make(map[string][]string) + +func parseOpeners(file *ini.File) error { openers, err := file.GetSection("openers") if err != nil { goto out @@ -19,11 +21,11 @@ func (config *AercConfig) parseOpeners(file *ini.File) error { if args, err := shlex.Split(command); err != nil { return err } else { - config.Openers[mimeType] = args + Openers[mimeType] = args } } out: - log.Debugf("aerc.conf: [openers] %#v", config.Openers) + log.Debugf("aerc.conf: [openers] %#v", Openers) return nil } diff --git a/config/statusline.go b/config/statusline.go index 1e7d723e..483241c0 100644 --- a/config/statusline.go +++ b/config/statusline.go @@ -11,23 +11,25 @@ type StatuslineConfig struct { DisplayMode string `ini:"display-mode"` } -func defaultStatuslineConfig() StatuslineConfig { - return StatuslineConfig{ +func defaultStatuslineConfig() *StatuslineConfig { + return &StatuslineConfig{ RenderFormat: "[%a] %S %>%T", Separator: " | ", DisplayMode: "", } } -func (config *AercConfig) parseStatusline(file *ini.File) error { +var Statusline = defaultStatuslineConfig() + +func parseStatusline(file *ini.File) error { statusline, err := file.GetSection("statusline") if err != nil { goto out } - if err := statusline.MapTo(&config.Statusline); err != nil { + if err := statusline.MapTo(&Statusline); err != nil { return err } out: - log.Debugf("aerc.conf: [statusline] %#v", config.Statusline) + log.Debugf("aerc.conf: [statusline] %#v", Statusline) return nil } diff --git a/config/templates.go b/config/templates.go index 32d838fc..5580c056 100644 --- a/config/templates.go +++ b/config/templates.go @@ -16,8 +16,8 @@ type TemplateConfig struct { Forwards string `ini:"forwards"` } -func defaultTemplatesConfig() TemplateConfig { - return TemplateConfig{ +func defaultTemplatesConfig() *TemplateConfig { + return &TemplateConfig{ TemplateDirs: []string{}, NewMessage: "new_message", QuotedReply: "quoted_reply", @@ -25,27 +25,29 @@ func defaultTemplatesConfig() TemplateConfig { } } -func (config *AercConfig) parseTemplates(file *ini.File) error { +var Templates = defaultTemplatesConfig() + +func parseTemplates(file *ini.File) error { if templatesSec, err := file.GetSection("templates"); err == nil { - if err := templatesSec.MapTo(&config.Templates); err != nil { + if err := templatesSec.MapTo(&Templates); err != nil { return err } templateDirs := templatesSec.Key("template-dirs").String() if templateDirs != "" { - config.Templates.TemplateDirs = strings.Split(templateDirs, ":") + Templates.TemplateDirs = strings.Split(templateDirs, ":") } } // append default paths to template-dirs for _, dir := range SearchDirs { - config.Templates.TemplateDirs = append( - config.Templates.TemplateDirs, path.Join(dir, "templates"), + Templates.TemplateDirs = append( + Templates.TemplateDirs, path.Join(dir, "templates"), ) } // we want to fail during startup if the templates are not ok // hence we do dummy executes here - t := config.Templates + t := Templates if err := templates.CheckTemplate(t.NewMessage, t.TemplateDirs); err != nil { return err } @@ -56,7 +58,7 @@ func (config *AercConfig) parseTemplates(file *ini.File) error { return err } - log.Debugf("aerc.conf: [templates] %#v", config.Templates) + log.Debugf("aerc.conf: [templates] %#v", Templates) return nil } diff --git a/config/triggers.go b/config/triggers.go index 2a357bc0..5f315362 100644 --- a/config/triggers.go +++ b/config/triggers.go @@ -17,16 +17,18 @@ type TriggersConfig struct { ExecuteCommand func(command []string) error } -func (config *AercConfig) parseTriggers(file *ini.File) error { +var Triggers = &TriggersConfig{} + +func parseTriggers(file *ini.File) error { triggers, err := file.GetSection("triggers") if err != nil { goto out } - if err := triggers.MapTo(&config.Triggers); err != nil { + if err := triggers.MapTo(&Triggers); err != nil { return err } out: - log.Debugf("aerc.conf: [triggers] %#v", config.Triggers) + log.Debugf("aerc.conf: [triggers] %#v", Triggers) return nil } @@ -52,16 +54,16 @@ func (trig *TriggersConfig) ExecTrigger(triggerCmd string, return trig.ExecuteCommand(command) } -func (trig *TriggersConfig) ExecNewEmail(account *AccountConfig, - conf *AercConfig, msg *models.MessageInfo, +func (trig *TriggersConfig) ExecNewEmail( + account *AccountConfig, msg *models.MessageInfo, ) { err := trig.ExecTrigger(trig.NewEmail, func(part string) (string, error) { formatstr, args, err := format.ParseMessageFormat( - part, conf.Ui.TimestampFormat, - conf.Ui.ThisDayTimeFormat, - conf.Ui.ThisWeekTimeFormat, - conf.Ui.ThisYearTimeFormat, + part, Ui.TimestampFormat, + Ui.ThisDayTimeFormat, + Ui.ThisWeekTimeFormat, + Ui.ThisYearTimeFormat, format.Ctx{ FromAddress: account.From, AccountName: account.Name, diff --git a/config/ui.go b/config/ui.go index 36b2a9a2..0fb6a248 100644 --- a/config/ui.go +++ b/config/ui.go @@ -82,7 +82,7 @@ const ( type UiConfigContext struct { ContextType uiContextType Regex *regexp.Regexp - UiConfig UIConfig + UiConfig *UIConfig } type uiContextKey struct { @@ -90,8 +90,8 @@ type uiContextKey struct { value string } -func defaultUiConfig() UIConfig { - return UIConfig{ +func defaultUiConfig() *UIConfig { + return &UIConfig{ AutoMarkRead: true, IndexFormat: "%-20.20D %-17.17n %Z %s", TimestampFormat: "2006-01-02 03:04 PM", @@ -136,9 +136,11 @@ func defaultUiConfig() UIConfig { } } -func (config *AercConfig) parseUi(file *ini.File) error { +var Ui = defaultUiConfig() + +func parseUi(file *ini.File) error { if ui, err := file.GetSection("ui"); err == nil { - if err := config.Ui.parse(ui); err != nil { + if err := Ui.parse(ui); err != nil { return err } } @@ -157,7 +159,7 @@ func (config *AercConfig) parseUi(file *ini.File) error { return err } contextualUi := UiConfigContext{ - UiConfig: uiSubConfig, + UiConfig: &uiSubConfig, } var index int @@ -190,31 +192,31 @@ func (config *AercConfig) parseUi(file *ini.File) error { default: return fmt.Errorf("Unknown Contextual Ui Section: %s", sectionName) } - config.Ui.contextualUis = append(config.Ui.contextualUis, &contextualUi) - config.Ui.contextualCounts[contextualUi.ContextType]++ + Ui.contextualUis = append(Ui.contextualUis, &contextualUi) + Ui.contextualCounts[contextualUi.ContextType]++ } // append default paths to styleset-dirs for _, dir := range SearchDirs { - config.Ui.StyleSetDirs = append( - config.Ui.StyleSetDirs, path.Join(dir, "stylesets"), + Ui.StyleSetDirs = append( + Ui.StyleSetDirs, path.Join(dir, "stylesets"), ) } - if err := config.Ui.loadStyleSet(config.Ui.StyleSetDirs); err != nil { + if err := Ui.loadStyleSet(Ui.StyleSetDirs); err != nil { return err } - for _, contextualUi := range config.Ui.contextualUis { + for _, contextualUi := range Ui.contextualUis { if contextualUi.UiConfig.StyleSetName == "" && len(contextualUi.UiConfig.StyleSetDirs) == 0 { continue // no need to do anything if nothing is overridden } // fill in the missing part from the base if contextualUi.UiConfig.StyleSetName == "" { - contextualUi.UiConfig.StyleSetName = config.Ui.StyleSetName + contextualUi.UiConfig.StyleSetName = Ui.StyleSetName } else if len(contextualUi.UiConfig.StyleSetDirs) == 0 { - contextualUi.UiConfig.StyleSetDirs = config.Ui.StyleSetDirs + contextualUi.UiConfig.StyleSetDirs = Ui.StyleSetDirs } // since at least one of them has changed, load the styleset if err := contextualUi.UiConfig.loadStyleSet( @@ -223,7 +225,7 @@ func (config *AercConfig) parseUi(file *ini.File) error { } } - log.Debugf("aerc.conf: [ui] %#v", config.Ui) + log.Debugf("aerc.conf: [ui] %#v", Ui) return nil } diff --git a/config/viewer.go b/config/viewer.go index 3f7c6934..d5e32ac8 100644 --- a/config/viewer.go +++ b/config/viewer.go @@ -18,8 +18,8 @@ type ViewerConfig struct { CloseOnReply bool `ini:"close-on-reply"` } -func defaultViewerConfig() ViewerConfig { - return ViewerConfig{ +func defaultViewerConfig() *ViewerConfig { + return &ViewerConfig{ Pager: "less -R", Alternatives: []string{"text/plain", "text/html"}, ShowHeaders: false, @@ -34,23 +34,25 @@ func defaultViewerConfig() ViewerConfig { } } -func (config *AercConfig) parseViewer(file *ini.File) error { +var Viewer = defaultViewerConfig() + +func parseViewer(file *ini.File) error { viewer, err := file.GetSection("viewer") if err != nil { goto out } - if err := viewer.MapTo(&config.Viewer); err != nil { + if err := viewer.MapTo(&Viewer); err != nil { return err } for key, val := range viewer.KeysHash() { switch key { case "alternatives": - config.Viewer.Alternatives = strings.Split(val, ",") + Viewer.Alternatives = strings.Split(val, ",") case "header-layout": - config.Viewer.HeaderLayout = parseLayout(val) + Viewer.HeaderLayout = parseLayout(val) } } out: - log.Debugf("aerc.conf: [viewer] %#v", config.Viewer) + log.Debugf("aerc.conf: [viewer] %#v", Viewer) return nil } diff --git a/lib/crypto/crypto.go b/lib/crypto/crypto.go index cb026696..e58e6075 100644 --- a/lib/crypto/crypto.go +++ b/lib/crypto/crypto.go @@ -4,6 +4,7 @@ import ( "bytes" "io" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib/crypto/gpg" "git.sr.ht/~rjarry/aerc/lib/crypto/pgp" "git.sr.ht/~rjarry/aerc/log" @@ -24,8 +25,8 @@ type Provider interface { ExportKey(string) (io.Reader, error) } -func New(s string) Provider { - switch s { +func New() Provider { + switch config.General.PgpProvider { case "auto": internal := &pgp.Mail{} if internal.KeyringExists() { diff --git a/lib/open.go b/lib/open.go index 2a4bdbcf..8477b8f1 100644 --- a/lib/open.go +++ b/lib/open.go @@ -6,20 +6,20 @@ import ( "runtime" "strings" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/log" ) func XDGOpen(uri string) error { - return XDGOpenMime(uri, "", nil, nil) + return XDGOpenMime(uri, "", nil) } func XDGOpenMime( - uri string, mimeType string, - openers map[string][]string, args []string, + uri string, mimeType string, args []string, ) error { if len(args) == 0 { // no explicit command provided, lookup opener from mime type - opener, ok := openers[mimeType] + opener, ok := config.Openers[mimeType] if ok { args = opener } else { diff --git a/lib/statusline/renderer.go b/lib/statusline/renderer.go index f128e6a2..993cfcc5 100644 --- a/lib/statusline/renderer.go +++ b/lib/statusline/renderer.go @@ -7,6 +7,7 @@ import ( "strings" "unicode" + "git.sr.ht/~rjarry/aerc/config" "github.com/mattn/go-runewidth" ) @@ -19,24 +20,25 @@ type renderParams struct { type renderFunc func(r renderParams) string -func newRenderer(renderFormat, textMode string) renderFunc { +func newRenderer() renderFunc { var texter Texter - switch strings.ToLower(textMode) { + switch strings.ToLower(config.Statusline.DisplayMode) { case "icon": texter = &icon{} default: texter = &text{} } - return renderer(texter, renderFormat) + return renderer(texter) } -func renderer(texter Texter, renderFormat string) renderFunc { +func renderer(texter Texter) renderFunc { var leftFmt, rightFmt string - if idx := strings.Index(renderFormat, "%>"); idx < 0 { - leftFmt = renderFormat + if idx := strings.Index(config.Statusline.RenderFormat, "%>"); idx < 0 { + leftFmt = config.Statusline.RenderFormat } else { - leftFmt, rightFmt = renderFormat[:idx], strings.Replace(renderFormat[idx:], "%>", "", 1) + leftFmt = config.Statusline.RenderFormat[:idx] + rightFmt = strings.Replace(config.Statusline.RenderFormat[idx:], "%>", "", 1) } return func(r renderParams) string { diff --git a/lib/statusline/state.go b/lib/statusline/state.go index 8384f200..528400b1 100644 --- a/lib/statusline/state.go +++ b/lib/statusline/state.go @@ -7,11 +7,10 @@ import ( ) type State struct { - separator string - renderer renderFunc - acct *accountState - fldr map[string]*folderState - width int + renderer renderFunc + acct *accountState + fldr map[string]*folderState + width int } type accountState struct { @@ -31,19 +30,18 @@ type folderState struct { Threading bool } -func NewState(name string, multipleAccts bool, conf config.StatuslineConfig) *State { +func NewState(name string, multipleAccts bool) *State { return &State{ - separator: conf.Separator, - renderer: newRenderer(conf.RenderFormat, conf.DisplayMode), - acct: &accountState{Name: name, Multiple: multipleAccts}, - fldr: make(map[string]*folderState), + renderer: newRenderer(), + acct: &accountState{Name: name, Multiple: multipleAccts}, + fldr: make(map[string]*folderState), } } func (s *State) StatusLine(folder string) string { return s.renderer(renderParams{ width: s.width, - sep: s.separator, + sep: config.Statusline.Separator, acct: s.acct, fldr: s.folderState(folder), }) diff --git a/lib/ui/stack.go b/lib/ui/stack.go index c0aca4e4..a4017007 100644 --- a/lib/ui/stack.go +++ b/lib/ui/stack.go @@ -10,10 +10,10 @@ import ( type Stack struct { children []Drawable - uiConfig config.UIConfig + uiConfig *config.UIConfig } -func NewStack(uiConfig config.UIConfig) *Stack { +func NewStack(uiConfig *config.UIConfig) *Stack { return &Stack{uiConfig: uiConfig} } diff --git a/widgets/account-wizard.go b/widgets/account-wizard.go index b6210cb7..0e2bda1e 100644 --- a/widgets/account-wizard.go +++ b/widgets/account-wizard.go @@ -41,7 +41,6 @@ const ( type AccountWizard struct { aerc *Aerc - conf *config.AercConfig step int steps []*ui.Grid focus int @@ -87,23 +86,22 @@ func showPasswordWarning(aerc *Aerc) { aerc.AddDialog(warning) } -func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { +func NewAccountWizard(aerc *Aerc) *AccountWizard { wizard := &AccountWizard{ - accountName: ui.NewTextInput("", &conf.Ui).Prompt("> "), + accountName: ui.NewTextInput("", config.Ui).Prompt("> "), aerc: aerc, - conf: conf, temporary: false, copySent: true, - email: ui.NewTextInput("", &conf.Ui).Prompt("> "), - fullName: ui.NewTextInput("", &conf.Ui).Prompt("> "), - imapPassword: ui.NewTextInput("", &conf.Ui).Prompt("] ").Password(true), - imapServer: ui.NewTextInput("", &conf.Ui).Prompt("> "), - imapStr: ui.NewText("imaps://", conf.Ui.GetStyle(config.STYLE_DEFAULT)), - imapUsername: ui.NewTextInput("", &conf.Ui).Prompt("> "), - smtpPassword: ui.NewTextInput("", &conf.Ui).Prompt("] ").Password(true), - smtpServer: ui.NewTextInput("", &conf.Ui).Prompt("> "), - smtpStr: ui.NewText("smtps://", conf.Ui.GetStyle(config.STYLE_DEFAULT)), - smtpUsername: ui.NewTextInput("", &conf.Ui).Prompt("> "), + email: ui.NewTextInput("", config.Ui).Prompt("> "), + fullName: ui.NewTextInput("", config.Ui).Prompt("> "), + imapPassword: ui.NewTextInput("", config.Ui).Prompt("] ").Password(true), + imapServer: ui.NewTextInput("", config.Ui).Prompt("> "), + imapStr: ui.NewText("imaps://", config.Ui.GetStyle(config.STYLE_DEFAULT)), + imapUsername: ui.NewTextInput("", config.Ui).Prompt("> "), + smtpPassword: ui.NewTextInput("", config.Ui).Prompt("] ").Password(true), + smtpServer: ui.NewTextInput("", config.Ui).Prompt("> "), + smtpStr: ui.NewText("smtps://", config.Ui.GetStyle(config.STYLE_DEFAULT)), + smtpUsername: ui.NewTextInput("", config.Ui).Prompt("> "), } // Autofill some stuff for the user @@ -172,10 +170,10 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { "aerc-accounts(5) man page.\n"+ "Press <Tab> and <Shift+Tab> to cycle between each field in this form, "+ "or <Ctrl+j> and <Ctrl+k>.", - conf.Ui.GetStyle(config.STYLE_DEFAULT))) + config.Ui.GetStyle(config.STYLE_DEFAULT))) basics.AddChild( ui.NewText("Name for this account? (e.g. 'Personal' or 'Work')", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(1, 0) basics.AddChild(wizard.accountName). At(2, 0) @@ -183,7 +181,7 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { At(3, 0) basics.AddChild( ui.NewText("Full name for outgoing emails? (e.g. 'John Doe')", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(4, 0) basics.AddChild(wizard.fullName). At(5, 0) @@ -191,11 +189,11 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { At(6, 0) basics.AddChild( ui.NewText("Your email address? (e.g. 'john@example.org')", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(7, 0) basics.AddChild(wizard.email). At(8, 0) - selector := NewSelector([]string{"Next"}, 0, &conf.Ui). + selector := NewSelector([]string{"Next"}, 0, config.Ui). OnChoose(func(option string) { email := wizard.email.String() if strings.ContainsRune(email, '@') { @@ -244,10 +242,10 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { {Strategy: ui.SIZE_WEIGHT, Size: ui.Const(1)}, }) incoming.AddChild(ui.NewText("\nConfigure incoming mail (IMAP)", - conf.Ui.GetStyle(config.STYLE_DEFAULT))) + config.Ui.GetStyle(config.STYLE_DEFAULT))) incoming.AddChild( ui.NewText("Username", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(1, 0) incoming.AddChild(wizard.imapUsername). At(2, 0) @@ -255,7 +253,7 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { At(3, 0) incoming.AddChild( ui.NewText("Password", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(4, 0) incoming.AddChild(wizard.imapPassword). At(5, 0) @@ -264,7 +262,7 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { incoming.AddChild( ui.NewText("Server address "+ "(e.g. 'mail.example.org' or 'mail.example.org:1313')", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(7, 0) incoming.AddChild(wizard.imapServer). At(8, 0) @@ -272,13 +270,13 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { At(9, 0) incoming.AddChild( ui.NewText("Connection mode", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(10, 0) imapMode := NewSelector([]string{ "IMAP over SSL/TLS", "IMAP with STARTTLS", "Insecure IMAP", - }, 0, &conf.Ui).Chooser(true).OnSelect(func(option string) { + }, 0, config.Ui).Chooser(true).OnSelect(func(option string) { switch option { case "IMAP over SSL/TLS": wizard.imapMode = IMAP_OVER_TLS @@ -290,7 +288,7 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { wizard.imapUri() }) incoming.AddChild(imapMode).At(11, 0) - selector = NewSelector([]string{"Previous", "Next"}, 1, &conf.Ui). + selector = NewSelector([]string{"Previous", "Next"}, 1, config.Ui). OnChoose(wizard.advance) incoming.AddChild(ui.NewFill(' ', tcell.StyleDefault)).At(12, 0) incoming.AddChild(wizard.imapStr).At(13, 0) @@ -323,10 +321,10 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { {Strategy: ui.SIZE_WEIGHT, Size: ui.Const(1)}, }) outgoing.AddChild(ui.NewText("\nConfigure outgoing mail (SMTP)", - conf.Ui.GetStyle(config.STYLE_DEFAULT))) + config.Ui.GetStyle(config.STYLE_DEFAULT))) outgoing.AddChild( ui.NewText("Username", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(1, 0) outgoing.AddChild(wizard.smtpUsername). At(2, 0) @@ -334,7 +332,7 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { At(3, 0) outgoing.AddChild( ui.NewText("Password", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(4, 0) outgoing.AddChild(wizard.smtpPassword). At(5, 0) @@ -343,7 +341,7 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { outgoing.AddChild( ui.NewText("Server address "+ "(e.g. 'mail.example.org' or 'mail.example.org:1313')", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(7, 0) outgoing.AddChild(wizard.smtpServer). At(8, 0) @@ -351,13 +349,13 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { At(9, 0) outgoing.AddChild( ui.NewText("Connection mode", - conf.Ui.GetStyle(config.STYLE_HEADER))). + config.Ui.GetStyle(config.STYLE_HEADER))). At(10, 0) smtpMode := NewSelector([]string{ "SMTP over SSL/TLS", "SMTP with STARTTLS", "Insecure SMTP", - }, 0, &conf.Ui).Chooser(true).OnSelect(func(option string) { + }, 0, config.Ui).Chooser(true).OnSelect(func(option string) { switch option { case "SMTP over SSL/TLS": wizard.smtpMode = SMTP_OVER_TLS @@ -369,15 +367,15 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { wizard.smtpUri() }) outgoing.AddChild(smtpMode).At(11, 0) - selector = NewSelector([]string{"Previous", "Next"}, 1, &conf.Ui). + selector = NewSelector([]string{"Previous", "Next"}, 1, config.Ui). OnChoose(wizard.advance) outgoing.AddChild(ui.NewFill(' ', tcell.StyleDefault)).At(12, 0) outgoing.AddChild(wizard.smtpStr).At(13, 0) outgoing.AddChild(ui.NewFill(' ', tcell.StyleDefault)).At(14, 0) outgoing.AddChild( ui.NewText("Copy sent messages to 'Sent' folder?", - conf.Ui.GetStyle(config.STYLE_HEADER))).At(15, 0) - copySent := NewSelector([]string{"Yes", "No"}, 0, &conf.Ui). + config.Ui.GetStyle(config.STYLE_HEADER))).At(15, 0) + copySent := NewSelector([]string{"Yes", "No"}, 0, config.Ui). Chooser(true).OnChoose(func(option string) { switch option { case "Yes": @@ -404,12 +402,12 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { "You can go back and double check your settings, or choose 'Finish' to\n"+ "save your settings to accounts.conf.\n\n"+ "To add another account in the future, run ':new-account'.", - conf.Ui.GetStyle(config.STYLE_DEFAULT))) + config.Ui.GetStyle(config.STYLE_DEFAULT))) selector = NewSelector([]string{ "Previous", "Finish & open tutorial", "Finish", - }, 1, &conf.Ui).OnChoose(func(option string) { + }, 1, config.Ui).OnChoose(func(option string) { switch option { case "Previous": wizard.advance("Previous") @@ -537,12 +535,11 @@ func (wizard *AccountWizard) finish(tutorial bool) { if wizard.copySent { account.CopyTo = "Sent" } - wizard.conf.Accounts = append(wizard.conf.Accounts, account) + config.Accounts = append(config.Accounts, &account) - view, err := NewAccountView(wizard.aerc, wizard.conf, &account, wizard.aerc, nil) + view, err := NewAccountView(wizard.aerc, &account, wizard.aerc, nil) if err != nil { - wizard.aerc.NewTab(errorScreen(err.Error(), wizard.conf.Ui), - account.Name) + wizard.aerc.NewTab(errorScreen(err.Error()), account.Name) return } wizard.aerc.accounts[account.Name] = view diff --git a/widgets/account.go b/widgets/account.go index 838dd624..6bcb5b83 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -26,7 +26,6 @@ type AccountView struct { sync.Mutex acct *config.AccountConfig aerc *Aerc - conf *config.AercConfig dirlist DirectoryLister labels []string grid *ui.Grid @@ -55,17 +54,17 @@ func (acct *AccountView) UiConfig() *config.UIConfig { return acct.uiConf } -func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountConfig, +func NewAccountView( + aerc *Aerc, acct *config.AccountConfig, host TabHost, deferLoop chan struct{}, ) (*AccountView, error) { - acctUiConf := conf.Ui.ForAccount(acct.Name) + acctUiConf := config.Ui.ForAccount(acct.Name) view := &AccountView{ acct: acct, aerc: aerc, - conf: conf, host: host, - state: statusline.NewState(acct.Name, len(conf.Accounts) > 1, conf.Statusline), + state: statusline.NewState(acct.Name, len(config.Accounts) > 1), uiConf: acctUiConf, } @@ -86,12 +85,12 @@ func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountCon } view.worker = worker - view.dirlist = NewDirectoryList(conf, acct, worker) + view.dirlist = NewDirectoryList(acct, worker) if acctUiConf.SidebarWidth > 0 { view.grid.AddChild(ui.NewBordered(view.dirlist, ui.BORDER_RIGHT, acctUiConf)) } - view.msglist = NewMessageList(conf, aerc) + view.msglist = NewMessageList(aerc, view) view.grid.AddChild(view.msglist).At(0, 1) go func() { @@ -291,8 +290,7 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) { acct.dirlist.UiConfig(name).ReverseThreadOrder, acct.dirlist.UiConfig(name).SortThreadSiblings, func(msg *models.MessageInfo) { - acct.conf.Triggers.ExecNewEmail(acct.acct, - acct.conf, msg) + config.Triggers.ExecNewEmail(acct.acct, msg) }, func() { if acct.dirlist.UiConfig(name).NewMessageBell { acct.host.Beep() @@ -526,7 +524,7 @@ func (acct *AccountView) UpdateSplitView() { return } orig := acct.split - acct.split = NewMessageViewer(acct, acct.conf, view) + acct.split = NewMessageViewer(acct, view) acct.grid.ReplaceChild(orig, acct.split) if orig != nil { orig.Close() @@ -585,7 +583,7 @@ func (acct *AccountView) Split(n int) error { acct.aerc.PushError(err.Error()) return } - acct.split = NewMessageViewer(acct, acct.conf, view) + acct.split = NewMessageViewer(acct, view) acct.grid.AddChild(acct.split).At(1, 1) }) ui.Invalidate() @@ -628,7 +626,7 @@ func (acct *AccountView) Vsplit(n int) error { acct.aerc.PushError(err.Error()) return } - acct.split = NewMessageViewer(acct, acct.conf, view) + acct.split = NewMessageViewer(acct, view) acct.grid.AddChild(acct.split).At(0, 2) }) ui.Invalidate() diff --git a/widgets/aerc.go b/widgets/aerc.go index 97e3c663..cf893a7d 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -29,7 +29,6 @@ type Aerc struct { cmd func(cmd []string) error cmdHistory lib.History complete func(cmd string) []string - conf *config.AercConfig focused ui.Interactive grid *ui.Grid simulating int @@ -52,15 +51,15 @@ type Choice struct { Command []string } -func NewAerc(conf *config.AercConfig, +func NewAerc( crypto crypto.Provider, cmd func(cmd []string) error, complete func(cmd string) []string, cmdHistory lib.History, deferLoop chan struct{}, ) *Aerc { - tabs := ui.NewTabs(&conf.Ui) + tabs := ui.NewTabs(config.Ui) - statusbar := ui.NewStack(conf.Ui) - statusline := NewStatusLine(conf.Ui) + statusbar := ui.NewStack(config.Ui) + statusline := NewStatusLine(config.Ui) statusbar.Push(statusline) grid := ui.NewGrid().Rows([]ui.GridSpec{ @@ -76,34 +75,32 @@ func NewAerc(conf *config.AercConfig, aerc := &Aerc{ accounts: make(map[string]*AccountView), - conf: conf, cmd: cmd, cmdHistory: cmdHistory, complete: complete, grid: grid, statusbar: statusbar, statusline: statusline, - prompts: ui.NewStack(conf.Ui), + prompts: ui.NewStack(config.Ui), tabs: tabs, Crypto: crypto, } statusline.SetAerc(aerc) - conf.Triggers.ExecuteCommand = cmd + config.Triggers.ExecuteCommand = cmd - for i, acct := range conf.Accounts { - view, err := NewAccountView(aerc, conf, &conf.Accounts[i], aerc, deferLoop) + for _, acct := range config.Accounts { + view, err := NewAccountView(aerc, acct, aerc, deferLoop) if err != nil { - tabs.Add(errorScreen(err.Error(), conf.Ui), acct.Name, nil) + tabs.Add(errorScreen(err.Error()), acct.Name, nil) } else { aerc.accounts[acct.Name] = view - conf := view.UiConfig() - tabs.Add(view, acct.Name, conf) + tabs.Add(view, acct.Name, view.UiConfig()) } } - if len(conf.Accounts) == 0 { - wizard := NewAccountWizard(aerc.Config(), aerc) + if len(config.Accounts) == 0 { + wizard := NewAccountWizard(aerc) wizard.Focus(true) aerc.NewTab(wizard, "New account") } @@ -202,8 +199,8 @@ func (aerc *Aerc) HumanReadableBindings() []string { format(config.FormatKeyStrokes(bind.Output)), )) } - if binds.Globals && aerc.conf.Bindings.Global != nil { - for _, bind := range aerc.conf.Bindings.Global.Bindings { + if binds.Globals && config.Binds.Global != nil { + for _, bind := range config.Binds.Global.Bindings { result = append(result, fmt.Sprintf(fmtStr+" (Globals)", format(config.FormatKeyStrokes(bind.Input)), format(config.FormatKeyStrokes(bind.Output)), @@ -229,35 +226,35 @@ func (aerc *Aerc) getBindings() *config.KeyBindings { } switch view := aerc.SelectedTabContent().(type) { case *AccountView: - binds := aerc.conf.Bindings.MessageList.ForAccount(selectedAccountName) + binds := config.Binds.MessageList.ForAccount(selectedAccountName) return binds.ForFolder(view.SelectedDirectory()) case *AccountWizard: - return aerc.conf.Bindings.AccountWizard + return config.Binds.AccountWizard case *Composer: switch view.Bindings() { case "compose::editor": - return aerc.conf.Bindings.ComposeEditor.ForAccount( + return config.Binds.ComposeEditor.ForAccount( selectedAccountName) case "compose::review": - return aerc.conf.Bindings.ComposeReview.ForAccount( + return config.Binds.ComposeReview.ForAccount( selectedAccountName) default: - return aerc.conf.Bindings.Compose.ForAccount( + return config.Binds.Compose.ForAccount( selectedAccountName) } case *MessageViewer: switch view.Bindings() { case "view::passthrough": - return aerc.conf.Bindings.MessageViewPassthrough.ForAccount( + return config.Binds.MessageViewPassthrough.ForAccount( selectedAccountName) default: - return aerc.conf.Bindings.MessageView.ForAccount( + return config.Binds.MessageView.ForAccount( selectedAccountName) } case *Terminal: - return aerc.conf.Bindings.Terminal + return config.Binds.Terminal default: - return aerc.conf.Bindings.Global + return config.Binds.Global } } @@ -319,8 +316,7 @@ func (aerc *Aerc) Event(event tcell.Event) bool { case config.BINDING_NOT_FOUND: } if bindings.Globals { - result, strokes = aerc.conf.Bindings.Global. - GetBinding(aerc.pendingKeys) + result, strokes = config.Binds.Global.GetBinding(aerc.pendingKeys) switch result { case config.BINDING_FOUND: aerc.simulate(strokes) @@ -335,7 +331,7 @@ func (aerc *Aerc) Event(event tcell.Event) bool { exKey := bindings.ExKey if aerc.simulating > 0 { // Keybindings still use : even if you change the ex key - exKey = aerc.conf.Bindings.Global.ExKey + exKey = config.Binds.Global.ExKey } if aerc.isExKey(event, exKey) { aerc.BeginExCommand("") @@ -367,10 +363,6 @@ func (aerc *Aerc) Event(event tcell.Event) bool { return false } -func (aerc *Aerc) Config() *config.AercConfig { - return aerc.conf -} - func (aerc *Aerc) SelectedAccount() *AccountView { return aerc.account(aerc.SelectedTabContent()) } @@ -387,13 +379,13 @@ func (aerc *Aerc) PrevAccount() (*AccountView, error) { if cur == nil { return nil, fmt.Errorf("no account selected, cannot get prev") } - for i, conf := range aerc.conf.Accounts { + for i, conf := range config.Accounts { if conf.Name == cur.Name() { i -= 1 if i == -1 { - i = len(aerc.conf.Accounts) - 1 + i = len(config.Accounts) - 1 } - conf = aerc.conf.Accounts[i] + conf = config.Accounts[i] return aerc.Account(conf.Name) } } @@ -405,13 +397,13 @@ func (aerc *Aerc) NextAccount() (*AccountView, error) { if cur == nil { return nil, fmt.Errorf("no account selected, cannot get next") } - for i, conf := range aerc.conf.Accounts { + for i, conf := range config.Accounts { if conf.Name == cur.Name() { i += 1 - if i == len(aerc.conf.Accounts) { + if i == len(config.Accounts) { i = 0 } - conf = aerc.conf.Accounts[i] + conf = config.Accounts[i] return aerc.Account(conf.Name) } } @@ -441,7 +433,7 @@ func (aerc *Aerc) account(d ui.Drawable) *AccountView { func (aerc *Aerc) SelectedAccountUiConfig() *config.UIConfig { acct := aerc.SelectedAccount() if acct == nil { - return &aerc.conf.Ui + return config.Ui } return acct.UiConfig() } @@ -459,10 +451,9 @@ func (aerc *Aerc) SelectedTab() *ui.Tab { } func (aerc *Aerc) NewTab(clickable ui.Drawable, name string) *ui.Tab { - var uiConf *config.UIConfig = nil + uiConf := config.Ui if acct := aerc.account(clickable); acct != nil { - conf := acct.UiConfig() - uiConf = conf + uiConf = acct.UiConfig() } tab := aerc.tabs.Add(clickable, name, uiConf) aerc.UpdateStatus() @@ -588,7 +579,7 @@ func (aerc *Aerc) BeginExCommand(cmd string) { return aerc.complete(cmd), "" } } - exline := NewExLine(aerc.conf, cmd, func(cmd string) { + exline := NewExLine(cmd, func(cmd string) { parts, err := shlex.Split(cmd) if err != nil { aerc.PushError(err.Error()) @@ -615,7 +606,7 @@ func (aerc *Aerc) PushPrompt(prompt *ExLine) { } func (aerc *Aerc) RegisterPrompt(prompt string, cmd []string) { - p := NewPrompt(aerc.conf, prompt, func(text string) { + p := NewPrompt(prompt, func(text string) { if text != "" { cmd = append(cmd, text) } @@ -641,7 +632,7 @@ func (aerc *Aerc) RegisterChoices(choices []Choice) { cmds[c.Key] = c.Command } prompt := strings.Join(texts, ", ") + "? " - p := NewPrompt(aerc.conf, prompt, func(text string) { + p := NewPrompt(prompt, func(text string) { cmd, ok := cmds[text] if !ok { return @@ -718,7 +709,7 @@ func (aerc *Aerc) Mailto(addr *url.URL) error { return errors.New("No account selected") } - composer, err := NewComposer(aerc, acct, aerc.Config(), + composer, err := NewComposer(aerc, acct, acct.AccountConfig(), acct.Worker(), "", h, models.OriginalMail{}) if err != nil { return nil @@ -766,9 +757,9 @@ func (aerc *Aerc) Mbox(source string) error { acctConf.Postpone = "Drafts" acctConf.CopyTo = "Sent" - mboxView, err := NewAccountView(aerc, aerc.conf, &acctConf, aerc, nil) + mboxView, err := NewAccountView(aerc, &acctConf, aerc, nil) if err != nil { - aerc.NewTab(errorScreen(err.Error(), aerc.conf.Ui), acctConf.Name) + aerc.NewTab(errorScreen(err.Error()), acctConf.Name) } else { aerc.accounts[acctConf.Name] = mboxView aerc.NewTab(mboxView, acctConf.Name) @@ -806,7 +797,7 @@ func (aerc *Aerc) CloseDialog() { func (aerc *Aerc) GetPassword(title string, prompt string) (chText chan string, chErr chan error) { chText = make(chan string, 1) chErr = make(chan error, 1) - getPasswd := NewGetPasswd(title, prompt, aerc.conf, func(pw string, err error) { + getPasswd := NewGetPasswd(title, prompt, func(pw string, err error) { defer func() { close(chErr) close(chText) @@ -848,8 +839,8 @@ func (aerc *Aerc) DecryptKeys(keys []openpgp.Key, symmetric bool) (b []byte, err } // errorScreen is a widget that draws an error in the middle of the context -func errorScreen(s string, conf config.UIConfig) ui.Drawable { - errstyle := conf.GetStyle(config.STYLE_ERROR) +func errorScreen(s string) ui.Drawable { + errstyle := config.Ui.GetStyle(config.STYLE_ERROR) text := ui.NewText(s, errstyle).Strategy(ui.TEXT_CENTER) grid := ui.NewGrid().Rows([]ui.GridSpec{ {Strategy: ui.SIZE_WEIGHT, Size: ui.Const(1)}, diff --git a/widgets/compose.go b/widgets/compose.go index 4cf7da16..4f08afa3 100644 --- a/widgets/compose.go +++ b/widgets/compose.go @@ -36,7 +36,6 @@ type Composer struct { parent models.OriginalMail // parent of current message, only set if reply acctConfig *config.AccountConfig - config *config.AercConfig acct *AccountView aerc *Aerc @@ -65,8 +64,9 @@ type Composer struct { textParts []*lib.Part } -func NewComposer(aerc *Aerc, acct *AccountView, conf *config.AercConfig, - acctConfig *config.AccountConfig, worker *types.Worker, template string, +func NewComposer( + aerc *Aerc, acct *AccountView, acctConfig *config.AccountConfig, + worker *types.Worker, template string, h *mail.Header, orig models.OriginalMail, ) (*Composer, error) { if h == nil { @@ -83,7 +83,6 @@ func NewComposer(aerc *Aerc, acct *AccountView, conf *config.AercConfig, acct: acct, acctConfig: acctConfig, aerc: aerc, - config: conf, header: h, parent: orig, email: email, @@ -132,17 +131,16 @@ func (c *Composer) SwitchAccount(newAcct *AccountView) error { return nil } -func (c *Composer) setupFor(acct *AccountView) error { +func (c *Composer) setupFor(view *AccountView) error { c.Lock() defer c.Unlock() - // set new account and accountConfig - c.acct = acct - c.acctConfig = acct.AccountConfig() - c.worker = acct.Worker() + // set new account + c.acct = view + c.worker = view.Worker() // Set from header if not already in header if fl, err := c.header.AddressList("from"); err != nil || fl == nil { - fl, err = mail.ParseAddressList(c.acctConfig.From) + fl, err = mail.ParseAddressList(view.acct.From) if err != nil { return err } @@ -152,9 +150,9 @@ func (c *Composer) setupFor(acct *AccountView) error { } // update completer - cmd := c.acctConfig.AddressBookCmd + cmd := view.acct.AddressBookCmd if cmd == "" { - cmd = c.config.Compose.AddressBookCmd + cmd = config.Compose.AddressBookCmd } cmpl := completer.New(cmd, func(err error) { c.aerc.PushError( @@ -187,12 +185,12 @@ func (c *Composer) setupFor(acct *AccountView) error { // update the crypto parts c.crypto = nil c.sign = false - if c.acctConfig.PgpAutoSign { + if c.acct.acct.PgpAutoSign { err := c.SetSign(true) log.Warnf("failed to enable message signing: %v", err) } c.encrypt = false - if c.acctConfig.PgpOpportunisticEncrypt { + if c.acct.acct.PgpOpportunisticEncrypt { c.SetEncrypt(true) } err := c.updateCrypto() @@ -204,7 +202,7 @@ func (c *Composer) setupFor(acct *AccountView) error { } func (c *Composer) buildComposeHeader(aerc *Aerc, cmpl *completer.Completer) { - c.layout = aerc.conf.Compose.HeaderLayout + c.layout = config.Compose.HeaderLayout c.editors = make(map[string]*headerEditor) c.focusable = make([]ui.MouseableDrawableInteractive, 0) uiConfig := c.acct.UiConfig() @@ -214,7 +212,7 @@ func (c *Composer) buildComposeHeader(aerc *Aerc, cmpl *completer.Completer) { h = strings.ToLower(h) c.layout[i][j] = h // normalize to lowercase e := newHeaderEditor(h, c.header, uiConfig) - if aerc.conf.Ui.CompletionPopovers { + if uiConfig.CompletionPopovers { e.input.TabComplete( cmpl.ForHeader(h), uiConfig.CompletionDelay, @@ -237,7 +235,7 @@ func (c *Composer) buildComposeHeader(aerc *Aerc, cmpl *completer.Completer) { if c.header.Has(h) { if _, ok := c.editors[h]; !ok { e := newHeaderEditor(h, c.header, uiConfig) - if aerc.conf.Ui.CompletionPopovers { + if uiConfig.CompletionPopovers { e.input.TabComplete( cmpl.ForHeader(h), uiConfig.CompletionDelay, @@ -499,7 +497,7 @@ func (c *Composer) AddTemplate(template string, data interface{}) error { } templateText, err := templates.ParseTemplateFromFile( - template, c.config.Templates.TemplateDirs, data) + template, config.Templates.TemplateDirs, data) if err != nil { return err } @@ -815,7 +813,7 @@ func (c *Composer) WriteMessage(header *mail.Header, writer io.Writer) error { } func (c *Composer) ShouldWarnAttachment() (bool, error) { - regex := c.config.Compose.NoAttachmentWarning + regex := config.Compose.NoAttachmentWarning if regex == nil || len(c.attachments) > 0 { return false, nil @@ -987,7 +985,7 @@ func (c *Composer) ShowTerminal() { c.grid.RemoveChild(c.review) } cmds := []string{ - c.config.Compose.Editor, + config.Compose.Editor, os.Getenv("EDITOR"), "vi", "nano", @@ -1261,7 +1259,7 @@ type reviewMessage struct { } func newReviewMessage(composer *Composer, err error) *reviewMessage { - bindings := composer.config.Bindings.ComposeReview.ForAccount( + bindings := config.Binds.ComposeReview.ForAccount( composer.acctConfig.Name, ) @@ -1400,7 +1398,7 @@ func newReviewMessage(composer *Composer, err error) *reviewMessage { } func (c *Composer) updateMultipart(p *lib.Part) error { - command, found := c.aerc.Config().Converters[p.MimeType] + command, found := config.Converters[p.MimeType] if !found { // unreachable return fmt.Errorf("no command defined for mime/type") diff --git a/widgets/dirlist.go b/widgets/dirlist.go index 0b41c024..4d27def2 100644 --- a/widgets/dirlist.go +++ b/widgets/dirlist.go @@ -48,7 +48,6 @@ type DirectoryLister interface { type DirectoryList struct { Scrollable - aercConf *config.AercConfig acctConf *config.AccountConfig store *lib.DirStore dirs []string @@ -60,13 +59,12 @@ type DirectoryList struct { skipSelectCancel context.CancelFunc } -func NewDirectoryList(conf *config.AercConfig, acctConf *config.AccountConfig, +func NewDirectoryList(acctConf *config.AccountConfig, worker *types.Worker, ) DirectoryLister { ctx, cancel := context.WithCancel(context.Background()) dirlist := &DirectoryList{ - aercConf: conf, acctConf: acctConf, store: lib.NewDirStore(), worker: worker, @@ -88,7 +86,7 @@ func (dirlist *DirectoryList) UiConfig(dir string) *config.UIConfig { if dir == "" { dir = dirlist.Selected() } - return dirlist.aercConf.Ui.ForAccount(dirlist.acctConf.Name).ForFolder(dir) + return config.Ui.ForAccount(dirlist.acctConf.Name).ForFolder(dir) } func (dirlist *DirectoryList) List() []string { diff --git a/widgets/exline.go b/widgets/exline.go index 5cf4338d..1f2d71e4 100644 --- a/widgets/exline.go +++ b/widgets/exline.go @@ -14,19 +14,18 @@ type ExLine struct { tabcomplete func(cmd string) ([]string, string) cmdHistory lib.History input *ui.TextInput - conf *config.AercConfig } -func NewExLine(conf *config.AercConfig, cmd string, commit func(cmd string), finish func(), +func NewExLine(cmd string, commit func(cmd string), finish func(), tabcomplete func(cmd string) ([]string, string), cmdHistory lib.History, ) *ExLine { - input := ui.NewTextInput("", &conf.Ui).Prompt(":").Set(cmd) - if conf.Ui.CompletionPopovers { + input := ui.NewTextInput("", config.Ui).Prompt(":").Set(cmd) + if config.Ui.CompletionPopovers { input.TabComplete( tabcomplete, - conf.Ui.CompletionDelay, - conf.Ui.CompletionMinChars, + config.Ui.CompletionDelay, + config.Ui.CompletionMinChars, ) } exline := &ExLine{ @@ -35,7 +34,6 @@ func NewExLine(conf *config.AercConfig, cmd string, commit func(cmd string), fin tabcomplete: tabcomplete, cmdHistory: cmdHistory, input: input, - conf: conf, } return exline } @@ -43,20 +41,20 @@ func NewExLine(conf *config.AercConfig, cmd string, commit func(cmd string), fin func (x *ExLine) TabComplete(tabComplete func(string) ([]string, string)) { x.input.TabComplete( tabComplete, - x.conf.Ui.CompletionDelay, - x.conf.Ui.CompletionMinChars, + config.Ui.CompletionDelay, + config.Ui.CompletionMinChars, ) } -func NewPrompt(conf *config.AercConfig, prompt string, commit func(text string), +func NewPrompt(prompt string, commit func(text string), tabcomplete func(cmd string) ([]string, string), ) *ExLine { - input := ui.NewTextInput("", &conf.Ui).Prompt(prompt) - if conf.Ui.CompletionPopovers { + input := ui.NewTextInput("", config.Ui).Prompt(prompt) + if config.Ui.CompletionPopovers { input.TabComplete( tabcomplete, - conf.Ui.CompletionDelay, - conf.Ui.CompletionMinChars, + config.Ui.CompletionDelay, + config.Ui.CompletionMinChars, ) } exline := &ExLine{ diff --git a/widgets/getpasswd.go b/widgets/getpasswd.go index 70a2648d..17274626 100644 --- a/widgets/getpasswd.go +++ b/widgets/getpasswd.go @@ -14,26 +14,24 @@ type GetPasswd struct { title string prompt string input *ui.TextInput - conf *config.AercConfig } -func NewGetPasswd(title string, prompt string, conf *config.AercConfig, - cb func(string, error), +func NewGetPasswd( + title string, prompt string, cb func(string, error), ) *GetPasswd { getpasswd := &GetPasswd{ callback: cb, title: title, prompt: prompt, - conf: conf, - input: ui.NewTextInput("", &conf.Ui).Password(true).Prompt("Password: "), + input: ui.NewTextInput("", config.Ui).Password(true).Prompt("Password: "), } getpasswd.input.Focus(true) return getpasswd } func (gp *GetPasswd) Draw(ctx *ui.Context) { - defaultStyle := gp.conf.Ui.GetStyle(config.STYLE_DEFAULT) - titleStyle := gp.conf.Ui.GetStyle(config.STYLE_TITLE) + defaultStyle := config.Ui.GetStyle(config.STYLE_DEFAULT) + titleStyle := config.Ui.GetStyle(config.STYLE_TITLE) ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', defaultStyle) ctx.Fill(0, 0, ctx.Width(), 1, ' ', titleStyle) diff --git a/widgets/msglist.go b/widgets/msglist.go index 85b8f168..4c805d51 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -21,7 +21,6 @@ import ( type MessageList struct { Scrollable - conf *config.AercConfig height int nmsgs int spinner *Spinner @@ -30,10 +29,9 @@ type MessageList struct { aerc *Aerc } -func NewMessageList(conf *config.AercConfig, aerc *Aerc) *MessageList { +func NewMessageList(aerc *Aerc, account *AccountView) *MessageList { ml := &MessageList{ - conf: conf, - spinner: NewSpinner(&conf.Ui), + spinner: NewSpinner(account.uiConf), isInitalizing: true, aerc: aerc, } @@ -310,7 +308,7 @@ func (ml *MessageList) MouseEvent(localX int, localY int, event tcell.Event) { ml.aerc.PushError(err.Error()) return } - viewer := NewMessageViewer(acct, ml.aerc.Config(), view) + viewer := NewMessageViewer(acct, view) ml.aerc.NewTab(viewer, msg.Envelope.Subject) }) } diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go index 875ff873..0c72fa79 100644 --- a/widgets/msgviewer.go +++ b/widgets/msgviewer.go @@ -28,7 +28,6 @@ var _ ProvidesMessages = (*MessageViewer)(nil) type MessageViewer struct { acct *AccountView - conf *config.AercConfig err error grid *ui.Grid switcher *PartSwitcher @@ -46,11 +45,11 @@ type PartSwitcher struct { mv *MessageViewer } -func NewMessageViewer(acct *AccountView, - conf *config.AercConfig, msg lib.MessageView, +func NewMessageViewer( + acct *AccountView, msg lib.MessageView, ) *MessageViewer { hf := HeaderLayoutFilter{ - layout: HeaderLayout(conf.Viewer.HeaderLayout), + layout: HeaderLayout(config.Viewer.HeaderLayout), keep: func(msg *models.MessageInfo, header string) bool { return fmtHeader(msg, header, "2", "3", "4", "5") != "" }, @@ -59,7 +58,6 @@ func NewMessageViewer(acct *AccountView, header, headerHeight := layout.grid( func(header string) ui.Drawable { hv := &HeaderView{ - conf: conf, Name: header, Value: fmtHeader( msg.MessageInfo(), @@ -94,7 +92,7 @@ func NewMessageViewer(acct *AccountView, {Strategy: ui.SIZE_EXACT, Size: ui.Const(headerHeight)}, } - if msg.MessageDetails() != nil || conf.Ui.IconUnencrypted != "" { + if msg.MessageDetails() != nil || acct.UiConfig().IconUnencrypted != "" { height := 1 if msg.MessageDetails() != nil && msg.MessageDetails().IsSigned && msg.MessageDetails().IsEncrypted { height = 2 @@ -112,7 +110,7 @@ func NewMessageViewer(acct *AccountView, }) switcher := &PartSwitcher{} - err := createSwitcher(acct, switcher, conf, msg) + err := createSwitcher(acct, switcher, msg) if err != nil { return &MessageViewer{ acct: acct, @@ -127,7 +125,7 @@ func NewMessageViewer(acct *AccountView, borderChar := acct.UiConfig().BorderCharHorizontal grid.AddChild(header).At(0, 0) - if msg.MessageDetails() != nil || conf.Ui.IconUnencrypted != "" { + if msg.MessageDetails() != nil || acct.UiConfig().IconUnencrypted != "" { grid.AddChild(NewPGPInfo(msg.MessageDetails(), acct.UiConfig())).At(1, 0) grid.AddChild(ui.NewFill(borderChar, borderStyle)).At(2, 0) grid.AddChild(switcher).At(3, 0) @@ -138,7 +136,6 @@ func NewMessageViewer(acct *AccountView, mv := &MessageViewer{ acct: acct, - conf: conf, grid: grid, msg: msg, switcher: switcher, @@ -186,9 +183,9 @@ func fmtHeader(msg *models.MessageInfo, header string, } } -func enumerateParts(acct *AccountView, conf *config.AercConfig, - msg lib.MessageView, body *models.BodyStructure, - index []int, +func enumerateParts( + acct *AccountView, msg lib.MessageView, + body *models.BodyStructure, index []int, ) ([]*PartViewer, error) { var parts []*PartViewer for i, part := range body.Parts { @@ -198,14 +195,14 @@ func enumerateParts(acct *AccountView, conf *config.AercConfig, pv := &PartViewer{part: part} parts = append(parts, pv) subParts, err := enumerateParts( - acct, conf, msg, part, curindex) + acct, msg, part, curindex) if err != nil { return nil, err } parts = append(parts, subParts...) continue } - pv, err := NewPartViewer(acct, conf, msg, part, curindex) + pv, err := NewPartViewer(acct, msg, part, curindex) if err != nil { return nil, err } @@ -214,13 +211,13 @@ func enumerateParts(acct *AccountView, conf *config.AercConfig, return parts, nil } -func createSwitcher(acct *AccountView, switcher *PartSwitcher, - conf *config.AercConfig, msg lib.MessageView, +func createSwitcher( + acct *AccountView, switcher *PartSwitcher, msg lib.MessageView, ) error { var err error switcher.selected = -1 - switcher.showHeaders = conf.Viewer.ShowHeaders - switcher.alwaysShowMime = conf.Viewer.AlwaysShowMime + switcher.showHeaders = config.Viewer.ShowHeaders + switcher.alwaysShowMime = config.Viewer.AlwaysShowMime if msg.MessageInfo().Error != nil { return fmt.Errorf("could not view message: %w", msg.MessageInfo().Error) @@ -228,30 +225,30 @@ func createSwitcher(acct *AccountView, switcher *PartSwitcher, if len(msg.BodyStructure().Parts) == 0 { switcher.selected = 0 - pv, err := NewPartViewer(acct, conf, msg, msg.BodyStructure(), nil) + pv, err := NewPartViewer(acct, msg, msg.BodyStructure(), nil) if err != nil { return err } switcher.parts = []*PartViewer{pv} } else { - switcher.parts, err = enumerateParts(acct, conf, msg, + switcher.parts, err = enumerateParts(acct, msg, msg.BodyStructure(), []int{}) if err != nil { return err } selectedPriority := -1 - log.Tracef("Selecting best message from %v", conf.Viewer.Alternatives) + log.Tracef("Selecting best message from %v", config.Viewer.Alternatives) for i, pv := range switcher.parts { // Switch to user's preferred mimetype if switcher.selected == -1 && pv.part.MIMEType != "multipart" { switcher.selected = i } mime := pv.part.FullMIMEType() - for idx, m := range conf.Viewer.Alternatives { + for idx, m := range config.Viewer.Alternatives { if m != mime { continue } - priority := len(conf.Viewer.Alternatives) - idx + priority := len(config.Viewer.Alternatives) - idx if priority > selectedPriority { selectedPriority = priority switcher.selected = i @@ -309,8 +306,8 @@ func (mv *MessageViewer) MarkedMessages() ([]uint32, error) { func (mv *MessageViewer) ToggleHeaders() { switcher := mv.switcher switcher.Cleanup() - mv.conf.Viewer.ShowHeaders = !mv.conf.Viewer.ShowHeaders - err := createSwitcher(mv.acct, switcher, mv.conf, mv.msg) + config.Viewer.ShowHeaders = !config.Viewer.ShowHeaders + err := createSwitcher(mv.acct, switcher, mv.msg) if err != nil { log.Errorf("cannot create switcher: %v", err) } @@ -318,8 +315,8 @@ func (mv *MessageViewer) ToggleHeaders() { } func (mv *MessageViewer) ToggleKeyPassthrough() bool { - mv.conf.Viewer.KeyPassthrough = !mv.conf.Viewer.KeyPassthrough - return mv.conf.Viewer.KeyPassthrough + config.Viewer.KeyPassthrough = !config.Viewer.KeyPassthrough + return config.Viewer.KeyPassthrough } func (mv *MessageViewer) SelectedMessagePart() *PartInfo { @@ -380,7 +377,7 @@ func (mv *MessageViewer) NextPart() { } func (mv *MessageViewer) Bindings() string { - if mv.conf.Viewer.KeyPassthrough { + if config.Viewer.KeyPassthrough { return "view::passthrough" } else { return "view" @@ -410,7 +407,7 @@ func (ps *PartSwitcher) Event(event tcell.Event) bool { func (ps *PartSwitcher) Draw(ctx *ui.Context) { height := len(ps.parts) - if height == 1 && !ps.alwaysShowMime { + if height == 1 && !config.Viewer.AlwaysShowMime { ps.parts[ps.selected].Draw(ctx) return } @@ -504,7 +501,6 @@ func (mv *MessageViewer) Focus(focus bool) { } type PartViewer struct { - conf *config.AercConfig acctConfig *config.AccountConfig err error fetched bool @@ -526,8 +522,8 @@ type PartViewer struct { const copying int32 = 1 -func NewPartViewer(acct *AccountView, conf *config.AercConfig, - msg lib.MessageView, part *models.BodyStructure, +func NewPartViewer( + acct *AccountView, msg lib.MessageView, part *models.BodyStructure, curindex []int, ) (*PartViewer, error) { var ( @@ -537,7 +533,7 @@ func NewPartViewer(acct *AccountView, conf *config.AercConfig, term *Terminal ) cmds := []string{ - conf.Viewer.Pager, + config.Viewer.Pager, os.Getenv("PAGER"), "less -R", } @@ -556,7 +552,7 @@ func NewPartViewer(acct *AccountView, conf *config.AercConfig, info := msg.MessageInfo() mime := part.FullMIMEType() - for _, f := range conf.Filters { + for _, f := range config.Filters { switch f.Type { case config.FILTER_MIMETYPE: if fnmatch.Match(f.Filter, mime, 0) { @@ -624,7 +620,6 @@ func NewPartViewer(acct *AccountView, conf *config.AercConfig, copy(index, curindex) pv := &PartViewer{ - conf: conf, acctConfig: acct.AccountConfig(), filter: filter, index: index, @@ -632,7 +627,7 @@ func NewPartViewer(acct *AccountView, conf *config.AercConfig, pager: pager, pagerin: pagerin, part: part, - showHeaders: conf.Viewer.ShowHeaders, + showHeaders: config.Viewer.ShowHeaders, term: term, grid: grid, uiConfig: acct.UiConfig(), @@ -724,7 +719,7 @@ func (pv *PartViewer) writeMailHeaders() { } func (pv *PartViewer) hyperlinks(r io.Reader) (reader io.Reader) { - if !pv.conf.Viewer.ParseHttpLinks { + if !config.Viewer.ParseHttpLinks { return r } reader, pv.links = parse.HttpLinks(r) @@ -738,7 +733,7 @@ var noFilterConfiguredCommands = [][]string{ } func newNoFilterConfigured(pv *PartViewer) *ui.Grid { - bindings := pv.conf.Bindings.MessageView.ForAccount(pv.acctConfig.Name) + bindings := config.Binds.MessageView.ForAccount(pv.acctConfig.Name) var actions []string @@ -774,7 +769,7 @@ func newNoFilterConfigured(pv *PartViewer) *ui.Grid { {Strategy: ui.SIZE_WEIGHT, Size: ui.Const(1)}, }) - uiConfig := pv.conf.Ui + uiConfig := config.Ui noFilter := fmt.Sprintf(`No filter configured for this mimetype ('%s') What would you like to do?`, pv.part.FullMIMEType()) @@ -827,7 +822,6 @@ func (pv *PartViewer) Event(event tcell.Event) bool { } type HeaderView struct { - conf *config.AercConfig Name string Value string ValueField ui.Drawable diff --git a/widgets/status.go b/widgets/status.go index 97ff9441..571fa8b0 100644 --- a/widgets/status.go +++ b/widgets/status.go @@ -22,7 +22,7 @@ type StatusMessage struct { message string } -func NewStatusLine(uiConfig config.UIConfig) *StatusLine { +func NewStatusLine(uiConfig *config.UIConfig) *StatusLine { return &StatusLine{ fallback: StatusMessage{ style: uiConfig.GetStyle(config.STYLE_STATUSLINE_DEFAULT), |