⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enter.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org> * Copyright (C) 2000 Edmund Grimley Evans <edmundo@rano.org> *  *     This program is free software; you can redistribute it and/or modify *     it under the terms of the GNU General Public License as published by *     the Free Software Foundation; either version 2 of the License, or *     (at your option) any later version. *  *     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, write to the Free Software *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. */ #if HAVE_CONFIG_H# include "config.h"#endif#include "mutt.h"#include "mutt_menu.h"#include "mutt_curses.h"#include "keymap.h"#include "history.h"#include <string.h>/* redraw flags for mutt_enter_string() */enum{  M_REDRAW_INIT = 1,	/* go to end of line and redraw */  M_REDRAW_LINE		/* redraw entire line */};static int my_wcwidth (wchar_t wc){  int n = wcwidth (wc);  if (IsWPrint (wc) && n > 0)    return n;  if (!(wc & ~0x7f))    return 2;  if (!(wc & ~0xffff))    return 6;  return 10;}/* combining mark / non-spacing character */#define COMB_CHAR(wc) (IsWPrint (wc) && !wcwidth (wc))static int my_wcswidth (const wchar_t *s, size_t n){  int w = 0;  while (n--)    w += my_wcwidth (*s++);  return w;}static int my_addwch (wchar_t wc){  int n = wcwidth (wc);  if (IsWPrint (wc) && n > 0)    return mutt_addwch (wc);  if (!(wc & ~0x7f))    return printw ("^%c", ((int)wc + 0x40) & 0x7f);  if (!(wc & ~0xffff))    return printw ("\\u%04x", (int)wc);  return printw ("\\u%08x", (int)wc);}static size_t width_ceiling (const wchar_t *s, size_t n, int w1){  const wchar_t *s0 = s;  int w = 0;  for (; n; s++, n--)    if ((w += my_wcwidth (*s)) > w1)      break;  return s - s0;  }static void my_wcstombs (char *dest, size_t dlen, const wchar_t *src, size_t slen){  mbstate_t st;  size_t k;  /* First convert directly into the destination buffer */  memset (&st, 0, sizeof (st));  for (; slen && dlen >= MB_LEN_MAX; dest += k, dlen -= k, src++, slen--)    if ((k = wcrtomb (dest, *src, &st)) == (size_t)(-1))      break;  /* If this works, we can stop now */  if (dlen >= MB_LEN_MAX) {    wcrtomb (dest, 0, &st);    return;  }  /* Otherwise convert any remaining data into a local buffer */  {    char buf[3 * MB_LEN_MAX];    char *p = buf;    for (; slen && p - buf < dlen; p += k, src++, slen--)      if ((k = wcrtomb (p, *src, &st)) == (size_t)(-1))	break;    p += wcrtomb (p, 0, &st);    /* If it fits into the destination buffer, we can stop now */    if (p - buf <= dlen) {      memcpy (dest, buf, p - buf);      return;    }    /* Otherwise we truncate the string in an ugly fashion */    memcpy (dest, buf, dlen);    dest[dlen - 1] = '\0'; /* assume original dlen > 0 */  }}size_t my_mbstowcs (wchar_t **pwbuf, size_t *pwbuflen, size_t i, char *buf){  wchar_t wc;  mbstate_t st;  size_t k;  wchar_t *wbuf;  size_t wbuflen;  wbuf = *pwbuf, wbuflen = *pwbuflen;  memset (&st, 0, sizeof (st));  for (; (k = mbrtowc (&wc, buf, MB_LEN_MAX, &st)) &&	 k != (size_t)(-1) && k != (size_t)(-2); buf += k)  {    if (i >= wbuflen)    {      wbuflen = i + 20;      safe_realloc (&wbuf, wbuflen * sizeof (*wbuf));    }    wbuf[i++] = wc;  }  *pwbuf = wbuf, *pwbuflen = wbuflen;  return i;}/* * Replace part of the wchar_t buffer, from FROM to CURPOS, by BUF. */static void replace_part (ENTER_STATE *state, size_t from, char *buf){  /* Save the suffix */  size_t savelen = state->lastchar - state->curpos;  wchar_t *savebuf = safe_calloc (savelen, sizeof (wchar_t));  memcpy (savebuf, state->wbuf + state->curpos, savelen * sizeof (wchar_t));  /* Convert to wide characters */  state->curpos = my_mbstowcs (&state->wbuf, &state->wbuflen, from, buf);  /* Make space for suffix */  if (state->curpos + savelen > state->wbuflen)  {    state->wbuflen = state->curpos + savelen;    safe_realloc (&state->wbuf, state->wbuflen * sizeof (wchar_t));  }  /* Restore suffix */  memcpy (state->wbuf + state->curpos, savebuf, savelen * sizeof (wchar_t));  state->lastchar = state->curpos + savelen;  FREE (&savebuf);}/* * Returns: *	1 need to redraw the screen and call me again *	0 if input was given * 	-1 if abort. */int  mutt_enter_string(char *buf, size_t buflen, int y, int x, int flags){  int rv;  ENTER_STATE *es = mutt_new_enter_state ();  rv = _mutt_enter_string (buf, buflen, y, x, flags, 0, NULL, NULL, es);  mutt_free_enter_state (&es);  return rv;}int _mutt_enter_string (char *buf, size_t buflen, int y, int x,			int flags, int multiple, char ***files, int *numfiles,			ENTER_STATE *state){  int width = COLS - x - 1;  int redraw;  int pass = (flags & M_PASS);  int first = 1;  int ch, w, r;  size_t i;  wchar_t *tempbuf = 0;  size_t templen = 0;  history_class_t hclass;  wchar_t wc;  mbstate_t mbstate;  int rv = 0;  memset (&mbstate, 0, sizeof (mbstate));    if (state->wbuf)  {    /* Coming back after return 1 */    redraw = M_REDRAW_LINE;  }  else  {    /* Initialise wbuf from buf */    state->wbuflen = 0;    state->lastchar = my_mbstowcs (&state->wbuf, &state->wbuflen, 0, buf);    redraw = M_REDRAW_INIT;  }  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;      for (;;)  {    if (redraw && !pass)    {      if (redraw == M_REDRAW_INIT)      {	/* Go to end of line */	state->curpos = state->lastchar;	state->begin = width_ceiling (state->wbuf, state->lastchar, my_wcswidth (state->wbuf, state->lastchar) - width + 1);      }       if (state->curpos < state->begin ||	  my_wcswidth (state->wbuf + state->begin, state->curpos - state->begin) >= width)	state->begin = width_ceiling (state->wbuf, state->lastchar, my_wcswidth (state->wbuf, state->curpos) - width / 2);      move (y, x);      w = 0;      for (i = state->begin; i < state->lastchar; i++)      {	w += my_wcwidth (state->wbuf[i]);	if (w > width)	  break;	my_addwch (state->wbuf[i]);      }      clrtoeol ();      move (y, x + my_wcswidth (state->wbuf + state->begin, state->curpos - state->begin));    }    mutt_refresh ();    if ((ch = km_dokey (MENU_EDITOR)) == -1)    {      rv = -1;       goto bye;    }    if (ch != OP_NULL)    {      first = 0;      if (ch != OP_EDITOR_COMPLETE && ch != OP_EDITOR_COMPLETE_QUERY)	state->tabs = 0;      redraw = M_REDRAW_LINE;      switch (ch)      {	case OP_EDITOR_HISTORY_UP:	  state->curpos = state->lastchar;	  replace_part (state, 0, mutt_history_prev (hclass));	  redraw = M_REDRAW_INIT;	  break;	case OP_EDITOR_HISTORY_DOWN:	  state->curpos = state->lastchar;	  replace_part (state, 0, mutt_history_next (hclass));	  redraw = M_REDRAW_INIT;	  break;	case OP_EDITOR_BACKSPACE:	  if (state->curpos == 0)	    BEEP ();	  else	  {	    i = state->curpos;	    while (i && COMB_CHAR (state->wbuf[i - 1]))	      --i;	    if (i)	      --i;	    memmove (state->wbuf + i, state->wbuf + state->curpos, (state->lastchar - state->curpos) * sizeof (wchar_t));	    state->lastchar -= state->curpos - i;	    state->curpos = i;	  }	  break;	case OP_EDITOR_BOL:	  state->curpos = 0;	  break;	case OP_EDITOR_EOL:	  redraw= M_REDRAW_INIT;	  break;	case OP_EDITOR_KILL_LINE:	  state->curpos = state->lastchar = 0;	  break;	case OP_EDITOR_KILL_EOL:	  state->lastchar = state->curpos;	  break;	case OP_EDITOR_BACKWARD_CHAR:	  if (state->curpos == 0)	    BEEP ();	  else	  {	    while (state->curpos && COMB_CHAR (state->wbuf[state->curpos - 1]))	      state->curpos--;	    if (state->curpos)	      state->curpos--;	  }	  break;	case OP_EDITOR_FORWARD_CHAR:	  if (state->curpos == state->lastchar)	    BEEP ();	  else	  {	    ++state->curpos;	    while (state->curpos < state->lastchar && COMB_CHAR (state->wbuf[state->curpos]))	      ++state->curpos;	  }	  break;	case OP_EDITOR_BACKWARD_WORD:	  if (state->curpos == 0)	    BEEP ();	  else	  {	    while (state->curpos && iswspace (state->wbuf[state->curpos - 1]))	      --state->curpos;	    while (state->curpos && !iswspace (state->wbuf[state->curpos - 1]))	      --state->curpos;	  }	  break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -