diff options
-rw-r--r-- | app/account.go | 24 | ||||
-rw-r--r-- | doc/aerc-accounts.5.scd | 7 | ||||
-rw-r--r-- | lib/pama/switch.go | 36 | ||||
-rw-r--r-- | lib/pama/switch_test.go | 67 |
4 files changed, 133 insertions, 1 deletions
diff --git a/app/account.go b/app/account.go index 7a2cf582..5577e461 100644 --- a/app/account.go +++ b/app/account.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + "strings" "sync" "time" @@ -12,6 +13,7 @@ import ( "git.sr.ht/~rjarry/aerc/lib/hooks" "git.sr.ht/~rjarry/aerc/lib/log" "git.sr.ht/~rjarry/aerc/lib/marker" + "git.sr.ht/~rjarry/aerc/lib/pama" "git.sr.ht/~rjarry/aerc/lib/sort" "git.sr.ht/~rjarry/aerc/lib/state" "git.sr.ht/~rjarry/aerc/lib/templates" @@ -337,7 +339,27 @@ func (acct *AccountView) newStore(name string) *lib.MessageStore { PushError(msg) } }, - acct.updateSplitView, + func(msg *models.MessageInfo) { + acct.updateSplitView(msg) + + auto := false + if c := acct.AccountConfig(); c != nil { + r, ok := c.Params["pama-auto-switch"] + if ok { + if strings.ToLower(r) == "true" { + auto = true + } + } + } + if !auto { + return + } + var name string + if msg != nil && msg.Envelope != nil { + name = pama.FromSubject(msg.Envelope.Subject) + } + pama.DebouncedSwitchProject(name) + }, ) store.Configure(acct.SortCriteria(uiConf)) store.SetMarker(marker.New(store)) diff --git a/doc/aerc-accounts.5.scd b/doc/aerc-accounts.5.scd index 9f52ef8a..399da629 100644 --- a/doc/aerc-accounts.5.scd +++ b/doc/aerc-accounts.5.scd @@ -187,6 +187,13 @@ Note that many of these configuration options are written for you, such as Default: _true_ +*pama-auto-switch* = _true_|_false_ + If _true_, the patch manager will automatically switch to an existing + project for the *:patch* command if the subject contains a '[PATCH <project>]' + segment. + + Default: _false_ + *pgp-auto-sign* = _true_|_false_ If _true_, all outgoing emails from this account will be signed (if a signing key is available). diff --git a/lib/pama/switch.go b/lib/pama/switch.go index 4d6b25f7..8190f3c8 100644 --- a/lib/pama/switch.go +++ b/lib/pama/switch.go @@ -2,6 +2,10 @@ package pama import ( "fmt" + "regexp" + "time" + + "git.sr.ht/~rjarry/aerc/lib/log" ) func (m PatchManager) SwitchProject(name string) error { @@ -27,3 +31,35 @@ func (m PatchManager) SwitchProject(name string) error { } return storeErr(m.store().SetCurrent(name)) } + +var switchDebouncer *time.Timer + +func DebouncedSwitchProject(name string) { + if switchDebouncer != nil { + if switchDebouncer.Stop() { + log.Debugf("pama: switch debounced") + } + } + if name == "" { + return + } + switchDebouncer = time.AfterFunc(500*time.Millisecond, func() { + if err := New().SwitchProject(name); err != nil { + log.Debugf("could not switch to project %s: %v", + name, err) + } else { + log.Debugf("project switch to project %s", name) + } + }) +} + +var fromSubject = regexp.MustCompile( + `\[\s*(RFC|DRAFT|[Dd]raft)*\s*(PATCH|[Pp]atch)\s+([^\s\]]+)\s*[vV]*[0-9/]*\s*\] `) + +func FromSubject(s string) string { + matches := fromSubject.FindStringSubmatch(s) + if len(matches) >= 3 { + return matches[3] + } + return "" +} diff --git a/lib/pama/switch_test.go b/lib/pama/switch_test.go new file mode 100644 index 00000000..04c72dfa --- /dev/null +++ b/lib/pama/switch_test.go @@ -0,0 +1,67 @@ +package pama_test + +import ( + "testing" + + "git.sr.ht/~rjarry/aerc/lib/pama" +) + +func TestFromSubject(t *testing.T) { + tests := []struct { + s string + want string + }{ + { + s: "[PATCH aerc] pama: new patch", + want: "aerc", + }, + { + s: "[PATCH aerc v2] pama: new patch", + want: "aerc", + }, + { + s: "[PATCH aerc 1/2] pama: new patch", + want: "aerc", + }, + { + s: "[Patch aerc] pama: new patch", + want: "aerc", + }, + { + s: "[patch aerc] pama: new patch", + want: "aerc", + }, + { + s: "[RFC PATCH aerc] pama: new patch", + want: "aerc", + }, + { + s: "[DRAFT PATCH aerc] pama: new patch", + want: "aerc", + }, + { + s: "RE: [PATCH aerc v1] pama: new patch", + want: "aerc", + }, + { + s: "[PATCH] pama: new patch", + want: "", + }, + { + s: "just a subject line", + want: "", + }, + { + s: "just a subject line with unrelated [asdf aerc v1]", + want: "", + }, + } + + for _, test := range tests { + got := pama.FromSubject(test.s) + if got != test.want { + t.Errorf("failed to get name from '%s': "+ + "got '%s', want '%s'", test.s, got, test.want) + } + } +} |