Blame view

mail/z.c 4.1 KB
1 2
/* GNU Mailutils -- a suite of utilities for electronic mail
   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
3

4
   GNU Mailutils is free software; you can redistribute it and/or modify
5 6 7 8
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

9
   GNU Mailutils is distributed in the hope that it will be useful,
10 11 12 13 14
   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
15
   along with GNU Mailutils; if not, write to the Free Software
Wojciech Polak authored
16
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA  */
17 18 19

#include "mail.h"

Sergey Poznyakoff authored
20 21 22 23 24
/* Scroll directions */
#define D_BWD  -1 /* z- */
#define D_NONE 0  /* z. */
#define D_FWD  1  /* z+ */

25
/*
Sergey Poznyakoff authored
26 27 28 29 30
 * z [+|-|. [count]]
 * Optional [count] specifies number of pages to skip before
 * displaying from lines. Default is 1.
 * . modifier causes command to redisplay the current page, i.e.
 * starting from the current message.
31 32
 */

Sergey Poznyakoff authored
33
static int
34 35
z_parse_args(int argc, char **argv,
	     unsigned int *return_count, int *return_dir)
Sergey Poznyakoff authored
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
{
  int count = 1;
  int mul = 1;
  int dir = D_FWD;
  int an = 0;
  char *argp = NULL;

  argp = &argv[an][1];
  if (*argp == 0)
    {
      an++;
      if (an < argc)
	argp = argv[an];
    }

  if (*argp)
    {
      switch (*argp++)
       {
       case '+':
	 break;
       case '-':
	 dir = D_BWD;
	 break;
       case '.':
	 dir = D_NONE;
	 break;
       default:
64
	 util_error (_("Bad arguments for the scrolling command"));
Sergey Poznyakoff authored
65 66 67 68 69 70 71 72 73 74 75
	 return 1;
       }

      if (*argp == 0)
	{
	  an++;
	  if (an < argc)
	    argp = argv[an];
	}

      argc -= an;
76

Sergey Poznyakoff authored
77 78
      if (argc > 1)
	{
79
	  util_error (_("Too many arguments for the scrolling command"));
Sergey Poznyakoff authored
80 81
	  return 1;
	}
82

Sergey Poznyakoff authored
83 84 85 86
      if (argp && *argp)
	{
	  if (dir == D_NONE)
	    {
87
	      util_error (_("argument not applicable for z."));
Sergey Poznyakoff authored
88 89 90
	      return 1;
	    }

91
	  if ((mul = strtoul (argp, NULL, 10)) == 0)
Sergey Poznyakoff authored
92
	    {
93
	      util_error (_("Bad number of pages"));
Sergey Poznyakoff authored
94 95 96 97 98
	      return 1;
	    }
	}

   }
99

Sergey Poznyakoff authored
100 101
 *return_count = mul * count;
 *return_dir = dir;
102

Sergey Poznyakoff authored
103 104 105
 return 0;
}

106 107 108
int
mail_z (int argc, char **argv)
{
Sergey Poznyakoff authored
109
  unsigned int i, nlines;
110
  unsigned int pagelines = util_screen_lines();
111
  unsigned int count;
Sergey Poznyakoff authored
112
  int dir;
113
  int crs, end;
114
  
Sergey Poznyakoff authored
115 116 117 118
  if (z_parse_args(argc, argv, &count, &dir))
    return 1;

  nlines = pagelines;
119

Sergey Poznyakoff authored
120
  count *= pagelines;
121
  crs = cursor;
Sergey Poznyakoff authored
122 123 124
  switch (dir)
    {
    case D_BWD:
125
      if (crs < nlines)
Sergey Poznyakoff authored
126
	{
127
	  fprintf (stdout, _("On first screenful of messages\n"));
Sergey Poznyakoff authored
128 129
	  return 0;
	}
130 131
      if (crs < count)
	crs = 1;
Sergey Poznyakoff authored
132
      else
133
	crs -= count;
Sergey Poznyakoff authored
134 135 136
      break;

    case D_FWD:
137
      if (crs + pagelines > total)
Sergey Poznyakoff authored
138
	{
139
	  fprintf (stdout, _("On last screenful of messages\n"));
Sergey Poznyakoff authored
140 141 142
	  return 0;
	}

143
      crs += count;
144

145 146
      if (crs + nlines > total)
	nlines = total - crs + 1;
147

Sergey Poznyakoff authored
148 149
      if (nlines <= 0)
	{
150
	  fprintf (stdout, _("On last screenful of messages\n"));
Sergey Poznyakoff authored
151 152
	  return 0;
	}
153
      break;
154

Sergey Poznyakoff authored
155
    case D_NONE:
156
      {
157
	/* z. is a GNU extension, so it will be more useful
158
	   when we reach the last message to show a full screen
159
	   of the last message.  This behaviour is used on startup
160
	   when displaying the summary and the headers, new messages
161
	   are last but we want to display a screenful with the
162
	   real crs set by summary() to the new message.  */
163

164 165 166 167
	/* Find the start of the last screen page.  */
	int lastpage =  total - pagelines + 1;
	if (lastpage <= 0)
	  lastpage = 1;
168

169
	if (crs > (unsigned int)lastpage)
170
	  {
171 172 173 174 175 176 177
	    crs = lastpage;

	    if (crs + nlines > total)
	      nlines = total - crs;

	    util_range_msg (crs, crs + nlines,
			    MSG_NODELETED|MSG_SILENT, mail_from0, NULL);
178 179
	    return 1;
	  }
180 181
	else if (crs + nlines > total)
	  nlines = total - crs + 1;
182
      }
Sergey Poznyakoff authored
183 184
      break;
    }
185

186
  cursor = crs;
187
  end = cursor + nlines - 1;
188 189
  i = 0;
  do
Sergey Poznyakoff authored
190
    {
191
      int cnt = util_range_msg (crs, end,
192 193 194 195 196
				MSG_NODELETED|MSG_SILENT, mail_from0, NULL);
      if (cnt == 0)
	break;
      i += cnt;
      crs += nlines;
Sergey Poznyakoff authored
197
    }
198
  while (i < nlines && crs <= total);
199

200 201
  return 1;
}