1 /* $NetBSD: v_z.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */
3 * Copyright (c) 1992, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1992, 1993, 1994, 1995, 1996
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
13 #include <sys/cdefs.h>
16 static const char sccsid
[] = "Id: v_z.c,v 10.12 2001/06/25 15:19:36 skimo Exp (Berkeley) Date: 2001/06/25 15:19:36 ";
19 __RCSID("$NetBSD: v_z.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
22 #include <sys/types.h>
23 #include <sys/queue.h>
26 #include <bitstring.h>
30 #include "../common/common.h"
34 * v_z -- [count]z[count][-.+^<CR>]
37 * PUBLIC: int v_z __P((SCR *, VICMD *));
40 v_z(SCR
*sp
, VICMD
*vp
)
46 * The first count is the line to use. If the value doesn't
47 * exist, use the last line.
49 if (F_ISSET(vp
, VC_C1SET
)) {
51 if (!db_exist(sp
, lno
) && db_last(sp
, &lno
))
54 lno
= vp
->m_start
.lno
;
56 /* Set default return cursor line. */
57 vp
->m_final
.lno
= lno
;
58 vp
->m_final
.cno
= vp
->m_start
.cno
;
61 * The second count is the displayed window size, i.e. the 'z' command
62 * is another way to get artificially small windows. Note, you can't
63 * grow beyond the size of the window.
66 * A window size of 0 was historically allowed, and simply ignored.
67 * This could be much more simply done by modifying the value of the
68 * O_WINDOW option, but that's not how it worked historically.
70 if (F_ISSET(vp
, VC_C2SET
) && vp
->count2
!= 0) {
71 if (vp
->count2
> O_VAL(sp
, O_WINDOW
))
72 vp
->count2
= O_VAL(sp
, O_WINDOW
);
73 if (vs_crel(sp
, vp
->count2
))
77 switch (vp
->character
) {
78 case '-': /* Put the line at the bottom. */
79 if (vs_sm_fill(sp
, lno
, P_BOTTOM
))
82 case '.': /* Put the line in the middle. */
83 if (vs_sm_fill(sp
, lno
, P_MIDDLE
))
88 * If the user specified a line number, put that line at the
89 * top and move the cursor to it. Otherwise, scroll forward
90 * a screen from the current screen.
92 if (F_ISSET(vp
, VC_C1SET
)) {
93 if (vs_sm_fill(sp
, lno
, P_TOP
))
95 if (vs_sm_position(sp
, &vp
->m_final
, 0, P_TOP
))
98 if (vs_sm_scroll(sp
, &vp
->m_final
, sp
->t_rows
, Z_PLUS
))
103 * If the user specified a line number, put that line at the
104 * bottom, move the cursor to it, and then display the screen
105 * before that one. Otherwise, scroll backward a screen from
106 * the current screen.
109 * Note, we match the off-by-one characteristics of historic
112 if (F_ISSET(vp
, VC_C1SET
)) {
113 if (vs_sm_fill(sp
, lno
, P_BOTTOM
))
115 if (vs_sm_position(sp
, &vp
->m_final
, 0, P_TOP
))
117 if (vs_sm_fill(sp
, vp
->m_final
.lno
, P_BOTTOM
))
120 if (vs_sm_scroll(sp
, &vp
->m_final
, sp
->t_rows
, Z_CARAT
))
123 default: /* Put the line at the top for <cr>. */
124 value
= KEY_VAL(sp
, vp
->character
);
125 if (value
!= K_CR
&& value
!= K_NL
) {
126 v_emsg(sp
, vp
->kp
->usage
, VIM_USAGE
);
129 if (vs_sm_fill(sp
, lno
, P_TOP
))
138 * Change the relative size of the current screen.
140 * PUBLIC: int vs_crel __P((SCR *, long));
143 vs_crel(SCR
*sp
, long int count
)
145 sp
->t_minrows
= sp
->t_rows
= count
;
146 if (sp
->t_rows
> sp
->rows
- 1)
147 sp
->t_minrows
= sp
->t_rows
= sp
->rows
- 1;
148 TMAP
= HMAP
+ (sp
->t_rows
- 1);
149 F_SET(sp
, SC_SCR_REDRAW
);