diff options
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), |