diff options
-rw-r--r-- | config/columns.go | 53 | ||||
-rw-r--r-- | config/hooks.go | 40 | ||||
-rw-r--r-- | config/statusline.go | 96 | ||||
-rw-r--r-- | config/ui.go | 257 | ||||
-rw-r--r-- | config/ui_test.go | 65 |
5 files changed, 0 insertions, 511 deletions
diff --git a/config/columns.go b/config/columns.go index e1389bc0..c909d0ad 100644 --- a/config/columns.go +++ b/config/columns.go @@ -2,9 +2,7 @@ package config import ( "bytes" - "crypto/sha256" "fmt" - "reflect" "regexp" "strconv" "strings" @@ -118,54 +116,3 @@ func ParseColumnDefs(key *ini.Key, section *ini.Section) ([]*ColumnDef, error) { } return columns, nil } - -func ColumnDefsToIni(defs []*ColumnDef, keyName string) string { - var s strings.Builder - var cols []string - templates := make(map[string]string) - - for _, def := range defs { - col := def.Name - switch { - case def.Flags.Has(ALIGN_LEFT): - col += "<" - case def.Flags.Has(ALIGN_CENTER): - col += ":" - case def.Flags.Has(ALIGN_RIGHT): - col += ">" - } - switch { - case def.Flags.Has(WIDTH_FIT): - col += "=" - case def.Flags.Has(WIDTH_AUTO): - col += "*" - case def.Flags.Has(WIDTH_FRACTION): - col += fmt.Sprintf("%.0f%%", def.Width*100) - default: - col += fmt.Sprintf("%.0f", def.Width) - } - cols = append(cols, col) - tree := reflect.ValueOf(def.Template.Tree) - text := tree.Elem().FieldByName("text").String() - templates[fmt.Sprintf("column-%s", def.Name)] = text - } - - s.WriteString(fmt.Sprintf("%s = %s\n", keyName, strings.Join(cols, ","))) - for name, text := range templates { - s.WriteString(fmt.Sprintf("%s = %s\n", name, text)) - } - - return s.String() -} - -var templateFieldNameRe = regexp.MustCompile(`\{\{\.?(\w+)\}\}`) - -func columnNameFromTemplate(s string) string { - match := templateFieldNameRe.FindStringSubmatch(s) - if match == nil { - h := sha256.New() - h.Write([]byte(s)) - return fmt.Sprintf("%x", h.Sum(nil)[:3]) - } - return strings.ReplaceAll(strings.ToLower(match[1]), "info", "") -} diff --git a/config/hooks.go b/config/hooks.go index b1b71a25..ed81296d 100644 --- a/config/hooks.go +++ b/config/hooks.go @@ -1,8 +1,6 @@ package config import ( - "strings" - "git.sr.ht/~rjarry/aerc/log" "github.com/go-ini/ini" ) @@ -23,44 +21,6 @@ func parseHooks(file *ini.File) error { return err } - newEmail := file.Section("triggers").Key("new-email").String() - if Hooks.MailReceived == "" && newEmail != "" { - Hooks.MailReceived = convertNewEmailTrigger(newEmail) - Warnings = append(Warnings, Warning{ - Title: "DEPRECATION NOTICE: [triggers].new-email", - Body: ` -The new-email trigger has been replaced by [hooks].email-received. - -Your configuration in this instance was automatically converted to: - -[hooks] -mail-received = ` + Hooks.MailReceived + ` - -Please verify the accuracy of the above translation. - -Your configuration file was not changed. To make this change permanent and to -dismiss this deprecation warning on launch, copy the above lines into aerc.conf -and remove new-email from it. See aerc-config(5) for more details. -`, - }) - } - log.Debugf("aerc.conf: [hooks] %#v", Hooks) return nil } - -func convertNewEmailTrigger(old string) string { - translations := map[string]string{ - "%a": "$AERC_FROM_ADDRESS", - "%n": "$AERC_FROM_NAME", - "%s": "$AERC_SUBJECT", - "%f": "$AERC_FROM_NAME <$AERC_FROM_ADDRESS>", - "%u": `$(echo "$AERC_FROM_ADDRESS" | cut -d@ -f1)`, - "%v": `$(echo "$AERC_FROM_NAME" | cut -d' ' -f1)`, - } - for replace, with := range translations { - old = strings.ReplaceAll(old, replace, with) - } - old = strings.TrimPrefix(old, "exec ") - return strings.ReplaceAll(old, "%%", "%") -} diff --git a/config/statusline.go b/config/statusline.go index 1c2c6240..7af0d744 100644 --- a/config/statusline.go +++ b/config/statusline.go @@ -1,10 +1,6 @@ package config import ( - "regexp" - "strings" - - "git.sr.ht/~rjarry/aerc/lib/templates" "git.sr.ht/~rjarry/aerc/log" "github.com/go-ini/ini" ) @@ -24,33 +20,6 @@ func parseStatusline(file *ini.File) error { return err } - if key, err := statusline.GetKey("render-format"); err == nil { - columns, err := convertRenderFormat(key.String()) - if err != nil { - return err - } - Statusline.StatusColumns = columns - log.Warnf("%s %s", - "The [statusline] render-format setting has been replaced by status-columns.", - "render-format will be removed in aerc 0.17.") - Warnings = append(Warnings, Warning{ - Title: "DEPRECATION WARNING: [statusline].render-format", - Body: ` -The render-format setting is deprecated. It has been replaced by status-columns. - -Your configuration in this instance was automatically converted to: - -[statusline] -` + ColumnDefsToIni(columns, "status-columns") + ` -Your configuration file was not changed. To make this change permanent and to -dismiss this deprecation warning on launch, copy the above lines into aerc.conf -and remove render-format from it. See aerc-config(5) for more details. - -render-format will be removed in aerc 0.17. -`, - }) - } - log.Debugf("aerc.conf: [statusline] %#v", Statusline) return nil } @@ -67,68 +36,3 @@ func (s *StatuslineConfig) ParseColumns(sec *ini.Section, key *ini.Key) ([]*Colu } return ParseColumnDefs(key, sec) } - -var ( - renderFmtRe = regexp.MustCompile(`%(-?\d+)?(\.\d+)?[acdmSTp]`) - statuslineMute = false -) - -func convertRenderFormat(renderFormat string) ([]*ColumnDef, error) { - var columns []*ColumnDef - - tokens := strings.Split(renderFormat, "%>") - - left := renderFmtRe.ReplaceAllStringFunc( - tokens[0], renderVerbToTemplate) - left = strings.TrimSpace(left) - t, err := templates.ParseTemplate("column-left", left) - if err != nil { - return nil, err - } - columns = append(columns, &ColumnDef{ - Name: "left", - Template: t, - Flags: ALIGN_LEFT | WIDTH_AUTO, - }) - - if len(tokens) == 2 { - right := renderFmtRe.ReplaceAllStringFunc( - tokens[1], renderVerbToTemplate) - right = strings.TrimSpace(right) - t, err := templates.ParseTemplate("column-right", right) - if err != nil { - return nil, err - } - columns = append(columns, &ColumnDef{ - Name: "right", - Template: t, - Flags: ALIGN_RIGHT | WIDTH_AUTO, - }) - } - - if statuslineMute { - columns = nil - } - - return columns, nil -} - -func renderVerbToTemplate(verb string) (template string) { - switch verb[len(verb)-1] { - case 'a': - template = `{{.Account}}` - case 'c': - template = `{{.ConnectionInfo}}` - case 'd': - template = `{{.Folder}}` - case 'S': - template = `{{.StatusInfo}}` - case 'T': - template = `{{.TrayInfo}}` - case 'p': - template = `{{cwd}}` - case 'm': - statuslineMute = true - } - return template -} diff --git a/config/ui.go b/config/ui.go index f339066e..ed0b4a33 100644 --- a/config/ui.go +++ b/config/ui.go @@ -1,17 +1,13 @@ package config import ( - "bytes" "fmt" "math" "path" "regexp" - "strconv" - "strings" "text/template" "time" - "git.sr.ht/~rjarry/aerc/lib/templates" "git.sr.ht/~rjarry/aerc/log" "github.com/emersion/go-message/mail" "github.com/gdamore/tcell/v2" @@ -111,8 +107,6 @@ type uiContextKey struct { value string } -const unreadExists string = `{{if .Unread}}{{humanReadable .Unread}}/{{end}}{{if .Exists}}{{humanReadable .Exists}}{{end}}` - var Ui = &UIConfig{ contextualCounts: make(map[uiContextType]int), contextualCache: make(map[uiContextKey]*UIConfig), @@ -125,8 +119,6 @@ func parseUi(file *ini.File) error { return err } - var ctxSubjectSections []*ini.Section - for _, section := range file.Sections() { var err error groups := uiContextualSectionRe.FindStringSubmatch(section.Name()) @@ -134,13 +126,6 @@ func parseUi(file *ini.File) error { continue } ctx, separator, value := groups[1], groups[2], groups[3] - if ctx == "subject" { - log.Warnf( - "%s contextual subject config has been replaced by dynamic msglist_* styles.", - section.Name()) - ctxSubjectSections = append(ctxSubjectSections, section) - continue - } uiSubConfig := UIConfig{} if err = uiSubConfig.parse(section); err != nil { @@ -169,30 +154,6 @@ func parseUi(file *ini.File) error { Ui.contextualCounts[contextualUi.ContextType]++ } - if len(ctxSubjectSections) > 0 { - f := ini.Empty() - for _, sec := range ctxSubjectSections { - s, _ := f.NewSection(sec.Name()) - for k, v := range sec.KeysHash() { - s.NewKey(k, v) //nolint:errcheck // who cares? - } - } - var buf bytes.Buffer - f.WriteTo(&buf) //nolint:errcheck // who cares? - w := Warning{ - Title: "DEPRECATION WARNING: SUBJECT UI SECTIONS", - Body: fmt.Sprintf(` -Contextual UI configuration based on subject value has been deprecated and -replaced by dynamic msglist_* styles in stylesets. - -The following configuration sections from aerc.conf have been ignored: - -%sYou should remove them to get rid of that warning and update your styleset(s) -accordingly. See aerc-stylesets(7) for more details.`, buf.String()), - } - Warnings = append(Warnings, w) - } - // append default paths to styleset-dirs for _, dir := range SearchDirs { Ui.StyleSetDirs = append( @@ -236,70 +197,6 @@ func (config *UIConfig) parse(section *ini.Section) error { config.MessageViewTimestampFormat = config.TimestampFormat } - if key, err := section.GetKey("index-format"); err == nil { - columns, err := convertIndexFormat(key.String()) - if err != nil { - return err - } - config.IndexColumns = columns - log.Warnf("%s %s", - "The index-format setting has been replaced by index-columns.", - "index-format will be removed in aerc 0.17.") - w := Warning{ - Title: "DEPRECATION WARNING: [" + section.Name() + "].index-format", - Body: fmt.Sprintf(` -The index-format setting is deprecated. It has been replaced by index-columns. - -Your configuration in this instance was automatically converted to: - -[%s] -%s -Your configuration file was not changed. To make this change permanent and to -dismiss this deprecation warning on launch, copy the above lines into aerc.conf -and remove index-format from it. See aerc-config(5) for more details. - -index-format will be removed in aerc 0.17. -`, section.Name(), ColumnDefsToIni(columns, "index-columns")), - } - Warnings = append(Warnings, w) - } - if key, err := section.GetKey("dirlist-format"); err == nil { - left, right := convertDirlistFormat(key.String()) - l, err := templates.ParseTemplate(left, left) - if err != nil { - return err - } - r, err := templates.ParseTemplate(right, right) - if err != nil { - return err - } - config.DirListLeft = l - config.DirListRight = r - log.Warnf("%s %s", - "The dirlist-format setting has been replaced by dirlist-left and dirlist-right.", - "dirlist-format will be removed in aerc 0.17.") - w := Warning{ - Title: "DEPRECATION WARNING: [" + section.Name() + "].dirlist-format", - Body: fmt.Sprintf(` -The dirlist-format setting is deprecated. It has been replaced by dirlist-left -and dirlist-right. - -Your configuration in this instance was automatically converted to: - -[%s] -dirlist-left = %s -dirlist-right = %s - -Your configuration file was not changed. To make this change permanent and to -dismiss this deprecation warning on launch, copy the above lines into aerc.conf -and remove dirlist-format from it. See aerc-config(5) for more details. - -dirlist-format will be removed in aerc 0.17. -`, section.Name(), left, right), - } - Warnings = append(Warnings, w) - } - return nil } @@ -329,160 +226,6 @@ func (*UIConfig) ParseCompletionMinChars(section *ini.Section, key *ini.Key) (in return key.Int() } -var indexFmtRegexp = regexp.MustCompile(`%(-?\d+)?(\.\d+)?([ACDFRTZadfgilnrstuv])`) - -func convertIndexFormat(indexFormat string) ([]*ColumnDef, error) { - matches := indexFmtRegexp.FindAllStringSubmatch(indexFormat, -1) - if matches == nil { - return nil, fmt.Errorf("invalid index-format") - } - - var columns []*ColumnDef - - for _, m := range matches { - alignWidth := m[1] - verb := m[3] - - var width float64 = 0 - var flags ColumnFlags = ALIGN_LEFT - f, name := indexVerbToTemplate([]rune(verb)[0]) - if verb == "Z" { - width = 4 - flags = ALIGN_RIGHT - } - - t, err := templates.ParseTemplate(fmt.Sprintf("column-%s", name), f) - if err != nil { - return nil, err - } - - if alignWidth != "" { - width, err = strconv.ParseFloat(alignWidth, 64) - if err != nil { - return nil, err - } - if width < 0 { - width = -width - } else { - flags = ALIGN_RIGHT - } - } - if width == 0 { - flags |= WIDTH_AUTO - } else { - flags |= WIDTH_EXACT - } - - columns = append(columns, &ColumnDef{ - Name: name, - Width: width, - Flags: flags, - Template: t, - }) - } - - return columns, nil -} - -func indexVerbToTemplate(verb rune) (f, name string) { - switch verb { - case '%': - f = string(verb) - case 'a': - f = `{{(index .From 0).Address}}` - name = "sender" - case 'A': - f = `{{if eq (len .ReplyTo) 0}}{{(index .From 0).Address}}{{else}}{{(index .ReplyTo 0).Address}}{{end}}` - name = "reply-to" - case 'C': - f = "{{.Number}}" - name = "num" - case 'd', 'D': - f = "{{.DateAutoFormat .Date.Local}}" - name = "date" - case 'f': - f = `{{index (.From | persons) 0}}` - name = "from" - case 'F': - f = `{{.Peer | names | join ", "}}` - name = "peers" - case 'g': - f = `{{.Labels | join ", "}}` - name = "labels" - case 'i': - f = "{{.MessageId}}" - name = "msg-id" - case 'n': - f = `{{index (.From | names) 0}}` - name = "name" - case 'r': - f = `{{.To | persons | join ", "}}` - name = "to" - case 'R': - f = `{{.Cc | persons | join ", "}}` - name = "cc" - case 's': - f = "{{.ThreadPrefix}}{{.Subject}}" - name = "subject" - case 't': - f = "{{(index .To 0).Address}}" - name = "to0" - case 'T': - f = "{{.Account}}" - name = "account" - case 'u': - f = "{{index (.From | mboxes) 0}}" - name = "mboxes" - case 'v': - f = "{{index (.From | names) 0}}" - name = "name" - case 'Z': - f = `{{.Flags | join ""}}` - name = "flags" - case 'l': - f = "{{.Size}}" - name = "size" - default: - f = "%" + string(verb) - } - if name == "" { - name = columnNameFromTemplate(f) - } - return -} - -func convertDirlistFormat(format string) (string, string) { - tmpl := regexp.MustCompile(`%>?[Nnr]`).ReplaceAllStringFunc( - format, - func(s string) string { - runes := []rune(s) - switch runes[len(runes)-1] { - case 'N': - s = `{{.Folder | compactDir}}` - case 'n': - s = `{{.Folder}}` - case 'r': - s = unreadExists - default: - return s - } - if strings.HasPrefix(string(runes), "%>") { - s = "%>" + s - } - return s - }, - ) - tokens := strings.SplitN(tmpl, "%>", 2) - switch len(tokens) { - case 2: - return strings.TrimSpace(tokens[0]), strings.TrimSpace(tokens[1]) - case 1: - return strings.TrimSpace(tokens[0]), "" - default: - return "", "" - } -} - func (ui *UIConfig) loadStyleSet(styleSetDirs []string) error { ui.style = NewStyleSet() err := ui.style.LoadStyleSet(ui.StyleSetName, styleSetDirs) diff --git a/config/ui_test.go b/config/ui_test.go deleted file mode 100644 index 188fae01..00000000 --- a/config/ui_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package config - -import ( - "reflect" - "testing" - "text/template" - - "github.com/stretchr/testify/assert" -) - -func templateText(t *template.Template) string { - // unfortunately, the original template text is stored as a private - // field, for test purposes, access its value via reflection - v := reflect.ValueOf(t).Elem() - return v.FieldByName("text").String() -} - -func TestConvertIndexFormat(t *testing.T) { - columns, err := convertIndexFormat("%-20.20D %-17.17n %Z %s") - if err != nil { - t.Fatal(err) - } - assert.Len(t, columns, 4) - - assert.Equal(t, "date", columns[0].Name) - assert.Equal(t, 20.0, columns[0].Width) - assert.Equal(t, ALIGN_LEFT|WIDTH_EXACT, columns[0].Flags) - assert.Equal(t, `{{.DateAutoFormat .Date.Local}}`, - templateText(columns[0].Template)) - - assert.Equal(t, "name", columns[1].Name) - assert.Equal(t, 17.0, columns[1].Width) - assert.Equal(t, ALIGN_LEFT|WIDTH_EXACT, columns[1].Flags) - assert.Equal(t, `{{index (.From | names) 0}}`, - templateText(columns[1].Template)) - - assert.Equal(t, "flags", columns[2].Name) - assert.Equal(t, 4.0, columns[2].Width) - assert.Equal(t, ALIGN_RIGHT|WIDTH_EXACT, columns[2].Flags) - assert.Equal(t, `{{.Flags | join ""}}`, - templateText(columns[2].Template)) - - assert.Equal(t, "subject", columns[3].Name) - assert.Equal(t, 0.0, columns[3].Width) - assert.Equal(t, ALIGN_LEFT|WIDTH_AUTO, columns[3].Flags) - assert.Equal(t, `{{.ThreadPrefix}}{{.Subject}}`, templateText(columns[3].Template)) -} - -func TestConvertDirlistFormat(t *testing.T) { - left, right := convertDirlistFormat("%n %>r") - assert.Equal(t, "{{.Folder}}", left) - assert.Equal(t, unreadExists, right) - - left, right = convertDirlistFormat("%n %>r ") - assert.Equal(t, "{{.Folder}}", left) - assert.Equal(t, unreadExists, right) - - left, right = convertDirlistFormat("%r%>n") - assert.Equal(t, unreadExists, left) - assert.Equal(t, "{{.Folder}}", right) - - left, right = convertDirlistFormat("%>N") - assert.Equal(t, "", left) - assert.Equal(t, "{{.Folder | compactDir}}", right) -} |