j = mutt_strlen ((char *) buf); strfcpy ((char *) buf + j, savebuf, buflen - j); save_len = mutt_strlen (savebuf); last_begin = begin;
int _mutt_enter_string (unsigned char *buf, size_t buflen, int y, int x,		       int flags, int multiple, char ***files, int *numfiles){  event_t event;  int curpos = 0;		/* the location of the cursor */  int lastchar = 0; 		/* offset of the last char in the string */  int begin = 0;		/* first character displayed on the line */  int ch;			/* last typed character */  int width = COLS - x - 1;	/* width of field */  int redraw = M_REDRAW_INIT;	/* when/what to redraw */  int pass = (flags == M_PASS);  int first = 1;  int j;  char tempbuf[_POSIX_PATH_MAX] = "";  history_class_t hclass;  int tabs = 0; /* number of *consecutive* TABs */    if (flags & (M_FILE | M_EFILE))    hclass = HC_FILE;  else if (flags & M_CMD)    hclass = HC_CMD;  else if (flags & M_ALIAS)    hclass = HC_ALIAS;  else if (flags & M_COMMAND)    hclass = HC_COMMAND;  else if (flags & M_PATTERN)    hclass = HC_PATTERN;  else     hclass = HC_OTHER;  FOREVER  {    if (redraw)    {      if (redraw == M_REDRAW_INIT)      {	/* full redraw */	lastchar = curpos = mutt_strlen ((char *) buf);	begin = lastchar - width;      }      if (begin < 0)	begin = 0;      switch (redraw)      {	case M_REDRAW_PREV_EOL:	  j = curpos - 1;	  break;	case M_REDRAW_EOL:	  j = curpos;	  break;	default:	  j = begin;      }      move (y, x + j - begin);      for (; j < lastchar && j < begin + width; j++)	ADDCH (buf[j]);      clrtoeol ();      if (redraw != M_REDRAW_INIT)	move (y, x + curpos - begin);      redraw = 0;    }    mutt_refresh ();    /* first look to see if a keypress is an editor operation.  km_dokey()     * returns 0 if there is no entry in the keymap, so restore the last     * keypress and continue normally.     */    if ((ch = km_dokey (MENU_EDITOR)) == -1)    {      buf[curpos] = 0;      return (-1);    }    if (ch != OP_NULL)    {      first = 0; /* make sure not to clear the buffer */      if (ch != OP_EDITOR_COMPLETE)	tabs = 0;      switch (ch)      {	case OP_EDITOR_HISTORY_UP:	  if (!pass)	  {	    strfcpy ((char *) buf, mutt_history_prev (hclass), buflen);	    redraw = M_REDRAW_INIT;	  }	  break;	case OP_EDITOR_HISTORY_DOWN:	  if (!pass)	  {	    strfcpy ((char *) buf, mutt_history_next (hclass), buflen);	    redraw = M_REDRAW_INIT;	  }	  break;	case OP_EDITOR_BACKSPACE:	  if (curpos == 0)	  {	    BEEP ();	    break;	  }	  for (j = curpos ; j < lastchar ; j++)	    buf[j - 1] = buf[j];	  curpos--;	  lastchar--;	  if (!pass)	  {	    if (curpos > begin)	    {	      if (lastchar == curpos)	      {		move (y, x + curpos - begin);		delch ();	      }	      else		redraw = M_REDRAW_EOL;	    }	    else	    {	      begin -= width / 2;	      redraw = M_REDRAW_LINE;	    }	  }	  break;	case OP_EDITOR_BOL:	  /* reposition the cursor at the begininning of the line */	  curpos = 0;	  if (!pass)	  {	    if (begin)	    {	      /* the first char is not displayed, so readjust */	      begin = 0;	      redraw = M_REDRAW_LINE;	    }	    else	      move (y, x);	  }	  break;	case OP_EDITOR_EOL:	  curpos = lastchar;	  if (!pass)	  {	    if (lastchar < begin + width)	      move (y, x + lastchar - begin);	    else	    {	      begin = lastchar - width / 2;	      redraw = M_REDRAW_LINE;	    }	  }	  break;	case OP_EDITOR_KILL_LINE:	  lastchar = curpos = 0;	  if (!pass)	  {	    begin = 0;	    redraw = M_REDRAW_LINE;	  }	  break;	case OP_EDITOR_KILL_EOL:	  lastchar = curpos;	  if (!pass)	    clrtoeol ();	  break;	case OP_EDITOR_BACKWARD_CHAR:	  if (curpos == 0)	  {	    BEEP ();	  }	  else	  {	    curpos--;	    if (!pass)	    {	      if (curpos < begin)	      {		begin -= width / 2;		redraw = M_REDRAW_LINE;	      }	      else		move (y, x + curpos - begin);	    }	  }	  break;	case OP_EDITOR_FORWARD_CHAR:	  if (curpos == lastchar)	  {	    BEEP ();	  }	  else	  {	    curpos++;	    if (!pass)	    {	      if (curpos >= begin + width)	      {		begin = curpos - width / 2;		redraw = M_REDRAW_LINE;	      }	      else		move (y, x + curpos - begin);	    }	  }	  break;	case OP_EDITOR_DELETE_CHAR:	  if (curpos != lastchar)	  {	    for (j = curpos; j < lastchar; j++)	      buf[j] = buf[j + 1];	    lastchar--;	    if (!pass)	      redraw = M_REDRAW_EOL;	  }	  else	    BEEP ();	  break;	case OP_EDITOR_KILL_WORD:	  /* delete to begining of word */	  if (curpos != 0)	  {	    j = curpos;	    while (j > 0 && ISSPACE (buf[j - 1]))	      j--;	    if (j > 0)	    {	      if (isalnum (buf[j - 1]))	      {		for (j--; j > 0 && isalnum (buf[j - 1]); j--)		  ;	      }	      else		j--;	    }	    ch = j; /* save current position */	    while (curpos < lastchar)	      buf[j++] = buf[curpos++];	    lastchar = j;	    curpos = ch; /* restore current position */	    /* update screen */	    if (!pass)	    {	      if (curpos < begin)	      {		begin = curpos - width / 2;		redraw = M_REDRAW_LINE;	      }	      else		redraw = M_REDRAW_EOL;	    }	  }	  break;	case OP_EDITOR_BUFFY_CYCLE:	  if (flags & M_EFILE)	  {	    first = 1; /* clear input if user types a real key later */	    buf[curpos] = 0;	    mutt_buffy ((char *) buf);	    redraw = M_REDRAW_INIT;	    break;	  }	  else if (!(flags & M_FILE))	    goto self_insert;	  /* fall through to completion routine (M_FILE) */	case OP_EDITOR_COMPLETE:	  tabs++;	  if (flags & M_CMD)	  {	    buf[curpos] = 0;	    for (j = curpos - 1; j >= 0 && buf[j] != ' '; j--);	    if (mutt_strcmp (tempbuf, (char *) buf) == 0)	    {	      mutt_select_file ((char *) buf + j + 1, buflen - j - 1, 0);	      set_option (OPTNEEDREDRAW);	      return (1);	    }	    if (mutt_complete ((char *) buf + j + 1, buflen - (j + 1)) == 0)	      strfcpy (tempbuf, (char *) buf + j + 1, sizeof (tempbuf));	    else	      BEEP ();	    redraw = M_REDRAW_INIT;	  }	  else if (flags & M_ALIAS)	  {	    /* invoke the alias-menu to get more addresses */	    buf[curpos] = 0;	    for (j = curpos - 1 ; j >= 0 && buf[j] != ',' ; j--);	    for (++j; buf[j] == ' '; j++)	      ;	    if (mutt_alias_complete ((char *) buf + j, buflen - j))	    {	      redraw = M_REDRAW_INIT;	      continue;	    }	    return (1);	  }	  else if (flags & M_COMMAND)	  {	    buf[curpos] = 0;	    if (buf[lastchar - 1] == '=' && 		mutt_var_value_complete ((char *) buf, buflen, curpos))	    {	      tabs=0;	      redraw = M_REDRAW_INIT;	      continue;	    }	    else if (mutt_command_complete ((char *) buf, buflen, curpos, tabs))	    {	      redraw = M_REDRAW_INIT;	      continue;	    }	  }	  else if (flags & (M_FILE | M_EFILE))	  {	    buf[curpos] = 0;	    /* see if the path has changed from the last time */	    if (mutt_strcmp (tempbuf, (char *) buf) == 0)	    {	      _mutt_select_file ((char *) buf, buflen, 0, multiple, files, numfiles);	      set_option (OPTNEEDREDRAW);	      if (buf[0])	      {		mutt_pretty_mailbox ((char *) buf);		mutt_history_add (hclass, (char *) buf);		return (0);	      }	      return (-1);	    }	    if (mutt_complete ((char *) buf, buflen) == 0)	      strfcpy (tempbuf, (char *) buf, sizeof (tempbuf));	    else	      BEEP (); /* let the user know that nothing matched */	    redraw = M_REDRAW_INIT;	  }	  else	    goto self_insert;	  break;	case OP_EDITOR_COMPLETE_QUERY:	  if (flags & M_ALIAS)	  {	    /* invoke the query-menu to get more addresses */	    buf[curpos] = 0;	    if (curpos)	    {	      for (j = curpos - 1 ; j >= 0 && buf[j] != ',' ; j--);	      for (j++; buf[j] == ' '; j++);	      mutt_query_complete ((char *) buf + j, buflen - j);	    }	    else	      mutt_query_menu ((char *) buf, buflen);	    return (1);	  }	  else	    goto self_insert;	case OP_EDITOR_QUOTE_CHAR:	  ADDCH (LastKey);	  event = mutt_getch ();	  if(event.ch != -1)	  {	    LastKey = event.ch;	    move (y, x + curpos - begin);	    goto self_insert;	  }	default:	  BEEP ();      }    }    else    {self_insert:      tabs = 0;      /* use the raw keypress */      ch = LastKey;      if (first && (flags & M_CLEAR))      {	first = 0;	if (IsPrint (ch))	{	  mutt_ungetch (ch, 0);	  buf[0] = 0;	  redraw = M_REDRAW_INIT;	  continue;	}      }      if (CI_is_return (ch))      {	buf[lastchar] = 0;	if (!pass)	  mutt_history_add (hclass, (char *) buf);	if (multiple)	{	  char **tfiles;	  *numfiles = 1;	  tfiles = safe_malloc (*numfiles * sizeof (char *));	  mutt_expand_path ((char *) buf, buflen);	  tfiles[0] = safe_strdup ((char *) buf);	  *files = tfiles;	}	return (0);      }      else if ((ch < ' ' || IsPrint (ch)) && (lastchar + 1 < buflen))      {	for (j = lastchar; j > curpos; j--)	  buf[j] = buf[j - 1];	buf[curpos++] = ch;	lastchar++;	if (!pass)	{	  if (curpos >= begin + width)	  {	    begin = curpos - width / 2;	    redraw = M_REDRAW_LINE;	  }	  else if (curpos == lastchar)	    ADDCH (ch);	  else	    redraw = M_REDRAW_PREV_EOL;	}      }      else      {	mutt_flushinp ();	BEEP ();      }    }  }  /* not reached */}