diff options
author | Robin Jarry <robin@jarry.cc> | 2022-11-13 18:40:11 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-11-16 16:11:56 +0100 |
commit | b9e5346d6a136244212c913c80a2661d69de692c (patch) | |
tree | 94ca6b4b8406f47f743edb795c3591572dda4ed6 /config/config.go | |
parent | 46e027bde57204a2383193bd35cabcd0a5dfaaf8 (diff) | |
download | aerc-b9e5346d6a136244212c913c80a2661d69de692c.tar.gz |
config: move [ui] parsing in separate file
The config.go file is getting too big. Move the aerc.conf [ui] section
parsing logic into a dedicated ui.go file.
Add a defaultUiConfig() function to also get the default configuration
values in a separate file.
Extract fragmented bits of code in AercConfig.parseConfig() in a new
AercConfig.parseUi() function defined in ui.go.
Change parseUiConfig() into a UIConfig.parse() method.
Change some methods receiver args to pointers to avoid unnecessary
copies.
No functional change.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Diffstat (limited to 'config/config.go')
-rw-r--r-- | config/config.go | 321 |
1 files changed, 5 insertions, 316 deletions
diff --git a/config/config.go b/config/config.go index 7a880b6d..91fd99a2 100644 --- a/config/config.go +++ b/config/config.go @@ -8,13 +8,10 @@ import ( "path" "regexp" "strings" - "time" "unicode" - "github.com/gdamore/tcell/v2" "github.com/go-ini/ini" "github.com/google/shlex" - "github.com/imdario/mergo" "github.com/kyoh86/xdg" "github.com/mitchellh/go-homedir" @@ -28,75 +25,6 @@ type GeneralConfig struct { UnsafeAccountsConf bool `ini:"unsafe-accounts-conf"` } -type UIConfig struct { - AutoMarkRead bool `ini:"auto-mark-read"` - IndexFormat string `ini:"index-format"` - TimestampFormat string `ini:"timestamp-format"` - ThisDayTimeFormat string `ini:"this-day-time-format"` - ThisWeekTimeFormat string `ini:"this-week-time-format"` - ThisYearTimeFormat string `ini:"this-year-time-format"` - MessageViewTimestampFormat string `ini:"message-view-timestamp-format"` - MessageViewThisDayTimeFormat string `ini:"message-view-this-day-time-format"` - MessageViewThisWeekTimeFormat string `ini:"message-view-this-week-time-format"` - MessageViewThisYearTimeFormat string `ini:"message-view-this-year-time-format"` - ShowHeaders []string `delim:","` - RenderAccountTabs string `ini:"render-account-tabs"` - PinnedTabMarker string `ini:"pinned-tab-marker"` - SidebarWidth int `ini:"sidebar-width"` - PreviewHeight int `ini:"preview-height"` - EmptyMessage string `ini:"empty-message"` - EmptyDirlist string `ini:"empty-dirlist"` - MouseEnabled bool `ini:"mouse-enabled"` - ThreadingEnabled bool `ini:"threading-enabled"` - ForceClientThreads bool `ini:"force-client-threads"` - ClientThreadsDelay time.Duration `ini:"client-threads-delay"` - FuzzyComplete bool `ini:"fuzzy-complete"` - NewMessageBell bool `ini:"new-message-bell"` - Spinner string `ini:"spinner"` - SpinnerDelimiter string `ini:"spinner-delimiter"` - IconUnencrypted string `ini:"icon-unencrypted"` - IconEncrypted string `ini:"icon-encrypted"` - IconSigned string `ini:"icon-signed"` - IconSignedEncrypted string `ini:"icon-signed-encrypted"` - IconUnknown string `ini:"icon-unknown"` - IconInvalid string `ini:"icon-invalid"` - DirListFormat string `ini:"dirlist-format"` - DirListDelay time.Duration `ini:"dirlist-delay"` - DirListTree bool `ini:"dirlist-tree"` - DirListCollapse int `ini:"dirlist-collapse"` - Sort []string `delim:" "` - NextMessageOnDelete bool `ini:"next-message-on-delete"` - CompletionDelay time.Duration `ini:"completion-delay"` - CompletionMinChars int `ini:"completion-min-chars"` - CompletionPopovers bool `ini:"completion-popovers"` - StyleSetDirs []string `ini:"stylesets-dirs" delim:":"` - StyleSetName string `ini:"styleset-name"` - style StyleSet - // customize border appearance - BorderCharVertical rune `ini:"-"` - BorderCharHorizontal rune `ini:"-"` - - ReverseOrder bool `ini:"reverse-msglist-order"` - ReverseThreadOrder bool `ini:"reverse-thread-order"` - SortThreadSiblings bool `ini:"sort-thread-siblings"` -} - -type ContextType int - -const ( - UI_CONTEXT_FOLDER ContextType = iota - UI_CONTEXT_ACCOUNT - UI_CONTEXT_SUBJECT - BIND_CONTEXT_ACCOUNT - BIND_CONTEXT_FOLDER -) - -type UIConfigContext struct { - ContextType ContextType - Regex *regexp.Regexp - UiConfig UIConfig -} - const ( FILTER_MIMETYPE = iota FILTER_HEADER @@ -326,61 +254,6 @@ func (config *AercConfig) LoadConfig(file *ini.File) error { } } - if ui, err := file.GetSection("ui"); err == nil { - if err := parseUiConfig(ui, &config.Ui); err != nil { - return err - } - } - - for _, sectionName := range file.SectionStrings() { - if !strings.Contains(sectionName, "ui:") { - continue - } - - uiSection, err := file.GetSection(sectionName) - if err != nil { - return err - } - uiSubConfig := UIConfig{} - if err := parseUiConfig(uiSection, &uiSubConfig); err != nil { - return err - } - contextualUi := UIConfigContext{ - UiConfig: uiSubConfig, - } - - var index int - switch { - case strings.Contains(sectionName, "~"): - index = strings.Index(sectionName, "~") - regex := string(sectionName[index+1:]) - contextualUi.Regex, err = regexp.Compile(regex) - if err != nil { - return err - } - case strings.Contains(sectionName, "="): - index = strings.Index(sectionName, "=") - value := string(sectionName[index+1:]) - contextualUi.Regex, err = regexp.Compile(regexp.QuoteMeta(value)) - if err != nil { - return err - } - default: - return fmt.Errorf("Invalid Ui Context regex in %s", sectionName) - } - - switch sectionName[3:index] { - case "account": - contextualUi.ContextType = UI_CONTEXT_ACCOUNT - case "folder": - contextualUi.ContextType = UI_CONTEXT_FOLDER - case "subject": - contextualUi.ContextType = UI_CONTEXT_SUBJECT - default: - return fmt.Errorf("Unknown Contextual Ui Section: %s", sectionName) - } - config.ContextualUis = append(config.ContextualUis, contextualUi) - } if triggers, err := file.GetSection("triggers"); err == nil { if err := triggers.MapTo(&config.Triggers); err != nil { return err @@ -396,11 +269,8 @@ func (config *AercConfig) LoadConfig(file *ini.File) error { } } - // append default paths to template-dirs and styleset-dirs + // append default paths to template-dirs for _, dir := range SearchDirs { - config.Ui.StyleSetDirs = append( - config.Ui.StyleSetDirs, path.Join(dir, "stylesets"), - ) config.Templates.TemplateDirs = append( config.Templates.TemplateDirs, path.Join(dir, "templates"), ) @@ -418,82 +288,6 @@ func (config *AercConfig) LoadConfig(file *ini.File) error { if err := templates.CheckTemplate(t.Forwards, t.TemplateDirs); err != nil { return err } - if err := config.Ui.loadStyleSet( - config.Ui.StyleSetDirs); err != nil { - return err - } - - for idx, contextualUi := range config.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 == "" { - config.ContextualUis[idx].UiConfig.StyleSetName = config.Ui.StyleSetName - } else if len(contextualUi.UiConfig.StyleSetDirs) == 0 { - config.ContextualUis[idx].UiConfig.StyleSetDirs = config.Ui.StyleSetDirs - } - // since at least one of them has changed, load the styleset - if err := config.ContextualUis[idx].UiConfig.loadStyleSet( - config.ContextualUis[idx].UiConfig.StyleSetDirs); err != nil { - return err - } - } - - return nil -} - -func parseUiConfig(section *ini.Section, config *UIConfig) error { - if err := section.MapTo(config); err != nil { - return err - } - - if key, err := section.GetKey("border-char-vertical"); err == nil { - chars := []rune(key.String()) - if len(chars) != 1 { - return fmt.Errorf("%v must be one and only one character", key) - } - config.BorderCharVertical = chars[0] - } - if key, err := section.GetKey("border-char-horizontal"); err == nil { - chars := []rune(key.String()) - if len(chars) != 1 { - return fmt.Errorf("%v must be one and only one character", key) - } - config.BorderCharHorizontal = chars[0] - } - - // Values with type=time.Duration must be explicitly set. If these - // values are given a default in the struct passed to ui.MapTo, which - // they are, a zero-value in the config won't overwrite the default. - if key, err := section.GetKey("dirlist-delay"); err == nil { - dur, err := key.Duration() - if err != nil { - return err - } - config.DirListDelay = dur - } - if key, err := section.GetKey("completion-delay"); err == nil { - dur, err := key.Duration() - if err != nil { - return err - } - config.CompletionDelay = dur - } - - if config.MessageViewTimestampFormat == "" { - config.MessageViewTimestampFormat = config.TimestampFormat - } - if config.MessageViewThisDayTimeFormat == "" { - config.MessageViewThisDayTimeFormat = config.TimestampFormat - } - if config.MessageViewThisWeekTimeFormat == "" { - config.MessageViewThisWeekTimeFormat = config.TimestampFormat - } - if config.MessageViewThisDayTimeFormat == "" { - config.MessageViewThisDayTimeFormat = config.TimestampFormat - } return nil } @@ -547,47 +341,7 @@ func LoadConfigFromFile(root *string, accts []string) (*AercConfig, error) { UnsafeAccountsConf: false, }, - Ui: UIConfig{ - AutoMarkRead: true, - IndexFormat: "%-20.20D %-17.17n %Z %s", - TimestampFormat: "2006-01-02 03:04 PM", - ThisDayTimeFormat: "", - ThisWeekTimeFormat: "", - ThisYearTimeFormat: "", - ShowHeaders: []string{ - "From", "To", "Cc", "Bcc", "Subject", "Date", - }, - RenderAccountTabs: "auto", - PinnedTabMarker: "`", - SidebarWidth: 20, - PreviewHeight: 12, - EmptyMessage: "(no messages)", - EmptyDirlist: "(no folders)", - MouseEnabled: false, - ClientThreadsDelay: 50 * time.Millisecond, - NewMessageBell: true, - FuzzyComplete: false, - Spinner: "[..] , [..] , [..] , [..] , [..], [..] , [..] , [..] ", - SpinnerDelimiter: ",", - IconUnencrypted: "", - IconSigned: "[s]", - IconEncrypted: "[e]", - IconSignedEncrypted: "", - IconUnknown: "[s?]", - IconInvalid: "[s!]", - DirListFormat: "%n %>r", - DirListDelay: 200 * time.Millisecond, - NextMessageOnDelete: true, - CompletionDelay: 250 * time.Millisecond, - CompletionMinChars: 1, - CompletionPopovers: true, - StyleSetDirs: []string{}, - StyleSetName: "default", - // border defaults - BorderCharVertical: ' ', - BorderCharHorizontal: ' ', - }, - + Ui: defaultUiConfig(), ContextualUis: []UIConfigContext{}, Viewer: ViewerConfig{ @@ -630,6 +384,9 @@ func LoadConfigFromFile(root *string, accts []string) (*AercConfig, error) { if err = config.LoadConfig(file); err != nil { return nil, err } + if err := config.parseUi(file); err != nil { + return nil, err + } if ui, err := file.GetSection("general"); err == nil { if err := ui.MapTo(&config.General); err != nil { @@ -641,7 +398,6 @@ func LoadConfigFromFile(root *string, accts []string) (*AercConfig, error) { } logging.Debugf("aerc.conf: [general] %#v", config.General) - logging.Debugf("aerc.conf: [ui] %#v", config.Ui) logging.Debugf("aerc.conf: [statusline] %#v", config.Statusline) logging.Debugf("aerc.conf: [viewer] %#v", config.Viewer) logging.Debugf("aerc.conf: [compose] %#v", config.Compose) @@ -669,73 +425,6 @@ func parseLayout(layout string) [][]string { return l } -func (ui *UIConfig) loadStyleSet(styleSetDirs []string) error { - ui.style = NewStyleSet() - err := ui.style.LoadStyleSet(ui.StyleSetName, styleSetDirs) - if err != nil { - return fmt.Errorf("Unable to load default styleset: %w", err) - } - - return nil -} - -func (config AercConfig) mergeContextualUi(baseUi UIConfig, - contextType ContextType, s string, -) UIConfig { - for _, contextualUi := range config.ContextualUis { - if contextualUi.ContextType != contextType { - continue - } - - if !contextualUi.Regex.Match([]byte(s)) { - continue - } - - err := mergo.Merge(&baseUi, contextualUi.UiConfig, mergo.WithOverride) - if err != nil { - logging.Warnf("merge ui failed: %v", err) - } - if contextualUi.UiConfig.StyleSetName != "" { - baseUi.style = contextualUi.UiConfig.style - } - return baseUi - } - - return baseUi -} - -func (config AercConfig) GetUiConfig(params map[ContextType]string) *UIConfig { - baseUi := config.Ui - - for k, v := range params { - baseUi = config.mergeContextualUi(baseUi, k, v) - } - - return &baseUi -} - -func (config *AercConfig) GetContextualUIConfigs() []UIConfigContext { - return config.ContextualUis -} - -func (uiConfig UIConfig) GetStyle(so StyleObject) tcell.Style { - return uiConfig.style.Get(so) -} - -func (uiConfig UIConfig) GetStyleSelected(so StyleObject) tcell.Style { - return uiConfig.style.Selected(so) -} - -func (uiConfig UIConfig) GetComposedStyle(base StyleObject, - styles []StyleObject, -) tcell.Style { - return uiConfig.style.Compose(base, styles) -} - -func (uiConfig UIConfig) GetComposedStyleSelected(base StyleObject, styles []StyleObject) tcell.Style { - return uiConfig.style.ComposeSelected(base, styles) -} - func contains(list []string, v string) bool { for _, item := range list { if item == v { |