update to 1.01
[nvi.git] / ex / ex_z.c
blob80f63084db9684f81fe70386839c9382dbb4c916
1 /*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
6 */
8 #ifndef lint
9 static char sccsid[] = "$Id: ex_z.c,v 8.4 1993/12/02 14:02:39 bostic Exp $ (Berkeley) $Date: 1993/12/02 14:02:39 $";
10 #endif /* not lint */
12 #include <sys/types.h>
14 #include <stdlib.h>
15 #include <string.h>
17 #include "vi.h"
18 #include "excmd.h"
21 * ex_z -- :[line] z [^-.+=] [count] [flags]
23 * Adjust window.
25 int
26 ex_z(sp, ep, cmdp)
27 SCR *sp;
28 EXF *ep;
29 EXCMDARG *cmdp;
31 recno_t cnt, equals, lno;
32 int eofcheck;
35 * !!!
36 * If no count specified, use either two times the size of the
37 * scrolling region, or the size of the window option. POSIX
38 * 1003.2 claims that the latter is correct, but historic ex/vi
39 * documentation and practice appear to use the scrolling region.
40 * I'm using the window size as it means that the entire screen
41 * is used instead of losing a line to roundoff. Note, we drop
42 * a line from the cnt if using the window size to leave room for
43 * the next ex prompt.
45 if (F_ISSET(cmdp, E_COUNT))
46 cnt = cmdp->count;
47 else
48 #ifdef HISTORIC_PRACTICE
49 cnt = O_VAL(sp, O_SCROLL) * 2;
50 #else
51 cnt = O_VAL(sp, O_WINDOW) - 1;
52 #endif
54 equals = 0;
55 eofcheck = 0;
56 lno = cmdp->addr1.lno;
58 switch (F_ISSET(cmdp,
59 E_F_CARAT | E_F_DASH | E_F_DOT | E_F_EQUAL | E_F_PLUS)) {
60 case E_F_CARAT: /* Display cnt * 2 before the line. */
61 eofcheck = 1;
62 if (lno > cnt * 2)
63 cmdp->addr1.lno = (lno - cnt * 2) + 1;
64 else
65 cmdp->addr1.lno = 1;
66 cmdp->addr2.lno = (cmdp->addr1.lno + cnt) - 1;
67 break;
68 case E_F_DASH: /* Line goes at the bottom of the screen. */
69 cmdp->addr1.lno = lno > cnt ? (lno - cnt) + 1 : 1;
70 cmdp->addr2.lno = lno;
71 break;
72 case E_F_DOT: /* Line goes in the middle of the screen. */
74 * !!!
75 * Historically, the "middleness" of the line overrode the
76 * count, so that "3z.19" or "3z.20" would display the first
77 * 12 lines of the file, i.e. (N - 1) / 2 lines before and
78 * after the specified line.
80 eofcheck = 1;
81 cnt = (cnt - 1) / 2;
82 cmdp->addr1.lno = lno > cnt ? lno - cnt : 1;
83 cmdp->addr2.lno = lno + cnt;
84 break;
85 case E_F_EQUAL: /* Center with hyphens. */
87 * !!!
88 * Strangeness. The '=' flag is like the '.' flag (see the
89 * above comment, it applies here as well) but with a special
90 * little hack. Print out lines of hyphens before and after
91 * the specified line. Additionally, the cursor remains set
92 * on that line.
94 eofcheck = 1;
95 cnt = (cnt - 1) / 2;
96 cmdp->addr1.lno = lno > cnt ? lno - cnt : 1;
97 cmdp->addr2.lno = lno - 1;
98 if (ex_pr(sp, ep, cmdp))
99 return (1);
100 (void)ex_printf(EXCOOKIE,
101 "%s", "----------------------------------------\n");
102 cmdp->addr2.lno = cmdp->addr1.lno = equals = lno;
103 if (ex_pr(sp, ep, cmdp))
104 return (1);
105 (void)ex_printf(EXCOOKIE,
106 "%s", "----------------------------------------\n");
107 cmdp->addr1.lno = lno + 1;
108 cmdp->addr2.lno = (lno + cnt) - 1;
109 break;
110 default:
111 /* If no line specified, move to the next one. */
112 if (F_ISSET(cmdp, E_ADDRDEF))
113 ++lno;
114 /* FALLTHROUGH */
115 case E_F_PLUS: /* Line goes at the top of the screen. */
116 eofcheck = 1;
117 cmdp->addr1.lno = lno;
118 cmdp->addr2.lno = (lno + cnt) - 1;
119 break;
122 if (eofcheck) {
123 if (file_lline(sp, ep, &lno))
124 return (1);
125 if (cmdp->addr2.lno > lno)
126 cmdp->addr2.lno = lno;
129 if (ex_pr(sp, ep, cmdp))
130 return (1);
131 if (equals)
132 sp->lno = equals;
133 return (0);