1/*	$NetBSD: v_z.c,v 1.2 2013/11/22 15:52:06 christos Exp $ */
2/*-
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.
7 *
8 * See the LICENSE file for redistribution information.
9 */
10
11#include "config.h"
12
13#include <sys/cdefs.h>
14#if 0
15#ifndef lint
16static 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 ";
17#endif /* not lint */
18#else
19__RCSID("$NetBSD$");
20#endif
21
22#include <sys/types.h>
23#include <sys/queue.h>
24#include <sys/time.h>
25
26#include <bitstring.h>
27#include <limits.h>
28#include <stdio.h>
29
30#include "../common/common.h"
31#include "vi.h"
32
33/*
34 * v_z -- [count]z[count][-.+^<CR>]
35 *	Move the screen.
36 *
37 * PUBLIC: int v_z __P((SCR *, VICMD *));
38 */
39int
40v_z(SCR *sp, VICMD *vp)
41{
42	db_recno_t lno;
43	e_key_t value;
44
45	/*
46	 * The first count is the line to use.  If the value doesn't
47	 * exist, use the last line.
48	 */
49	if (F_ISSET(vp, VC_C1SET)) {
50		lno = vp->count;
51		if (!db_exist(sp, lno) && db_last(sp, &lno))
52			return (1);
53	} else
54		lno = vp->m_start.lno;
55
56	/* Set default return cursor line. */
57	vp->m_final.lno = lno;
58	vp->m_final.cno = vp->m_start.cno;
59
60	/*
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.
64	 *
65	 * !!!
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.
69	 */
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))
74			return (1);
75	}
76
77	switch (vp->character) {
78	case '-':		/* Put the line at the bottom. */
79		if (vs_sm_fill(sp, lno, P_BOTTOM))
80			return (1);
81		break;
82	case '.':		/* Put the line in the middle. */
83		if (vs_sm_fill(sp, lno, P_MIDDLE))
84			return (1);
85		break;
86	case '+':
87		/*
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.
91		 */
92		if (F_ISSET(vp, VC_C1SET)) {
93			if (vs_sm_fill(sp, lno, P_TOP))
94				return (1);
95			if (vs_sm_position(sp, &vp->m_final, 0, P_TOP))
96				return (1);
97		} else
98			if (vs_sm_scroll(sp, &vp->m_final, sp->t_rows, Z_PLUS))
99				return (1);
100		break;
101	case '^':
102		/*
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.
107		 *
108		 * !!!
109		 * Note, we match the off-by-one characteristics of historic
110		 * vi, here.
111		 */
112		if (F_ISSET(vp, VC_C1SET)) {
113			if (vs_sm_fill(sp, lno, P_BOTTOM))
114				return (1);
115			if (vs_sm_position(sp, &vp->m_final, 0, P_TOP))
116				return (1);
117			if (vs_sm_fill(sp, vp->m_final.lno, P_BOTTOM))
118				return (1);
119		} else
120			if (vs_sm_scroll(sp, &vp->m_final, sp->t_rows, Z_CARAT))
121				return (1);
122		break;
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);
127			return (1);
128		}
129		if (vs_sm_fill(sp, lno, P_TOP))
130			return (1);
131		break;
132	}
133	return (0);
134}
135
136/*
137 * vs_crel --
138 *	Change the relative size of the current screen.
139 *
140 * PUBLIC: int vs_crel __P((SCR *, long));
141 */
142int
143vs_crel(SCR *sp, long int count)
144{
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);
150	return (0);
151}
152