NeoMutt  2019-11-11
Teaching an old dog new tricks
DOXYGEN
edit.c File Reference

GUI basic built-in text editor. More...

#include "config.h"
#include <ctype.h>
#include <errno.h>
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "mutt/mutt.h"
#include "address/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "mutt.h"
#include "alias.h"
#include "context.h"
#include "curs_lib.h"
#include "globals.h"
#include "hdrline.h"
#include "mutt_curses.h"
#include "mutt_header.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "protos.h"
+ Include dependency graph for edit.c:

Go to the source code of this file.

Functions

static char ** be_snarf_data (FILE *fp, char **buf, int *bufmax, int *buflen, LOFF_T offset, int bytes, int prefix)
 Read data from a file into a buffer. More...
 
static char ** be_snarf_file (const char *path, char **buf, int *max, int *len, bool verbose)
 Read a file into a buffer. More...
 
static int be_barf_file (const char *path, char **buf, int buflen)
 Write a buffer to a file. More...
 
static void be_free_memory (char **buf, int buflen)
 Free an array of buffers. More...
 
static char ** be_include_messages (char *msg, char **buf, int *bufmax, int *buflen, int pfx, int inc_hdrs)
 Gather the contents of some messages. More...
 
static void be_print_header (struct Envelope *env)
 Print a message Header. More...
 
static void be_edit_header (struct Envelope *e, bool force)
 Edit the message headers. More...
 
int mutt_builtin_editor (const char *path, struct Email *e_new, struct Email *e_cur)
 Show the user the built-in editor. More...
 

Variables

char * C_Escape
 Config: Escape character to use for functions in the built-in editor. More...
 
static char * EditorHelp1
 
static char * EditorHelp2
 

Detailed Description

GUI basic built-in text editor.

Authors
  • Michael R. Elkins
  • 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 edit.c.

Function Documentation

◆ be_snarf_data()

static char** be_snarf_data ( FILE *  fp,
char **  buf,
int *  bufmax,
int *  buflen,
LOFF_T  offset,
int  bytes,
int  prefix 
)
static

Read data from a file into a buffer.

Parameters
[in]fpFile to read from
[out]bufBuffer allocated to save data
[out]bufmaxAllocated size of buffer
[out]buflenBytes of buffer used
[in]offsetStart reading at this file offset
[in]bytesRead this many bytes
[in]prefixIf true, prefix the lines with the C_IndentString
Return values
ptrPointer to allocated buffer

Definition at line 95 of file edit.c.

97 {
98  char tmp[8192];
99  char *p = tmp;
100  int tmplen = sizeof(tmp);
101 
102  tmp[sizeof(tmp) - 1] = '\0';
103  if (prefix)
104  {
105  mutt_str_strfcpy(tmp, C_IndentString, sizeof(tmp));
106  tmplen = mutt_str_strlen(tmp);
107  p = tmp + tmplen;
108  tmplen = sizeof(tmp) - tmplen;
109  }
110 
111  fseeko(fp, offset, SEEK_SET);
112  while (bytes > 0)
113  {
114  if (!fgets(p, tmplen - 1, fp))
115  break;
116  bytes -= mutt_str_strlen(p);
117  if (*bufmax == *buflen)
118  mutt_mem_realloc(&buf, sizeof(char *) * (*bufmax += 25));
119  buf[(*buflen)++] = mutt_str_strdup(tmp);
120  }
121  if (buf && (*bufmax == *buflen))
122  { /* Do not smash memory past buf */
123  mutt_mem_realloc(&buf, sizeof(char *) * (++*bufmax));
124  }
125  if (buf)
126  buf[*buflen] = NULL;
127  return buf;
128 }
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:137
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ be_snarf_file()

static char** be_snarf_file ( const char *  path,
char **  buf,
int *  max,
int *  len,
bool  verbose 
)
static

Read a file into a buffer.

Parameters
[in]pathFile to read
[out]bufBuffer allocated to save data
[out]maxAllocated size of buffer
[out]lenBytes of buffer used
[in]verboseIf true, report the file and bytes read
Return values
ptrPointer to allocated buffer

Definition at line 139 of file edit.c.

140 {
141  char tmp[1024];
142  struct stat sb;
143 
144  FILE *fp = fopen(path, "r");
145  if (fp)
146  {
147  fstat(fileno(fp), &sb);
148  buf = be_snarf_data(fp, buf, max, len, 0, sb.st_size, 0);
149  if (verbose)
150  {
151  snprintf(tmp, sizeof(tmp), "\"%s\" %lu bytes\n", path, (unsigned long) sb.st_size);
152  mutt_window_addstr(tmp);
153  }
154  mutt_file_fclose(&fp);
155  }
156  else
157  {
158  snprintf(tmp, sizeof(tmp), "%s: %s\n", path, strerror(errno));
159  mutt_window_addstr(tmp);
160  }
161  return buf;
162 }
static char ** be_snarf_data(FILE *fp, char **buf, int *bufmax, int *buflen, LOFF_T offset, int bytes, int prefix)
Read data from a file into a buffer.
Definition: edit.c:95
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ be_barf_file()

static int be_barf_file ( const char *  path,
char **  buf,
int  buflen 
)
static

Write a buffer to a file.

Parameters
[in]pathPath to write to
[out]bufBuffer to read from
[in]buflenLength of buffer
Return values
0Success
-1Error

Definition at line 172 of file edit.c.

173 {
174  FILE *fp = fopen(path, "w");
175  if (!fp)
176  {
177  mutt_window_addstr(strerror(errno));
178  mutt_window_addch('\n');
179  return -1;
180  }
181  for (int i = 0; i < buflen; i++)
182  fputs(buf[i], fp);
183  if (fclose(fp) == 0)
184  return 0;
185  mutt_window_printf("fclose: %s\n", strerror(errno));
186  return -1;
187 }
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:424
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:366
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ be_free_memory()

static void be_free_memory ( char **  buf,
int  buflen 
)
static

Free an array of buffers.

Parameters
[out]bufBuffer to free
[in]buflenNumber of buffers to free

Definition at line 194 of file edit.c.

195 {
196  while (buflen-- > 0)
197  FREE(&buf[buflen]);
198  FREE(&buf);
199 }
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

◆ be_include_messages()

static char** be_include_messages ( char *  msg,
char **  buf,
int *  bufmax,
int *  buflen,
int  pfx,
int  inc_hdrs 
)
static

Gather the contents of some messages.

Parameters
[in]msgList of message numbers (space or comma separated)
[out]bufBuffer allocated to save data
[out]bufmaxAllocated size of buffer
[out]buflenBytes of buffer used
[in]pfxPrefix
[in]inc_hdrsIf true, include the message headers
Return values
ptrPointer to allocated buffer

Definition at line 211 of file edit.c.

213 {
214  int n;
215  // int offset, bytes;
216  char tmp[1024];
217 
218  if (!msg || !buf || !bufmax || !buflen)
219  return buf;
220 
221  while ((msg = strtok(msg, " ,")))
222  {
223  if ((mutt_str_atoi(msg, &n) == 0) && (n > 0) && (n <= Context->mailbox->msg_count))
224  {
225  n--;
226 
227  /* add the attribution */
228  if (C_Attribution)
229  {
230  setlocale(LC_TIME, NONULL(C_AttributionLocale));
231  mutt_make_string(tmp, sizeof(tmp) - 1, 0, C_Attribution, Context,
233  setlocale(LC_TIME, "");
234  strcat(tmp, "\n");
235  }
236 
237  if (*bufmax == *buflen)
238  mutt_mem_realloc(&buf, sizeof(char *) * (*bufmax += 25));
239  buf[(*buflen)++] = mutt_str_strdup(tmp);
240 
241 #if 0
242  /* This only worked for mbox Mailboxes because they had Context->fp set.
243  * As that no longer exists, the code is now completely broken. */
244  bytes = Context->mailbox->emails[n]->content->length;
245  if (inc_hdrs)
246  {
247  offset = Context->mailbox->emails[n]->offset;
248  bytes += Context->mailbox->emails[n]->content->offset - offset;
249  }
250  else
251  offset = Context->mailbox->emails[n]->content->offset;
252  buf = be_snarf_data(Context->fp, buf, bufmax, buflen, offset, bytes, pfx);
253 #endif
254 
255  if (*bufmax == *buflen)
256  mutt_mem_realloc(&buf, sizeof(char *) * (*bufmax += 25));
257  buf[(*buflen)++] = mutt_str_strdup("\n");
258  }
259  else
260  mutt_window_printf(_("%d: invalid message number.\n"), n);
261  msg = NULL;
262  }
263  return buf;
264 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:37
int mutt_str_atoi(const char *str, int *dst)
Convert ASCII string to an integer.
Definition: string.c:262
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:100
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
struct Body * content
List of MIME parts.
Definition: email.h:90
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
static char ** be_snarf_data(FILE *fp, char **buf, int *bufmax, int *buflen, LOFF_T offset, int bytes, int prefix)
Read data from a file into a buffer.
Definition: edit.c:95
struct Mailbox * mailbox
Definition: context.h:50
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:83
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:424
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
WHERE char * C_Attribution
Config: Message to start a reply, "On DATE, PERSON wrote:".
Definition: globals.h:99
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ be_print_header()

static void be_print_header ( struct Envelope env)
static

Print a message Header.

Parameters
envEnvelope to print

Definition at line 270 of file edit.c.

271 {
272  char tmp[8192];
273 
274  if (!TAILQ_EMPTY(&env->to))
275  {
276  mutt_window_addstr("To: ");
277  tmp[0] = '\0';
278  mutt_addrlist_write(tmp, sizeof(tmp), &env->to, true);
279  mutt_window_addstr(tmp);
280  mutt_window_addch('\n');
281  }
282  if (!TAILQ_EMPTY(&env->cc))
283  {
284  mutt_window_addstr("Cc: ");
285  tmp[0] = '\0';
286  mutt_addrlist_write(tmp, sizeof(tmp), &env->cc, true);
287  mutt_window_addstr(tmp);
288  mutt_window_addch('\n');
289  }
290  if (!TAILQ_EMPTY(&env->bcc))
291  {
292  mutt_window_addstr("Bcc: ");
293  tmp[0] = '\0';
294  mutt_addrlist_write(tmp, sizeof(tmp), &env->bcc, true);
295  mutt_window_addstr(tmp);
296  mutt_window_addch('\n');
297  }
298  if (env->subject)
299  {
300  mutt_window_addstr("Subject: ");
302  mutt_window_addch('\n');
303  }
304  mutt_window_addch('\n');
305 }
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1137
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:366
char * subject
Email&#39;s subject.
Definition: envelope.h:66
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
#define TAILQ_EMPTY(head)
Definition: queue.h:715
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ be_edit_header()

static void be_edit_header ( struct Envelope e,
bool  force 
)
static

Edit the message headers.

Parameters
eEmail
forceoverride the $ask* vars (used for the ~h command)

Definition at line 312 of file edit.c.

313 {
314  char tmp[8192];
315 
317 
318  mutt_window_addstr("To: ");
319  tmp[0] = '\0';
321  mutt_addrlist_write(tmp, sizeof(tmp), &e->to, false);
322  if (TAILQ_EMPTY(&e->to) || force)
323  {
324  if (mutt_enter_string(tmp, sizeof(tmp), 4, MUTT_COMP_NO_FLAGS) == 0)
325  {
326  mutt_addrlist_clear(&e->to);
327  mutt_addrlist_parse2(&e->to, tmp);
328  mutt_expand_aliases(&e->to);
329  mutt_addrlist_to_intl(&e->to, NULL); /* XXX - IDNA error reporting? */
330  tmp[0] = '\0';
331  mutt_addrlist_write(tmp, sizeof(tmp), &e->to, true);
333  }
334  }
335  else
336  {
337  mutt_addrlist_to_intl(&e->to, NULL); /* XXX - IDNA error reporting? */
338  mutt_window_addstr(tmp);
339  }
340  mutt_window_addch('\n');
341 
342  if (!e->subject || force)
343  {
344  mutt_window_addstr("Subject: ");
345  mutt_str_strfcpy(tmp, e->subject ? e->subject : "", sizeof(tmp));
346  if (mutt_enter_string(tmp, sizeof(tmp), 9, MUTT_COMP_NO_FLAGS) == 0)
347  mutt_str_replace(&e->subject, tmp);
348  mutt_window_addch('\n');
349  }
350 
351  if ((TAILQ_EMPTY(&e->cc) && C_Askcc) || force)
352  {
353  mutt_window_addstr("Cc: ");
354  tmp[0] = '\0';
356  mutt_addrlist_write(tmp, sizeof(tmp), &e->cc, false);
357  if (mutt_enter_string(tmp, sizeof(tmp), 4, MUTT_COMP_NO_FLAGS) == 0)
358  {
359  mutt_addrlist_clear(&e->cc);
360  mutt_addrlist_parse2(&e->cc, tmp);
361  mutt_expand_aliases(&e->cc);
362  tmp[0] = '\0';
363  mutt_addrlist_to_intl(&e->cc, NULL);
364  mutt_addrlist_write(tmp, sizeof(tmp), &e->cc, true);
366  }
367  else
368  mutt_addrlist_to_intl(&e->cc, NULL);
369  mutt_window_addch('\n');
370  }
371 
372  if (C_Askbcc || force)
373  {
374  mutt_window_addstr("Bcc: ");
375  tmp[0] = '\0';
377  mutt_addrlist_write(tmp, sizeof(tmp), &e->bcc, false);
378  if (mutt_enter_string(tmp, sizeof(tmp), 5, MUTT_COMP_NO_FLAGS) == 0)
379  {
381  mutt_addrlist_parse2(&e->bcc, tmp);
383  mutt_addrlist_to_intl(&e->bcc, NULL);
384  tmp[0] = '\0';
385  mutt_addrlist_write(tmp, sizeof(tmp), &e->bcc, true);
387  }
388  else
389  mutt_addrlist_to_intl(&e->bcc, NULL);
390  mutt_window_addch('\n');
391  }
392 }
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:303
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1298
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1381
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1137
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:606
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:62
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:212
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:198
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:366
char * subject
Email&#39;s subject.
Definition: envelope.h:66
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1216
int mutt_enter_string(char *buf, size_t buflen, int col, CompletionFlags flags)
Ask the user for a string.
Definition: enter.c:146
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
#define TAILQ_EMPTY(head)
Definition: queue.h:715
WHERE bool C_Askbcc
Config: Ask the user for the blind-carbon-copy recipients.
Definition: globals.h:200
WHERE bool C_Askcc
Config: Ask the user for the carbon-copy recipients.
Definition: globals.h:201
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_builtin_editor()

int mutt_builtin_editor ( const char *  path,
struct Email e_new,
struct Email e_cur 
)

Show the user the built-in editor.

Parameters
pathFile to read
e_newNew Email
e_curCurrent Email
Return values
0Success
-1Error

Definition at line 402 of file edit.c.

403 {
404  char **buf = NULL;
405  int bufmax = 0, buflen = 0;
406  char tmp[1024];
407  bool abort = false;
408  bool done = false;
409  char *p = NULL;
410 
411  scrollok(stdscr, true);
412 
413  be_edit_header(e_new->env, false);
414 
415  mutt_window_addstr(_("(End message with a . on a line by itself)\n"));
416 
417  buf = be_snarf_file(path, buf, &bufmax, &buflen, false);
418 
419  tmp[0] = '\0';
420  while (!done)
421  {
422  if (mutt_enter_string(tmp, sizeof(tmp), 0, MUTT_COMP_NO_FLAGS) == -1)
423  {
424  tmp[0] = '\0';
425  continue;
426  }
427  mutt_window_addch('\n');
428 
429  if (C_Escape && (tmp[0] == C_Escape[0]) && (tmp[1] != C_Escape[0]))
430  {
431  /* remove trailing whitespace from the line */
432  p = tmp + mutt_str_strlen(tmp) - 1;
433  while ((p >= tmp) && IS_SPACE(*p))
434  *p-- = '\0';
435 
436  p = tmp + 2;
437  SKIPWS(p);
438 
439  switch (tmp[1])
440  {
441  case '?':
444  break;
445  case 'b':
446  mutt_addrlist_parse2(&e_new->env->bcc, p);
447  mutt_expand_aliases(&e_new->env->bcc);
448  break;
449  case 'c':
450  mutt_addrlist_parse2(&e_new->env->cc, p);
451  mutt_expand_aliases(&e_new->env->cc);
452  break;
453  case 'h':
454  be_edit_header(e_new->env, true);
455  break;
456  case 'F':
457  case 'f':
458  case 'm':
459  case 'M':
460  if (Context)
461  {
462  if (!*p && e_cur)
463  {
464  /* include the current message */
465  p = tmp + mutt_str_strlen(tmp) + 1;
466  snprintf(tmp + mutt_str_strlen(tmp),
467  sizeof(tmp) - mutt_str_strlen(tmp), " %d", e_cur->msgno + 1);
468  }
469  buf = be_include_messages(p, buf, &bufmax, &buflen, (tolower(tmp[1]) == 'm'),
470  (isupper((unsigned char) tmp[1])));
471  }
472  else
473  mutt_window_addstr(_("No mailbox.\n"));
474  break;
475  case 'p':
476  mutt_window_addstr("-----\n");
477  mutt_window_addstr(_("Message contains:\n"));
478  be_print_header(e_new->env);
479  for (int i = 0; i < buflen; i++)
480  mutt_window_addstr(buf[i]);
481  /* L10N: This entry is shown AFTER the message content,
482  not IN the middle of the content.
483  So it doesn't mean "(message will continue)"
484  but means "(press any key to continue using neomutt)". */
485  mutt_window_addstr(_("(continue)\n"));
486  break;
487  case 'q':
488  done = true;
489  break;
490  case 'r':
491  if (*p)
492  {
493  mutt_str_strfcpy(tmp, p, sizeof(tmp));
494  mutt_expand_path(tmp, sizeof(tmp));
495  buf = be_snarf_file(tmp, buf, &bufmax, &buflen, true);
496  }
497  else
498  mutt_window_addstr(_("missing filename.\n"));
499  break;
500  case 's':
501  mutt_str_replace(&e_new->env->subject, p);
502  break;
503  case 't':
504  mutt_addrlist_parse(&e_new->env->to, p);
505  mutt_expand_aliases(&e_new->env->to);
506  break;
507  case 'u':
508  if (buflen)
509  {
510  buflen--;
511  mutt_str_strfcpy(tmp, buf[buflen], sizeof(tmp));
512  tmp[mutt_str_strlen(tmp) - 1] = '\0';
513  FREE(&buf[buflen]);
514  buf[buflen] = NULL;
515  continue;
516  }
517  else
518  mutt_window_addstr(_("No lines in message.\n"));
519  break;
520 
521  case 'e':
522  case 'v':
523  if (be_barf_file(path, buf, buflen) == 0)
524  {
525  const char *tag = NULL;
526  char *err = NULL;
527  be_free_memory(buf, buflen);
528  buf = NULL;
529  bufmax = 0;
530  buflen = 0;
531 
532  if (C_EditHeaders)
533  {
534  mutt_env_to_local(e_new->env);
535  mutt_edit_headers(NONULL(C_Visual), path, e_new, NULL);
536  if (mutt_env_to_intl(e_new->env, &tag, &err))
537  mutt_window_printf(_("Bad IDN in '%s': '%s'"), tag, err);
538  /* tag is a statically allocated string and should not be freed */
539  FREE(&err);
540  }
541  else
543 
544  buf = be_snarf_file(path, buf, &bufmax, &buflen, false);
545 
546  mutt_window_addstr(_("(continue)\n"));
547  }
548  break;
549  case 'w':
550  be_barf_file((p[0] != '\0') ? p : path, buf, buflen);
551  break;
552  case 'x':
553  abort = true;
554  done = true;
555  break;
556  default:
557  mutt_window_printf(_("%s: unknown editor command (~? for help)\n"), tmp);
558  break;
559  }
560  }
561  else if (mutt_str_strcmp(".", tmp) == 0)
562  done = true;
563  else
564  {
565  mutt_str_strcat(tmp, sizeof(tmp), "\n");
566  if (buflen == bufmax)
567  mutt_mem_realloc(&buf, sizeof(char *) * (bufmax += 25));
568  buf[buflen++] = mutt_str_strdup((tmp[1] == '~') ? tmp + 1 : tmp);
569  }
570 
571  tmp[0] = '\0';
572  }
573 
574  if (!abort)
575  be_barf_file(path, buf, buflen);
576  be_free_memory(buf, buflen);
577 
578  return abort ? -1 : 0;
579 }
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:37
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:303
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:457
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
#define _(a)
Definition: message.h:28
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:606
int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
Convert an Envelope&#39;s Address fields to Punycode format.
Definition: envelope.c:309
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:134
static void be_edit_header(struct Envelope *e, bool force)
Edit the message headers.
Definition: edit.c:312
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:215
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:62
struct Envelope * env
Envelope information.
Definition: email.h:89
#define SKIPWS(ch)
Definition: string2.h:47
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
static char ** be_snarf_file(const char *path, char **buf, int *max, int *len, bool verbose)
Read a file into a buffer.
Definition: edit.c:139
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
static char ** be_include_messages(char *msg, char **buf, int *bufmax, int *buflen, int pfx, int inc_hdrs)
Gather the contents of some messages.
Definition: edit.c:211
#define IS_SPACE(ch)
Definition: string2.h:38
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:395
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope&#39;s Address fields to local format.
Definition: envelope.c:271
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:424
void mutt_edit_headers(const char *editor, const char *body, struct Email *e, struct Buffer *fcc)
Let the user edit the message header and body.
Definition: mutt_header.c:167
static char * EditorHelp2
Definition: edit.c:73
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:366
char * C_Escape
Config: Escape character to use for functions in the built-in editor.
Definition: edit.c:57
char * subject
Email&#39;s subject.
Definition: envelope.h:66
static void be_print_header(struct Envelope *env)
Print a message Header.
Definition: edit.c:270
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
int mutt_enter_string(char *buf, size_t buflen, int col, CompletionFlags flags)
Ask the user for a string.
Definition: enter.c:146
#define FREE(x)
Definition: memory.h:40
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:351
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
static int be_barf_file(const char *path, char **buf, int buflen)
Write a buffer to a file.
Definition: edit.c:172
int msgno
Number displayed to the user.
Definition: email.h:86
WHERE char * C_Visual
Config: Editor to use when &#39;~v&#39; is given in the built-in editor.
Definition: globals.h:150
static char * EditorHelp1
Definition: edit.c:62
static void be_free_memory(char **buf, int buflen)
Free an array of buffers.
Definition: edit.c:194
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_Escape

char* C_Escape

Config: Escape character to use for functions in the built-in editor.

Definition at line 57 of file edit.c.

◆ EditorHelp1

char* EditorHelp1
static
Initial value:
=
N_("~~ insert a line beginning with a single ~\n"
"~b users add users to the Bcc: field\n"
"~c users add users to the Cc: field\n"
"~f messages include messages\n"
"~F messages same as ~f, except also include headers\n"
"~h edit the message header\n"
"~m messages include and quote messages\n"
"~M messages same as ~m, except include headers\n"
"~p print the message\n")
#define N_(a)
Definition: message.h:32

Definition at line 62 of file edit.c.

◆ EditorHelp2

char* EditorHelp2
static
Initial value:
=
N_("~q write file and quit editor\n"
"~r file read a file into the editor\n"
"~t users add users to the To: field\n"
"~u recall the previous line\n"
"~v edit message with the $visual editor\n"
"~w file write message to file\n"
"~x abort changes and quit editor\n"
"~? this message\n"
". on a line by itself ends input\n")
#define N_(a)
Definition: message.h:32

Definition at line 73 of file edit.c.