98 #define ANSI_NO_FLAGS 0 99 #define ANSI_OFF (1 << 0) 100 #define ANSI_BLINK (1 << 1) 101 #define ANSI_BOLD (1 << 2) 102 #define ANSI_UNDERLINE (1 << 3) 103 #define ANSI_REVERSE (1 << 4) 104 #define ANSI_COLOR (1 << 5) 203 static struct Email *OldEmail = NULL;
210 static struct Resize *Resize = NULL;
213 N_(
"Not available in this menu");
216 N_(
"Function not permitted in attach-message mode");
221 {
N_(
"Exit"), OP_EXIT },
222 {
N_(
"PrevPg"), OP_PREV_PAGE },
223 {
N_(
"NextPg"), OP_NEXT_PAGE },
224 {
N_(
"Help"), OP_HELP },
230 static const struct Mapping PagerHelpHelp[] = {
232 {
N_(
"Exit"), OP_EXIT },
233 {
N_(
"PrevPg"), OP_PREV_PAGE },
234 {
N_(
"NextPg"), OP_NEXT_PAGE },
240 static const struct Mapping PagerNormalHelp[] = {
242 {
N_(
"Exit"), OP_EXIT },
243 {
N_(
"PrevPg"), OP_PREV_PAGE },
244 {
N_(
"NextPg"), OP_NEXT_PAGE },
245 {
N_(
"View Attachm."), OP_VIEW_ATTACHMENTS },
246 {
N_(
"Del"), OP_DELETE },
247 {
N_(
"Reply"), OP_REPLY },
248 {
N_(
"Next"), OP_MAIN_NEXT_UNDELETED },
249 {
N_(
"Help"), OP_HELP },
255 static const struct Mapping PagerNewsHelp[] = {
258 {
N_(
"Exit"), OP_EXIT },
259 {
N_(
"PrevPg"), OP_PREV_PAGE },
260 {
N_(
"NextPg"), OP_NEXT_PAGE },
261 {
N_(
"Post"), OP_POST },
262 {
N_(
"Followup"), OP_FOLLOWUP },
263 {
N_(
"Del"), OP_DELETE },
264 {
N_(
"Next"), OP_MAIN_NEXT_UNDELETED },
265 {
N_(
"Help"), OP_HELP },
271 #define IS_HEADER(x) ((x) == MT_COLOR_HEADER || (x) == MT_COLOR_HDRDEFAULT) 273 #define IsAttach(pager) (pager && (pager)->body) 274 #define IsMsgAttach(pager) \ 275 (pager && (pager)->fp && (pager)->body && (pager)->body->email) 276 #define IsEmail(pager) (pager && (pager)->email && !(pager)->body) 278 #define NUM_SIG_LINES 4 280 #define CHECK_MODE(test) \ 284 mutt_error(_(Not_available_in_this_menu)); \ 288 #define CHECK_READONLY \ 289 if (!Context || Context->mailbox->readonly) \ 292 mutt_error(_(Mailbox_is_read_only)); \ 296 #define CHECK_ATTACH \ 300 mutt_error(_(Function_not_permitted_in_attach_message_mode)); \ 304 #define CHECK_ACL(aclbit, action) \ 305 if (!Context || !(Context->mailbox->rights & aclbit)) \ 309 mutt_error(_("%s: Operation not permitted by ACL"), action); \ 362 const int *cnt = (
const int *) m1;
365 if (*cnt < stx->
first)
367 if (*cnt >= stx->
last)
386 static int last_color;
394 if (line_info[n].continuation)
414 def_color = (line_info[m].
syntax)[0].color;
424 def_color = qc->
color;
426 while (qc && (qc->
length > cnt))
428 def_color = qc->
color;
435 if ((flags & MUTT_SHOWCOLOR) && line_info[m].
chunks)
437 matching_chunk = bsearch(&cnt, line_info[m].syntax, line_info[m].chunks,
439 if (matching_chunk && (cnt >= matching_chunk->
first) &&
440 (cnt < matching_chunk->last))
442 color = matching_chunk->
color;
446 if ((flags &
MUTT_SEARCH) && line_info[m].search_cnt)
448 matching_chunk = bsearch(&cnt, line_info[m].search, line_info[m].search_cnt,
450 if (matching_chunk && (cnt >= matching_chunk->
first) &&
451 (cnt < matching_chunk->last))
459 if (special || a->
attr)
484 color ^= A_UNDERLINE;
500 if (color != last_color)
517 line_info[n + 1].
type = line_info[n].
type;
518 (line_info[n + 1].
syntax)[0].
color = (line_info[n].syntax)[0].color;
522 for (m = n; m >= 0; m--)
523 if (line_info[m].continuation == 0)
526 (line_info[n + 1].
syntax)[0].first = m;
527 (line_info[n + 1].
syntax)[0].last =
528 (line_info[n].continuation) ? cnt + (line_info[n].
syntax)[0].last : cnt;
538 qc->
index = (*q_level)++;
552 struct QClass *q_list = quote_list;
553 new_class->
index = -1;
557 if (q_list->
index >= index)
563 q_list = q_list->
down;
564 else if (q_list->
next)
565 q_list = q_list->
next;
568 while (!q_list->
next)
575 q_list = q_list->
next;
590 struct QClass *ptr = NULL;
594 if ((*quote_list)->down)
596 ptr = (*quote_list)->
next;
597 FREE(&(*quote_list)->prefix);
613 size_t length,
bool *force_redraw,
int *q_level)
615 struct QClass *q_list = *quote_list;
616 struct QClass *qc = NULL, *tmp = NULL, *ptr = NULL, *save = NULL;
617 const char *tail_qptr = NULL;
618 int offset, tail_lng;
637 if (length <= q_list->length)
643 if (length == q_list->
length)
652 strncpy(tmp->prefix, qptr, length);
658 tmp->next = q_list->
next;
676 if (q_list == *quote_list)
679 index = q_list->
index;
712 index = q_list->
index;
719 *force_redraw =
true;
725 q_list = q_list->
next;
741 q_list = q_list->
down;
742 tail_lng = length - offset;
743 tail_qptr = qptr + offset;
747 if (length <= q_list->length)
752 if (length == q_list->
length)
761 strncpy(tmp->prefix, qptr, length);
767 tmp->next = q_list->
next;
778 tmp->
up = q_list->
up;
780 if (tmp->up->down == q_list)
787 index = q_list->
index;
817 index = q_list->
index;
824 *force_redraw =
true;
829 q_list = q_list->
next;
843 q_list = q_list->
down;
844 tail_lng = length - offset;
845 tail_qptr = qptr + offset;
852 q_list = q_list->
next;
863 strncpy(tmp->prefix, qptr, length);
868 tmp->next = ptr->down;
869 ptr->down->prev = tmp;
889 q_list = q_list->
next;
900 strncpy(qc->
prefix, qptr, length);
906 qc->
next = *quote_list;
907 (*quote_list)->
prev = qc;
926 for (; (p[0] == q[0]) && (q[0] !=
'\0') && (p[0] !=
'\0') && (q[0] !=
'\a') &&
932 return (
int) (*p - *q);
966 bool is_quote =
false;
967 regmatch_t pmatch_internal[1], smatch[1];
970 pmatch = pmatch_internal;
976 if (smatch[0].rm_so > 0)
978 char c = line[smatch[0].rm_so];
979 line[smatch[0].rm_so] = 0;
984 line[smatch[0].rm_so] = c;
1007 int last,
struct QClass **quote_list,
int *q_level,
1008 bool *force_redraw,
bool q_classify)
1011 struct ColorLineList *head = NULL;
1012 regmatch_t pmatch[1];
1017 if ((n == 0) ||
IS_HEADER(line_info[n - 1].type) ||
1029 if ((n > 0) && ((buf[0] ==
' ') || (buf[0] ==
'\t')))
1031 line_info[n].
type = line_info[n - 1].
type;
1034 (line_info[n].
syntax)[0].
color = (line_info[n - 1].syntax)[0].color;
1050 if (regexec(&color_line->
regex, buf, 0, NULL, 0) == 0)
1054 if (line_info[n].is_cont_hdr)
1058 for (j = n - 1; j >= 0 && line_info[j].
is_cont_hdr; --j)
1060 line_info[j].
type = line_info[n].
type;
1066 line_info[j].
type = line_info[n].
type;
1069 *force_redraw =
true;
1086 while ((i < last) && (
check_sig(buf, line_info, i - 1) == 0) &&
1091 if (line_info[i].chunks)
1099 else if (
check_sig(buf, line_info, n - 1) == 0)
1104 if (q_classify && (line_info[n].quote == NULL))
1107 pmatch[0].rm_eo - pmatch[0].rm_so,
1108 force_redraw, q_level);
1124 if ((nl > 0) && (buf[nl - 1] ==
'\n'))
1148 (regexec(&color_line->
regex, buf + offset, 1, pmatch,
1149 ((offset != 0) ? REG_NOTBOL : 0)) == 0))
1151 if (pmatch[0].rm_eo != pmatch[0].rm_so)
1157 if (line_info[n].chunks == SHRT_MAX)
1162 if (++(line_info[n].chunks) > 1)
1165 (line_info[n].chunks) *
sizeof(
struct TextSyntax));
1168 i = line_info[n].
chunks - 1;
1169 pmatch[0].rm_so += offset;
1170 pmatch[0].rm_eo += offset;
1171 if (!found || (pmatch[0].rm_so < (line_info[n].syntax)[i].first) ||
1172 ((pmatch[0].rm_so == (line_info[n].syntax)[i].first) &&
1173 (pmatch[0].rm_eo > (line_info[n].syntax)[i].last)))
1176 (line_info[n].
syntax)[i].first = pmatch[0].rm_so;
1177 (line_info[n].
syntax)[i].last = pmatch[0].rm_eo;
1197 offset = (line_info[n].
syntax)[i].last;
1198 }
while (found || null_rx);
1210 if ((nl > 0) && (buf[nl - 1] ==
'\n'))
1225 if (regexec(&color_line->
regex, buf + offset, 1, pmatch,
1226 ((offset != 0) ? REG_NOTBOL : 0)) == 0)
1228 if (pmatch[0].rm_eo != pmatch[0].rm_so)
1232 if (++(line_info[n].chunks) > 1)
1235 (line_info[n].chunks) *
sizeof(
struct TextSyntax));
1238 i = line_info[n].
chunks - 1;
1239 pmatch[0].rm_so += offset;
1240 pmatch[0].rm_eo += offset;
1241 if (!found || (pmatch[0].rm_so < (line_info[n].syntax)[i].first) ||
1242 ((pmatch[0].rm_so == (line_info[n].syntax)[i].first) &&
1243 (pmatch[0].rm_eo > (line_info[n].syntax)[i].last)))
1246 (line_info[n].
syntax)[i].first = pmatch[0].rm_so;
1247 (line_info[n].
syntax)[i].last = pmatch[0].rm_eo;
1260 offset = (line_info[n].
syntax)[i].last;
1261 }
while (found || null_rx);
1274 while (*str && (isdigit(*str) || *str ==
';'))
1276 return (*str ==
'm');
1290 while (isdigit(buf[x]) || (buf[x] ==
';'))
1307 if ((buf[pos] ==
'1') && ((pos + 1 == x) || (buf[pos + 1] ==
';')))
1312 else if ((buf[pos] ==
'4') && ((pos + 1 == x) || (buf[pos + 1] ==
';')))
1317 else if ((buf[pos] ==
'5') && ((pos + 1 == x) || (buf[pos + 1] ==
';')))
1322 else if ((buf[pos] ==
'7') && ((pos + 1 == x) || (buf[pos + 1] ==
';')))
1327 else if ((buf[pos] ==
'0') && ((pos + 1 == x) || (buf[pos + 1] ==
';')))
1337 else if ((buf[pos] ==
'3') && isdigit(buf[pos + 1]))
1345 a->
fg = buf[pos + 1] -
'0';
1348 else if ((buf[pos] ==
'4') && isdigit(buf[pos + 1]))
1356 a->
bg = buf[pos + 1] -
'0';
1361 while ((pos < x) && (buf[pos] !=
';'))
1386 const char *s = src;
1393 while (s[0] !=
'\0')
1395 if ((s[0] ==
'\010') && (s > src))
1408 else if ((s[0] ==
'\033') && (s[1] ==
'[') &&
is_ansi(s + 2))
1413 else if (strip_markers && (s[0] ==
'\033') && (s[1] ==
']') &&
1417 while (*s++ !=
'\a')
1437 static int fill_buffer(FILE *fp, LOFF_T *last_pos, LOFF_T offset,
unsigned char **buf,
1438 unsigned char **fmt,
size_t *blen,
int *buf_ready)
1443 if (*buf_ready == 0)
1445 if (offset != *last_pos)
1446 fseeko(fp, offset, SEEK_SET);
1455 *last_pos = ftello(fp);
1456 b_read = (int) (*last_pos - offset);
1464 *fmt = (
unsigned char *) stripped.
data;
1487 int *pspace,
int *pvch,
int *pcol,
int *pspecial,
int width)
1490 int col =
C_Markers ? (*line_info)[n].continuation : 0;
1492 int ch, vch, last_special = -1, special = 0, t;
1501 memset(&mbstate, 0,
sizeof(mbstate));
1503 for (ch = 0, vch = 0; ch < cnt; ch += k, vch += k)
1506 while ((cnt - ch >= 2) && (buf[ch] ==
'\033') && (buf[ch + 1] ==
'[') &&
1507 is_ansi((
char *) buf + ch + 2))
1512 while ((cnt - ch >= 2) && (buf[ch] ==
'\033') && (buf[ch + 1] ==
']') &&
1516 while (buf[ch++] !=
'\a')
1525 k = mbrtowc(&wc, (
char *) buf + ch, cnt - ch, &mbstate);
1526 if ((k == (
size_t)(-2)) || (k == (
size_t)(-1)))
1528 if (k == (
size_t)(-1))
1529 memset(&mbstate, 0,
sizeof(mbstate));
1531 if (col + 4 > wrap_cols)
1545 if ((wc == 0x200B) || (wc == 0xFEFF))
1562 mbstate_t mbstate1 = mbstate;
1563 size_t k1 = mbrtowc(&wc1, (
char *) buf + ch + k, cnt - ch - k, &mbstate1);
1564 while ((k1 != (
size_t)(-2)) && (k1 != (
size_t)(-1)) && (k1 > 0) && (wc1 ==
'\b'))
1567 mbrtowc(&wc1, (
char *) buf + ch + k + k1, cnt - ch - k - k1, &mbstate1);
1568 if ((k2 == (
size_t)(-2)) || (k2 == (
size_t)(-1)) || (k2 == 0) || (!
IsWPrint(wc1)))
1573 special |= ((wc ==
'_') && (special & A_UNDERLINE)) ? A_UNDERLINE : A_BOLD;
1575 else if ((wc ==
'_') || (wc1 ==
'_'))
1577 special |= A_UNDERLINE;
1578 wc = (wc1 ==
'_') ? wc : wc1;
1589 k1 = mbrtowc(&wc1, (
char *) buf + ch + k, cnt - ch - k, &mbstate1);
1594 special || last_special || pa->
attr))
1597 last_special = special;
1608 if (col + t > wrap_cols)
1614 else if (wc ==
'\n')
1616 else if (wc ==
'\t')
1623 for (; col < t; col++)
1628 else if ((wc < 0x20) || (wc == 0x7f))
1630 if (col + 2 > wrap_cols)
1636 else if (wc < 0x100)
1638 if (col + 4 > wrap_cols)
1646 if (col + 1 > wrap_cols)
1656 *pspecial = special;
1679 int n,
int *last,
int *max,
PagerFlags flags,
1680 struct QClass **quote_list,
int *q_level,
bool *force_redraw,
1681 regex_t *search_re,
struct MuttWindow *win_pager)
1683 unsigned char *buf = NULL, *fmt = NULL;
1685 unsigned char *buf_ptr = NULL;
1686 int ch, vch, col, cnt, b_read;
1688 bool change_last =
false;
1694 struct AnsiAttr a = { 0, 0, 0, -1 };
1695 regmatch_t pmatch[1];
1706 for (ch = *last; ch < *max; ch++)
1708 memset(&((*line_info)[ch]), 0,
sizeof(
struct Line));
1709 (*line_info)[ch].type = -1;
1710 (*line_info)[ch].search_cnt = -1;
1712 ((*line_info)[ch].syntax)[0].first = -1;
1713 ((*line_info)[ch].syntax)[0].last = -1;
1717 struct Line *
const curr_line = &(*line_info)[n];
1722 if (
fill_buffer(fp, last_pos, curr_line->
offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1732 else if (buf[11] ==
'W')
1734 else if (buf[11] ==
'E')
1743 if (curr_line->
type == -1)
1746 if (
fill_buffer(fp, last_pos, curr_line->
offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1753 resolve_types((
char *) fmt, (
char *) buf, *line_info, n, *last,
1757 for (m = n + 1; m < *last && (*line_info)[m].offset && (*line_info)[m].continuation; m++)
1758 (*line_info)[m].type = curr_line->
type;
1777 if (
fill_buffer(fp, last_pos, curr_line->
offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1788 pmatch[0].rm_eo - pmatch[0].rm_so, force_redraw, q_level);
1798 if (
fill_buffer(fp, last_pos, curr_line->
offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1807 while (regexec(search_re, (
char *) fmt + offset, 1, pmatch,
1808 (offset ? REG_NOTBOL : 0)) == 0)
1817 pmatch[0].rm_so +=
offset;
1818 pmatch[0].rm_eo +=
offset;
1822 if (pmatch[0].rm_eo == pmatch[0].rm_so)
1825 offset = pmatch[0].rm_eo;
1831 if (!(flags &
MUTT_SHOW) && ((*line_info)[n + 1].offset > 0))
1837 if ((flags & MUTT_SHOWCOLOR) && *force_redraw && ((*line_info)[n + 1].offset > 0))
1844 b_read =
fill_buffer(fp, last_pos, curr_line->
offset, &buf, &fmt, &buflen, &buf_ready);
1853 cnt =
format_line(line_info, n, buf, flags, NULL, b_read, &ch, &vch, &col,
1855 buf_ptr = buf + cnt;
1864 while (ch && ((buf[ch] ==
' ') || (buf[ch] ==
'\t') || (buf[ch] ==
'\r')))
1872 buf_ptr = buf + cnt;
1879 while ((*buf_ptr ==
' ') || (*buf_ptr ==
'\t'))
1884 if (*buf_ptr ==
'\r')
1886 if (*buf_ptr ==
'\n')
1889 if (((
int) (buf_ptr - buf) < b_read) && !(*line_info)[n + 1].
continuation)
1890 append_line(*line_info, n, (
int) (buf_ptr - buf));
1891 (*line_info)[n + 1].offset = curr_line->
offset + (long) (buf_ptr - buf);
1894 if (!(flags & MUTT_SHOW))
1901 format_line(line_info, n, buf, flags, &a, cnt, &ch, &vch, &col, &special,
1905 #ifndef USE_SLANG_CURSES 1914 if (special || ((col != win_pager->
state.
cols) && (flags & (MUTT_SHOWCOLOR | MUTT_SEARCH))))
1920 if (flags & MUTT_SHOWCOLOR)
1924 def_color = ((*line_info)[m].syntax)[0].
color;
1926 def_color =
Colors->
defs[(*line_info)[m].type];
1931 if (col < win_pager->state.cols)
1937 if (flags & MUTT_SHOWCOLOR)
1941 if (!(flags & MUTT_SHOW))
1962 while ((cur > 0) && (nlines > 0))
2021 regerror(err, &rd->
search_re, buf,
sizeof(buf));
2070 for (
int i = 0; i <= rd->
topline; i++)
2073 for (
int i = 0; i < rd->
max_line; i++)
2155 char pager_progress_str[65];
2163 snprintf(pager_progress_str,
sizeof(pager_progress_str), OFF_T_FMT
"%%",
2168 const char *msg = (rd->
topline == 0) ?
2173 mutt_str_copy(pager_progress_str, msg,
sizeof(pager_progress_str));
2183 size_t l2 =
sizeof(buf);
2192 snprintf(bn,
sizeof(bn),
"%s (%s)", rd->
banner, pager_progress_str);
2241 static char searchbuf[256] = { 0 };
2243 int ch = 0, rc = -1;
2246 bool wrapped =
false;
2248 struct Menu *pager_menu = NULL;
2249 int old_PagerIndexLines;
2251 char *followup_to = NULL;
2272 rd.
fp = fopen(fname,
"r");
2279 if (stat(fname, &rd.
sb) != 0)
2308 for (
size_t i = 0; i < rd.
max_line; i++)
2387 bool do_new_mail =
false;
2409 for (
size_t i = oldcount; i < m->
msg_count; i++)
2445 if (extra->
email != e)
2475 clearok(stdscr,
true);
2481 for (
size_t i = 0; i <= rd.
topline; i++)
2492 rc = OP_REFORMAT_WINCH;
2541 rc = OP_MAIN_NEXT_UNDELETED;
2614 rc = OP_MAIN_NEXT_UNDELETED;
2619 case OP_SEARCH_NEXT:
2620 case OP_SEARCH_OPPOSITE:
2625 if (C_SearchContext < rd.extra->win_pager->state.rows)
2631 if ((!rd.
search_back && (ch == OP_SEARCH_NEXT)) ||
2686 if (rd.
topline - searchctx > 0)
2696 case OP_SEARCH_REVERSE:
2698 if (
mutt_get_field(((ch == OP_SEARCH) || (ch == OP_SEARCH_NEXT)) ?
2700 _(
"Reverse search for: "),
2706 if (strcmp(buf, searchbuf) == 0)
2711 if (ch == OP_SEARCH)
2712 ch = OP_SEARCH_NEXT;
2714 ch = OP_SEARCH_OPPOSITE;
2727 if (ch == OP_SEARCH)
2729 else if (ch == OP_SEARCH_REVERSE)
2735 for (
size_t i = 0; i < rd.
last_line; i++)
2746 regerror(err, &rd.
search_re, buf,
sizeof(buf));
2748 for (
size_t i = 0; i < rd.
max_line; i++)
2791 for (i = rd.
topline; i >= 0; i--)
2813 if (C_SearchContext < rd.extra->win_pager->state.rows)
2817 if (rd.
topline - searchctx > 0)
2824 case OP_SEARCH_TOGGLE:
2833 case OP_SORT_REVERSE:
2839 rc = OP_DISPLAY_MESSAGE;
2857 case OP_PAGER_HIDE_QUOTED:
2868 case OP_PAGER_SKIP_QUOTED:
2922 mutt_error(
_(
"No more unquoted text after quoted text"));
2928 case OP_PAGER_BOTTOM:
2949 clearok(stdscr,
true);
2961 case OP_BOUNCE_MESSAGE:
2987 case OP_COMPOSE_TO_SENDER:
3002 case OP_CHECK_TRADITIONAL:
3009 rc = OP_CHECK_TRADITIONAL;
3013 case OP_CREATE_ALIAS:
3015 struct AddressList *al = NULL;
3023 case OP_PURGE_MESSAGE:
3038 rc = OP_MAIN_NEXT_UNDELETED;
3042 case OP_MAIN_SET_FLAG:
3043 case OP_MAIN_CLEAR_FLAG:
3056 rc = OP_MAIN_NEXT_UNDELETED;
3062 case OP_DELETE_THREAD:
3063 case OP_DELETE_SUBTHREAD:
3064 case OP_PURGE_THREAD:
3074 int subthread = (ch == OP_DELETE_SUBTHREAD);
3078 if (ch == OP_PURGE_THREAD)
3089 rc = OP_MAIN_NEXT_UNDELETED;
3101 case OP_DISPLAY_ADDRESS:
3109 case OP_ENTER_COMMAND:
3131 rc = OP_REFORMAT_WINCH;
3138 case OP_FLAG_MESSAGE:
3149 rc = OP_MAIN_NEXT_UNDELETED;
3199 case OP_FORWARD_TO_GROUP:
3231 _(
"Reply by mail as poster prefers?")) !=
MUTT_YES))
3257 case OP_GROUP_REPLY:
3258 case OP_GROUP_CHAT_REPLY:
3265 if (ch == OP_GROUP_REPLY)
3267 else if (ch == OP_GROUP_CHAT_REPLY)
3269 else if (ch == OP_LIST_REPLY)
3285 case OP_RECALL_MESSAGE:
3297 case OP_FORWARD_MESSAGE:
3312 case OP_DECRYPT_SAVE:
3323 extra->
email, NULL);
3327 case OP_COPY_MESSAGE:
3328 case OP_DECODE_SAVE:
3329 case OP_DECODE_COPY:
3330 case OP_DECRYPT_COPY:
3332 if (!(
WithCrypto != 0) && (ch == OP_DECRYPT_COPY))
3341 const bool delete_original =
3342 (ch == OP_SAVE) || (ch == OP_DECODE_SAVE) || (ch == OP_DECRYPT_SAVE);
3343 const bool decode = (ch == OP_DECODE_SAVE) || (ch == OP_DECODE_COPY);
3344 const bool decrypt = (ch == OP_DECRYPT_SAVE) || (ch == OP_DECRYPT_COPY);
3352 rc = OP_MAIN_NEXT_UNDELETED;
3361 case OP_SHELL_ESCAPE:
3396 rc = OP_MAIN_NEXT_UNDELETED;
3416 case OP_UNDELETE_THREAD:
3417 case OP_UNDELETE_SUBTHREAD:
3428 (ch != OP_UNDELETE_THREAD));
3432 (ch != OP_UNDELETE_THREAD));
3438 rc = (ch == OP_DELETE_THREAD) ? OP_MAIN_NEXT_THREAD : OP_MAIN_NEXT_SUBTHREAD;
3454 case OP_MAILBOX_LIST:
3458 case OP_VIEW_ATTACHMENTS:
3462 rc = OP_ATTACH_COLLAPSE;
3502 mutt_message(ngettext(
"%d label changed",
"%d labels changed", rc), rc);
3511 case OP_FORGET_PASSPHRASE:
3515 case OP_EXTRACT_KEYS:
3535 case OP_CHECK_STATS:
3540 case OP_SIDEBAR_FIRST:
3541 case OP_SIDEBAR_LAST:
3542 case OP_SIDEBAR_NEXT:
3543 case OP_SIDEBAR_NEXT_NEW:
3544 case OP_SIDEBAR_PAGE_DOWN:
3545 case OP_SIDEBAR_PAGE_UP:
3546 case OP_SIDEBAR_PREV:
3547 case OP_SIDEBAR_PREV_NEW:
3557 case OP_SIDEBAR_TOGGLE_VISIBLE:
3577 case OP_DISPLAY_HEADERS:
3582 OldEmail = extra->
email;
3589 for (
size_t i = 0; i < rd.
max_line; i++)
3616 return (rc != -1) ? rc : 0;
int km_dokey(enum MenuType menu)
Determine what a keypress should do.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
struct Email ** emails
Array of Emails.
Convenience wrapper for the gui headers.
int mutt_save_message(struct Mailbox *m, struct EmailList *el, bool delete_original, bool decode, bool decrypt)
Save an email.
void mutt_update_index(struct Menu *menu, struct Context *ctx, int check, int oldcount, const struct Email *cur_email)
Update the index.
int mutt_thread_set_flag(struct Email *e, int flag, bool bf, bool subthread)
Set a flag on an entire thread.
enum MailboxType type
Mailbox type.
bool mutt_mailbox_list(void)
List the mailboxes with new mail.
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
int msg_count
Total number of messages.
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
#define mutt_set_flag(m, e, flag, bf)
#define SEND_TO_SENDER
Compose new email to sender.
int msg_in_pager
Message currently shown in the pager.
void mutt_pipe_message(struct Mailbox *m, struct EmailList *el)
Pipe a message.
The envelope/body of an email.
#define MUTT_CLEAR
Clear input if printable character is pressed.
WHERE bool C_DeleteUntag
Config: Untag messages when they are marked for deletion.
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
bool mutt_mb_is_display_corrupting_utf8(wchar_t wc)
Will this character corrupt the display?
struct ColorLineList body_list
List of colours applied to the email body.
void window_set_focus(struct MuttWindow *win)
Set the Window focus.
'NNTP' (Usenet) Mailbox type
Structs that make up an email.
String processing routines to generate the mail index.
The "currently-open" mailbox.
Convenience wrapper for the send headers.
void mutt_color_free(struct Colors *c, uint32_t fg, uint32_t bg)
Free a colour.
GUI manage the main index (list of emails)
#define mutt_message(...)
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
WHERE char * C_TsIconFormat
Config: printf-like format string for the terminal's icon title.
void mutt_display_address(struct Envelope *env)
Display the address of a message.
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
int pair
Curses colour pair.
int * defs
Array of all fixed colours, see enum ColorId.
void mutt_save_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct Email *e, struct Menu *menu)
Save a list of attachments.
bool attach_del
Has an attachment marked for deletion.
struct MuttWindow * mutt_window_find(struct MuttWindow *root, enum WindowType type)
Find a Window of a given type.
#define SEND_FORWARD
Forward email.
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size (CURSES)
WHERE bool OptNeedResort
(pseudo) used to force a re-sort
void index_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
Format a menu item for the index list - Implements Menu::make_entry()
void mutt_check_stats(void)
Forcibly update mailbox stats.
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
int pair
Colour pair index.
void mutt_enter_command(void)
enter a neomutt command
String manipulation buffer.
WHERE bool C_BeepNew
Config: Make a noise when new mail arrives.
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, int flags)
Read a line from a file.
int index_color(int line)
Calculate the colour for a line of the index - Implements Menu::color()
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Messages to be purged (bypass trash)
A division of the screen.
void mutt_window_move_abs(int col, int row)
Move the cursor to an absolute screen position.
WHERE bool C_BrailleFriendly
Config: Move the cursor to the beginning of the line.
Index panel (list of emails)
uint16_t SendFlags
Flags for mutt_send_message(), e.g. SEND_REPLY.
All user-callable functions.
#define SEND_POSTPONED
Recall a postponed email.
Container for Accounts, Notifications.
#define MUTT_PATTERN
Pattern mode - only used for history classes.
#define MUTT_ACL_DELETE
Delete a message.
#define mutt_get_field(field, buf, buflen, complete)
int vcount
The number of virtual messages.
Convenience wrapper for the config headers.
Menu showing log messages.
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
void mutt_print_message(struct Mailbox *m, struct EmailList *el)
Print a message.
WHERE char ProtectedHeaderMarker[256]
Unique ANSI string to mark protected headers in an email.
#define SEND_NO_FLAGS
No flags are set.
void mutt_beep(bool force)
Irritate the user.
Some miscellaneous functions.
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
AnsiFlags attr
Attributes, e.g. underline, bold, etc.
void mutt_attach_reply(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
Attach a reply.
Pager pager (email viewer)
bool tagged
Email is tagged.
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
void mutt_window_clear(struct MuttWindow *win)
Clear a Window.
Pager: empty lines after message.
void mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Parse and execute user-defined hooks.
Many unsorted constants and some structs.
bool old
Email is seen, but unread.
Message headers (takes a pattern)
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
void mutt_what_key(void)
Ask the user to press a key.
struct Envelope * env
Envelope information.
Convenience wrapper for the core headers.
void alias_create(struct AddressList *al, const struct ConfigSubset *sub)
Create a new Alias from an Address.
bool mutt_mailbox_notify(struct Mailbox *m_cur)
Notify the user if there's new mail.
WHERE char * C_StatusFormat
Config: printf-like format string for the index's status line.
void mutt_shell_escape(void)
invoke a command in a subshell
Pager: markers, line continuation.
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
#define SEND_LIST_REPLY
Reply to mailing list.
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
const char * OpStrings[][2]
void * mdata
Driver specific data.
struct ColorLineList hdr_list
List of colours applied to the email headers.
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Usenet network mailbox type; talk to an NNTP server.
#define SEND_KEY
Mail a PGP public key.
WHERE int C_ToggleQuotedShowLevels
Config: Number of quote levels to show with toggle-quoted.
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
void menu_status_line(char *buf, size_t buflen, struct Menu *menu, struct Mailbox *m, const char *p)
Create the status line.
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
void mutt_make_string_info(char *buf, size_t buflen, int cols, const char *s, struct HdrFormatInfo *hfi, MuttFormatFlags flags)
Create pager status bar string.
void mutt_refresh(void)
Force a refresh of the screen.
Side panel containing Accounts or groups of data.
Window size depends on its children.
Prototypes for many functions.
void mutt_attach_bounce(struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
Bounce function, from the attachment menu.
WHERE short C_Wrap
Config: Width to wrap text in the pager.
struct TextSyntax * search
struct WindowState state
Current state of the Window.
WHERE struct Regex * C_QuoteRegex
Config: Regex to match quoted text in a reply.
#define APPLICATION_PGP
Use PGP to encrypt/sign.
WHERE bool OptAttachMsg
(pseudo) used by attach-message
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
struct AddressList * mutt_get_address(struct Envelope *env, const char **prefix)
Get an Address from an Envelope.
bool stop_matching
Used by the pager for body patterns, to prevent the color from being retried once it fails...
struct MuttWindow * RootWindow
Parent of all Windows.
void km_error_key(enum MenuType menu)
Handle an unbound key sequence.
Status bar (takes a pattern)
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
WHERE bool C_TsEnabled
Config: Allow NeoMutt to set the terminal status line and icon.
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
WHERE char AttachmentMarker[256]
Unique ANSI string to mark PGP messages in an email.
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Nondestructive flags change (IMAP)
Manage where the email is piped to external commands.
char * dptr
Current read/write position.
const struct Mapping * help_data
Data for the Help Bar.
char * data
Pointer to data.
wchar_t ReplacementChar
When a Unicode character can't be displayed, use this instead.
A line of text in the pager.
Messages that have been read.
API for encryption/signing of emails.
int mutt_window_wrap_cols(int width, short wrap)
Calculate the wrap column for a given screen width.
bool verbose
Display status messages?
WHERE bool C_Markers
Config: Display a '+' at the beginning of wrapped lines in the pager.
int vnum
Virtual message number.
WHERE char * C_NewMailCommand
Config: External command to run when new mail arrives.
#define SEND_NEWS
Reply to a news article.
Handling of email attachments.
void dlg_select_attachment(struct Email *e)
Show the attachments in a Menu.
WHERE bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
#define STAILQ_FOREACH(var, head, field)
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
bool TsSupported
Terminal Setting is supported.
int mx_mbox_check(struct Mailbox *m)
Check for new mail - Wrapper for MxOps::mbox_check()
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
#define SEND_REPLY
Reply to sender.
NNTP-specific Mailbox data -.
WHERE char * C_TsStatusFormat
Config: printf-like format string for the terminal's status (window title)
bool CharsetIsUtf8
Is the user's current character set utf-8?
WHERE bool C_WrapSearch
Config: Wrap around when the search hits the end.
int mutt_resend_message(FILE *fp, struct Context *ctx, struct Email *e_cur, struct ConfigSubset *sub)
Resend an email.
bool mutt_strn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings (to a maximum), safely.
GUI display a user-configurable status line.
void mutt_attach_forward(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Forward an Attachment.
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
match a regex against a string, with provided options
regex_t regex
Compiled regex.
void mutt_pipe_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter)
Pipe a list of attachments to a command.
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Highlighting for a line of text.
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
void ci_bounce_message(struct Mailbox *m, struct EmailList *el)
Bounce an email.
int mutt_window_addch(int ch)
Write one character to a Window.
#define SEND_GROUP_REPLY
Reply to all.
Routines for managing attachments.
Send/reply with an attachment.
bool flagged
Marked important?
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
void mutt_help(enum MenuType menu, int wraplen)
Display the help menu.
int mutt_color_alloc(struct Colors *c, uint32_t fg, uint32_t bg)
Allocate a colour pair.
void window_set_visible(struct MuttWindow *win, bool visible)
Set a Window visible or hidden.
bool deleted
Email is deleted.
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Cached regular expression.
struct MuttWindow * parent
Parent Window.
MIME attachments text (entire line)
char * followup_to
List of 'followup-to' fields.
WHERE unsigned char C_Quit
Config: Prompt before exiting NeoMutt.
void mutt_timeout_hook(void)
Execute any timeout hooks.
int mutt_select_sort(bool reverse)
Ask the user for a sort method.
int mutt_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el, struct ConfigSubset *sub)
Send an email.
#define MUTT_EOL
don't strip \n / \r\n
Mapping between user-readable string and a constant.
void crypt_extract_keys_from_messages(struct Mailbox *m, struct EmailList *el)
Extract keys from a message.
#define MUTT_ACL_SEEN
Change the 'seen' status of a message.
#define STAILQ_HEAD_INITIALIZER(head)
void mutt_attach_mail_sender(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur)
Compose an email to the sender in the email attachment.
short req_rows
Number of rows required.
void mutt_ts_icon(char *str)
Set the icon in the terminal title bar.
struct TextSyntax * syntax
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
void mutt_show_error(void)
Show the user an error message.
struct ColorLineList attach_list
List of colours applied to the attachment headers.
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
bool changed
Mailbox has been modified.
int mutt_change_flag(struct Mailbox *m, struct EmailList *el, bool bf)
Change the flag on a Message.
void ctx_free(struct Context **ptr)
Free a Context.
Hundreds of global variables to back the user variables.
Handling of global boolean variables.
#define mutt_debug(LEVEL,...)
struct ConfigSubset * sub
Inherited config items.
New mail received in Mailbox.
void mutt_ts_status(char *str)
Set the text of the terminal title bar.
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
int el_add_tagged(struct EmailList *el, struct Context *ctx, struct Email *e, bool use_tagged)
Get a list of the tagged Emails.
Convenience wrapper for the library headers.
void mutt_curses_set_attr(int attr)
Set the attributes for text.
WHERE char * C_PagerFormat
Config: printf-like format string for the pager's status bar.
Window wants as much space as possible.
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
bool mutt_mb_is_lower(const char *s)
Does a multi-byte string contain only lowercase characters?
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
struct Email * email
header information for message/rfc822
int quotes_used
Number of colours for quoted email text.
struct MuttWindow * dialog_find(struct MuttWindow *win)
Find the parent Dialog of a Window.
void mutt_attach_resend(FILE *fp, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
int mutt_system(const char *cmd)
Run an external command.
unsigned int is_cont_hdr
this line is a continuation of the previous header line
void mutt_draw_statusline(int cols, const char *buf, size_t buflen)
Draw a highlighted status bar.
A regular expression and a color to highlight a line.
unsigned char C_FollowupToPoster
Config: (nntp) Reply to the poster if 'poster' is in the 'Followup-To' header.
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
int msgno
Number displayed to the user.
const char * mutt_make_version(void)
Generate the NeoMutt version string.
User answered 'Yes', or assume 'Yes'.
int * quotes
Array of colours for quoted email text.
unsigned char C_PostModerated
Config: (nntp) Allow posting to moderated newsgroups.
int mutt_addwch(wchar_t wc)
addwch would be provided by an up-to-date curses library
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.