1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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
}
|