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

📄 pager.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 5 页
字号:
	  break;    }    /* is anything left to do? */    if (ch >= cnt)      break;        k = mbrtowc (&wc, (char *)buf+ch, cnt-ch, &mbstate);    if (k == -2 || k == -1)    {      dprint (1, (debugfile, "%s:%d: mbrtowc returned %d; errno = %d.\n",		  __FILE__, __LINE__, k, errno));      if (col + 4 > wrap_cols)	break;      col += 4;      if (pa)	printw ("\\%03o", buf[ch]);      k = 1;      continue;    }    if (k == 0)      k = 1;    /* Handle backspace */    special = 0;    if (IsWPrint (wc))    {      wchar_t wc1;      mbstate_t mbstate1;      int k1, k2;      while ((wc1 = 0, mbstate1 = mbstate,	      k1 = k + mbrtowc (&wc1, (char *)buf+ch+k, cnt-ch-k, &mbstate1),	      k1 - k > 0 && wc1 == '\b') &&	     (wc1 = 0,	      k2 = mbrtowc (&wc1, (char *)buf+ch+k1, cnt-ch-k1, &mbstate1),	      k2 > 0 && IsWPrint (wc1)))      {	if (wc == wc1)	{	  special |= (wc == '_' && special & A_UNDERLINE)	    ? A_UNDERLINE : A_BOLD;	}	else if (wc == '_' || wc1 == '_')	{	  special |= A_UNDERLINE;	  wc = (wc1 == '_') ? wc : wc1;	}	else	{	  /* special = 0; / * overstrike: nothing to do! */	  wc = wc1;	}	ch += k1;	k = k2;	mbstate = mbstate1;      }    }    if (pa &&	((flags & (M_SHOWCOLOR | M_SEARCH | M_PAGER_MARKER)) ||	 special || last_special || pa->attr))    {      resolve_color (*lineInfo, n, vch, flags, special, pa);      last_special = special;    }    if (IsWPrint (wc))    {      if (wc == ' ')	space = ch;      t = wcwidth (wc);      if (col + t > wrap_cols)	break;      col += t;      if (pa)	mutt_addwch (wc);    }    else if (wc == '\n')      break;    else if (wc == '\t')    {      space = ch;      t = (col & ~7) + 8;      if (t > wrap_cols)	break;      if (pa)	for (; col < t; col++)	  addch (' ');      else	col = t;    }    else if (wc < 0x20 || wc == 0x7f)    {      if (col + 2 > wrap_cols)	break;      col += 2;      if (pa)	printw ("^%c", ('@' + wc) & 0x7f);    }    else if (wc < 0x100)    {      if (col + 4 > wrap_cols)	break;      col += 4;      if (pa)	printw ("\\%03o", wc);    }    else    {      if (col + 1 > wrap_cols)	break;      ++col;      if (pa)	addch (replacement_char ());    }  }  *pspace = space;  *pcol = col;  *pvch = vch;  *pspecial = special;  return ch;}/* * Args: *	flags	M_SHOWFLAT, show characters (used for displaying help) *		M_SHOWCOLOR, show characters in color *			otherwise don't show characters *		M_HIDE, don't show quoted text *		M_SEARCH, resolve search patterns *		M_TYPES, compute line's type *		M_PAGER_NSKIP, keeps leading whitespace *		M_PAGER_MARKER, eventually show markers * * Return values: *	-1	EOF was reached *	0	normal exit, line was not displayed *	>0	normal exit, line was displayed */static intdisplay_line (FILE *f, LOFF_T *last_pos, struct line_t **lineInfo, int n, 	      int *last, int *max, int flags, struct q_class_t **QuoteList,	      int *q_level, int *force_redraw, regex_t *SearchRE){  unsigned char buf[LONG_STRING], fmt[LONG_STRING];  unsigned char *buf_ptr = buf;  int ch, vch, col, cnt, b_read;  int buf_ready = 0, change_last = 0;  int special;  int offset;  int def_color;  int m;  ansi_attr a = {0,0,0,-1};  regmatch_t pmatch[1];  if (n == *last)  {    (*last)++;    change_last = 1;  }  if (*last == *max)  {    safe_realloc (lineInfo, sizeof (struct line_t) * (*max += LINES));    for (ch = *last; ch < *max ; ch++)    {      memset (&((*lineInfo)[ch]), 0, sizeof (struct line_t));      (*lineInfo)[ch].type = -1;      (*lineInfo)[ch].search_cnt = -1;      (*lineInfo)[ch].syntax = safe_malloc (sizeof (struct syntax_t));      ((*lineInfo)[ch].syntax)[0].first = ((*lineInfo)[ch].syntax)[0].last = -1;    }  }  /* only do color hiliting if we are viewing a message */  if (flags & (M_SHOWCOLOR | M_TYPES))  {    if ((*lineInfo)[n].type == -1)    {      /* determine the line class */      if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, buf, fmt, sizeof (buf), &buf_ready) < 0)      {	if (change_last)	  (*last)--;	return (-1);      }      resolve_types ((char *) fmt, (char *) buf, *lineInfo, n, *last,		      QuoteList, q_level, force_redraw, flags & M_SHOWCOLOR);      /* avoid race condition for continuation lines when scrolling up */      for (m = n + 1; m < *last && (*lineInfo)[m].offset && (*lineInfo)[m].continuation; m++)	(*lineInfo)[m].type = (*lineInfo)[n].type;    }    /* this also prevents searching through the hidden lines */    if ((flags & M_HIDE) && (*lineInfo)[n].type == MT_COLOR_QUOTED)      flags = 0; /* M_NOSHOW */  }  /* At this point, (*lineInfo[n]).quote may still be undefined. We    * don't want to compute it every time M_TYPES is set, since this   * would slow down the "bottom" function unacceptably. A compromise   * solution is hence to call regexec() again, just to find out the   * length of the quote prefix.   */  if ((flags & M_SHOWCOLOR) && !(*lineInfo)[n].continuation &&      (*lineInfo)[n].type == MT_COLOR_QUOTED && (*lineInfo)[n].quote == NULL)  {    if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, buf, fmt, sizeof (buf), &buf_ready) < 0)    {      if (change_last)	(*last)--;      return (-1);    }    regexec ((regex_t *) QuoteRegexp.rx, (char *) fmt, 1, pmatch, 0);    (*lineInfo)[n].quote = classify_quote (QuoteList,			    (char *) fmt + pmatch[0].rm_so,			    pmatch[0].rm_eo - pmatch[0].rm_so,			    force_redraw, q_level);  }  if ((flags & M_SEARCH) && !(*lineInfo)[n].continuation && (*lineInfo)[n].search_cnt == -1)   {    if (fill_buffer (f, last_pos, (*lineInfo)[n].offset, buf, fmt, sizeof (buf), &buf_ready) < 0)    {      if (change_last)	(*last)--;      return (-1);    }    offset = 0;    (*lineInfo)[n].search_cnt = 0;    while (regexec (SearchRE, (char *) fmt + offset, 1, pmatch, (offset ? REG_NOTBOL : 0)) == 0)    {      if (++((*lineInfo)[n].search_cnt) > 1)	safe_realloc (&((*lineInfo)[n].search),		      ((*lineInfo)[n].search_cnt) * sizeof (struct syntax_t));      else	(*lineInfo)[n].search = safe_malloc (sizeof (struct syntax_t));      pmatch[0].rm_so += offset;      pmatch[0].rm_eo += offset;      ((*lineInfo)[n].search)[(*lineInfo)[n].search_cnt - 1].first = pmatch[0].rm_so;      ((*lineInfo)[n].search)[(*lineInfo)[n].search_cnt - 1].last = pmatch[0].rm_eo;      if (pmatch[0].rm_eo == pmatch[0].rm_so)	offset++; /* avoid degenerate cases */      else	offset = pmatch[0].rm_eo;      if (!fmt[offset])	break;    }  }  if (!(flags & M_SHOW) && (*lineInfo)[n+1].offset > 0)  {    /* we've already scanned this line, so just exit */    return (0);  }  if ((flags & M_SHOWCOLOR) && *force_redraw && (*lineInfo)[n+1].offset > 0)  {    /* no need to try to display this line... */    return (1); /* fake display */  }  if ((b_read = fill_buffer (f, last_pos, (*lineInfo)[n].offset, buf, fmt, 			      sizeof (buf), &buf_ready)) < 0)  {    if (change_last)      (*last)--;    return (-1);  }  /* now chose a good place to break the line */  cnt = format_line (lineInfo, n, buf, flags, 0, b_read, &ch, &vch, &col, &special);  buf_ptr = buf + cnt;  /* move the break point only if smart_wrap is set */  if (option (OPTWRAP))  {    if (cnt < b_read)    {      if (ch != -1 && buf[cnt] != ' ' && buf[cnt] != '\t' && buf[cnt] != '\n' && buf[cnt] != '\r')      {	buf_ptr = buf + ch;	/* skip trailing blanks */	while (ch && (buf[ch] == ' ' || buf[ch] == '\t' || buf[ch] == '\r'))	  ch--;        /* a very long word with leading spaces causes infinite wrapping */        if ((!ch) && (flags & M_PAGER_NSKIP))          buf_ptr = buf + cnt;        else          cnt = ch + 1;      }      else	buf_ptr = buf + cnt; /* a very long word... */    }    if (!(flags & M_PAGER_NSKIP))      /* skip leading blanks on the next line too */      while (*buf_ptr == ' ' || *buf_ptr == '\t') 	buf_ptr++;  }  if (*buf_ptr == '\r')    buf_ptr++;  if (*buf_ptr == '\n')    buf_ptr++;  if ((int) (buf_ptr - buf) < b_read && !(*lineInfo)[n+1].continuation)    append_line (*lineInfo, n, (int) (buf_ptr - buf));  (*lineInfo)[n+1].offset = (*lineInfo)[n].offset + (long) (buf_ptr - buf);  /* if we don't need to display the line we are done */  if (!(flags & M_SHOW))    return 0;  /* display the line */  format_line (lineInfo, n, buf, flags, &a, cnt, &ch, &vch, &col, &special);  /* avoid a bug in ncurses... */#ifndef USE_SLANG_CURSES  if (col == 0)  {    SETCOLOR (MT_COLOR_NORMAL);    addch (' ');  }#endif  /* end the last color pattern (needed by S-Lang) */  if (special || (col != COLS && (flags & (M_SHOWCOLOR | M_SEARCH))))    resolve_color (*lineInfo, n, vch, flags, 0, &a);            /*   * Fill the blank space at the end of the line with the prevailing color.   * ncurses does an implicit clrtoeol() when you do addch('\n') so we have   * to make sure to reset the color *after* that   */  if (flags & M_SHOWCOLOR)  {    m = ((*lineInfo)[n].continuation) ? ((*lineInfo)[n].syntax)[0].first : n;    if ((*lineInfo)[m].type == MT_COLOR_HEADER)      def_color = ((*lineInfo)[m].syntax)[0].color;    else      def_color = ColorDefs[ (*lineInfo)[m].type ];    attrset (def_color);#ifdef HAVE_BKGDSET    bkgdset (def_color | ' ');#endif  }  /* ncurses always wraps lines when you get to the right side of the   * screen, but S-Lang seems to only wrap if the next character is *not*   * a newline (grr!).   */#ifndef USE_SLANG_CURSES    if (col < COLS)#endif      addch ('\n');  /*   * reset the color back to normal.  This *must* come after the   * addch('\n'), otherwise the color for this line will not be   * filled to the right margin.   */  if (flags & M_SHOWCOLOR)  {    SETCOLOR(MT_COLOR_NORMAL);    BKGDSET(MT_COLOR_NORMAL);  }  /* build a return code */  if (!(flags & M_SHOW))    flags = 0;  return (flags);}static intupNLines (int nlines, struct line_t *info, int cur, int hiding){  while (cur > 0 && nlines > 0)  {    cur--;    if (!hiding || info[cur].type != MT_COLOR_QUOTED)      nlines--;  }  return cur;}static struct mapping_t PagerHelp[] = {  { N_("Exit"),	OP_EXIT },  { N_("PrevPg"), OP_PREV_PAGE },  { N_("NextPg"), OP_NEXT_PAGE },  { NULL,	0 }};static struct mapping_t PagerHelpExtra[] = {  { N_("View Attachm."), OP_VIEW_ATTACHMENTS },  { N_("Del"), OP_DELETE },  { N_("Reply"), OP_REPLY },  { N_("Next"),	OP_MAIN_NEXT_UNDELETED },  { NULL,	0 }};/* This pager is actually not so simple as it once was.  It now operates in   two modes: one for viewing messages and the other for viewing help.  These   can be distinguished by whether or not ``hdr'' is NULL.  The ``hdr'' arg   is there so that we can do operations on the current message without the   need to pop back out to the main-menu.  */int mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra){  static char searchbuf[STRING];  char buffer[LONG_STRING];  char helpstr[SHORT_STRING*2];  char tmphelp[SHORT_STRING*2];  int maxLine, lastLine = 0;  struct line_t *lineInfo;  struct q_class_t *QuoteList = NULL;  int i, j, ch = 0, rc = -1, hideQuoted = 0, q_level = 0, force_redraw = 0;  int lines = 0, curline = 0, topline = 0, oldtopline = 0, err, first = 1;  int r = -1;  int redraw = REDRAW_FULL;  FILE *fp = NULL;  LOFF_T last_pos = 0, last_offset = 0;  int old_smart_wrap, old_markers;  struct stat sb;  regex_t SearchRE;  int SearchCompiled = 0, SearchFlag = 0, SearchBack = 0;  int has_types = (IsHeader(extra) || (flags & M_SHOWCOLOR)) ? M_TYPES : 0; /* main message or rfc822 attachment */  int bodyoffset = 1;			/* offset of first line of real text */  int statusoffset = 0; 		/* offset for the status bar */  int helpoffset = LINES - 2;		/* offset for the help bar. */  int bodylen = LINES - 2 - bodyoffset; /* length of displayable area */  MUTTMENU *index = NULL;		/* the Pager Index (PI) */  int indexoffset = 0;			/* offset for the PI */  int indexlen = PagerIndexLines;	/* indexlen not always == PIL */  int indicator = indexlen / 3; 	/* the indicator line of the PI */  int old_PagerIndexLines;		/* some people want to resize it  					 * while inside the pager... */  if (!(flags & M_SHOWCOLOR))    flags |= M_SHOWFLAT;  if ((fp = fopen (fname, "r")) == NULL)  {    mutt_perror (fname);    return (-1);  }  if (stat (fname, &sb) != 0)  {    mutt_perror (fname);    fclose (fp);    return (-1);  }  unlink (fname);  /* Initialize variables */  if (IsHeader (extra) && !extra->hdr->read)  {    Context->msgnotreadyet = extra->hdr->msgno;    mutt_set_flag (Context, extra->hdr, M_READ, 1);  }  lineInfo = safe_malloc (sizeof (struct line_t) * (maxLine = LINES));  for (i = 0 ; i < maxLine ; i++)  {    memset (&lineInfo[i], 0, sizeof (struct line_t));    lineInfo[i].type = -1;    lineInfo[i].search_cnt = -1;    lineInfo[i].syntax = safe_malloc (sizeof (struct syntax_t));    (lineInfo[i].syntax)[0].first = (lineInfo[i].syntax)[0].last = -1;  }  mutt_compile_help (helpstr, sizeof (helpstr), MENU_PAGER, PagerHelp);  if (IsHeader (extra))  {    strfcpy (tmphelp, helpstr, sizeof (tmphelp));    mutt_compile_help (buffer, sizeof (buffer), MENU_PAGER, PagerHelpExtra);    snprintf (helpstr, sizeof (helpstr), "%s %s", tmphelp, buffer);  }  if (!InHelp)  {    strfcpy (tmphelp, helpstr, sizeof (tmphelp));    mutt_make_help (buffer, sizeof (buffer), _("Help"), MENU_PAGER, OP_HELP);    snprintf (helpstr, sizeof (helpstr), "%s %s", tmphelp, buffer);  }  while (ch != -1)  {    mutt_curs_set (0);#ifdef USE_IMAP    imap_keepalive ();#endif        if (redraw & REDRAW_FULL)    {      SETCOLOR (MT_COLOR_NORMAL);      /* clear() doesn't optimize screen redraws */      move (0, 0);      clrtobot ();      if (IsHeader (extra) && Context->vcount + 1 < PagerIndexLines)	indexlen = Context->vcount + 1;      else	indexlen = PagerIndexLines;      indicator = indexlen / 3;      if (option (OPTSTATUSONTOP))      {	indexoffset = 0;	statusoffset = IsHeader (extra) ? indexlen : 0;	bodyoffset = statusoffset + 1;	helpoffset = LINES - 2;	bodylen = helpoffset - bodyoffset;	if (!option (OPTHELP))	  bodylen++;      }      else      {	helpoffset = 0;	indexoffset = 1;	statusoffset = LINES - 2;	if (!option (OPTHELP))	  indexoffset = 0;	bodyoffset = indexoffset + (IsHeader (extra) ? indexlen : 0);	bodylen = statusoffset - bodyoffset;      }      if (option (OPTHELP))      {	SETCOLOR (MT_COLOR_STATUS);	move (helpoffset, 0);	mutt_paddstr (COLS, helpstr);	SETCOLOR (MT_COLOR_NORMAL);

⌨️ 快捷键说明

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