NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

Match patterns to emails. More...

#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "mutt/lib.h"
#include "mutt.h"
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Pattern
 A simple (non-regex) pattern. More...
 
struct  PatternCache
 Cache commonly-used patterns. More...
 

Macros

#define MUTT_ALIAS_SIMPLESEARCH   "~f %s | ~t %s | ~c %s"
 
#define MUTT_PC_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_PC_FULL_MSG   (1 << 0)
 Enable body and header matching. More...
 
#define MUTT_PC_PATTERN_DYNAMIC   (1 << 1)
 Enable runtime date range evaluation. More...
 
#define MUTT_PC_SEND_MODE_SEARCH   (1 << 2)
 Allow send-mode body searching. More...
 
#define MUTT_PAT_EXEC_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_MATCH_FULL_ADDRESS   (1 << 0)
 Match the full address. More...
 

Typedefs

typedef uint8_t PatternCompFlags
 Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG. More...
 
typedef uint8_t PatternExecFlags
 Flags for mutt_pattern_exec(), e.g. MUTT_MATCH_FULL_ADDRESS. More...
 

Enumerations

enum  PatternType {
  MUTT_PAT_AND = MUTT_MT_MAX, MUTT_PAT_OR, MUTT_PAT_THREAD, MUTT_PAT_PARENT,
  MUTT_PAT_CHILDREN, MUTT_PAT_TO, MUTT_PAT_CC, MUTT_PAT_COLLAPSED,
  MUTT_PAT_SUBJECT, MUTT_PAT_FROM, MUTT_PAT_DATE, MUTT_PAT_DATE_RECEIVED,
  MUTT_PAT_DUPLICATED, MUTT_PAT_UNREFERENCED, MUTT_PAT_BROKEN, MUTT_PAT_ID,
  MUTT_PAT_ID_EXTERNAL, MUTT_PAT_BODY, MUTT_PAT_HEADER, MUTT_PAT_HORMEL,
  MUTT_PAT_WHOLE_MSG, MUTT_PAT_SENDER, MUTT_PAT_MESSAGE, MUTT_PAT_SCORE,
  MUTT_PAT_SIZE, MUTT_PAT_REFERENCE, MUTT_PAT_RECIPIENT, MUTT_PAT_LIST,
  MUTT_PAT_SUBSCRIBED_LIST, MUTT_PAT_PERSONAL_RECIP, MUTT_PAT_PERSONAL_FROM, MUTT_PAT_ADDRESS,
  MUTT_PAT_CRYPT_SIGN, MUTT_PAT_CRYPT_VERIFIED, MUTT_PAT_CRYPT_ENCRYPT, MUTT_PAT_PGP_KEY,
  MUTT_PAT_XLABEL, MUTT_PAT_SERVERSEARCH, MUTT_PAT_DRIVER_TAGS, MUTT_PAT_MIMEATTACH,
  MUTT_PAT_MIMETYPE, MUTT_PAT_NEWSGROUPS, MUTT_PAT_MAX
}
 Types of pattern to match. More...
 

Functions

 SLIST_HEAD (PatternList, Pattern)
 
int mutt_pattern_exec (struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
 Match a pattern against an email header. More...
 
int mutt_pattern_alias_exec (struct Pattern *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
 Match a pattern against an alias. More...
 
struct PatternList * mutt_pattern_comp (struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
 Create a Pattern. More...
 
void mutt_check_simple (struct Buffer *s, const char *simple)
 Convert a simple search into a real request. More...
 
void mutt_pattern_free (struct PatternList **pat)
 Free a Pattern. More...
 
bool dlg_select_pattern (char *buf, size_t buflen)
 Show menu to select a Pattern. More...
 
int mutt_which_case (const char *s)
 
int mutt_is_list_recipient (bool all_addr, struct Envelope *e)
 Matches known mailing lists. More...
 
int mutt_is_subscribed_list_recipient (bool all_addr, struct Envelope *e)
 Matches subscribed mailing lists. More...
 
int mutt_pattern_func (struct Context *ctx, int op, char *prompt)
 Perform some Pattern matching. More...
 
int mutt_pattern_alias_func (int op, char *prompt, struct AliasMenuData *mdata, struct Menu *menu)
 Perform some Pattern matching for Alias. More...
 
int mutt_search_command (struct Mailbox *m, struct Menu *menu, int cur, int op)
 Perform a search. More...
 
int mutt_search_alias_command (struct Menu *menu, int cur, int op)
 Perform a search. More...
 
bool mutt_limit_current_thread (struct Context *ctx, struct Email *e)
 Limit the email view to the current thread. More...
 

Detailed Description

Match patterns to emails.

Authors
  • Richard Russon
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file lib.h.

Macro Definition Documentation

◆ MUTT_ALIAS_SIMPLESEARCH

#define MUTT_ALIAS_SIMPLESEARCH   "~f %s | ~t %s | ~c %s"

Definition at line 57 of file lib.h.

◆ MUTT_PC_NO_FLAGS

#define MUTT_PC_NO_FLAGS   0

No flags are set.

Definition at line 60 of file lib.h.

◆ MUTT_PC_FULL_MSG

#define MUTT_PC_FULL_MSG   (1 << 0)

Enable body and header matching.

Definition at line 61 of file lib.h.

◆ MUTT_PC_PATTERN_DYNAMIC

#define MUTT_PC_PATTERN_DYNAMIC   (1 << 1)

Enable runtime date range evaluation.

Definition at line 62 of file lib.h.

◆ MUTT_PC_SEND_MODE_SEARCH

#define MUTT_PC_SEND_MODE_SEARCH   (1 << 2)

Allow send-mode body searching.

Definition at line 63 of file lib.h.

◆ MUTT_PAT_EXEC_NO_FLAGS

#define MUTT_PAT_EXEC_NO_FLAGS   0

No flags are set.

Definition at line 94 of file lib.h.

◆ MUTT_MATCH_FULL_ADDRESS

#define MUTT_MATCH_FULL_ADDRESS   (1 << 0)

Match the full address.

Definition at line 95 of file lib.h.

Typedef Documentation

◆ PatternCompFlags

typedef uint8_t PatternCompFlags

Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG.

Definition at line 59 of file lib.h.

◆ PatternExecFlags

typedef uint8_t PatternExecFlags

Flags for mutt_pattern_exec(), e.g. MUTT_MATCH_FULL_ADDRESS.

Definition at line 93 of file lib.h.

Enumeration Type Documentation

◆ PatternType

Types of pattern to match.

Note
This enum piggy-backs on top of MessageType
See also
mutt_pattern_comp(), mutt_pattern_exec()
Enumerator
MUTT_PAT_AND 

Both patterns must match.

MUTT_PAT_OR 

Either pattern can match.

MUTT_PAT_THREAD 

Pattern matches email thread.

MUTT_PAT_PARENT 

Pattern matches parent.

MUTT_PAT_CHILDREN 

Pattern matches a child email.

MUTT_PAT_TO 

Pattern matches 'To:' field.

MUTT_PAT_CC 

Pattern matches 'Cc:' field.

MUTT_PAT_COLLAPSED 

Thread is collapsed.

MUTT_PAT_SUBJECT 

Pattern matches 'Subject:' field.

MUTT_PAT_FROM 

Pattern matches 'From:' field.

MUTT_PAT_DATE 

Pattern matches 'Date:' field.

MUTT_PAT_DATE_RECEIVED 

Pattern matches date received.

MUTT_PAT_DUPLICATED 

Duplicate message.

MUTT_PAT_UNREFERENCED 

Message is unreferenced in the thread.

MUTT_PAT_BROKEN 

Message is part of a broken thread.

MUTT_PAT_ID 

Pattern matches email's Message-Id.

MUTT_PAT_ID_EXTERNAL 

Message-Id is among results from an external query.

MUTT_PAT_BODY 

Pattern matches email's body.

MUTT_PAT_HEADER 

Pattern matches email's header.

MUTT_PAT_HORMEL 

Pattern matches email's spam score.

MUTT_PAT_WHOLE_MSG 

Pattern matches raw email text.

MUTT_PAT_SENDER 

Pattern matches sender.

MUTT_PAT_MESSAGE 

Pattern matches message number.

MUTT_PAT_SCORE 

Pattern matches email's score.

MUTT_PAT_SIZE 

Pattern matches email's size.

MUTT_PAT_REFERENCE 

Pattern matches 'References:' or 'In-Reply-To:' field.

MUTT_PAT_RECIPIENT 

User is a recipient of the email.

MUTT_PAT_LIST 

Email is on mailing list.

MUTT_PAT_SUBSCRIBED_LIST 

Email is on subscribed mailing list.

MUTT_PAT_PERSONAL_RECIP 

Email is addressed to the user.

MUTT_PAT_PERSONAL_FROM 

Email is from the user.

MUTT_PAT_ADDRESS 

Pattern matches any address field.

MUTT_PAT_CRYPT_SIGN 

Message is signed.

MUTT_PAT_CRYPT_VERIFIED 

Message is crypographically verified.

MUTT_PAT_CRYPT_ENCRYPT 

Message is encrypted.

MUTT_PAT_PGP_KEY 

Message has PGP key.

MUTT_PAT_XLABEL 

Pattern matches keyword/label.

MUTT_PAT_SERVERSEARCH 

Server-side pattern matches.

MUTT_PAT_DRIVER_TAGS 

Pattern matches message tags.

MUTT_PAT_MIMEATTACH 

Pattern matches number of attachments.

MUTT_PAT_MIMETYPE 

Pattern matches MIME type.

MUTT_PAT_NEWSGROUPS 

Pattern matches newsgroup.

MUTT_PAT_MAX 

Definition at line 124 of file lib.h.

125 {
127  MUTT_PAT_OR,
131  MUTT_PAT_TO,
132  MUTT_PAT_CC,
135  MUTT_PAT_FROM,
136  MUTT_PAT_DATE,
141  MUTT_PAT_ID,
143  MUTT_PAT_BODY,
150  MUTT_PAT_SIZE,
153  MUTT_PAT_LIST,
167 #ifdef USE_NNTP
169 #endif
170  MUTT_PAT_MAX,
171 };
Pattern matches message number.
Definition: lib.h:148
Pattern matches email&#39;s Message-Id.
Definition: lib.h:141
Pattern matches email&#39;s body.
Definition: lib.h:143
Message is signed.
Definition: lib.h:158
Email is on mailing list.
Definition: lib.h:153
Pattern matches &#39;To:&#39; field.
Definition: lib.h:131
Pattern matches date received.
Definition: lib.h:137
Pattern matches &#39;References:&#39; or &#39;In-Reply-To:&#39; field.
Definition: lib.h:151
Message is unreferenced in the thread.
Definition: lib.h:139
Pattern matches &#39;From:&#39; field.
Definition: lib.h:135
Pattern matches email&#39;s header.
Definition: lib.h:144
Server-side pattern matches.
Definition: lib.h:163
Message is encrypted.
Definition: lib.h:160
Message is crypographically verified.
Definition: lib.h:159
Pattern matches sender.
Definition: lib.h:147
Pattern matches keyword/label.
Definition: lib.h:162
Email is addressed to the user.
Definition: lib.h:155
Email is from the user.
Definition: lib.h:156
Pattern matches newsgroup.
Definition: lib.h:168
Pattern matches any address field.
Definition: lib.h:157
Message is part of a broken thread.
Definition: lib.h:140
Email is on subscribed mailing list.
Definition: lib.h:154
Pattern matches MIME type.
Definition: lib.h:166
Message-Id is among results from an external query.
Definition: lib.h:142
Pattern matches number of attachments.
Definition: lib.h:165
Pattern matches &#39;Date:&#39; field.
Definition: lib.h:136
Thread is collapsed.
Definition: lib.h:133
Pattern matches &#39;Cc:&#39; field.
Definition: lib.h:132
Duplicate message.
Definition: lib.h:138
Both patterns must match.
Definition: lib.h:126
Either pattern can match.
Definition: lib.h:127
Pattern matches parent.
Definition: lib.h:129
Pattern matches email&#39;s spam score.
Definition: lib.h:145
User is a recipient of the email.
Definition: lib.h:152
Pattern matches raw email text.
Definition: lib.h:146
Pattern matches a child email.
Definition: lib.h:130
Pattern matches message tags.
Definition: lib.h:164
Pattern matches email thread.
Definition: lib.h:128
Message has PGP key.
Definition: lib.h:161
Pattern matches email&#39;s score.
Definition: lib.h:149
Pattern matches email&#39;s size.
Definition: lib.h:150
Pattern matches &#39;Subject:&#39; field.
Definition: lib.h:134

Function Documentation

◆ SLIST_HEAD()

SLIST_HEAD ( PatternList  ,
Pattern   
)

◆ mutt_pattern_exec()

int mutt_pattern_exec ( struct Pattern pat,
PatternExecFlags  flags,
struct Mailbox m,
struct Email e,
struct PatternCache cache 
)

Match a pattern against an email header.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
eEmail
cacheCache for common Patterns
Return values
1Success, pattern matched
0Pattern did not match
-1Error

flags: MUTT_MATCH_FULL_ADDRESS - match both personal and machine address cache: For repeated matches against the same Header, passing in non-NULL will store some of the cacheable pattern matches in this structure.

Definition at line 1097 of file exec.c.

1099 {
1100  struct Message *msg = pattern_needs_msg(m, pat) ? mx_msg_open(m, e->msgno) : NULL;
1101  const int rc = pattern_exec(pat, flags, m, e, msg, cache);
1102  mx_msg_close(m, &msg);
1103  return rc;
1104 }
static bool pattern_needs_msg(const struct Mailbox *m, const struct Pattern *pat)
Check whether a pattern needs a full message.
Definition: exec.c:745
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
A local copy of an email.
Definition: mxapi.h:41
struct Message::@1 flags
static int pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct Message *msg, struct PatternCache *cache)
Match a pattern against an email header.
Definition: exec.c:792
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
int msgno
Number displayed to the user.
Definition: email.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_alias_exec()

int mutt_pattern_alias_exec ( struct Pattern pat,
PatternExecFlags  flags,
struct AliasView av,
struct PatternCache cache 
)

Match a pattern against an alias.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
avAliasView
cacheCache for common Patterns
Return values
1Success, pattern matched
0Pattern did not match
-1Error

flags: MUTT_MATCH_FULL_ADDRESS - match both personal and machine address cache: For repeated matches against the same Alias, passing in non-NULL will store some of the cacheable pattern matches in this structure.

Definition at line 1120 of file exec.c.

1122 {
1123  switch (pat->op)
1124  {
1125  case MUTT_PAT_FROM: /* alias */
1126  if (!av->alias)
1127  return 0;
1128  return pat->pat_not ^ (av->alias->name && patmatch(pat, av->alias->name));
1129  case MUTT_PAT_CC: /* comment */
1130  if (!av->alias)
1131  return 0;
1132  return pat->pat_not ^ (av->alias->comment && patmatch(pat, av->alias->comment));
1133  case MUTT_PAT_TO: /* alias address list */
1134  if (!av->alias)
1135  return 0;
1136  return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
1137  1, &av->alias->addr);
1138  case MUTT_PAT_AND:
1139  return pat->pat_not ^ (perform_alias_and(pat->child, flags, av, cache) > 0);
1140  case MUTT_PAT_OR:
1141  return pat->pat_not ^ (perform_alias_or(pat->child, flags, av, cache) > 0);
1142  }
1143 
1144  return 0;
1145 }
struct PatternList * child
Arguments to logical operation.
Definition: lib.h:82
char * name
Short name.
Definition: alias.h:35
Pattern matches &#39;To:&#39; field.
Definition: lib.h:131
static int match_addrlist(struct Pattern *pat, bool match_personal, int n,...)
Match a Pattern against an Address list.
Definition: exec.c:365
Pattern matches &#39;From:&#39; field.
Definition: lib.h:135
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:71
bool pat_not
Pattern should be inverted (not)
Definition: lib.h:71
struct Alias * alias
Alias.
Definition: gui.h:44
struct Message::@1 flags
char * comment
Free-form comment string.
Definition: alias.h:37
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: lib.h:70
static int perform_alias_or(struct PatternList *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Perform a logical OR on a set of Patterns.
Definition: exec.c:342
Pattern matches &#39;Cc:&#39; field.
Definition: lib.h:132
Both patterns must match.
Definition: lib.h:126
static bool perform_alias_and(struct PatternList *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Perform a logical AND on a set of Patterns.
Definition: exec.c:297
Either pattern can match.
Definition: lib.h:127
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:95
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_comp()

struct PatternList* mutt_pattern_comp ( struct Mailbox m,
struct Menu menu,
const char *  s,
PatternCompFlags  flags,
struct Buffer err 
)

Create a Pattern.

Parameters
mMailbox
menuCurrent Menu
sPattern string
flagsFlags, e.g. MUTT_PC_FULL_MSG
errBuffer for error messages
Return values
ptrNewly allocated Pattern

Definition at line 1092 of file compile.c.

1094 {
1095  /* curlist when assigned will always point to a list containing at least one node
1096  * with a Pattern value. */
1097  struct PatternList *curlist = NULL;
1098  struct PatternList *tmp = NULL, *tmp2 = NULL;
1099  struct PatternList *last = NULL;
1100  bool pat_not = false;
1101  bool all_addr = false;
1102  bool pat_or = false;
1103  bool implicit = true; /* used to detect logical AND operator */
1104  bool is_alias = false;
1105  short thread_op;
1106  const struct PatternFlags *entry = NULL;
1107  char *p = NULL;
1108  char *buf = NULL;
1109  struct Buffer ps;
1110 
1111  if (!s || !*s)
1112  {
1113  mutt_buffer_strcpy(err, _("empty pattern"));
1114  return NULL;
1115  }
1116 
1117  mutt_buffer_init(&ps);
1118  ps.dptr = (char *) s;
1119  ps.dsize = mutt_str_len(s);
1120 
1121  while (*ps.dptr)
1122  {
1123  SKIPWS(ps.dptr);
1124  switch (*ps.dptr)
1125  {
1126  case '^':
1127  ps.dptr++;
1128  all_addr = !all_addr;
1129  break;
1130  case '!':
1131  ps.dptr++;
1132  pat_not = !pat_not;
1133  break;
1134  case '@':
1135  ps.dptr++;
1136  is_alias = !is_alias;
1137  break;
1138  case '|':
1139  if (!pat_or)
1140  {
1141  if (!curlist)
1142  {
1143  mutt_buffer_printf(err, _("error in pattern at: %s"), ps.dptr);
1144  return NULL;
1145  }
1146 
1147  struct Pattern *pat = SLIST_FIRST(curlist);
1148 
1149  if (SLIST_NEXT(pat, entries))
1150  {
1151  /* A & B | C == (A & B) | C */
1152  tmp = mutt_pattern_node_new();
1153  pat = SLIST_FIRST(tmp);
1154  pat->op = MUTT_PAT_AND;
1155  pat->child = curlist;
1156 
1157  curlist = tmp;
1158  last = curlist;
1159  }
1160 
1161  pat_or = true;
1162  }
1163  ps.dptr++;
1164  implicit = false;
1165  pat_not = false;
1166  all_addr = false;
1167  is_alias = false;
1168  break;
1169  case '%':
1170  case '=':
1171  case '~':
1172  {
1173  struct Pattern *pat = NULL;
1174  if (ps.dptr[1] == '\0')
1175  {
1176  mutt_buffer_printf(err, _("missing pattern: %s"), ps.dptr);
1177  goto cleanup;
1178  }
1179  thread_op = 0;
1180  if (ps.dptr[1] == '(')
1181  thread_op = MUTT_PAT_THREAD;
1182  else if ((ps.dptr[1] == '<') && (ps.dptr[2] == '('))
1183  thread_op = MUTT_PAT_PARENT;
1184  else if ((ps.dptr[1] == '>') && (ps.dptr[2] == '('))
1185  thread_op = MUTT_PAT_CHILDREN;
1186  if (thread_op)
1187  {
1188  ps.dptr++; /* skip ~ */
1189  if ((thread_op == MUTT_PAT_PARENT) || (thread_op == MUTT_PAT_CHILDREN))
1190  ps.dptr++;
1191  p = find_matching_paren(ps.dptr + 1);
1192  if (p[0] != ')')
1193  {
1194  mutt_buffer_printf(err, _("mismatched parentheses: %s"), ps.dptr);
1195  goto cleanup;
1196  }
1197  tmp = mutt_pattern_node_new();
1198  pat = SLIST_FIRST(tmp);
1199  pat->op = thread_op;
1200  if (last)
1201  SLIST_NEXT(SLIST_FIRST(last), entries) = pat;
1202  else
1203  curlist = tmp;
1204  last = tmp;
1205  pat->pat_not ^= pat_not;
1206  pat->all_addr |= all_addr;
1207  pat->is_alias |= is_alias;
1208  pat_not = false;
1209  all_addr = false;
1210  is_alias = false;
1211  /* compile the sub-expression */
1212  buf = mutt_strn_dup(ps.dptr + 1, p - (ps.dptr + 1));
1213  tmp2 = mutt_pattern_comp(m, menu, buf, flags, err);
1214  if (!tmp2)
1215  {
1216  FREE(&buf);
1217  goto cleanup;
1218  }
1219  FREE(&buf);
1220  pat->child = tmp2;
1221  ps.dptr = p + 1; /* restore location */
1222  break;
1223  }
1224  if (implicit && pat_or)
1225  {
1226  /* A | B & C == (A | B) & C */
1227  tmp = mutt_pattern_node_new();
1228  pat = SLIST_FIRST(tmp);
1229  pat->op = MUTT_PAT_OR;
1230  pat->child = curlist;
1231  curlist = tmp;
1232  last = tmp;
1233  pat_or = false;
1234  }
1235 
1236  tmp = mutt_pattern_node_new();
1237  pat = SLIST_FIRST(tmp);
1238  pat->pat_not = pat_not;
1239  pat->all_addr = all_addr;
1240  pat->is_alias = is_alias;
1241  pat->string_match = (ps.dptr[0] == '=');
1242  pat->group_match = (ps.dptr[0] == '%');
1243  pat_not = false;
1244  all_addr = false;
1245  is_alias = false;
1246 
1247  if (last)
1248  SLIST_NEXT(SLIST_FIRST(last), entries) = pat;
1249  else
1250  curlist = tmp;
1251  if (curlist != last)
1252  FREE(&last);
1253  last = tmp;
1254 
1255  ps.dptr++; /* move past the ~ */
1256  entry = lookup_tag(*ps.dptr);
1257  if (!entry)
1258  {
1259  mutt_buffer_printf(err, _("%c: invalid pattern modifier"), *ps.dptr);
1260  goto cleanup;
1261  }
1262  if (entry->flags && ((flags & entry->flags) == 0))
1263  {
1264  mutt_buffer_printf(err, _("%c: not supported in this mode"), *ps.dptr);
1265  goto cleanup;
1266  }
1267  if (flags & MUTT_PC_SEND_MODE_SEARCH)
1268  pat->sendmode = true;
1269 
1270  pat->op = entry->op;
1271 
1272  ps.dptr++; /* eat the operator and any optional whitespace */
1273  SKIPWS(ps.dptr);
1274 
1275  if (entry->eat_arg)
1276  {
1277  if (ps.dptr[0] == '\0')
1278  {
1279  mutt_buffer_printf(err, "%s", _("missing parameter"));
1280  goto cleanup;
1281  }
1282  switch (entry->eat_arg)
1283  {
1284  case EAT_REGEX:
1285  if (!eat_regex(pat, flags, &ps, err))
1286  goto cleanup;
1287  break;
1288  case EAT_DATE:
1289  if (!eat_date(pat, flags, &ps, err))
1290  goto cleanup;
1291  break;
1292  case EAT_RANGE:
1293  if (!eat_range(pat, flags, &ps, err))
1294  goto cleanup;
1295  break;
1296  case EAT_MESSAGE_RANGE:
1297  if (!eat_message_range(pat, flags, &ps, err, m, menu))
1298  goto cleanup;
1299  break;
1300  case EAT_QUERY:
1301  if (!eat_query(pat, flags, &ps, err, m))
1302  goto cleanup;
1303  break;
1304  default:
1305  break;
1306  }
1307  }
1308  implicit = true;
1309  break;
1310  }
1311 
1312  case '(':
1313  {
1314  p = find_matching_paren(ps.dptr + 1);
1315  if (p[0] != ')')
1316  {
1317  mutt_buffer_printf(err, _("mismatched parentheses: %s"), ps.dptr);
1318  goto cleanup;
1319  }
1320  /* compile the sub-expression */
1321  buf = mutt_strn_dup(ps.dptr + 1, p - (ps.dptr + 1));
1322  tmp = mutt_pattern_comp(m, menu, buf, flags, err);
1323  FREE(&buf);
1324  if (!tmp)
1325  goto cleanup;
1326  struct Pattern *pat = SLIST_FIRST(tmp);
1327  if (last)
1328  SLIST_NEXT(SLIST_FIRST(last), entries) = pat;
1329  else
1330  curlist = tmp;
1331  last = tmp;
1332  pat = SLIST_FIRST(tmp);
1333  pat->pat_not ^= pat_not;
1334  pat->all_addr |= all_addr;
1335  pat->is_alias |= is_alias;
1336  pat_not = false;
1337  all_addr = false;
1338  is_alias = false;
1339  ps.dptr = p + 1; /* restore location */
1340  break;
1341  }
1342 
1343  default:
1344  mutt_buffer_printf(err, _("error in pattern at: %s"), ps.dptr);
1345  goto cleanup;
1346  }
1347  }
1348  if (!curlist)
1349  {
1350  mutt_buffer_strcpy(err, _("empty pattern"));
1351  return NULL;
1352  }
1353  if (curlist != tmp)
1354  FREE(&tmp);
1355  if (SLIST_NEXT(SLIST_FIRST(curlist), entries))
1356  {
1357  tmp = mutt_pattern_node_new();
1358  struct Pattern *pat = SLIST_FIRST(tmp);
1359  pat->op = pat_or ? MUTT_PAT_OR : MUTT_PAT_AND;
1360  pat->child = curlist;
1361  curlist = tmp;
1362  }
1363 
1364  return curlist;
1365 
1366 cleanup:
1367  mutt_pattern_free(&curlist);
1368  return NULL;
1369 }
struct PatternList * child
Arguments to logical operation.
Definition: lib.h:82
enum PatternEat eat_arg
Definition: private.h:55
bool group_match
Check a group of Addresses.
Definition: lib.h:74
Process a number (range)
Definition: private.h:41
static struct PatternList * mutt_pattern_node_new(void)
Create a new list containing a Pattern.
Definition: compile.c:1074
static bool eat_date(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err)
Parse a date pattern - Implements eat_arg_t.
Definition: compile.c:976
static bool eat_regex(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err)
Parse a regex - Implements eat_arg_t.
Definition: compile.c:80
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Process a regex.
Definition: private.h:39
static char * find_matching_paren(char *s)
Find the matching parenthesis.
Definition: compile.c:1016
A simple (non-regex) pattern.
Definition: lib.h:68
bool is_alias
Is there an alias for this Address?
Definition: lib.h:76
int op
Operation to perform, e.g. MUTT_PAT_SCORE.
Definition: private.h:52
bool all_addr
All Addresses in the list must match.
Definition: lib.h:72
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:548
#define SKIPWS(ch)
Definition: string2.h:46
#define MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition: lib.h:63
bool string_match
Check a string for a match.
Definition: lib.h:73
bool pat_not
Pattern should be inverted (not)
Definition: lib.h:71
#define SLIST_NEXT(elm, field)
Definition: queue.h:270
static bool eat_message_range(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err, struct Mailbox *m, struct Menu *menu)
Parse a range of message numbers - Implements eat_arg_t.
Definition: compile.c:931
struct PatternList * mutt_pattern_comp(struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1092
Process a message number (range)
Definition: private.h:42
#define SLIST_FIRST(head)
Definition: queue.h:229
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: lib.h:70
const struct PatternFlags * lookup_tag(char tag)
Lookup a pattern modifier.
Definition: flags.c:197
static bool eat_query(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err, struct Mailbox *m)
Parse a query for an external search program - Implements eat_arg_t.
Definition: compile.c:155
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
static bool eat_range(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err)
Parse a number range - Implements eat_arg_t.
Definition: compile.c:627
Both patterns must match.
Definition: lib.h:126
Either pattern can match.
Definition: lib.h:127
bool sendmode
Evaluate searches in send-mode.
Definition: lib.h:78
Pattern matches parent.
Definition: lib.h:129
#define FREE(x)
Definition: memory.h:40
Pattern matches a child email.
Definition: lib.h:130
Mapping between user character and internal constant.
Definition: private.h:49
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
Pattern matches email thread.
Definition: lib.h:128
PatternCompFlags flags
Pattern flags, e.g. MUTT_PC_FULL_MSG.
Definition: private.h:53
Process a date (range)
Definition: private.h:40
Process a query string.
Definition: private.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_check_simple()

void mutt_check_simple ( struct Buffer buf,
const char *  simple 
)

Convert a simple search into a real request.

Parameters
bufBuffer for the result
simpleSearch string to convert

Definition at line 113 of file pattern.c.

114 {
115  bool do_simple = true;
116 
117  for (const char *p = mutt_buffer_string(buf); p && (p[0] != '\0'); p++)
118  {
119  if ((p[0] == '\\') && (p[1] != '\0'))
120  p++;
121  else if ((p[0] == '~') || (p[0] == '=') || (p[0] == '%'))
122  {
123  do_simple = false;
124  break;
125  }
126  }
127 
128  /* XXX - is mutt_istr_cmp() right here, or should we use locale's
129  * equivalences? */
130 
131  if (do_simple) /* yup, so spoof a real request */
132  {
133  /* convert old tokens into the new format */
134  if (mutt_istr_equal("all", mutt_buffer_string(buf)) ||
135  mutt_str_equal("^", mutt_buffer_string(buf)) ||
136  mutt_str_equal(".", mutt_buffer_string(buf))) /* ~A is more efficient */
137  {
138  mutt_buffer_strcpy(buf, "~A");
139  }
140  else if (mutt_istr_equal("del", mutt_buffer_string(buf)))
141  mutt_buffer_strcpy(buf, "~D");
142  else if (mutt_istr_equal("flag", mutt_buffer_string(buf)))
143  mutt_buffer_strcpy(buf, "~F");
144  else if (mutt_istr_equal("new", mutt_buffer_string(buf)))
145  mutt_buffer_strcpy(buf, "~N");
146  else if (mutt_istr_equal("old", mutt_buffer_string(buf)))
147  mutt_buffer_strcpy(buf, "~O");
148  else if (mutt_istr_equal("repl", mutt_buffer_string(buf)))
149  mutt_buffer_strcpy(buf, "~Q");
150  else if (mutt_istr_equal("read", mutt_buffer_string(buf)))
151  mutt_buffer_strcpy(buf, "~R");
152  else if (mutt_istr_equal("tag", mutt_buffer_string(buf)))
153  mutt_buffer_strcpy(buf, "~T");
154  else if (mutt_istr_equal("unread", mutt_buffer_string(buf)))
155  mutt_buffer_strcpy(buf, "~U");
156  else
157  {
158  struct Buffer *tmp = mutt_buffer_pool_get();
159  quote_simple(mutt_buffer_string(buf), tmp);
160  mutt_file_expand_fmt(buf, simple, mutt_buffer_string(tmp));
162  }
163  }
164 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
static void quote_simple(const char *str, struct Buffer *buf)
Apply simple quoting to a string.
Definition: pattern.c:95
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
union Pattern::@3 p
String manipulation buffer.
Definition: buffer.h:33
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
void mutt_file_expand_fmt(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1450
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_free()

void mutt_pattern_free ( struct PatternList **  pat)

Free a Pattern.

Parameters
[out]patPattern to free

Definition at line 1038 of file compile.c.

1039 {
1040  if (!pat || !*pat)
1041  return;
1042 
1043  struct Pattern *np = SLIST_FIRST(*pat), *next = NULL;
1044 
1045  while (np)
1046  {
1047  next = SLIST_NEXT(np, entries);
1048 
1049  if (np->is_multi)
1051  else if (np->string_match || np->dynamic)
1052  FREE(&np->p.str);
1053  else if (np->group_match)
1054  np->p.group = NULL;
1055  else if (np->p.regex)
1056  {
1057  regfree(np->p.regex);
1058  FREE(&np->p.regex);
1059  }
1060 
1061  mutt_pattern_free(&np->child);
1062  FREE(&np);
1063 
1064  np = next;
1065  }
1066 
1067  FREE(pat);
1068 }
struct PatternList * child
Arguments to logical operation.
Definition: lib.h:82
regex_t * regex
Compiled regex, for non-pattern matching.
Definition: lib.h:84
bool group_match
Check a group of Addresses.
Definition: lib.h:74
union Pattern::@3 p
bool is_multi
Multiple case (only for ~I pattern now)
Definition: lib.h:79
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
A simple (non-regex) pattern.
Definition: lib.h:68
bool dynamic
Evaluate date ranges at run time.
Definition: lib.h:77
bool string_match
Check a string for a match.
Definition: lib.h:73
#define SLIST_NEXT(elm, field)
Definition: queue.h:270
#define SLIST_FIRST(head)
Definition: queue.h:229
char * str
String, if string_match is set.
Definition: lib.h:86
struct Group * group
Address group if group_match is set.
Definition: lib.h:85
#define FREE(x)
Definition: memory.h:40
struct ListHead multi_cases
Multiple strings for ~I pattern.
Definition: lib.h:87
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_select_pattern()

bool dlg_select_pattern ( char *  buf,
size_t  buflen 
)

Show menu to select a Pattern.

Parameters
bufBuffer for the selected Pattern
buflenLength of buffer
Return values
trueA selection was made

Definition at line 345 of file dlgpattern.c.

346 {
348  struct Menu *menu = create_pattern_menu(dlg);
349 
350  struct MuttWindow *win_menu = menu->win;
351 
352  // NT_COLOR is handled by the SimpleDialog
355 
356  bool rc = false;
357  bool done = false;
358  while (!done)
359  {
360  switch (menu_loop(menu))
361  {
362  case OP_GENERIC_SELECT_ENTRY:
363  {
364  const int index = menu_get_index(menu);
365  struct PatternEntry *entry = ((struct PatternEntry *) menu->mdata) + index;
366  mutt_str_copy(buf, entry->tag, buflen);
367  rc = true;
368  done = true;
369  break;
370  }
371 
372  case OP_EXIT:
373  done = true;
374  break;
375  }
376  }
377 
378  simple_dialog_free(&dlg);
379  return rc;
380 }
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:165
Definition: lib.h:67
Generic selection list.
Definition: type.h:45
static const struct Mapping PatternHelp[]
Help Bar for the Pattern selection dialog.
Definition: dlgpattern.c:99
Container for Accounts, Notifications.
Definition: neomutt.h:36
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
void * mdata
Private data.
Definition: lib.h:155
const char * tag
Copied to buffer if selected.
Definition: dlgpattern.c:93
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
static int pattern_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: dlgpattern.c:293
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
Pattern Dialog, create_pattern_menu()
Definition: mutt_window.h:87
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:128
A line in the Pattern Completion menu.
Definition: dlgpattern.c:90
static int pattern_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: dlgpattern.c:317
static struct Menu * create_pattern_menu(struct MuttWindow *dlg)
Create the Pattern Completion menu.
Definition: dlgpattern.c:179
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_which_case()

int mutt_which_case ( const char *  s)

◆ mutt_is_list_recipient()

int mutt_is_list_recipient ( bool  all_addr,
struct Envelope e 
)

Matches known mailing lists.

Parameters
all_addrIf true, ALL Addresses must be mailing lists
eEnvelope
Return values
true
  • One Address is a mailing list (all_addr is false)
  • All the Addresses are mailing lists (all_addr is true)

Definition at line 454 of file exec.c.

455 {
456  return mutt_is_predicate_recipient(all_addr, e, &mutt_is_mail_list);
457 }
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list? - Implements addr_predicate_t.
Definition: maillist.c:44
static int mutt_is_predicate_recipient(bool all_addr, struct Envelope *e, addr_predicate_t p)
Test an Envelopes Addresses using a predicate function.
Definition: exec.c:417
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_subscribed_list_recipient()

int mutt_is_subscribed_list_recipient ( bool  all_addr,
struct Envelope e 
)

Matches subscribed mailing lists.

Parameters
all_addrIf true, ALL Addresses must be on the subscribed list
eEnvelope
Return values
true
  • One Address is subscribed (all_addr is false)
  • All the Addresses are subscribed (all_addr is true)

Definition at line 441 of file exec.c.

442 {
444 }
bool mutt_is_subscribed_list(const struct Address *addr)
Is this the email address of a user-subscribed mailing list? - Implements addr_predicate_t.
Definition: maillist.c:56
static int mutt_is_predicate_recipient(bool all_addr, struct Envelope *e, addr_predicate_t p)
Test an Envelopes Addresses using a predicate function.
Definition: exec.c:417
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_func()

int mutt_pattern_func ( struct Context ctx,
int  op,
char *  prompt 
)

Perform some Pattern matching.

Parameters
ctxCurrent Mailbox
opOperation to perform, e.g. MUTT_LIMIT
promptPrompt to show the user
Return values
0Success
-1Failure

Definition at line 342 of file pattern.c.

343 {
344  if (!ctx || !ctx->mailbox)
345  return -1;
346 
347  struct Mailbox *m = ctx->mailbox;
348 
349  struct Buffer err;
350  int rc = -1;
351  struct Progress *progress = NULL;
352  struct Buffer *buf = mutt_buffer_pool_get();
353 
354  mutt_buffer_strcpy(buf, NONULL(ctx->pattern));
355  if (prompt || (op != MUTT_LIMIT))
356  {
357  if ((mutt_buffer_get_field(prompt, buf, MUTT_PATTERN | MUTT_CLEAR, false,
358  NULL, NULL, NULL) != 0) ||
360  {
362  return -1;
363  }
364  }
365 
366  mutt_message(_("Compiling search pattern..."));
367 
368  char *simple = mutt_buffer_strdup(buf);
369  const char *const c_simple_search =
370  cs_subset_string(NeoMutt->sub, "simple_search");
371  mutt_check_simple(buf, NONULL(c_simple_search));
372  const char *pbuf = buf->data;
373  while (*pbuf == ' ')
374  pbuf++;
375  const bool match_all = mutt_str_equal(pbuf, "~A");
376 
377  mutt_buffer_init(&err);
378  err.dsize = 256;
379  err.data = mutt_mem_malloc(err.dsize);
380  struct PatternList *pat =
381  mutt_pattern_comp(m, ctx->menu, buf->data, MUTT_PC_FULL_MSG, &err);
382  if (!pat)
383  {
384  mutt_error("%s", err.data);
385  goto bail;
386  }
387 
388 #ifdef USE_IMAP
389  if ((m->type == MUTT_IMAP) && (!imap_search(m, pat)))
390  goto bail;
391 #endif
392 
393  progress = progress_new(_("Executing command on matching messages..."), MUTT_PROGRESS_READ,
394  (op == MUTT_LIMIT) ? m->msg_count : m->vcount);
395 
396  if (op == MUTT_LIMIT)
397  {
398  m->vcount = 0;
399  ctx->vsize = 0;
400  ctx->collapsed = false;
401  int padding = mx_msg_padding_size(m);
402 
403  for (int i = 0; i < m->msg_count; i++)
404  {
405  struct Email *e = m->emails[i];
406  if (!e)
407  break;
408 
409  progress_update(progress, i, -1);
410  /* new limit pattern implicitly uncollapses all threads */
411  e->vnum = -1;
412  e->visible = false;
413  e->collapsed = false;
414  e->num_hidden = 0;
415  if (match_all ||
417  {
418  e->vnum = m->vcount;
419  e->visible = true;
420  m->v2r[m->vcount] = i;
421  m->vcount++;
422  struct Body *b = e->body;
423  ctx->vsize += b->length + b->offset - b->hdr_offset + padding;
424  }
425  }
426  }
427  else
428  {
429  for (int i = 0; i < m->vcount; i++)
430  {
431  struct Email *e = mutt_get_virt_email(m, i);
432  if (!e)
433  continue;
434  progress_update(progress, i, -1);
436  {
437  switch (op)
438  {
439  case MUTT_UNDELETE:
440  mutt_set_flag(m, e, MUTT_PURGE, false);
441  /* fallthrough */
442  case MUTT_DELETE:
443  mutt_set_flag(m, e, MUTT_DELETE, (op == MUTT_DELETE));
444  break;
445  case MUTT_TAG:
446  case MUTT_UNTAG:
447  mutt_set_flag(m, e, MUTT_TAG, (op == MUTT_TAG));
448  break;
449  }
450  }
451  }
452  }
453  progress_free(&progress);
454 
456 
457  if (op == MUTT_LIMIT)
458  {
459  /* drop previous limit pattern */
460  FREE(&ctx->pattern);
462 
463  if (m->msg_count && !m->vcount)
464  mutt_error(_("No messages matched criteria"));
465 
466  /* record new limit pattern, unless match all */
467  if (!match_all)
468  {
469  ctx->pattern = simple;
470  simple = NULL; /* don't clobber it */
471  ctx->limit_pattern =
472  mutt_pattern_comp(m, ctx->menu, buf->data, MUTT_PC_FULL_MSG, &err);
473  }
474  }
475 
476  rc = 0;
477 
478 bail:
480  FREE(&simple);
481  mutt_pattern_free(&pat);
482  FREE(&err.data);
483 
484  return rc;
485 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
bool imap_search(struct Mailbox *m, const struct PatternList *pat)
Find messages in mailbox matching a pattern.
Definition: search.c:229
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
int msg_count
Total number of messages.
Definition: mailbox.h:91
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:66
The envelope/body of an email.
Definition: email.h:37
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:58
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: context.c:412
struct Body * body
List of MIME parts.
Definition: email.h:91
#define mutt_error(...)
Definition: logging.h:88
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:268
void mutt_check_simple(struct Buffer *buf, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:113
Messages in limited view.
Definition: mutt.h:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
Messages to be un-deleted.
Definition: mutt.h:95
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
Progress tracks elements, according to $read_inc
Definition: lib.h:46
Messages to be purged (bypass trash)
Definition: mutt.h:96
Container for Accounts, Notifications.
Definition: neomutt.h:36
A Progress Bar.
Definition: progress.c:47
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:60
int vcount
The number of virtual messages.
Definition: mailbox.h:102
The body of an email.
Definition: body.h:34
struct Mailbox * mailbox
Definition: context.h:49
struct Menu * menu
Needed for pattern compilation.
Definition: context.h:45
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
struct PatternList * mutt_pattern_comp(struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1092
off_t vsize
Size (in bytes) of the messages shown.
Definition: context.h:39
bool visible
Is this message part of the view?
Definition: email.h:74
#define SLIST_FIRST(head)
Definition: queue.h:229
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
Messages to be deleted.
Definition: mutt.h:94
A mailbox.
Definition: mailbox.h:81
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition: email.h:75
struct PatternList * limit_pattern
Compiled limit pattern.
Definition: context.h:41
Tagged messages.
Definition: mutt.h:99
char * data
Pointer to data.
Definition: buffer.h:35
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:73
int vnum
Virtual message number.
Definition: email.h:88
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int mutt_pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Match a pattern against an email header.
Definition: exec.c:1097
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:101
bool collapsed
Are all threads collapsed?
Definition: context.h:47
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
Messages to be un-tagged.
Definition: mutt.h:100
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size()
Definition: mx.c:1540
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:61
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
char * pattern
Limit pattern string.
Definition: context.h:40
static unsigned char * pbuf
Cache PGP data packet.
Definition: pgppacket.c:38
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:95
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_alias_func()

int mutt_pattern_alias_func ( int  op,
char *  prompt,
struct AliasMenuData mdata,
struct Menu menu 
)

Perform some Pattern matching for Alias.

Parameters
opOperation to perform, e.g. MUTT_LIMIT
promptPrompt to show the user
mdataMenu data holding Aliases
menuCurrent menu
Return values
0Success
-1Failure

Definition at line 241 of file pattern.c.

243 {
244  int rc = -1;
245  struct Progress *progress = NULL;
246  struct Buffer *buf = mutt_buffer_pool_get();
247 
248  mutt_buffer_strcpy(buf, mdata->str);
249  if (prompt)
250  {
251  if ((mutt_buffer_get_field(prompt, buf, MUTT_PATTERN | MUTT_CLEAR, false,
252  NULL, NULL, NULL) != 0) ||
254  {
256  return -1;
257  }
258  }
259 
260  mutt_message(_("Compiling search pattern..."));
261 
262  bool match_all = false;
263  struct PatternList *pat = NULL;
264  char *simple = mutt_buffer_strdup(buf);
265  if (simple)
266  {
268  const char *pbuf = buf->data;
269  while (*pbuf == ' ')
270  pbuf++;
271  match_all = mutt_str_equal(pbuf, "~A");
272 
273  struct Buffer err = mutt_buffer_make(0);
274  pat = mutt_pattern_comp(NULL, menu, buf->data, MUTT_PC_FULL_MSG, &err);
275  if (!pat)
276  {
277  mutt_error("%s", mutt_buffer_string(&err));
278  mutt_buffer_dealloc(&err);
279  goto bail;
280  }
281  }
282  else
283  {
284  match_all = true;
285  }
286 
287  progress = progress_new(_("Executing command on matching messages..."),
288  MUTT_PROGRESS_READ, ARRAY_SIZE(&mdata->ava));
289 
290  int vcounter = 0;
291  struct AliasView *avp = NULL;
292  ARRAY_FOREACH(avp, &mdata->ava)
293  {
294  progress_update(progress, ARRAY_FOREACH_IDX, -1);
295 
296  if (match_all ||
298  {
299  avp->is_visible = true;
300  vcounter++;
301  }
302  else
303  {
304  avp->is_visible = false;
305  }
306  }
307  progress_free(&progress);
308 
309  FREE(&mdata->str);
310  if (!match_all)
311  {
312  mdata->str = simple;
313  simple = NULL;
314  }
315 
316  if (menu)
317  {
318  menu->max = vcounter;
319  menu_set_index(menu, 0);
320  }
321 
323 
324  rc = 0;
325 
326 bail:
328  FREE(&simple);
329  mutt_pattern_free(&pat);
330 
331  return rc;
332 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:58
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_error(...)
Definition: logging.h:88
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:268
void mutt_check_simple(struct Buffer *buf, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:113
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
Progress tracks elements, according to $read_inc
Definition: lib.h:46
GUI data wrapping an Alias.
Definition: gui.h:35
A Progress Bar.
Definition: progress.c:47
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:60
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
char * str
String representing the limit being used.
Definition: gui.h:54
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
struct PatternList * mutt_pattern_comp(struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1092
bool is_visible
Is visible?
Definition: gui.h:43
#define SLIST_FIRST(head)
Definition: queue.h:229
int mutt_pattern_alias_exec(struct Pattern *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Match a pattern against an alias.
Definition: exec.c:1120
char * data
Pointer to data.
Definition: buffer.h:35
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int max
Number of entries in the menu.
Definition: lib.h:71
#define MUTT_ALIAS_SIMPLESEARCH
Definition: lib.h:57
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct AliasViewArray ava
Array of AliasView.
Definition: gui.h:55
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:61
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
static unsigned char * pbuf
Cache PGP data packet.
Definition: pgppacket.c:38
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:95
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_search_command()

int mutt_search_command ( struct Mailbox m,
struct Menu menu,
int  cur,
int  op 
)

Perform a search.

Parameters
mMailbox to search through
menuCurrent Menu
curIndex number of current email
opOperation to perform, e.g. OP_SEARCH_NEXT
Return values
>=0Index of matching email
-1No match, or error

Definition at line 496 of file pattern.c.

497 {
498  struct Progress *progress = NULL;
499  int rc = -1;
500 
501  if ((*LastSearch == '\0') || ((op != OP_SEARCH_NEXT) && (op != OP_SEARCH_OPPOSITE)))
502  {
503  char buf[256];
504  mutt_str_copy(buf, (LastSearch[0] != '\0') ? LastSearch : "", sizeof(buf));
505  if ((mutt_get_field(
506  ((op == OP_SEARCH) || (op == OP_SEARCH_NEXT)) ? _("Search for: ") : _("Reverse search for: "),
507  buf, sizeof(buf), MUTT_CLEAR | MUTT_PATTERN, false, NULL, NULL) != 0) ||
508  (buf[0] == '\0'))
509  {
510  return -1;
511  }
512 
513  if ((op == OP_SEARCH) || (op == OP_SEARCH_NEXT))
514  OptSearchReverse = false;
515  else
516  OptSearchReverse = true;
517 
518  /* compare the *expanded* version of the search pattern in case
519  * $simple_search has changed while we were searching */
520  struct Buffer *tmp = mutt_buffer_pool_get();
521  mutt_buffer_strcpy(tmp, buf);
522  const char *const c_simple_search =
523  cs_subset_string(NeoMutt->sub, "simple_search");
524  mutt_check_simple(tmp, NONULL(c_simple_search));
525 
527  {
528  struct Buffer err;
529  mutt_buffer_init(&err);
530  OptSearchInvalid = true;
531  mutt_str_copy(LastSearch, buf, sizeof(LastSearch));
533  mutt_message(_("Compiling search pattern..."));
535  err.dsize = 256;
536  err.data = mutt_mem_malloc(err.dsize);
537  SearchPattern = mutt_pattern_comp(m, menu, tmp->data, MUTT_PC_FULL_MSG, &err);
538  if (!SearchPattern)
539  {
541  mutt_error("%s", err.data);
542  FREE(&err.data);
543  LastSearch[0] = '\0';
544  LastSearchExpn[0] = '\0';
545  return -1;
546  }
547  FREE(&err.data);
549  }
550 
552  }
553 
554  if (OptSearchInvalid)
555  {
556  for (int i = 0; i < m->msg_count; i++)
557  m->emails[i]->searched = false;
558 #ifdef USE_IMAP
559  if ((m->type == MUTT_IMAP) && (!imap_search(m, SearchPattern)))
560  return -1;
561 #endif
562  OptSearchInvalid = false;
563  }
564 
565  int incr = OptSearchReverse ? -1 : 1;
566  if (op == OP_SEARCH_OPPOSITE)
567  incr = -incr;
568 
569  progress = progress_new(_("Searching..."), MUTT_PROGRESS_READ, m->vcount);
570 
571  for (int i = cur + incr, j = 0; j != m->vcount; j++)
572  {
573  const char *msg = NULL;
574  progress_update(progress, j, -1);
575  const bool c_wrap_search = cs_subset_bool(NeoMutt->sub, "wrap_search");
576  if (i > m->vcount - 1)
577  {
578  i = 0;
579  if (c_wrap_search)
580  msg = _("Search wrapped to top");
581  else
582  {
583  mutt_message(_("Search hit bottom without finding match"));
584  goto done;
585  }
586  }
587  else if (i < 0)
588  {
589  i = m->vcount - 1;
590  if (c_wrap_search)
591  msg = _("Search wrapped to bottom");
592  else
593  {
594  mutt_message(_("Search hit top without finding match"));
595  goto done;
596  }
597  }
598 
599  struct Email *e = mutt_get_virt_email(m, i);
600  if (e->searched)
601  {
602  /* if we've already evaluated this message, use the cached value */
603  if (e->matched)
604  {
606  if (msg && *msg)
607  mutt_message(msg);
608  rc = i;
609  goto done;
610  }
611  }
612  else
613  {
614  /* remember that we've already searched this message */
615  e->searched = true;
617  MUTT_MATCH_FULL_ADDRESS, m, e, NULL);
618  if (e->matched > 0)
619  {
621  if (msg && *msg)
622  mutt_message(msg);
623  rc = i;
624  goto done;
625  }
626  }
627 
628  if (SigInt)
629  {
630  mutt_error(_("Search interrupted"));
631  SigInt = false;
632  goto done;
633  }
634 
635  i += incr;
636  }
637 
638  mutt_error(_("Not found"));
639 done:
640  progress_free(&progress);
641  return rc;
642 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
bool imap_search(struct Mailbox *m, const struct PatternList *pat)
Find messages in mailbox matching a pattern.
Definition: search.c:229
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
The envelope/body of an email.
Definition: email.h:37
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:58
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: context.c:412
#define mutt_error(...)
Definition: logging.h:88
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:67
void mutt_check_simple(struct Buffer *buf, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:113
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
static char LastSearch[256]
last pattern searched for
Definition: pattern.c:87
Progress tracks elements, according to $read_inc
Definition: lib.h:46
bool searched
Email has been searched.
Definition: email.h:67
Container for Accounts, Notifications.
Definition: neomutt.h:36
A Progress Bar.
Definition: progress.c:47
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:60
int vcount
The number of virtual messages.
Definition: mailbox.h:102
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
struct PatternList * mutt_pattern_comp(struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1092
static char LastSearchExpn[1024]
expanded version of LastSearch
Definition: pattern.c:88
#define SLIST_FIRST(head)
Definition: queue.h:229
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
char * data
Pointer to data.
Definition: buffer.h:35
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
WHERE bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: options.h:51
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int mutt_pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Match a pattern against an email header.
Definition: exec.c:1097
static struct PatternList * SearchPattern
current search pattern
Definition: pattern.c:86
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:61
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:95
WHERE bool OptSearchReverse
(pseudo) used by ci_search_command
Definition: options.h:52
bool matched
Search matches this Email.
Definition: email.h:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_search_alias_command()

int mutt_search_alias_command ( struct Menu menu,
int  cur,
int  op 
)

Perform a search.

Parameters
menuMenu to search through
curIndex number of current alias
opOperation to perform, e.g. OP_SEARCH_NEXT
Return values
>=0Index of matching alias
-1No match, or error

Definition at line 652 of file pattern.c.

653 {
654  struct Progress *progress = NULL;
655  const struct AliasMenuData *mdata = menu->mdata;
656  const struct AliasViewArray *ava = &mdata->ava;
657  int rc = -1;
658 
659  if ((*LastSearch == '\0') || ((op != OP_SEARCH_NEXT) && (op != OP_SEARCH_OPPOSITE)))
660  {
661  char buf[256];
662  mutt_str_copy(buf, (LastSearch[0] != '\0') ? LastSearch : "", sizeof(buf));
663  if ((mutt_get_field(
664  ((op == OP_SEARCH) || (op == OP_SEARCH_NEXT)) ? _("Search for: ") : _("Reverse search for: "),
665  buf, sizeof(buf), MUTT_CLEAR | MUTT_PATTERN, false, NULL, NULL) != 0) ||
666  (buf[0] == '\0'))
667  {
668  return -1;
669  }
670 
671  if ((op == OP_SEARCH) || (op == OP_SEARCH_NEXT))
672  OptSearchReverse = false;
673  else
674  OptSearchReverse = true;
675 
676  /* compare the *expanded* version of the search pattern in case
677  * $simple_search has changed while we were searching */
678  struct Buffer *tmp = mutt_buffer_pool_get();
679  mutt_buffer_strcpy(tmp, buf);
681 
683  {
684  struct Buffer err;
685  mutt_buffer_init(&err);
686  OptSearchInvalid = true;
687  mutt_str_copy(LastSearch, buf, sizeof(LastSearch));
689  mutt_message(_("Compiling search pattern..."));
691  err.dsize = 256;
692  err.data = mutt_mem_malloc(err.dsize);
693  SearchPattern = mutt_pattern_comp(NULL, menu, tmp->data, MUTT_PC_FULL_MSG, &err);
694  if (!SearchPattern)
695  {
697  mutt_error("%s", err.data);
698  FREE(&err.data);
699  LastSearch[0] = '\0';
700  LastSearchExpn[0] = '\0';
701  return -1;
702  }
703  FREE(&err.data);
705  }
706 
708  }
709 
710  if (OptSearchInvalid)
711  {
712  struct AliasView *av = NULL;
713  ARRAY_FOREACH(av, ava)
714  {
715  av->is_searched = false;
716  }
717 
718  OptSearchInvalid = false;
719  }
720 
721  int incr = OptSearchReverse ? -1 : 1;
722  if (op == OP_SEARCH_OPPOSITE)
723  incr = -incr;
724 
725  progress = progress_new(_("Searching..."), MUTT_PROGRESS_READ, ARRAY_SIZE(ava));
726 
727  for (int i = cur + incr, j = 0; j != ARRAY_SIZE(ava); j++)
728  {
729  const char *msg = NULL;
730  progress_update(progress, j, -1);
731  const bool c_wrap_search = cs_subset_bool(NeoMutt->sub, "wrap_search");
732  if (i > ARRAY_SIZE(ava) - 1)
733  {
734  i = 0;
735  if (c_wrap_search)
736  msg = _("Search wrapped to top");
737  else
738  {
739  mutt_message(_("Search hit bottom without finding match"));
740  goto done;
741  }
742  }
743  else if (i < 0)
744  {
745  i = ARRAY_SIZE(ava) - 1;
746  if (c_wrap_search)
747  msg = _("Search wrapped to bottom");
748  else
749  {
750  mutt_message(_("Search hit top without finding match"));
751  goto done;
752  }
753  }
754 
755  struct AliasView *av = ARRAY_GET(ava, i);
756  if (av->is_searched)
757  {
758  /* if we've already evaluated this message, use the cached value */
759  if (av->is_matched)
760  {
762  if (msg && *msg)
763  mutt_message(msg);
764  rc = i;
765  goto done;
766  }
767  }
768  else
769  {
770  /* remember that we've already searched this message */
771  av->is_searched = true;
773  MUTT_MATCH_FULL_ADDRESS, av, NULL);
774  if (av->is_matched > 0)
775  {
777  if (msg && *msg)
778  mutt_message(msg);
779  rc = i;
780  goto done;
781  }
782  }
783 
784  if (SigInt)
785  {
786  mutt_error(_("Search interrupted"));
787  SigInt = false;
788  goto done;
789  }
790 
791  i += incr;
792  }
793 
794  mutt_error(_("Not found"));
795 done:
796  progress_free(&progress);
797  return rc;
798 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:58
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_error(...)
Definition: logging.h:88
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:67
AliasView array wrapper with Pattern information -.
Definition: gui.h:52
void mutt_check_simple(struct Buffer *buf, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:113
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:105
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
static char LastSearch[256]
last pattern searched for
Definition: pattern.c:87
Progress tracks elements, according to $read_inc
Definition: lib.h:46
bool is_matched
Search matches this Alias.
Definition: gui.h:40
GUI data wrapping an Alias.
Definition: gui.h:35
Container for Accounts, Notifications.
Definition: neomutt.h:36
A Progress Bar.
Definition: progress.c:47
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:60
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
struct PatternList * mutt_pattern_comp(struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1092
static char LastSearchExpn[1024]
expanded version of LastSearch
Definition: pattern.c:88
void * mdata
Private data.
Definition: lib.h:155
#define SLIST_FIRST(head)
Definition: queue.h:229
int mutt_pattern_alias_exec(struct Pattern *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Match a pattern against an alias.
Definition: exec.c:1120
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
char * data
Pointer to data.
Definition: buffer.h:35
bool is_searched
Alias has been searched.
Definition: gui.h:39
WHERE bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: options.h:51
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
static struct PatternList * SearchPattern
current search pattern
Definition: pattern.c:86
#define MUTT_ALIAS_SIMPLESEARCH
Definition: lib.h:57
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct AliasViewArray ava
Array of AliasView.
Definition: gui.h:55
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:61
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:95
WHERE bool OptSearchReverse
(pseudo) used by ci_search_command
Definition: options.h:52
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_limit_current_thread()

bool mutt_limit_current_thread ( struct Context ctx,
struct Email e 
)

Limit the email view to the current thread.

Parameters
ctxCurrent Mailbox
eCurrent Email
Return values
trueSuccess
falseFailure

Definition at line 192 of file pattern.c.

193 {
194  if (!ctx || !ctx->mailbox || !e)
195  return false;
196 
197  struct Mailbox *m = ctx->mailbox;
198 
199  struct MuttThread *me = top_of_thread(e);
200  if (!me)
201  return false;
202 
203  m->vcount = 0;
204  ctx->vsize = 0;
205  ctx->collapsed = false;
206 
207  for (int i = 0; i < m->msg_count; i++)
208  {
209  e = m->emails[i];
210  if (!e)
211  break;
212 
213  e->vnum = -1;
214  e->visible = false;
215  e->collapsed = false;
216  e->num_hidden = 0;
217 
218  if (top_of_thread(e) == me)
219  {
220  struct Body *body = e->body;
221 
222  e->vnum = m->vcount;
223  e->visible = true;
224  m->v2r[m->vcount] = i;
225  m->vcount++;
226  ctx->vsize += (body->length + body->offset - body->hdr_offset);
227  }
228  }
229  return true;
230 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
struct Body * body
List of MIME parts.
Definition: email.h:91
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
int vcount
The number of virtual messages.
Definition: mailbox.h:102
The body of an email.
Definition: body.h:34
struct Mailbox * mailbox
Definition: context.h:49
off_t vsize
Size (in bytes) of the messages shown.
Definition: context.h:39
bool visible
Is this message part of the view?
Definition: email.h:74
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
A mailbox.
Definition: mailbox.h:81
static struct MuttThread * top_of_thread(struct Email *e)
Find the first email in the current thread.
Definition: pattern.c:172
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition: email.h:75
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:73
int vnum
Virtual message number.
Definition: email.h:88
An Email conversation.
Definition: thread.h:34
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:101
bool collapsed
Are all threads collapsed?
Definition: context.h:47
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function: