NeoMutt  2018-07-16 +952-a2da0a
Teaching an old dog new tricks
DOXYGEN
enter.c File Reference

GUI ask the user to enter a string. More...

#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include "mutt/mutt.h"
#include "mutt.h"
#include "alias.h"
#include "browser.h"
#include "curs_lib.h"
#include "enter_state.h"
#include "globals.h"
#include "keymap.h"
#include "mailbox.h"
#include "mutt_curses.h"
#include "mutt_history.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "opcodes.h"
#include "protos.h"
#include "query.h"
+ Include dependency graph for enter.c:

Go to the source code of this file.

Macros

#define COMB_CHAR(wc)   (IsWPrint(wc) && !wcwidth(wc))
 

Enumerations

enum  RedrawFlags { MUTT_REDRAW_INIT = 1, MUTT_REDRAW_LINE }
 redraw flags for mutt_enter_string_full() More...
 

Functions

static int my_addwch (wchar_t wc)
 Display one wide character on screen. More...
 
static void replace_part (struct EnterState *state, size_t from, char *buf)
 Search and replace on a buffer. More...
 
struct EnterStatemutt_enter_state_new (void)
 Create a new EnterState. More...
 
int mutt_enter_string (char *buf, size_t buflen, int col, int flags)
 Ask the user for a string. More...
 
int mutt_enter_string_full (char *buf, size_t buflen, int col, int flags, bool multiple, char ***files, int *numfiles, struct EnterState *state)
 Ask the user for a string. More...
 
void mutt_enter_state_free (struct EnterState **esp)
 Free an EnterState. More...
 

Detailed Description

GUI ask the user to enter a string.

Authors
  • Michael R. Elkins
  • Edmund Grimley Evans

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 enter.c.

Macro Definition Documentation

#define COMB_CHAR (   wc)    (IsWPrint(wc) && !wcwidth(wc))

Definition at line 63 of file enter.c.

Enumeration Type Documentation

redraw flags for mutt_enter_string_full()

Enumerator
MUTT_REDRAW_INIT 

go to end of line and redraw

MUTT_REDRAW_LINE 

redraw entire line

Definition at line 56 of file enter.c.

57 {
58  MUTT_REDRAW_INIT = 1,
60 };
redraw entire line
Definition: enter.c:59
go to end of line and redraw
Definition: enter.c:58

Function Documentation

static int my_addwch ( wchar_t  wc)
static

Display one wide character on screen.

Parameters
wcCharacter to display
Return values
OKSuccess
ERRFailure

Definition at line 71 of file enter.c.

72 {
73  int n = wcwidth(wc);
74  if (IsWPrint(wc) && n > 0)
75  return mutt_addwch(wc);
76  if (!(wc & ~0x7f))
77  return printw("^%c", ((int) wc + 0x40) & 0x7f);
78  if (!(wc & ~0xffff))
79  return printw("\\u%04x", (int) wc);
80  return printw("\\u%08x", (int) wc);
81 }
#define IsWPrint(wc)
Definition: mbyte.h:41
int mutt_addwch(wchar_t wc)
addwch would be provided by an up-to-date curses library
Definition: curs_lib.c:877

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void replace_part ( struct EnterState state,
size_t  from,
char *  buf 
)
static

Search and replace on a buffer.

Parameters
stateCurrent state of the input buffer
fromStarting point for the replacement
bufReplacement string

Definition at line 89 of file enter.c.

90 {
91  /* Save the suffix */
92  size_t savelen = state->lastchar - state->curpos;
93  wchar_t *savebuf = NULL;
94 
95  if (savelen)
96  {
97  savebuf = mutt_mem_calloc(savelen, sizeof(wchar_t));
98  memcpy(savebuf, state->wbuf + state->curpos, savelen * sizeof(wchar_t));
99  }
100 
101  /* Convert to wide characters */
102  state->curpos = mutt_mb_mbstowcs(&state->wbuf, &state->wbuflen, from, buf);
103 
104  if (savelen)
105  {
106  /* Make space for suffix */
107  if (state->curpos + savelen > state->wbuflen)
108  {
109  state->wbuflen = state->curpos + savelen;
110  mutt_mem_realloc(&state->wbuf, state->wbuflen * sizeof(wchar_t));
111  }
112 
113  /* Restore suffix */
114  memcpy(state->wbuf + state->curpos, savebuf, savelen * sizeof(wchar_t));
115  FREE(&savebuf);
116  }
117 
118  state->lastchar = state->curpos + savelen;
119 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
wchar_t * wbuf
Definition: enter_state.h:33
size_t wbuflen
Definition: enter_state.h:34
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:124
size_t curpos
Definition: enter_state.h:36
size_t mutt_mb_mbstowcs(wchar_t **pwbuf, size_t *pwbuflen, size_t i, char *buf)
Convert a string from multibyte to wide characters.
Definition: mbyte.c:286
#define FREE(x)
Definition: memory.h:46
size_t lastchar
Definition: enter_state.h:35

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

struct EnterState* mutt_enter_state_new ( void  )

Create a new EnterState.

Return values
ptrNew EnterState

Definition at line 125 of file enter.c.

126 {
127  return mutt_mem_calloc(1, sizeof(struct EnterState));
128 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
Keep our place when entering a string.
Definition: enter_state.h:31

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_enter_string ( char *  buf,
size_t  buflen,
int  col,
int  flags 
)

Ask the user for a string.

Parameters
bufBuffer to store the string
buflenBuffer length
colInitial cursor position
flagsFlags such as MUTT_FILE
Return values
0if input was given
-1if abort

This function is for very basic input, currently used only by the built-in editor. It does not handle screen redrawing on resizes well, because there is no active menu for the built-in editor. Most callers should prefer mutt_get_field() instead.

Definition at line 144 of file enter.c.

145 {
146  int rc;
147  struct EnterState *es = mutt_enter_state_new();
148  do
149  {
150  if (SigWinch)
151  {
152  SigWinch = 0;
154  clearok(stdscr, TRUE);
155  }
156  rc = mutt_enter_string_full(buf, buflen, col, flags, false, NULL, NULL, es);
157  } while (rc == 1);
159  return rc;
160 }
int mutt_enter_string_full(char *buf, size_t buflen, int col, int flags, bool multiple, char ***files, int *numfiles, struct EnterState *state)
Ask the user for a string.
Definition: enter.c:176
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:98
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:91
Keep our place when entering a string.
Definition: enter_state.h:31
void mutt_enter_state_free(struct EnterState **esp)
Free an EnterState.
Definition: enter.c:806
struct EnterState * mutt_enter_state_new(void)
Create a new EnterState.
Definition: enter.c:125

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_enter_string_full ( char *  buf,
size_t  buflen,
int  col,
int  flags,
bool  multiple,
char ***  files,
int *  numfiles,
struct EnterState state 
)

Ask the user for a string.

Parameters
[in]bufBuffer to store the string
[in]buflenBuffer length
[in]colInitial cursor position
[in]flagsFlags such as MUTT_FILE
[in]multipleAllow multiple matches
[out]filesList of files selected
[out]numfilesNumber of files selected
[out]stateCurrent state (if function is called repeatedly)
Return values
1Redraw the screen and call the function again
0Selection made
-1Aborted

Definition at line 176 of file enter.c.

178 {
179  int width = MuttMessageWindow->cols - col - 1;
180  int redraw;
181  int pass = (flags & MUTT_PASS);
182  int first = 1;
183  int ch, w, r;
184  size_t i;
185  wchar_t *tempbuf = NULL;
186  size_t templen = 0;
187  enum HistoryClass hclass;
188  wchar_t wc;
189  mbstate_t mbstate;
190 
191  int rc = 0;
192  memset(&mbstate, 0, sizeof(mbstate));
193 
194  if (state->wbuf)
195  {
196  /* Coming back after return 1 */
197  redraw = MUTT_REDRAW_LINE;
198  first = 0;
199  }
200  else
201  {
202  /* Initialise wbuf from buf */
203  state->wbuflen = 0;
204  state->lastchar = mutt_mb_mbstowcs(&state->wbuf, &state->wbuflen, 0, buf);
205  redraw = MUTT_REDRAW_INIT;
206  }
207 
208  if (flags & MUTT_FILE)
209  hclass = HC_FILE;
210  else if (flags & MUTT_EFILE)
211  hclass = HC_MBOX;
212  else if (flags & MUTT_CMD)
213  hclass = HC_CMD;
214  else if (flags & MUTT_ALIAS)
215  hclass = HC_ALIAS;
216  else if (flags & MUTT_COMMAND)
217  hclass = HC_COMMAND;
218  else if (flags & MUTT_PATTERN)
219  hclass = HC_PATTERN;
220  else
221  hclass = HC_OTHER;
222 
223  while (true)
224  {
225  if (redraw && !pass)
226  {
227  if (redraw == MUTT_REDRAW_INIT)
228  {
229  /* Go to end of line */
230  state->curpos = state->lastchar;
231  state->begin = mutt_mb_width_ceiling(
232  state->wbuf, state->lastchar,
233  mutt_mb_wcswidth(state->wbuf, state->lastchar) - width + 1);
234  }
235  if (state->curpos < state->begin ||
236  mutt_mb_wcswidth(state->wbuf + state->begin, state->curpos - state->begin) >= width)
237  {
238  state->begin = mutt_mb_width_ceiling(
239  state->wbuf, state->lastchar,
240  mutt_mb_wcswidth(state->wbuf, state->curpos) - width / 2);
241  }
243  w = 0;
244  for (i = state->begin; i < state->lastchar; i++)
245  {
246  w += mutt_mb_wcwidth(state->wbuf[i]);
247  if (w > width)
248  break;
249  my_addwch(state->wbuf[i]);
250  }
253  col + mutt_mb_wcswidth(state->wbuf + state->begin,
254  state->curpos - state->begin));
255  }
256  mutt_refresh();
257 
258  ch = km_dokey(MENU_EDITOR);
259  if (ch < 0)
260  {
261  rc = (SigWinch && ch == -2) ? 1 : -1;
262  goto bye;
263  }
264 
265  if (ch != OP_NULL)
266  {
267  first = 0;
268  if (ch != OP_EDITOR_COMPLETE && ch != OP_EDITOR_COMPLETE_QUERY)
269  state->tabs = 0;
270  redraw = MUTT_REDRAW_LINE;
271  switch (ch)
272  {
273  case OP_EDITOR_HISTORY_UP:
274  state->curpos = state->lastchar;
275  if (mutt_hist_at_scratch(hclass))
276  {
277  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
278  mutt_hist_save_scratch(hclass, buf);
279  }
280  replace_part(state, 0, mutt_hist_prev(hclass));
281  redraw = MUTT_REDRAW_INIT;
282  break;
283 
284  case OP_EDITOR_HISTORY_DOWN:
285  state->curpos = state->lastchar;
286  if (mutt_hist_at_scratch(hclass))
287  {
288  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
289  mutt_hist_save_scratch(hclass, buf);
290  }
291  replace_part(state, 0, mutt_hist_next(hclass));
292  redraw = MUTT_REDRAW_INIT;
293  break;
294 
295  case OP_EDITOR_HISTORY_SEARCH:
296  state->curpos = state->lastchar;
297  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
298  mutt_hist_complete(buf, buflen, hclass);
299  replace_part(state, 0, buf);
300  rc = 1;
301  goto bye;
302  break;
303 
304  case OP_EDITOR_BACKSPACE:
305  if (state->curpos == 0)
306  BEEP();
307  else
308  {
309  i = state->curpos;
310  while (i && COMB_CHAR(state->wbuf[i - 1]))
311  i--;
312  if (i)
313  i--;
314  memmove(state->wbuf + i, state->wbuf + state->curpos,
315  (state->lastchar - state->curpos) * sizeof(wchar_t));
316  state->lastchar -= state->curpos - i;
317  state->curpos = i;
318  }
319  break;
320 
321  case OP_EDITOR_BOL:
322  state->curpos = 0;
323  break;
324 
325  case OP_EDITOR_EOL:
326  redraw = MUTT_REDRAW_INIT;
327  break;
328 
329  case OP_EDITOR_KILL_LINE:
330  state->curpos = 0;
331  state->lastchar = 0;
332  break;
333 
334  case OP_EDITOR_KILL_EOL:
335  state->lastchar = state->curpos;
336  break;
337 
338  case OP_EDITOR_BACKWARD_CHAR:
339  if (state->curpos == 0)
340  BEEP();
341  else
342  {
343  while (state->curpos && COMB_CHAR(state->wbuf[state->curpos - 1]))
344  state->curpos--;
345  if (state->curpos)
346  state->curpos--;
347  }
348  break;
349 
350  case OP_EDITOR_FORWARD_CHAR:
351  if (state->curpos == state->lastchar)
352  BEEP();
353  else
354  {
355  state->curpos++;
356  while (state->curpos < state->lastchar &&
357  COMB_CHAR(state->wbuf[state->curpos]))
358  {
359  state->curpos++;
360  }
361  }
362  break;
363 
364  case OP_EDITOR_BACKWARD_WORD:
365  if (state->curpos == 0)
366  BEEP();
367  else
368  {
369  while (state->curpos && iswspace(state->wbuf[state->curpos - 1]))
370  state->curpos--;
371  while (state->curpos && !iswspace(state->wbuf[state->curpos - 1]))
372  state->curpos--;
373  }
374  break;
375 
376  case OP_EDITOR_FORWARD_WORD:
377  if (state->curpos == state->lastchar)
378  BEEP();
379  else
380  {
381  while (state->curpos < state->lastchar && iswspace(state->wbuf[state->curpos]))
382  state->curpos++;
383  while (state->curpos < state->lastchar &&
384  !iswspace(state->wbuf[state->curpos]))
385  {
386  state->curpos++;
387  }
388  }
389  break;
390 
391  case OP_EDITOR_CAPITALIZE_WORD:
392  case OP_EDITOR_UPCASE_WORD:
393  case OP_EDITOR_DOWNCASE_WORD:
394  if (state->curpos == state->lastchar)
395  {
396  BEEP();
397  break;
398  }
399  while (state->curpos && !iswspace(state->wbuf[state->curpos]))
400  state->curpos--;
401  while (state->curpos < state->lastchar && iswspace(state->wbuf[state->curpos]))
402  state->curpos++;
403  while (state->curpos < state->lastchar && !iswspace(state->wbuf[state->curpos]))
404  {
405  if (ch == OP_EDITOR_DOWNCASE_WORD)
406  state->wbuf[state->curpos] = towlower(state->wbuf[state->curpos]);
407  else
408  {
409  state->wbuf[state->curpos] = towupper(state->wbuf[state->curpos]);
410  if (ch == OP_EDITOR_CAPITALIZE_WORD)
411  ch = OP_EDITOR_DOWNCASE_WORD;
412  }
413  state->curpos++;
414  }
415  break;
416 
417  case OP_EDITOR_DELETE_CHAR:
418  if (state->curpos == state->lastchar)
419  BEEP();
420  else
421  {
422  i = state->curpos;
423  while (i < state->lastchar && COMB_CHAR(state->wbuf[i]))
424  i++;
425  if (i < state->lastchar)
426  i++;
427  while (i < state->lastchar && COMB_CHAR(state->wbuf[i]))
428  i++;
429  memmove(state->wbuf + state->curpos, state->wbuf + i,
430  (state->lastchar - i) * sizeof(wchar_t));
431  state->lastchar -= i - state->curpos;
432  }
433  break;
434 
435  case OP_EDITOR_KILL_WORD:
436  /* delete to beginning of word */
437  if (state->curpos != 0)
438  {
439  i = state->curpos;
440  while (i && iswspace(state->wbuf[i - 1]))
441  i--;
442  if (i)
443  {
444  if (iswalnum(state->wbuf[i - 1]))
445  {
446  for (--i; (i > 0) && iswalnum(state->wbuf[i - 1]); i--)
447  ;
448  }
449  else
450  i--;
451  }
452  memmove(state->wbuf + i, state->wbuf + state->curpos,
453  (state->lastchar - state->curpos) * sizeof(wchar_t));
454  state->lastchar += i - state->curpos;
455  state->curpos = i;
456  }
457  break;
458 
459  case OP_EDITOR_KILL_EOW:
460  /* delete to end of word */
461 
462  /* first skip over whitespace */
463  for (i = state->curpos; (i < state->lastchar) && iswspace(state->wbuf[i]); i++)
464  ;
465 
466  /* if there are any characters left.. */
467  if (i < state->lastchar)
468  {
469  /* if the current character is alphanumeric.. */
470  if (iswalnum(state->wbuf[i]))
471  {
472  /* skip over the rest of the word consistent of only alphanumerics */
473  for (; (i < state->lastchar) && iswalnum(state->wbuf[i]); i++)
474  ;
475  }
476  else
477  {
478  /* skip over one non-alphanumeric character */
479  i++;
480  }
481  }
482 
483  memmove(state->wbuf + state->curpos, state->wbuf + i,
484  (state->lastchar - i) * sizeof(wchar_t));
485  state->lastchar += state->curpos - i;
486  break;
487 
488  case OP_EDITOR_MAILBOX_CYCLE:
489  if (flags & MUTT_EFILE)
490  {
491  first = 1; /* clear input if user types a real key later */
492  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
493  mutt_mailbox(buf, buflen);
494  state->curpos = state->lastchar =
495  mutt_mb_mbstowcs(&state->wbuf, &state->wbuflen, 0, buf);
496  break;
497  }
498  else if (!(flags & MUTT_FILE))
499  {
500  goto self_insert;
501  }
502  /* fallthrough */
503 
504  case OP_EDITOR_COMPLETE:
505  case OP_EDITOR_COMPLETE_QUERY:
506  state->tabs++;
507  if (flags & MUTT_CMD)
508  {
509  for (i = state->curpos;
510  (i > 0) && !mutt_mb_is_shell_char(state->wbuf[i - 1]); i--)
511  {
512  }
513  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
514  if (tempbuf && templen == state->lastchar - i &&
515  !memcmp(tempbuf, state->wbuf + i, (state->lastchar - i) * sizeof(wchar_t)))
516  {
517  mutt_select_file(buf, buflen,
518  (flags & MUTT_EFILE) ? MUTT_SEL_FOLDER : 0, NULL, NULL);
519  if (*buf)
520  replace_part(state, i, buf);
521  rc = 1;
522  goto bye;
523  }
524  if (mutt_complete(buf, buflen) == 0)
525  {
526  templen = state->lastchar - i;
527  mutt_mem_realloc(&tempbuf, templen * sizeof(wchar_t));
528  }
529  else
530  BEEP();
531 
532  replace_part(state, i, buf);
533  }
534  else if (flags & MUTT_ALIAS && ch == OP_EDITOR_COMPLETE)
535  {
536  /* invoke the alias-menu to get more addresses */
537  for (i = state->curpos;
538  (i > 0) && (state->wbuf[i - 1] != ',') && (state->wbuf[i - 1] != ':'); i--)
539  {
540  }
541  for (; (i < state->lastchar) && (state->wbuf[i] == ' '); i++)
542  ;
543  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
544  r = mutt_alias_complete(buf, buflen);
545  replace_part(state, i, buf);
546  if (!r)
547  {
548  rc = 1;
549  goto bye;
550  }
551  break;
552  }
553  else if (flags & MUTT_LABEL && ch == OP_EDITOR_COMPLETE)
554  {
555  for (i = state->curpos;
556  (i > 0) && (state->wbuf[i - 1] != ',') && (state->wbuf[i - 1] != ':'); i--)
557  {
558  }
559  for (; (i < state->lastchar) && (state->wbuf[i] == ' '); i++)
560  ;
561  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
562  r = mutt_label_complete(buf, buflen, state->tabs);
563  replace_part(state, i, buf);
564  if (!r)
565  {
566  rc = 1;
567  goto bye;
568  }
569  break;
570  }
571  else if (flags & MUTT_PATTERN && ch == OP_EDITOR_COMPLETE)
572  {
573  for (i = state->curpos; (i > 0) && (state->wbuf[i - 1] != '~'); i--)
574  ;
575  if ((i > 0) && (i < state->curpos) && (state->wbuf[i - 1] == '~') &&
576  (state->wbuf[i] == 'y'))
577  {
578  i++;
579  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
580  r = mutt_label_complete(buf, buflen, state->tabs);
581  replace_part(state, i, buf);
582  if (!r)
583  {
584  rc = 1;
585  goto bye;
586  }
587  }
588  else
589  goto self_insert;
590  break;
591  }
592  else if (flags & MUTT_ALIAS && ch == OP_EDITOR_COMPLETE_QUERY)
593  {
594  i = state->curpos;
595  if (i != 0)
596  {
597  for (; (i > 0) && (state->wbuf[i - 1] != ','); i--)
598  ;
599  for (; (i < state->curpos) && (state->wbuf[i] == ' '); i++)
600  ;
601  }
602 
603  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
604  mutt_query_complete(buf, buflen);
605  replace_part(state, i, buf);
606 
607  rc = 1;
608  goto bye;
609  }
610  else if (flags & MUTT_COMMAND)
611  {
612  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
613  i = strlen(buf);
614  if (i && buf[i - 1] == '=' && mutt_var_value_complete(buf, buflen, i))
615  state->tabs = 0;
616  else if (!mutt_command_complete(buf, buflen, i, state->tabs))
617  BEEP();
618  replace_part(state, 0, buf);
619  }
620  else if (flags & (MUTT_FILE | MUTT_EFILE))
621  {
622  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
623 
624  /* see if the path has changed from the last time */
625  if ((!tempbuf && !state->lastchar) ||
626  (tempbuf && templen == state->lastchar &&
627  !memcmp(tempbuf, state->wbuf, state->lastchar * sizeof(wchar_t))))
628  {
629  mutt_select_file(buf, buflen,
630  ((flags & MUTT_EFILE) ? MUTT_SEL_FOLDER : 0) |
631  (multiple ? MUTT_SEL_MULTI : 0),
632  files, numfiles);
633  if (*buf)
634  {
635  mutt_pretty_mailbox(buf, buflen);
636  if (!pass)
637  mutt_hist_add(hclass, buf, true);
638  rc = 0;
639  goto bye;
640  }
641 
642  /* file selection cancelled */
643  rc = 1;
644  goto bye;
645  }
646 
647  if (mutt_complete(buf, buflen) == 0)
648  {
649  templen = state->lastchar;
650  mutt_mem_realloc(&tempbuf, templen * sizeof(wchar_t));
651  memcpy(tempbuf, state->wbuf, templen * sizeof(wchar_t));
652  }
653  else
654  BEEP(); /* let the user know that nothing matched */
655  replace_part(state, 0, buf);
656  }
657 #ifdef USE_NOTMUCH
658  else if (flags & MUTT_NM_QUERY)
659  {
660  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
661  i = strlen(buf);
662  if (!mutt_nm_query_complete(buf, buflen, i, state->tabs))
663  BEEP();
664 
665  replace_part(state, 0, buf);
666  }
667  else if (flags & MUTT_NM_TAG)
668  {
669  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
670  if (!mutt_nm_tag_complete(buf, buflen, state->tabs))
671  BEEP();
672 
673  replace_part(state, 0, buf);
674  }
675 
676 #endif
677  else
678  goto self_insert;
679  break;
680 
681  case OP_EDITOR_QUOTE_CHAR:
682  {
683  struct Event event;
684  do
685  {
686  event = mutt_getch();
687  } while (event.ch == -2);
688  if (event.ch >= 0)
689  {
690  LastKey = event.ch;
691  goto self_insert;
692  }
693  }
694  break;
695 
696  case OP_EDITOR_TRANSPOSE_CHARS:
697  if (state->lastchar < 2)
698  BEEP();
699  else
700  {
701  wchar_t t;
702 
703  if (state->curpos == 0)
704  state->curpos = 2;
705  else if (state->curpos < state->lastchar)
706  state->curpos++;
707 
708  t = state->wbuf[state->curpos - 2];
709  state->wbuf[state->curpos - 2] = state->wbuf[state->curpos - 1];
710  state->wbuf[state->curpos - 1] = t;
711  }
712  break;
713 
714  default:
715  BEEP();
716  }
717  }
718  else
719  {
720  self_insert:
721 
722  state->tabs = 0;
723  /* use the raw keypress */
724  ch = LastKey;
725 
726  /* quietly ignore all other function keys */
727  if (ch & ~0xff)
728  continue;
729 
730  /* gather the octets into a wide character */
731  {
732  char c;
733  size_t k;
734 
735  c = ch;
736  k = mbrtowc(&wc, &c, 1, &mbstate);
737  if (k == (size_t)(-2))
738  continue;
739  else if (k && k != 1)
740  {
741  memset(&mbstate, 0, sizeof(mbstate));
742  continue;
743  }
744  }
745 
746  if (first && (flags & MUTT_CLEAR))
747  {
748  first = 0;
749  if (IsWPrint(wc)) /* why? */
750  {
751  state->curpos = 0;
752  state->lastchar = 0;
753  }
754  }
755 
756  if (wc == '\r' || wc == '\n')
757  {
758  /* Convert from wide characters */
759  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->lastchar);
760  if (!pass)
761  mutt_hist_add(hclass, buf, true);
762 
763  if (multiple)
764  {
765  char **tfiles = NULL;
766  *numfiles = 1;
767  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
768  mutt_expand_path(buf, buflen);
769  tfiles[0] = mutt_str_strdup(buf);
770  *files = tfiles;
771  }
772  rc = 0;
773  goto bye;
774  }
775  else if (wc && (wc < ' ' || IsWPrint(wc))) /* why? */
776  {
777  if (state->lastchar >= state->wbuflen)
778  {
779  state->wbuflen = state->lastchar + 20;
780  mutt_mem_realloc(&state->wbuf, state->wbuflen * sizeof(wchar_t));
781  }
782  memmove(state->wbuf + state->curpos + 1, state->wbuf + state->curpos,
783  (state->lastchar - state->curpos) * sizeof(wchar_t));
784  state->wbuf[state->curpos++] = wc;
785  state->lastchar++;
786  }
787  else
788  {
789  mutt_flushinp();
790  BEEP();
791  }
792  }
793  }
794 
795 bye:
796 
797  mutt_hist_reset_state(hclass);
798  FREE(&tempbuf);
799  return rc;
800 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
wchar_t * wbuf
Definition: enter_state.h:33
#define MUTT_CLEAR
clear input if printable character is pressed
Definition: mutt.h:63
Miscellaneous strings.
Definition: history.h:48
char * mutt_hist_next(enum HistoryClass hclass)
Get the next string in a History.
Definition: history.c:517
#define MUTT_ALIAS
do alias "completion" by calling up the alias-menu
Definition: mutt.h:58
#define IsWPrint(wc)
Definition: mbyte.h:41
int km_dokey(int menu)
Determine what a keypress should do.
Definition: keymap.c:572
NeoMutt commands.
Definition: history.h:45
HistoryClass
Type to differentiate different histories.
Definition: history.h:41
void mutt_pretty_mailbox(char *s, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:606
void mutt_select_file(char *file, size_t filelen, int flags, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:1087
void mutt_hist_complete(char *buf, size_t buflen, enum HistoryClass hclass)
Complete a string from a history list.
Definition: mutt_history.c:132
int mutt_label_complete(char *buf, size_t buflen, int numtabs)
Complete a label name.
Definition: init.c:3423
#define MUTT_LABEL
do label completion
Definition: mutt.h:66
void mutt_mailbox(char *s, size_t slen)
incoming folders completion routine
Definition: mailbox.c:693
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:81
void mutt_hist_add(enum HistoryClass hclass, const char *str, bool save)
Add a string to a history.
Definition: history.c:479
size_t wbuflen
Definition: enter_state.h:34
bool mutt_nm_tag_complete(char *buf, size_t buflen, int numtabs)
Complete to the nearest notmuch tag.
Definition: init.c:3545
#define MUTT_NM_QUERY
Notmuch query mode.
Definition: mutt.h:67
Mailboxes.
Definition: history.h:49
int mutt_command_complete(char *buf, size_t buflen, int pos, int numtabs)
Complete a command name.
Definition: init.c:3253
size_t mutt_mb_width_ceiling(const wchar_t *s, size_t n, int w1)
Keep the end of the string on-screen.
Definition: mbyte.c:214
bool mutt_nm_query_complete(char *buf, size_t buflen, int pos, int numtabs)
Complete to the nearest notmuch tag.
Definition: init.c:3487
External commands.
Definition: history.h:43
#define MUTT_PATTERN
pattern mode - only used for history classes
Definition: mutt.h:65
#define MUTT_SEL_FOLDER
Definition: browser.h:42
An event such as a keypress.
Definition: mutt_curses.h:107
void mutt_mb_wcstombs(char *dest, size_t dlen, const wchar_t *src, size_t slen)
Convert a string from wide to multibyte characters.
Definition: mbyte.c:231
Aliases.
Definition: history.h:44
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:157
#define MUTT_NM_TAG
Notmuch tag +/- mode.
Definition: mutt.h:68
int LastKey
contains the last key the user pressed
Definition: keymap.c:144
int mutt_mb_wcswidth(const wchar_t *s, size_t n)
Measure the screen width of a string.
Definition: mbyte.c:196
#define MUTT_COMMAND
do command completion
Definition: mutt.h:64
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:91
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:124
Patterns.
Definition: history.h:47
#define MUTT_CMD
do completion on previous word
Definition: mutt.h:61
size_t begin
Definition: enter_state.h:37
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:99
#define MUTT_PASS
password mode (no echo)
Definition: mutt.h:62
struct Event mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:180
bool mutt_hist_at_scratch(enum HistoryClass hclass)
Is the current History position at the &#39;scratch&#39; place?
Definition: history.c:635
#define BEEP()
Definition: mutt_curses.h:79
void mutt_hist_save_scratch(enum HistoryClass hclass, const char *str)
Save a temporary string to the History.
Definition: history.c:653
int mutt_query_complete(char *buf, size_t buflen)
Perform auto-complete using an Address Query.
Definition: query.c:564
static int my_addwch(wchar_t wc)
Display one wide character on screen.
Definition: enter.c:71
size_t curpos
Definition: enter_state.h:36
int mutt_alias_complete(char *buf, size_t buflen)
alias completion routine
Definition: alias.c:597
#define COMB_CHAR(wc)
Definition: enter.c:63
static void replace_part(struct EnterState *state, size_t from, char *buf)
Search and replace on a buffer.
Definition: enter.c:89
Text entry area.
Definition: keymap.h:70
#define MUTT_SEL_MULTI
Definition: browser.h:41
#define MUTT_FILE
do file completion
Definition: mutt.h:59
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:162
char * mutt_hist_prev(enum HistoryClass hclass)
Get the previous string in a History.
Definition: history.c:545
int mutt_complete(char *buf, size_t buflen)
Attempt to complete a partial pathname.
Definition: complete.c:57
bool mutt_mb_is_shell_char(wchar_t ch)
Is character not typically part of a pathname.
Definition: mbyte.c:332
size_t mutt_mb_mbstowcs(wchar_t **pwbuf, size_t *pwbuflen, size_t i, char *buf)
Convert a string from multibyte to wide characters.
Definition: mbyte.c:286
#define MUTT_EFILE
do file completion, plus incoming folders
Definition: mutt.h:60
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:384
redraw entire line
Definition: enter.c:59
go to end of line and redraw
Definition: enter.c:58
#define FREE(x)
Definition: memory.h:46
int ch
raw key pressed
Definition: mutt_curses.h:109
int mutt_mb_wcwidth(wchar_t wc)
Measure the screen width of a character.
Definition: mbyte.c:178
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
void mutt_hist_reset_state(enum HistoryClass hclass)
Move the &#39;current&#39; position to the end of the History.
Definition: history.c:573
size_t lastchar
Definition: enter_state.h:35
Files.
Definition: history.h:46
int mutt_var_value_complete(char *buf, size_t buflen, int pos)
Complete a variable/value.
Definition: init.c:3599

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_enter_state_free ( struct EnterState **  esp)

Free an EnterState.

Parameters
espEnterState to free

Definition at line 806 of file enter.c.

807 {
808  if (!esp)
809  return;
810 
811  FREE(&(*esp)->wbuf);
812  FREE(esp);
813 }
#define FREE(x)
Definition: memory.h:46

+ Here is the caller graph for this function: