Print a line on screen.
1063{
1064 unsigned char *buf = NULL, *fmt = NULL;
1065 size_t buflen = 0;
1066 unsigned char *buf_ptr = NULL;
1067 int ch, vch, col, cnt, b_read;
1068 int buf_ready = 0;
1069 bool change_last = false;
1070 int special;
1071 int offset;
1072 const struct AttrColor *def_color = NULL;
1073 int m;
1074 int rc = -1;
1076 regmatch_t pmatch[1] = { 0 };
1077
1080
1082 {
1083 (*lines_used)++;
1084 change_last = true;
1085 }
1086
1088 {
1092 {
1093 memset(&((*
lines)[ch]), 0,
sizeof(
struct Line));
1094 (*lines)[ch].cid = -1;
1095 (*lines)[ch].search_arr_size = -1;
1097 ((*lines)[ch].syntax)[0].
first = -1;
1098 ((*lines)[ch].syntax)[0].last = -1;
1099 }
1100 }
1101
1102 struct Line *
const cur_line = &(*lines)[line_num];
1103
1105 {
1106
1107 if (
fill_buffer(fp, bytes_read, cur_line->
offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1108 {
1109 if (change_last)
1110 (*lines_used)--;
1111 goto out;
1112 }
1113
1114 if ((cur_line->
cont_line) && (line_num > 0))
1115 {
1116 struct Line *
const old_line = &(*lines)[line_num - 1];
1117 cur_line->
cid = old_line->
cid;
1119 }
1120 else
1121 {
1124 if ((blen > 11) && (buf[11] == 'M'))
1126 else if ((blen > 11) && (buf[11] == 'W'))
1128 else if ((blen > 11) && (buf[11] == 'E'))
1130 else
1132 }
1133 }
1134
1135
1137 {
1138 if (cur_line->
cid == -1)
1139 {
1140
1141 if (
fill_buffer(fp, bytes_read, cur_line->
offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1142 {
1143 if (change_last)
1144 (*lines_used)--;
1145 goto out;
1146 }
1147
1149 {
1150 resolve_types(win_pager, (
char *) fmt, (
char *) buf, *lines, line_num, *lines_used,
1152 }
1153 else
1154 {
1156 }
1157
1158
1159 for (m = line_num + 1;
1160 m < *lines_used && (*lines)[m].offset && (*lines)[m].cont_line; m++)
1161 {
1162 (*lines)[m].cid = cur_line->
cid;
1163 }
1164 }
1165
1166
1169 (!cur_line->
quote || (cur_line->
quote->
quote_n >= c_toggle_quoted_show_levels)))
1170 {
1171 flags = 0;
1172 }
1173 }
1174
1175
1176
1177
1178
1179
1182 {
1183 if (
fill_buffer(fp, bytes_read, cur_line->
offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1184 {
1185 if (change_last)
1186 (*lines_used)--;
1187 goto out;
1188 }
1189
1192 {
1194 pmatch[0].rm_eo - pmatch[0].rm_so,
1195 force_redraw, q_level);
1196 }
1197 else
1198 {
1199 goto out;
1200 }
1201 }
1202
1204 {
1205 if (
fill_buffer(fp, bytes_read, cur_line->
offset, &buf, &fmt, &buflen, &buf_ready) < 0)
1206 {
1207 if (change_last)
1208 (*lines_used)--;
1209 goto out;
1210 }
1211
1212 offset = 0;
1214 while (regexec(search_re, (char *) fmt + offset, 1, pmatch,
1215 (offset ? REG_NOTBOL : 0)) == 0)
1216 {
1218 {
1220
1223 memset(ts, 0, sizeof(*ts));
1224 }
1225 else
1226 {
1228 }
1229 pmatch[0].rm_so += offset;
1230 pmatch[0].rm_eo += offset;
1233
1234 if (pmatch[0].rm_eo == pmatch[0].rm_so)
1235 offset++;
1236 else
1237 offset = pmatch[0].rm_eo;
1238 if (!fmt[offset])
1239 break;
1240 }
1241 }
1242
1243 if (!(flags &
MUTT_SHOW) && ((*lines)[line_num + 1].offset > 0))
1244 {
1245
1246 rc = 0;
1247 goto out;
1248 }
1249 if ((flags &
MUTT_SHOWCOLOR) && *force_redraw && ((*lines)[line_num + 1].offset > 0))
1250 {
1251
1252 rc = 1;
1253 goto out;
1254 }
1255
1256 b_read =
fill_buffer(fp, bytes_read, cur_line->
offset, &buf, &fmt, &buflen, &buf_ready);
1257 if (b_read < 0)
1258 {
1259 if (change_last)
1260 (*lines_used)--;
1261 goto out;
1262 }
1263
1264
1265 cnt =
format_line(win_pager, lines, line_num, buf, flags, NULL, b_read, &ch,
1266 &vch, &col, &special, win_pager->
state.
cols, ansi_list);
1267 buf_ptr = buf + cnt;
1268
1269
1271 if (c_smart_wrap)
1272 {
1275 {
1276 buf_ptr = buf + ch;
1277
1278 while (ch && ((buf[ch] == ' ') || (buf[ch] == '\t') || (buf[ch] == '\r')))
1279 ch--;
1280
1281
1282
1283 if (ch == 0)
1284 buf_ptr = buf + cnt;
1285 else
1286 cnt = ch + 1;
1287 }
1288
1289
1290 while ((*buf_ptr == ' ') || (*buf_ptr == '\t'))
1291 buf_ptr++;
1292 }
1293
1294 if (*buf_ptr == '\r')
1295 buf_ptr++;
1296 if (*buf_ptr == '\n')
1297 buf_ptr++;
1298
1299 if (((int) (buf_ptr - buf) < b_read) && !(*lines)[line_num + 1].cont_line)
1300 append_line(*lines, line_num, (
int) (buf_ptr - buf));
1301 (*lines)[line_num + 1].offset = cur_line->
offset + (long) (buf_ptr - buf);
1302
1303
1305 {
1306 rc = 0;
1307 goto out;
1308 }
1309
1311 {
1314 }
1315
1316
1317 format_line(win_pager, lines, line_num, buf, flags, &ansi, cnt, &ch, &vch,
1318 &col, &special, win_pager->
state.
cols, ansi_list);
1319
1320
1321 if (col == 0)
1322 {
1324 {
1327 }
1328 else
1329 {
1331 }
1332
1334 }
1335
1336
1337
1338
1340 {
1343 {
1344 def_color = ((*lines)[m].syntax)[0].
attr_color;
1345 }
1346 else
1347 {
1349 }
1352 if (def_color)
1354 else
1355 ac_eol = ac_normal;
1357 }
1358
1359 if (col < win_pager->state.cols)
1360 {
1362 {
1368 }
1369 else
1370 {
1371
1374 }
1376 }
1377
1378
1379
1380
1383
1384
1386 flags = 0;
1387
1388 rc = flags;
1389
1390out:
1393 return rc;
1394}
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
ColorId
List of all coloured objects.
@ MT_COLOR_MESSAGE
Informational message.
@ MT_COLOR_HEADER
Message headers (takes a pattern)
@ MT_COLOR_STRIPE_EVEN
Stripes: even lines of the Help Page.
@ MT_COLOR_ERROR
Error message.
@ MT_COLOR_NORMAL
Plain text.
@ MT_COLOR_STRIPE_ODD
Stripes: odd lines of the Help Page.
@ MT_COLOR_WARNING
Warning messages.
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
bool mutt_isspace(int arg)
Wrapper for isspace(3)
static int format_line(struct MuttWindow *win, struct Line **lines, int line_num, unsigned char *buf, PagerFlags flags, struct AnsiColor *ansi, int cnt, int *pspace, int *pvch, int *pcol, int *pspecial, int width, struct AttrColorList *ansi_list)
Display a line of text in the pager.
static int fill_buffer(FILE *fp, LOFF_T *bytes_read, LOFF_T offset, unsigned char **buf, unsigned char **fmt, size_t *blen, int *buf_ready)
Fill a buffer from a file.
bool color_is_header(enum ColorId cid)
Colour is for an Email header.
static void resolve_types(struct MuttWindow *win, char *buf, char *raw, struct Line *lines, int line_num, int lines_used, struct QuoteStyle **quote_list, int *q_level, bool *force_redraw, bool q_classify)
Determine the style for a line of text.
static void append_line(struct Line *lines, int line_num, int cnt)
Add a new Line to the array.
#define FREE(x)
Free memory and set the pointer to NULL.
#define MUTT_MEM_CALLOC(n, type)
#define MUTT_MEM_REALLOC(pptr, n, type)
const struct AttrColor * merged_color_overlay(const struct AttrColor *base, const struct AttrColor *over)
Combine two colours.
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.
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
const struct AttrColor * mutt_curses_set_normal_backed_color_by_id(enum ColorId cid)
Set the colour and attributes by the Colour ID.
const struct AttrColor * mutt_curses_set_color_by_id(enum ColorId cid)
Set the colour and attributes by the Colour ID.
void mutt_curses_set_color(const struct AttrColor *ac)
Set the colour and attributes for text.
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
struct QuoteStyle * qstyle_classify(struct QuoteStyle **quote_list, const char *qptr, size_t length, bool *force_redraw, int *q_level)
Find a style for a string.
#define COLOR_QUOTED(cid)
A curses colour and its attributes.
A line of text in the pager.
short search_arr_size
Number of items in search array.
struct TextSyntax * search
Array of search text in the line.
bool cont_line
Continuation of a previous line (wrapped by NeoMutt)
short cid
Default line colour, e.g. MT_COLOR_SIGNATURE.
struct QuoteStyle * quote
Quoting style for this line (pointer into PagerPrivateData->quote_list)
LOFF_T offset
Offset into Email file (PagerPrivateData->fp)
struct TextSyntax * syntax
Array of coloured text in the line.
struct WindowState state
Current state of the Window.
void * wdata
Private data.
struct MuttWindow * parent
Parent Window.
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.
int quote_n
The quoteN colour index for this level.
Cached regular expression.
Highlighting for a piece of text.
const struct AttrColor * attr_color
Curses colour of text.
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.