diff options
author | Koni Marti <koni.marti@gmail.com> | 2023-11-24 16:03:11 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-12-30 15:42:09 +0100 |
commit | 6f8f3d718c8b0303d16d9bfae2770a031678df59 (patch) | |
tree | 8211c92e944f3f6a53750cbcd930682f664e0f9b /commands | |
parent | f8c9e7fff564667700c3dbc239d55db8fcd032a6 (diff) | |
download | aerc-6f8f3d718c8b0303d16d9bfae2770a031678df59.tar.gz |
patch/find: add find sub-cmd
Implement the :patch find command. Search and filter for a given commit
by subject line in the current accout and current folder.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'commands')
-rw-r--r-- | commands/patch/find.go | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/commands/patch/find.go b/commands/patch/find.go new file mode 100644 index 00000000..9579e1f8 --- /dev/null +++ b/commands/patch/find.go @@ -0,0 +1,132 @@ +package patch + +import ( + "errors" + "fmt" + "net/textproto" + "strings" + + "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" + "git.sr.ht/~rjarry/aerc/commands/account" + "git.sr.ht/~rjarry/aerc/lib/pama" + "git.sr.ht/~rjarry/aerc/lib/pama/models" + "git.sr.ht/~rjarry/go-opt" +) + +type Find struct { + Filter bool `opt:"-f"` + Commit []string `opt:"..." required:"true" complete:"Complete"` +} + +func init() { + register(Find{}) +} + +func (Find) Aliases() []string { + return []string{"find"} +} + +func (*Find) Complete(arg string) []string { + m := pama.New() + p, err := m.CurrentProject() + if err != nil { + return nil + } + + options := make([]string, len(p.Commits)) + for i, c := range p.Commits { + options[i] = fmt.Sprintf("%-6.6s %s", c.ID, c.Subject) + } + + return commands.FilterList(options, arg, nil) +} + +func (s Find) Execute(_ []string) error { + m := pama.New() + p, err := m.CurrentProject() + if err != nil { + return err + } + + if len(s.Commit) == 0 { + return errors.New("missing commit hash") + } + + lexed := opt.LexArgs(strings.TrimSpace(s.Commit[0])) + + hash, err := lexed.ArgSafe(0) + if err != nil { + return err + } + + if len(hash) < 4 { + return errors.New("Commit hash is too short.") + } + + var c models.Commit + for _, commit := range p.Commits { + if strings.Contains(commit.ID, hash) { + c = commit + break + } + } + if c.ID == "" { + var err error + c, err = m.Find(hash, p) + if err != nil { + return err + } + } + + // If Message-Id is provided, find it in store + if c.MessageId != "" { + if selectMessageId(c.MessageId) { + return nil + } + } + + // Fallback to a search based on the subject line + args := []string{"search"} + if s.Filter { + args[0] = "filter" + } + + headers := make(textproto.MIMEHeader) + args = append(args, fmt.Sprintf("-H Subject:%s", c.Subject)) + headers.Add("Subject", c.Subject) + + cmd := account.SearchFilter{ + Headers: headers, + } + + return cmd.Execute(args) +} + +func selectMessageId(msgid string) bool { + acct := app.SelectedAccount() + if acct == nil { + return false + } + store := acct.Store() + if store == nil { + return false + } + for uid, msg := range store.Messages { + if msg == nil { + continue + } + if msg.RFC822Headers == nil { + continue + } + id, err := msg.RFC822Headers.MessageID() + if err != nil { + continue + } + if id == msgid { + store.Select(uid) + return true + } + } + return false +} |