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