NeoMutt  2020-06-26-30-g76c339
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/lib.h"
#include "address/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "edit.h"
#include "context.h"
#include "globals.h"
#include "hdrline.h"
#include "mutt_header.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 94 of file edit.c.

96 {
97  char tmp[8192];
98  char *p = tmp;
99  int tmplen = sizeof(tmp);
100 
101  tmp[sizeof(tmp) - 1] = '\0';
102  if (prefix)
103  {
104  mutt_str_copy(tmp, C_IndentString, sizeof(tmp));
105  tmplen = mutt_str_len(tmp);
106  p = tmp + tmplen;
107  tmplen = sizeof(tmp) - tmplen;
108  }
109 
110  fseeko(fp, offset, SEEK_SET);
111  while (bytes > 0)
112  {
113  if (!fgets(p, tmplen - 1, fp))
114  break;
115  bytes -= mutt_str_len(p);
116  if (*bufmax == *buflen)
117  mutt_mem_realloc(&buf, sizeof(char *) * (*bufmax += 25));
118  buf[(*buflen)++] = mutt_str_dup(tmp);
119  }
120  if (buf && (*bufmax == *buflen))
121  { /* Do not smash memory past buf */
122  mutt_mem_realloc(&buf, sizeof(char *) * (++*bufmax));
123  }
124  if (buf)
125  buf[*buflen] = NULL;
126  return buf;
127 }
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:131
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
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_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:639
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:724
+ 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 138 of file edit.c.

139 {
140  char tmp[1024];
141  struct stat sb;
142 
143  FILE *fp = fopen(path, "r");
144  if (fp)
145  {
146  fstat(fileno(fp), &sb);
147  buf = be_snarf_data(fp, buf, max, len, 0, sb.st_size, 0);
148  if (verbose)
149  {
150  snprintf(tmp, sizeof(tmp), "\"%s\" %lu bytes\n", path, (unsigned long) sb.st_size);
151  mutt_window_addstr(tmp);
152  }
153  mutt_file_fclose(&fp);
154  }
155  else
156  {
157  snprintf(tmp, sizeof(tmp), "%s: %s\n", path, strerror(errno));
158  mutt_window_addstr(tmp);
159  }
160  return buf;
161 }
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:94
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:521
+ 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 171 of file edit.c.

172 {
173  FILE *fp = fopen(path, "w");
174  if (!fp)
175  {
176  mutt_window_addstr(strerror(errno));
177  mutt_window_addch('\n');
178  return -1;
179  }
180  for (int i = 0; i < buflen; i++)
181  fputs(buf[i], fp);
182  if (mutt_file_fclose(&fp) == 0)
183  return 0;
184  mutt_window_printf("fclose: %s\n", strerror(errno));
185  return -1;
186 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:549
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:491
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:521
+ 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 193 of file edit.c.

194 {
195  while (buflen-- > 0)
196  FREE(&buf[buflen]);
197  FREE(&buf);
198 }
#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 210 of file edit.c.

212 {
213  int n;
214  // int offset, bytes;
215  char tmp[1024];
216 
217  if (!msg || !buf || !bufmax || !buflen)
218  return buf;
219 
220  while ((msg = strtok(msg, " ,")))
221  {
222  if ((mutt_str_atoi(msg, &n) == 0) && (n > 0) && (n <= Context->mailbox->msg_count))
223  {
224  n--;
225 
226  /* add the attribution */
227  if (C_Attribution)
228  {
229  setlocale(LC_TIME, NONULL(C_AttributionLocale));
230  mutt_make_string(tmp, sizeof(tmp) - 1, 0, C_Attribution, Context,
232  setlocale(LC_TIME, "");
233  strcat(tmp, "\n");
234  }
235 
236  if (*bufmax == *buflen)
237  mutt_mem_realloc(&buf, sizeof(char *) * (*bufmax += 25));
238  buf[(*buflen)++] = mutt_str_dup(tmp);
239 
240 #if 0
241  /* This only worked for mbox Mailboxes because they had Context->fp set.
242  * As that no longer exists, the code is now completely broken. */
243  bytes = Context->mailbox->emails[n]->content->length;
244  if (inc_hdrs)
245  {
246  offset = Context->mailbox->emails[n]->offset;
247  bytes += Context->mailbox->emails[n]->content->offset - offset;
248  }
249  else
250  offset = Context->mailbox->emails[n]->content->offset;
251  buf = be_snarf_data(Context->fp, buf, bufmax, buflen, offset, bytes, pfx);
252 #endif
253 
254  if (*bufmax == *buflen)
255  mutt_mem_realloc(&buf, sizeof(char *) * (*bufmax += 25));
256  buf[(*buflen)++] = mutt_str_dup("\n");
257  }
258  else
259  mutt_window_printf(_("%d: invalid message number.\n"), n);
260  msg = NULL;
261  }
262  return buf;
263 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
The "current" mailbox.
Definition: context.h:37
#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:257
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:98
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:59
struct Body * content
List of MIME parts.
Definition: email.h:90
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
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:94
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:549
int n
Definition: acutest.h:492
WHERE char * C_Attribution
Config: Message to start a reply, "On DATE, PERSON wrote:".
Definition: globals.h:97
+ 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 269 of file edit.c.

270 {
271  char tmp[8192];
272 
273  if (!TAILQ_EMPTY(&env->to))
274  {
275  mutt_window_addstr("To: ");
276  tmp[0] = '\0';
277  mutt_addrlist_write(&env->to, tmp, sizeof(tmp), true);
278  mutt_window_addstr(tmp);
279  mutt_window_addch('\n');
280  }
281  if (!TAILQ_EMPTY(&env->cc))
282  {
283  mutt_window_addstr("Cc: ");
284  tmp[0] = '\0';
285  mutt_addrlist_write(&env->cc, tmp, sizeof(tmp), true);
286  mutt_window_addstr(tmp);
287  mutt_window_addch('\n');
288  }
289  if (!TAILQ_EMPTY(&env->bcc))
290  {
291  mutt_window_addstr("Bcc: ");
292  tmp[0] = '\0';
293  mutt_addrlist_write(&env->bcc, tmp, sizeof(tmp), true);
294  mutt_window_addstr(tmp);
295  mutt_window_addch('\n');
296  }
297  if (env->subject)
298  {
299  mutt_window_addstr("Subject: ");
301  mutt_window_addch('\n');
302  }
303  mutt_window_addch('\n');
304 }
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
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:491
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:521
#define TAILQ_EMPTY(head)
Definition: queue.h:714
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1147
+ 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 311 of file edit.c.

312 {
313  char tmp[8192];
314 
316 
317  mutt_window_addstr("To: ");
318  tmp[0] = '\0';
320  mutt_addrlist_write(&e->to, tmp, sizeof(tmp), false);
321  if (TAILQ_EMPTY(&e->to) || force)
322  {
323  if (mutt_enter_string(tmp, sizeof(tmp), 4, MUTT_COMP_NO_FLAGS) == 0)
324  {
325  mutt_addrlist_clear(&e->to);
326  mutt_addrlist_parse2(&e->to, tmp);
327  mutt_expand_aliases(&e->to);
328  mutt_addrlist_to_intl(&e->to, NULL); /* XXX - IDNA error reporting? */
329  tmp[0] = '\0';
330  mutt_addrlist_write(&e->to, tmp, sizeof(tmp), true);
332  }
333  }
334  else
335  {
336  mutt_addrlist_to_intl(&e->to, NULL); /* XXX - IDNA error reporting? */
337  mutt_window_addstr(tmp);
338  }
339  mutt_window_addch('\n');
340 
341  if (!e->subject || force)
342  {
343  mutt_window_addstr("Subject: ");
344  mutt_str_copy(tmp, e->subject ? e->subject : "", sizeof(tmp));
345  if (mutt_enter_string(tmp, sizeof(tmp), 9, MUTT_COMP_NO_FLAGS) == 0)
346  mutt_str_replace(&e->subject, tmp);
347  mutt_window_addch('\n');
348  }
349 
350  if ((TAILQ_EMPTY(&e->cc) && C_Askcc) || force)
351  {
352  mutt_window_addstr("Cc: ");
353  tmp[0] = '\0';
355  mutt_addrlist_write(&e->cc, tmp, sizeof(tmp), false);
356  if (mutt_enter_string(tmp, sizeof(tmp), 4, MUTT_COMP_NO_FLAGS) == 0)
357  {
358  mutt_addrlist_clear(&e->cc);
359  mutt_addrlist_parse2(&e->cc, tmp);
360  mutt_expand_aliases(&e->cc);
361  tmp[0] = '\0';
362  mutt_addrlist_to_intl(&e->cc, NULL);
363  mutt_addrlist_write(&e->cc, tmp, sizeof(tmp), true);
365  }
366  else
367  mutt_addrlist_to_intl(&e->cc, NULL);
368  mutt_window_addch('\n');
369  }
370 
371  if (C_Askbcc || force)
372  {
373  mutt_window_addstr("Bcc: ");
374  tmp[0] = '\0';
376  mutt_addrlist_write(&e->bcc, tmp, sizeof(tmp), false);
377  if (mutt_enter_string(tmp, sizeof(tmp), 5, MUTT_COMP_NO_FLAGS) == 0)
378  {
380  mutt_addrlist_parse2(&e->bcc, tmp);
382  mutt_addrlist_to_intl(&e->bcc, NULL);
383  tmp[0] = '\0';
384  mutt_addrlist_write(&e->bcc, tmp, sizeof(tmp), true);
386  }
387  else
388  mutt_addrlist_to_intl(&e->bcc, NULL);
389  mutt_window_addch('\n');
390  }
391 }
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:295
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1332
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:1414
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:616
int mutt_window_mvaddstr(struct MuttWindow *win, int col, int row, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:379
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:365
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:450
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:491
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:1250
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:724
int mutt_enter_string(char *buf, size_t buflen, int col, CompletionFlags flags)
Ask the user for a string.
Definition: enter.c:145
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:46
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:521
#define TAILQ_EMPTY(head)
Definition: queue.h:714
WHERE bool C_Askbcc
Config: Ask the user for the blind-carbon-copy recipients.
Definition: globals.h:192
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1147
WHERE bool C_Askcc
Config: Ask the user for the carbon-copy recipients.
Definition: globals.h:193
+ 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 401 of file edit.c.

402 {
403  char **buf = NULL;
404  int bufmax = 0, buflen = 0;
405  char tmp[1024];
406  bool abort = false;
407  bool done = false;
408  char *p = NULL;
409 
410  scrollok(stdscr, true);
411 
412  be_edit_header(e_new->env, false);
413 
414  mutt_window_addstr(_("(End message with a . on a line by itself)\n"));
415 
416  buf = be_snarf_file(path, buf, &bufmax, &buflen, false);
417 
418  tmp[0] = '\0';
419  while (!done)
420  {
421  if (mutt_enter_string(tmp, sizeof(tmp), 0, MUTT_COMP_NO_FLAGS) == -1)
422  {
423  tmp[0] = '\0';
424  continue;
425  }
426  mutt_window_addch('\n');
427 
428  if (C_Escape && (tmp[0] == C_Escape[0]) && (tmp[1] != C_Escape[0]))
429  {
430  /* remove trailing whitespace from the line */
431  p = tmp + mutt_str_len(tmp) - 1;
432  while ((p >= tmp) && IS_SPACE(*p))
433  *p-- = '\0';
434 
435  p = tmp + 2;
436  SKIPWS(p);
437 
438  switch (tmp[1])
439  {
440  case '?':
443  break;
444  case 'b':
445  mutt_addrlist_parse2(&e_new->env->bcc, p);
446  mutt_expand_aliases(&e_new->env->bcc);
447  break;
448  case 'c':
449  mutt_addrlist_parse2(&e_new->env->cc, p);
450  mutt_expand_aliases(&e_new->env->cc);
451  break;
452  case 'h':
453  be_edit_header(e_new->env, true);
454  break;
455  case 'F':
456  case 'f':
457  case 'm':
458  case 'M':
459  if (Context)
460  {
461  if ((*p == '\0') && e_cur)
462  {
463  /* include the current message */
464  p = tmp + mutt_str_len(tmp) + 1;
465  snprintf(tmp + mutt_str_len(tmp), sizeof(tmp) - mutt_str_len(tmp),
466  " %d", e_cur->msgno + 1);
467  }
468  buf = be_include_messages(p, buf, &bufmax, &buflen, (tolower(tmp[1]) == 'm'),
469  (isupper((unsigned char) tmp[1])));
470  }
471  else
472  mutt_window_addstr(_("No mailbox.\n"));
473  break;
474  case 'p':
475  mutt_window_addstr("-----\n");
476  mutt_window_addstr(_("Message contains:\n"));
477  be_print_header(e_new->env);
478  for (int i = 0; i < buflen; i++)
479  mutt_window_addstr(buf[i]);
480  /* L10N: This entry is shown AFTER the message content,
481  not IN the middle of the content. So it doesn't mean "(message
482  will continue)" but means "(press any key to continue using
483  neomutt)". */
484  mutt_window_addstr(_("(continue)\n"));
485  break;
486  case 'q':
487  done = true;
488  break;
489  case 'r':
490  if (*p)
491  {
492  struct Buffer *filename = mutt_buffer_pool_get();
493  mutt_buffer_strcpy(filename, p);
494  mutt_buffer_expand_path(filename);
495  buf = be_snarf_file(mutt_b2s(filename), buf, &bufmax, &buflen, true);
496  mutt_buffer_pool_release(&filename);
497  }
498  else
499  mutt_window_addstr(_("missing filename.\n"));
500  break;
501  case 's':
502  mutt_str_replace(&e_new->env->subject, p);
503  break;
504  case 't':
505  mutt_addrlist_parse(&e_new->env->to, p);
506  mutt_expand_aliases(&e_new->env->to);
507  break;
508  case 'u':
509  if (buflen)
510  {
511  buflen--;
512  mutt_str_copy(tmp, buf[buflen], sizeof(tmp));
513  tmp[mutt_str_len(tmp) - 1] = '\0';
514  FREE(&buf[buflen]);
515  buf[buflen] = NULL;
516  continue;
517  }
518  else
519  mutt_window_addstr(_("No lines in message.\n"));
520  break;
521 
522  case 'e':
523  case 'v':
524  if (be_barf_file(path, buf, buflen) != 0)
525  break;
526 
527  const char *tag = NULL;
528  char *err = NULL;
529  be_free_memory(buf, buflen);
530  buf = NULL;
531  bufmax = 0;
532  buflen = 0;
533 
534  if (C_EditHeaders)
535  {
536  mutt_env_to_local(e_new->env);
537  mutt_edit_headers(NONULL(C_Visual), path, e_new, NULL);
538  if (mutt_env_to_intl(e_new->env, &tag, &err))
539  mutt_window_printf(_("Bad IDN in '%s': '%s'"), tag, err);
540  /* tag is a statically allocated string and should not be freed */
541  FREE(&err);
542  }
543  else
545 
546  buf = be_snarf_file(path, buf, &bufmax, &buflen, false);
547 
548  mutt_window_addstr(_("(continue)\n"));
549  break;
550  case 'w':
551  be_barf_file((p[0] != '\0') ? p : path, buf, buflen);
552  break;
553  case 'x':
554  abort = true;
555  done = true;
556  break;
557  default:
558  mutt_window_printf(_("%s: unknown editor command (~? for help)\n"), tmp);
559  break;
560  }
561  }
562  else if (mutt_str_equal(".", tmp))
563  done = true;
564  else
565  {
566  mutt_str_cat(tmp, sizeof(tmp), "\n");
567  if (buflen == bufmax)
568  mutt_mem_realloc(&buf, sizeof(char *) * (bufmax += 25));
569  buf[buflen++] = mutt_str_dup((tmp[1] == '~') ? tmp + 1 : tmp);
570  }
571 
572  tmp[0] = '\0';
573  }
574 
575  if (!abort)
576  be_barf_file(path, buf, buflen);
577  be_free_memory(buf, buflen);
578 
579  return abort ? -1 : 0;
580 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
The "current" mailbox.
Definition: context.h:37
#define NONULL(x)
Definition: string2.h:37
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:295
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
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
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:616
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
static void be_edit_header(struct Envelope *e, bool force)
Edit the message headers.
Definition: edit.c:311
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:207
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
struct Envelope * env
Envelope information.
Definition: email.h:89
#define SKIPWS(ch)
Definition: string2.h:46
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
#define mutt_b2s(buf)
Definition: buffer.h:41
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:138
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:450
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
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:210
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:390
#define IS_SPACE(ch)
Definition: string2.h:38
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:549
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:168
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:639
static char * EditorHelp2
Definition: edit.c:72
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:491
char * C_Escape
Config: Escape character to use for functions in the built-in editor.
Definition: edit.c:56
char * subject
Email&#39;s subject.
Definition: envelope.h:66
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:327
static void be_print_header(struct Envelope *env)
Print a message Header.
Definition: edit.c:269
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:724
int mutt_enter_string(char *buf, size_t buflen, int col, CompletionFlags flags)
Ask the user for a string.
Definition: enter.c:145
#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:521
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:353
static int be_barf_file(const char *path, char **buf, int buflen)
Write a buffer to a file.
Definition: edit.c:171
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:144
static char * EditorHelp1
Definition: edit.c:61
static void be_free_memory(char **buf, int buflen)
Free an array of buffers.
Definition: edit.c:193
+ 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 56 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 61 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 72 of file edit.c.