source: trunk/third/nvi/vi/v_z.c @ 14302

Revision 14302, 3.5 KB checked in by ghudson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14301, which included commits to RCS files with non-trunk default branches.
Line 
1/*-
2 * Copyright (c) 1992, 1993, 1994
3 *      The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 *      Keith Bostic.  All rights reserved.
6 *
7 * See the LICENSE file for redistribution information.
8 */
9
10#include "config.h"
11
12#ifndef lint
13static const char sccsid[] = "@(#)v_z.c 10.10 (Berkeley) 5/16/96";
14#endif /* not lint */
15
16#include <sys/types.h>
17#include <sys/queue.h>
18#include <sys/time.h>
19
20#include <bitstring.h>
21#include <limits.h>
22#include <stdio.h>
23
24#include "../common/common.h"
25#include "vi.h"
26
27/*
28 * v_z -- [count]z[count][-.+^<CR>]
29 *      Move the screen.
30 *
31 * PUBLIC: int v_z __P((SCR *, VICMD *));
32 */
33int
34v_z(sp, vp)
35        SCR *sp;
36        VICMD *vp;
37{
38        recno_t lno;
39        u_int value;
40
41        /*
42         * The first count is the line to use.  If the value doesn't
43         * exist, use the last line.
44         */
45        if (F_ISSET(vp, VC_C1SET)) {
46                lno = vp->count;
47                if (!db_exist(sp, lno) && db_last(sp, &lno))
48                        return (1);
49        } else
50                lno = vp->m_start.lno;
51
52        /* Set default return cursor line. */
53        vp->m_final.lno = lno;
54        vp->m_final.cno = vp->m_start.cno;
55
56        /*
57         * The second count is the displayed window size, i.e. the 'z' command
58         * is another way to get artificially small windows.  Note, you can't
59         * grow beyond the size of the window.
60         *
61         * !!!
62         * A window size of 0 was historically allowed, and simply ignored.
63         * This could be much more simply done by modifying the value of the
64         * O_WINDOW option, but that's not how it worked historically.
65         */
66        if (F_ISSET(vp, VC_C2SET) && vp->count2 != 0) {
67                if (vp->count2 > O_VAL(sp, O_WINDOW))
68                        vp->count2 = O_VAL(sp, O_WINDOW);
69                if (vs_crel(sp, vp->count2))
70                        return (1);
71        }
72
73        switch (vp->character) {
74        case '-':               /* Put the line at the bottom. */
75                if (vs_sm_fill(sp, lno, P_BOTTOM))
76                        return (1);
77                break;
78        case '.':               /* Put the line in the middle. */
79                if (vs_sm_fill(sp, lno, P_MIDDLE))
80                        return (1);
81                break;
82        case '+':
83                /*
84                 * If the user specified a line number, put that line at the
85                 * top and move the cursor to it.  Otherwise, scroll forward
86                 * a screen from the current screen.
87                 */
88                if (F_ISSET(vp, VC_C1SET)) {
89                        if (vs_sm_fill(sp, lno, P_TOP))
90                                return (1);
91                        if (vs_sm_position(sp, &vp->m_final, 0, P_TOP))
92                                return (1);
93                } else
94                        if (vs_sm_scroll(sp, &vp->m_final, sp->t_rows, Z_PLUS))
95                                return (1);
96                break;
97        case '^':
98                /*
99                 * If the user specified a line number, put that line at the
100                 * bottom, move the cursor to it, and then display the screen
101                 * before that one.  Otherwise, scroll backward a screen from
102                 * the current screen.
103                 *
104                 * !!!
105                 * Note, we match the off-by-one characteristics of historic
106                 * vi, here.
107                 */
108                if (F_ISSET(vp, VC_C1SET)) {
109                        if (vs_sm_fill(sp, lno, P_BOTTOM))
110                                return (1);
111                        if (vs_sm_position(sp, &vp->m_final, 0, P_TOP))
112                                return (1);
113                        if (vs_sm_fill(sp, vp->m_final.lno, P_BOTTOM))
114                                return (1);
115                } else
116                        if (vs_sm_scroll(sp, &vp->m_final, sp->t_rows, Z_CARAT))
117                                return (1);
118                break;
119        default:                /* Put the line at the top for <cr>. */
120                value = KEY_VAL(sp, vp->character);
121                if (value != K_CR && value != K_NL) {
122                        v_emsg(sp, vp->kp->usage, VIM_USAGE);
123                        return (1);
124                }
125                if (vs_sm_fill(sp, lno, P_TOP))
126                        return (1);
127                break;
128        }
129        return (0);
130}
131
132/*
133 * vs_crel --
134 *      Change the relative size of the current screen.
135 *
136 * PUBLIC: int vs_crel __P((SCR *, long));
137 */
138int
139vs_crel(sp, count)
140        SCR *sp;
141        long count;
142{
143        sp->t_minrows = sp->t_rows = count;
144        if (sp->t_rows > sp->rows - 1)
145                sp->t_minrows = sp->t_rows = sp->rows - 1;
146        TMAP = HMAP + (sp->t_rows - 1);
147        F_SET(sp, SC_SCR_REDRAW);
148        return (0);
149}
Note: See TracBrowser for help on using the repository browser.