NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
enter.c File Reference
#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include "mutt/lib.h"
#include "core/neomutt.h"
#include "alias/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "history/lib.h"
#include "pattern/lib.h"
#include "browser.h"
#include "context.h"
#include "enter_state.h"
#include "init.h"
#include "keymap.h"
#include "mutt_globals.h"
#include "mutt_history.h"
#include "mutt_mailbox.h"
#include "muttlib.h"
#include "opcodes.h"
#include "protos.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  EnterRedrawFlags { ENTER_REDRAW_NONE = 0, ENTER_REDRAW_INIT, ENTER_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, CompletionFlags flags)
 Ask the user for a string. More...
 
int mutt_enter_string_full (char *buf, size_t buflen, int col, CompletionFlags flags, bool multiple, struct Mailbox *m, char ***files, int *numfiles, struct EnterState *state)
 Ask the user for a string. More...
 
void mutt_enter_state_free (struct EnterState **ptr)
 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

◆ COMB_CHAR

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

Definition at line 66 of file enter.c.

Enumeration Type Documentation

◆ EnterRedrawFlags

redraw flags for mutt_enter_string_full()

Enumerator
ENTER_REDRAW_NONE 

Nothing to redraw.

ENTER_REDRAW_INIT 

Go to end of line and redraw.

ENTER_REDRAW_LINE 

Redraw entire line.

Definition at line 58 of file enter.c.

59 {
60  ENTER_REDRAW_NONE = 0,
63 };

Function Documentation

◆ my_addwch()

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 74 of file enter.c.

75 {
76  int n = wcwidth(wc);
77  if (IsWPrint(wc) && (n > 0))
78  return mutt_addwch(wc);
79  if (!(wc & ~0x7f))
80  return mutt_window_printf("^%c", ((int) wc + 0x40) & 0x7f);
81  if (!(wc & ~0xffff))
82  return mutt_window_printf("\\u%04x", (int) wc);
83  return mutt_window_printf("\\u%08x", (int) wc);
84 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ replace_part()

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 92 of file enter.c.

93 {
94  /* Save the suffix */
95  size_t savelen = state->lastchar - state->curpos;
96  wchar_t *savebuf = NULL;
97 
98  if (savelen)
99  {
100  savebuf = mutt_mem_calloc(savelen, sizeof(wchar_t));
101  memcpy(savebuf, state->wbuf + state->curpos, savelen * sizeof(wchar_t));
102  }
103 
104  /* Convert to wide characters */
105  state->curpos = mutt_mb_mbstowcs(&state->wbuf, &state->wbuflen, from, buf);
106 
107  if (savelen)
108  {
109  /* Make space for suffix */
110  if (state->curpos + savelen > state->wbuflen)
111  {
112  state->wbuflen = state->curpos + savelen;
113  mutt_mem_realloc(&state->wbuf, state->wbuflen * sizeof(wchar_t));
114  }
115 
116  /* Restore suffix */
117  memcpy(state->wbuf + state->curpos, savebuf, savelen * sizeof(wchar_t));
118  FREE(&savebuf);
119  }
120 
121  state->lastchar = state->curpos + savelen;
122 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_enter_state_new()

struct EnterState* mutt_enter_state_new ( void  )

Create a new EnterState.

Return values
ptrNew EnterState

Definition at line 128 of file enter.c.

129 {
130  return mutt_mem_calloc(1, sizeof(struct EnterState));
131 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_enter_string()

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

Ask the user for a string.

Parameters
bufBuffer to store the string
buflenBuffer length
colInitial cursor position
flagsFlags, see CompletionFlags
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 147 of file enter.c.

148 {
149  int rc;
150  struct EnterState *es = mutt_enter_state_new();
151  do
152  {
153  if (SigWinch)
154  {
155  SigWinch = 0;
157  clearok(stdscr, true);
158  }
159  rc = mutt_enter_string_full(buf, buflen, col, flags, false, NULL, NULL, NULL, es);
160  } while (rc == 1);
162  return rc;
163 }
+ Here is the call graph for this function:

◆ mutt_enter_string_full()

int mutt_enter_string_full ( char *  buf,
size_t  buflen,
int  col,
CompletionFlags  flags,
bool  multiple,
struct Mailbox m,
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, see CompletionFlags
[in]multipleAllow multiple matches
[in]mMailbox
[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 180 of file enter.c.

183 {
184  int width = MessageWindow->state.cols - col - 1;
185  enum EnterRedrawFlags redraw = ENTER_REDRAW_NONE;
186  bool pass = (flags & MUTT_PASS);
187  bool first = true;
188  int ch;
189  wchar_t *tempbuf = NULL;
190  size_t templen = 0;
191  enum HistoryClass hclass;
192  int rc = 0;
193  mbstate_t mbstate;
194  memset(&mbstate, 0, sizeof(mbstate));
195 
196  if (state->wbuf)
197  {
198  /* Coming back after return 1 */
199  redraw = ENTER_REDRAW_LINE;
200  first = false;
201  }
202  else
203  {
204  /* Initialise wbuf from buf */
205  state->wbuflen = 0;
206  state->lastchar = mutt_mb_mbstowcs(&state->wbuf, &state->wbuflen, 0, buf);
207  redraw = ENTER_REDRAW_INIT;
208  }
209 
210  if (flags & MUTT_FILE)
211  hclass = HC_FILE;
212  else if (flags & MUTT_EFILE)
213  hclass = HC_MBOX;
214  else if (flags & MUTT_CMD)
215  hclass = HC_CMD;
216  else if (flags & MUTT_ALIAS)
217  hclass = HC_ALIAS;
218  else if (flags & MUTT_COMMAND)
219  hclass = HC_COMMAND;
220  else if (flags & MUTT_PATTERN)
221  hclass = HC_PATTERN;
222  else
223  hclass = HC_OTHER;
224 
225  while (true)
226  {
227  if (!pass)
228  {
229  if (redraw == ENTER_REDRAW_INIT)
230  {
231  /* Go to end of line */
232  state->curpos = state->lastchar;
233  state->begin = mutt_mb_width_ceiling(
234  state->wbuf, state->lastchar,
235  mutt_mb_wcswidth(state->wbuf, state->lastchar) - width + 1);
236  }
237  if ((state->curpos < state->begin) ||
238  (mutt_mb_wcswidth(state->wbuf + state->begin, state->curpos - state->begin) >= width))
239  {
240  state->begin = mutt_mb_width_ceiling(
241  state->wbuf, state->lastchar,
242  mutt_mb_wcswidth(state->wbuf, state->curpos) - (width / 2));
243  }
245  int w = 0;
246  for (size_t i = state->begin; i < state->lastchar; i++)
247  {
248  w += mutt_mb_wcwidth(state->wbuf[i]);
249  if (w > width)
250  break;
251  my_addwch(state->wbuf[i]);
252  }
255  col + mutt_mb_wcswidth(state->wbuf + state->begin,
256  state->curpos - state->begin),
257  0);
258  }
259  mutt_refresh();
260 
261  ch = km_dokey(MENU_EDITOR);
262  if (ch < 0)
263  {
264  rc = (SigWinch && (ch == -2)) ? 1 : -1;
265  goto bye;
266  }
267 
268  if (ch != OP_NULL)
269  {
270  first = false;
271  if ((ch != OP_EDITOR_COMPLETE) && (ch != OP_EDITOR_COMPLETE_QUERY))
272  state->tabs = 0;
273  redraw = ENTER_REDRAW_LINE;
274  switch (ch)
275  {
276  case OP_EDITOR_HISTORY_UP:
277  state->curpos = state->lastchar;
278  if (mutt_hist_at_scratch(hclass))
279  {
280  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
281  mutt_hist_save_scratch(hclass, buf);
282  }
283  replace_part(state, 0, mutt_hist_prev(hclass));
284  redraw = ENTER_REDRAW_INIT;
285  break;
286 
287  case OP_EDITOR_HISTORY_DOWN:
288  state->curpos = state->lastchar;
289  if (mutt_hist_at_scratch(hclass))
290  {
291  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
292  mutt_hist_save_scratch(hclass, buf);
293  }
294  replace_part(state, 0, mutt_hist_next(hclass));
295  redraw = ENTER_REDRAW_INIT;
296  break;
297 
298  case OP_EDITOR_HISTORY_SEARCH:
299  state->curpos = state->lastchar;
300  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
301  mutt_hist_complete(buf, buflen, hclass);
302  replace_part(state, 0, buf);
303  rc = 1;
304  goto bye;
305  break;
306 
307  case OP_EDITOR_BACKSPACE:
308  if (state->curpos == 0)
309  {
310  // Pressing backspace when no text is in the command prompt should exit the prompt
311  if (C_AbortBackspace && (state->lastchar == 0))
312  goto bye;
313  // Pressing backspace with text in the command prompt should just beep
314  mutt_beep(false);
315  }
316  else
317  {
318  size_t i = state->curpos;
319  while ((i > 0) && COMB_CHAR(state->wbuf[i - 1]))
320  i--;
321  if (i > 0)
322  i--;
323  memmove(state->wbuf + i, state->wbuf + state->curpos,
324  (state->lastchar - state->curpos) * sizeof(wchar_t));
325  state->lastchar -= state->curpos - i;
326  state->curpos = i;
327  }
328  break;
329 
330  case OP_EDITOR_BOL:
331  state->curpos = 0;
332  break;
333 
334  case OP_EDITOR_EOL:
335  redraw = ENTER_REDRAW_INIT;
336  break;
337 
338  case OP_EDITOR_KILL_LINE:
339  state->curpos = 0;
340  state->lastchar = 0;
341  break;
342 
343  case OP_EDITOR_KILL_EOL:
344  state->lastchar = state->curpos;
345  break;
346 
347  case OP_EDITOR_BACKWARD_CHAR:
348  if (state->curpos == 0)
349  mutt_beep(false);
350  else
351  {
352  while (state->curpos && COMB_CHAR(state->wbuf[state->curpos - 1]))
353  state->curpos--;
354  if (state->curpos)
355  state->curpos--;
356  }
357  break;
358 
359  case OP_EDITOR_FORWARD_CHAR:
360  if (state->curpos == state->lastchar)
361  mutt_beep(false);
362  else
363  {
364  state->curpos++;
365  while ((state->curpos < state->lastchar) &&
366  COMB_CHAR(state->wbuf[state->curpos]))
367  {
368  state->curpos++;
369  }
370  }
371  break;
372 
373  case OP_EDITOR_BACKWARD_WORD:
374  if (state->curpos == 0)
375  mutt_beep(false);
376  else
377  {
378  while (state->curpos && iswspace(state->wbuf[state->curpos - 1]))
379  state->curpos--;
380  while (state->curpos && !iswspace(state->wbuf[state->curpos - 1]))
381  state->curpos--;
382  }
383  break;
384 
385  case OP_EDITOR_FORWARD_WORD:
386  if (state->curpos == state->lastchar)
387  mutt_beep(false);
388  else
389  {
390  while ((state->curpos < state->lastchar) &&
391  iswspace(state->wbuf[state->curpos]))
392  {
393  state->curpos++;
394  }
395  while ((state->curpos < state->lastchar) &&
396  !iswspace(state->wbuf[state->curpos]))
397  {
398  state->curpos++;
399  }
400  }
401  break;
402 
403  case OP_EDITOR_CAPITALIZE_WORD:
404  case OP_EDITOR_UPCASE_WORD:
405  case OP_EDITOR_DOWNCASE_WORD:
406  if (state->curpos == state->lastchar)
407  {
408  mutt_beep(false);
409  break;
410  }
411  while (state->curpos && !iswspace(state->wbuf[state->curpos]))
412  state->curpos--;
413  while ((state->curpos < state->lastchar) && iswspace(state->wbuf[state->curpos]))
414  state->curpos++;
415  while ((state->curpos < state->lastchar) &&
416  !iswspace(state->wbuf[state->curpos]))
417  {
418  if (ch == OP_EDITOR_DOWNCASE_WORD)
419  state->wbuf[state->curpos] = towlower(state->wbuf[state->curpos]);
420  else
421  {
422  state->wbuf[state->curpos] = towupper(state->wbuf[state->curpos]);
423  if (ch == OP_EDITOR_CAPITALIZE_WORD)
424  ch = OP_EDITOR_DOWNCASE_WORD;
425  }
426  state->curpos++;
427  }
428  break;
429 
430  case OP_EDITOR_DELETE_CHAR:
431  if (state->curpos == state->lastchar)
432  mutt_beep(false);
433  else
434  {
435  size_t i = state->curpos;
436  while ((i < state->lastchar) && COMB_CHAR(state->wbuf[i]))
437  i++;
438  if (i < state->lastchar)
439  i++;
440  while ((i < state->lastchar) && COMB_CHAR(state->wbuf[i]))
441  i++;
442  memmove(state->wbuf + state->curpos, state->wbuf + i,
443  (state->lastchar - i) * sizeof(wchar_t));
444  state->lastchar -= i - state->curpos;
445  }
446  break;
447 
448  case OP_EDITOR_KILL_WORD:
449  /* delete to beginning of word */
450  if (state->curpos != 0)
451  {
452  size_t i = state->curpos;
453  while (i && iswspace(state->wbuf[i - 1]))
454  i--;
455  if (i > 0)
456  {
457  if (iswalnum(state->wbuf[i - 1]))
458  {
459  for (--i; (i > 0) && iswalnum(state->wbuf[i - 1]); i--)
460  ; // do nothing
461  }
462  else
463  i--;
464  }
465  memmove(state->wbuf + i, state->wbuf + state->curpos,
466  (state->lastchar - state->curpos) * sizeof(wchar_t));
467  state->lastchar += i - state->curpos;
468  state->curpos = i;
469  }
470  break;
471 
472  case OP_EDITOR_KILL_EOW:
473  {
474  /* delete to end of word */
475 
476  /* first skip over whitespace */
477  size_t i;
478  for (i = state->curpos; (i < state->lastchar) && iswspace(state->wbuf[i]); i++)
479  ; // do nothing
480 
481  /* if there are any characters left.. */
482  if (i < state->lastchar)
483  {
484  /* if the current character is alphanumeric.. */
485  if (iswalnum(state->wbuf[i]))
486  {
487  /* skip over the rest of the word consistent of only alphanumerics */
488  for (; (i < state->lastchar) && iswalnum(state->wbuf[i]); i++)
489  ; // do nothing
490  }
491  else
492  {
493  /* skip over one non-alphanumeric character */
494  i++;
495  }
496  }
497 
498  memmove(state->wbuf + state->curpos, state->wbuf + i,
499  (state->lastchar - i) * sizeof(wchar_t));
500  state->lastchar += state->curpos - i;
501  break;
502  }
503 
504  case OP_EDITOR_MAILBOX_CYCLE:
505  if (flags & MUTT_EFILE)
506  {
507  first = true; /* clear input if user types a real key later */
508  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
509 
510  struct Buffer *pool = mutt_buffer_pool_get();
511  mutt_buffer_addstr(pool, buf);
512  mutt_mailbox_next(m, pool);
513  mutt_str_copy(buf, mutt_buffer_string(pool), buflen);
515 
516  state->curpos = state->lastchar =
517  mutt_mb_mbstowcs(&state->wbuf, &state->wbuflen, 0, buf);
518  break;
519  }
520  else if (!(flags & MUTT_FILE))
521  {
522  goto self_insert;
523  }
524  /* fallthrough */
525 
526  case OP_EDITOR_COMPLETE:
527  case OP_EDITOR_COMPLETE_QUERY:
528  state->tabs++;
529  if (flags & MUTT_CMD)
530  {
531  size_t i;
532  for (i = state->curpos;
533  (i > 0) && !mutt_mb_is_shell_char(state->wbuf[i - 1]); i--)
534  {
535  }
536  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
537  if (tempbuf && (templen == (state->lastchar - i)) &&
538  (memcmp(tempbuf, state->wbuf + i, (state->lastchar - i) * sizeof(wchar_t)) == 0))
539  {
541  m, NULL, NULL);
542  if (buf[0] != '\0')
543  replace_part(state, i, buf);
544  rc = 1;
545  goto bye;
546  }
547  if (mutt_complete(buf, buflen) == 0)
548  {
549  templen = state->lastchar - i;
550  mutt_mem_realloc(&tempbuf, templen * sizeof(wchar_t));
551  }
552  else
553  mutt_beep(false);
554 
555  replace_part(state, i, buf);
556  }
557  else if ((flags & MUTT_ALIAS) && (ch == OP_EDITOR_COMPLETE))
558  {
559  /* invoke the alias-menu to get more addresses */
560  size_t i;
561  for (i = state->curpos;
562  (i > 0) && (state->wbuf[i - 1] != ',') && (state->wbuf[i - 1] != ':'); i--)
563  {
564  }
565  for (; (i < state->lastchar) && (state->wbuf[i] == ' '); i++)
566  ; // do nothing
567 
568  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
569  int rc2 = alias_complete(buf, buflen, NeoMutt->sub);
570  replace_part(state, i, buf);
571  if (rc2 != 1)
572  {
573  rc = 1;
574  goto bye;
575  }
576  break;
577  }
578  else if ((flags & MUTT_LABEL) && (ch == OP_EDITOR_COMPLETE))
579  {
580  size_t i;
581  for (i = state->curpos;
582  (i > 0) && (state->wbuf[i - 1] != ',') && (state->wbuf[i - 1] != ':'); i--)
583  {
584  }
585  for (; (i < state->lastchar) && (state->wbuf[i] == ' '); i++)
586  ; // do nothing
587 
588  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
589  int rc2 = mutt_label_complete(buf, buflen, state->tabs);
590  replace_part(state, i, buf);
591  if (rc2 != 1)
592  {
593  rc = 1;
594  goto bye;
595  }
596  break;
597  }
598  else if ((flags & MUTT_PATTERN) && (ch == OP_EDITOR_COMPLETE))
599  {
600  size_t i = state->curpos;
601  if (i && (state->wbuf[i - 1] == '~'))
602  {
603  if (dlg_select_pattern(buf, buflen))
604  replace_part(state, i - 1, buf);
605  rc = 1;
606  goto bye;
607  }
608  for (; (i > 0) && (state->wbuf[i - 1] != '~'); i--)
609  ; // do nothing
610 
611  if ((i > 0) && (i < state->curpos) && (state->wbuf[i - 1] == '~') &&
612  (state->wbuf[i] == 'y'))
613  {
614  i++;
615  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
616  int rc2 = mutt_label_complete(buf, buflen, state->tabs);
617  replace_part(state, i, buf);
618  if (rc2 != 1)
619  {
620  rc = 1;
621  goto bye;
622  }
623  }
624  else
625  goto self_insert;
626  break;
627  }
628  else if ((flags & MUTT_ALIAS) && (ch == OP_EDITOR_COMPLETE_QUERY))
629  {
630  size_t i = state->curpos;
631  if (i != 0)
632  {
633  for (; (i > 0) && (state->wbuf[i - 1] != ','); i--)
634  ; // do nothing
635 
636  for (; (i < state->curpos) && (state->wbuf[i] == ' '); i++)
637  ; // do nothing
638  }
639 
640  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
641  query_complete(buf, buflen, NeoMutt->sub);
642  replace_part(state, i, buf);
643 
644  rc = 1;
645  goto bye;
646  }
647  else if (flags & MUTT_COMMAND)
648  {
649  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
650  size_t i = strlen(buf);
651  if ((i != 0) && (buf[i - 1] == '=') &&
652  (mutt_var_value_complete(buf, buflen, i) != 0))
653  {
654  state->tabs = 0;
655  }
656  else if (mutt_command_complete(buf, buflen, i, state->tabs) == 0)
657  mutt_beep(false);
658  replace_part(state, 0, buf);
659  }
660  else if (flags & (MUTT_FILE | MUTT_EFILE))
661  {
662  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
663 
664  /* see if the path has changed from the last time */
665  if ((!tempbuf && !state->lastchar) ||
666  (tempbuf && (templen == state->lastchar) &&
667  (memcmp(tempbuf, state->wbuf, state->lastchar * sizeof(wchar_t)) == 0)))
668  {
669  mutt_select_file(buf, buflen,
671  (multiple ? MUTT_SEL_MULTI : MUTT_SEL_NO_FLAGS),
672  m, files, numfiles);
673  if (buf[0] != '\0')
674  {
675  mutt_pretty_mailbox(buf, buflen);
676  if (!pass)
677  mutt_hist_add(hclass, buf, true);
678  rc = 0;
679  goto bye;
680  }
681 
682  /* file selection cancelled */
683  rc = 1;
684  goto bye;
685  }
686 
687  if (mutt_complete(buf, buflen) == 0)
688  {
689  templen = state->lastchar;
690  mutt_mem_realloc(&tempbuf, templen * sizeof(wchar_t));
691  memcpy(tempbuf, state->wbuf, templen * sizeof(wchar_t));
692  }
693  else
694  mutt_beep(false); /* let the user know that nothing matched */
695  replace_part(state, 0, buf);
696  }
697 #ifdef USE_NOTMUCH
698  else if (flags & MUTT_NM_QUERY)
699  {
700  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
701  size_t len = strlen(buf);
702  if (!mutt_nm_query_complete(buf, buflen, len, state->tabs))
703  mutt_beep(false);
704 
705  replace_part(state, 0, buf);
706  }
707  else if (flags & MUTT_NM_TAG)
708  {
709  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
710  if (!mutt_nm_tag_complete(buf, buflen, state->tabs))
711  mutt_beep(false);
712 
713  replace_part(state, 0, buf);
714  }
715 #endif
716  else
717  goto self_insert;
718  break;
719 
720  case OP_EDITOR_QUOTE_CHAR:
721  {
722  struct KeyEvent event;
723  do
724  {
725  event = mutt_getch();
726  } while (event.ch == -2);
727  if (event.ch >= 0)
728  {
729  LastKey = event.ch;
730  goto self_insert;
731  }
732  break;
733  }
734 
735  case OP_EDITOR_TRANSPOSE_CHARS:
736  if (state->lastchar < 2)
737  mutt_beep(false);
738  else
739  {
740  wchar_t t;
741 
742  if (state->curpos == 0)
743  state->curpos = 2;
744  else if (state->curpos < state->lastchar)
745  state->curpos++;
746 
747  t = state->wbuf[state->curpos - 2];
748  state->wbuf[state->curpos - 2] = state->wbuf[state->curpos - 1];
749  state->wbuf[state->curpos - 1] = t;
750  }
751  break;
752 
753  default:
754  mutt_beep(false);
755  }
756  }
757  else
758  {
759  self_insert:
760  state->tabs = 0;
761  wchar_t wc;
762  /* use the raw keypress */
763  ch = LastKey;
764 
765  /* quietly ignore all other function keys */
766  if (ch & ~0xff)
767  continue;
768 
769  /* gather the octets into a wide character */
770  {
771  char c = ch;
772  size_t k = mbrtowc(&wc, &c, 1, &mbstate);
773  if (k == (size_t)(-2))
774  continue;
775  else if ((k != 0) && (k != 1))
776  {
777  memset(&mbstate, 0, sizeof(mbstate));
778  continue;
779  }
780  }
781 
782  if (first && (flags & MUTT_CLEAR))
783  {
784  first = false;
785  if (IsWPrint(wc)) /* why? */
786  {
787  state->curpos = 0;
788  state->lastchar = 0;
789  }
790  }
791 
792  if ((wc == '\r') || (wc == '\n'))
793  {
794  /* Convert from wide characters */
795  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->lastchar);
796  if (!pass)
797  mutt_hist_add(hclass, buf, true);
798 
799  if (multiple)
800  {
801  char **tfiles = NULL;
802  *numfiles = 1;
803  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
804  mutt_expand_path(buf, buflen);
805  tfiles[0] = mutt_str_dup(buf);
806  *files = tfiles;
807  }
808  rc = 0;
809  goto bye;
810  }
811  else if (wc && ((wc < ' ') || IsWPrint(wc))) /* why? */
812  {
813  if (state->lastchar >= state->wbuflen)
814  {
815  state->wbuflen = state->lastchar + 20;
816  mutt_mem_realloc(&state->wbuf, state->wbuflen * sizeof(wchar_t));
817  }
818  memmove(state->wbuf + state->curpos + 1, state->wbuf + state->curpos,
819  (state->lastchar - state->curpos) * sizeof(wchar_t));
820  state->wbuf[state->curpos++] = wc;
821  state->lastchar++;
822  }
823  else
824  {
825  mutt_flushinp();
826  mutt_beep(false);
827  }
828  }
829  }
830 
831 bye:
832 
833  mutt_hist_reset_state(hclass);
834  FREE(&tempbuf);
835  return rc;
836 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_enter_state_free()

void mutt_enter_state_free ( struct EnterState **  ptr)

Free an EnterState.

Parameters
[out]ptrEnterState to free

Definition at line 842 of file enter.c.

843 {
844  if (!ptr || !*ptr)
845  return;
846 
847  struct EnterState *es = *ptr;
848 
849  FREE(&es->wbuf);
850  FREE(ptr);
851 }
+ Here is the caller graph for this function:
mutt_mb_wcswidth
int mutt_mb_wcswidth(const wchar_t *s, size_t n)
Measure the screen width of a string.
Definition: mbyte.c:196
mutt_hist_reset_state
void mutt_hist_reset_state(enum HistoryClass hclass)
Move the 'current' position to the end of the History.
Definition: history.c:554
mutt_beep
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:99
mutt_window_clrtoeol
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:244
mutt_window_move
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:382
SigWinch
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:75
mutt_mem_calloc
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
MessageWindow
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
mutt_window_printf
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:550
mutt_addwch
int mutt_addwch(wchar_t wc)
addwch would be provided by an up-to-date curses library
Definition: curs_lib.c:1063
EnterState::lastchar
size_t lastchar
Definition: enter_state.h:36
COMB_CHAR
#define COMB_CHAR(wc)
Definition: enter.c:66
Buffer
String manipulation buffer.
Definition: buffer.h:33
mutt_hist_complete
void mutt_hist_complete(char *buf, size_t buflen, enum HistoryClass hclass)
Complete a string from a history list.
Definition: mutt_history.c:42
MUTT_PATTERN
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:64
MUTT_SEL_NO_FLAGS
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:41
EnterState::wbuflen
size_t wbuflen
Definition: enter_state.h:35
mutt_hist_add
void mutt_hist_add(enum HistoryClass hclass, const char *str, bool save)
Add a string to a history.
Definition: history.c:464
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
mutt_enter_state_new
struct EnterState * mutt_enter_state_new(void)
Create a new EnterState.
Definition: enter.c:128
FREE
#define FREE(x)
Definition: memory.h:40
ENTER_REDRAW_INIT
@ ENTER_REDRAW_INIT
Go to end of line and redraw.
Definition: enter.c:61
LastKey
int LastKey
contains the last key the user pressed
Definition: keymap.c:146
MUTT_LABEL
#define MUTT_LABEL
Do label completion.
Definition: mutt.h:65
mutt_mailbox_next
struct Mailbox * mutt_mailbox_next(struct Mailbox *m_cur, struct Buffer *s)
incoming folders completion routine
Definition: mutt_mailbox.c:312
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
ENTER_REDRAW_LINE
@ ENTER_REDRAW_LINE
Redraw entire line.
Definition: enter.c:62
HC_FILE
@ HC_FILE
Files.
Definition: lib.h:57
query_complete
int query_complete(char *buf, size_t buflen, struct ConfigSubset *sub)
Perform auto-complete using an Address Query.
Definition: dlgquery.c:606
mutt_getch
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:189
EnterState::begin
size_t begin
Definition: enter_state.h:38
EnterState::tabs
int tabs
Definition: enter_state.h:39
MUTT_ALIAS
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:57
mutt_label_complete
int mutt_label_complete(char *buf, size_t buflen, int numtabs)
Complete a label name.
Definition: init.c:1313
mutt_hist_at_scratch
bool mutt_hist_at_scratch(enum HistoryClass hclass)
Is the current History position at the 'scratch' place?
Definition: history.c:618
MUTT_FILE
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
mutt_expand_path
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
HistoryClass
HistoryClass
Type to differentiate different histories.
Definition: lib.h:52
MUTT_EFILE
#define MUTT_EFILE
Do file completion, plus incoming folders.
Definition: mutt.h:59
mutt_mb_width_ceiling
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:217
mutt_command_complete
int mutt_command_complete(char *buf, size_t buflen, int pos, int numtabs)
Complete a command name.
Definition: init.c:1131
MUTT_SEL_FOLDER
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:44
mutt_nm_tag_complete
bool mutt_nm_tag_complete(char *buf, size_t buflen, int numtabs)
Complete to the nearest notmuch tag.
Definition: init.c:1434
mutt_mb_is_shell_char
bool mutt_mb_is_shell_char(wchar_t ch)
Is character not typically part of a pathname.
Definition: mbyte.c:344
HC_PATTERN
@ HC_PATTERN
Patterns.
Definition: lib.h:58
HC_ALIAS
@ HC_ALIAS
Aliases.
Definition: lib.h:55
mutt_resize_screen
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size (CURSES)
Definition: resize.c:101
MUTT_SEL_MULTI
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:43
mutt_complete
int mutt_complete(char *buf, size_t buflen)
Attempt to complete a partial pathname.
Definition: complete.c:57
KeyEvent
An event such as a keypress.
Definition: keymap.h:63
mutt_mem_realloc
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
mutt_hist_save_scratch
void mutt_hist_save_scratch(enum HistoryClass hclass, const char *str)
Save a temporary string to the History.
Definition: history.c:635
EnterRedrawFlags
EnterRedrawFlags
redraw flags for mutt_enter_string_full()
Definition: enter.c:58
mutt_flushinp
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:923
MuttWindow::state
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
mutt_nm_query_complete
bool mutt_nm_query_complete(char *buf, size_t buflen, int pos, int numtabs)
Complete to the nearest notmuch tag.
Definition: init.c:1377
HC_MBOX
@ HC_MBOX
Mailboxes.
Definition: lib.h:60
MUTT_PASS
#define MUTT_PASS
Password mode (no echo)
Definition: mutt.h:61
MUTT_NM_TAG
#define MUTT_NM_TAG
Notmuch tag +/- mode.
Definition: mutt.h:67
my_addwch
static int my_addwch(wchar_t wc)
Display one wide character on screen.
Definition: enter.c:74
EnterState
Keep our place when entering a string.
Definition: enter_state.h:32
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
mutt_enter_string_full
int mutt_enter_string_full(char *buf, size_t buflen, int col, CompletionFlags flags, bool multiple, struct Mailbox *m, char ***files, int *numfiles, struct EnterState *state)
Ask the user for a string.
Definition: enter.c:180
mutt_mb_wcwidth
int mutt_mb_wcwidth(wchar_t wc)
Measure the screen width of a character.
Definition: mbyte.c:178
replace_part
static void replace_part(struct EnterState *state, size_t from, char *buf)
Search and replace on a buffer.
Definition: enter.c:92
C_AbortBackspace
WHERE bool C_AbortBackspace
Config: Hitting backspace against an empty prompt aborts the prompt.
Definition: mutt_globals.h:83
HC_OTHER
@ HC_OTHER
Miscellaneous strings.
Definition: lib.h:59
MENU_EDITOR
@ MENU_EDITOR
Text entry area.
Definition: keymap.h:77
MUTT_CMD
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:60
HC_CMD
@ HC_CMD
External commands.
Definition: lib.h:54
MUTT_CLEAR
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
mutt_refresh
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:108
EnterState::curpos
size_t curpos
Definition: enter_state.h:37
mutt_select_file
void mutt_select_file(char *file, size_t filelen, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:2208
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
ENTER_REDRAW_NONE
@ ENTER_REDRAW_NONE
Nothing to redraw.
Definition: enter.c:60
MUTT_COMMAND
#define MUTT_COMMAND
Do command completion.
Definition: mutt.h:63
alias_complete
int alias_complete(char *buf, size_t buflen, struct ConfigSubset *sub)
alias completion routine
Definition: dlgalias.c:375
mutt_buffer_addstr
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
mutt_mb_wcstombs
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:237
mutt_hist_prev
char * mutt_hist_prev(enum HistoryClass hclass)
Get the previous string in a History.
Definition: history.c:527
mutt_var_value_complete
int mutt_var_value_complete(char *buf, size_t buflen, int pos)
Complete a variable/value.
Definition: init.c:1487
km_dokey
int km_dokey(enum MenuType menu)
Determine what a keypress should do.
Definition: keymap.c:658
WindowState::cols
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
mutt_pretty_mailbox
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:523
dlg_select_pattern
bool dlg_select_pattern(char *buf, size_t buflen)
Show menu to select a Pattern.
Definition: dlgpattern.c:262
mutt_enter_state_free
void mutt_enter_state_free(struct EnterState **ptr)
Free an EnterState.
Definition: enter.c:842
HC_COMMAND
@ HC_COMMAND
NeoMutt commands.
Definition: lib.h:56
mutt_hist_next
char * mutt_hist_next(enum HistoryClass hclass)
Get the next string in a History.
Definition: history.c:500
KeyEvent::ch
int ch
raw key pressed
Definition: keymap.h:65
mutt_mb_mbstowcs
size_t mutt_mb_mbstowcs(wchar_t **pwbuf, size_t *pwbuflen, size_t i, const char *buf)
Convert a string from multibyte to wide characters.
Definition: mbyte.c:295
MUTT_NM_QUERY
#define MUTT_NM_QUERY
Notmuch query mode.
Definition: mutt.h:66
EnterState::wbuf
wchar_t * wbuf
Definition: enter_state.h:34
IsWPrint
#define IsWPrint(wc)
Definition: mbyte.h:40
mutt_str_copy
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:716