119304Speter/*- 219304Speter * Copyright (c) 1992, 1993, 1994 319304Speter * The Regents of the University of California. All rights reserved. 419304Speter * Copyright (c) 1992, 1993, 1994, 1995, 1996 519304Speter * Keith Bostic. All rights reserved. 619304Speter * 719304Speter * See the LICENSE file for redistribution information. 819304Speter */ 919304Speter 1019304Speter#include "config.h" 1119304Speter 1219304Speter#ifndef lint 13254225Speterstatic const char sccsid[] = "$Id: v_z.c,v 10.13 2011/12/02 17:26:59 zy Exp $"; 1419304Speter#endif /* not lint */ 1519304Speter 1619304Speter#include <sys/types.h> 1719304Speter#include <sys/queue.h> 1819304Speter#include <sys/time.h> 1919304Speter 2019304Speter#include <bitstring.h> 2119304Speter#include <limits.h> 2219304Speter#include <stdio.h> 2319304Speter 2419304Speter#include "../common/common.h" 2519304Speter#include "vi.h" 2619304Speter 2719304Speter/* 2819304Speter * v_z -- [count]z[count][-.+^<CR>] 2919304Speter * Move the screen. 3019304Speter * 3119304Speter * PUBLIC: int v_z __P((SCR *, VICMD *)); 3219304Speter */ 3319304Speterint 34254225Speterv_z(SCR *sp, VICMD *vp) 3519304Speter{ 3619304Speter recno_t lno; 37254225Speter e_key_t value; 3819304Speter 3919304Speter /* 4019304Speter * The first count is the line to use. If the value doesn't 4119304Speter * exist, use the last line. 4219304Speter */ 4319304Speter if (F_ISSET(vp, VC_C1SET)) { 4419304Speter lno = vp->count; 4519304Speter if (!db_exist(sp, lno) && db_last(sp, &lno)) 4619304Speter return (1); 4719304Speter } else 4819304Speter lno = vp->m_start.lno; 4919304Speter 5019304Speter /* Set default return cursor line. */ 5119304Speter vp->m_final.lno = lno; 5219304Speter vp->m_final.cno = vp->m_start.cno; 5319304Speter 5419304Speter /* 5519304Speter * The second count is the displayed window size, i.e. the 'z' command 5619304Speter * is another way to get artificially small windows. Note, you can't 5719304Speter * grow beyond the size of the window. 5819304Speter * 5919304Speter * !!! 6019304Speter * A window size of 0 was historically allowed, and simply ignored. 6119304Speter * This could be much more simply done by modifying the value of the 6219304Speter * O_WINDOW option, but that's not how it worked historically. 6319304Speter */ 6419304Speter if (F_ISSET(vp, VC_C2SET) && vp->count2 != 0) { 6519304Speter if (vp->count2 > O_VAL(sp, O_WINDOW)) 6619304Speter vp->count2 = O_VAL(sp, O_WINDOW); 6719304Speter if (vs_crel(sp, vp->count2)) 6819304Speter return (1); 6919304Speter } 7019304Speter 7119304Speter switch (vp->character) { 7219304Speter case '-': /* Put the line at the bottom. */ 7319304Speter if (vs_sm_fill(sp, lno, P_BOTTOM)) 7419304Speter return (1); 7519304Speter break; 7619304Speter case '.': /* Put the line in the middle. */ 7719304Speter if (vs_sm_fill(sp, lno, P_MIDDLE)) 7819304Speter return (1); 7919304Speter break; 8019304Speter case '+': 8119304Speter /* 8219304Speter * If the user specified a line number, put that line at the 8319304Speter * top and move the cursor to it. Otherwise, scroll forward 8419304Speter * a screen from the current screen. 8519304Speter */ 8619304Speter if (F_ISSET(vp, VC_C1SET)) { 8719304Speter if (vs_sm_fill(sp, lno, P_TOP)) 8819304Speter return (1); 8919304Speter if (vs_sm_position(sp, &vp->m_final, 0, P_TOP)) 9019304Speter return (1); 9119304Speter } else 9219304Speter if (vs_sm_scroll(sp, &vp->m_final, sp->t_rows, Z_PLUS)) 9319304Speter return (1); 9419304Speter break; 9519304Speter case '^': 9619304Speter /* 9719304Speter * If the user specified a line number, put that line at the 9819304Speter * bottom, move the cursor to it, and then display the screen 9919304Speter * before that one. Otherwise, scroll backward a screen from 10019304Speter * the current screen. 10119304Speter * 10219304Speter * !!! 10319304Speter * Note, we match the off-by-one characteristics of historic 10419304Speter * vi, here. 10519304Speter */ 10619304Speter if (F_ISSET(vp, VC_C1SET)) { 10719304Speter if (vs_sm_fill(sp, lno, P_BOTTOM)) 10819304Speter return (1); 10919304Speter if (vs_sm_position(sp, &vp->m_final, 0, P_TOP)) 11019304Speter return (1); 11119304Speter if (vs_sm_fill(sp, vp->m_final.lno, P_BOTTOM)) 11219304Speter return (1); 11319304Speter } else 11419304Speter if (vs_sm_scroll(sp, &vp->m_final, sp->t_rows, Z_CARAT)) 11519304Speter return (1); 11619304Speter break; 11719304Speter default: /* Put the line at the top for <cr>. */ 11819304Speter value = KEY_VAL(sp, vp->character); 11919304Speter if (value != K_CR && value != K_NL) { 12019304Speter v_emsg(sp, vp->kp->usage, VIM_USAGE); 12119304Speter return (1); 12219304Speter } 12319304Speter if (vs_sm_fill(sp, lno, P_TOP)) 12419304Speter return (1); 12519304Speter break; 12619304Speter } 12719304Speter return (0); 12819304Speter} 12919304Speter 13019304Speter/* 13119304Speter * vs_crel -- 13219304Speter * Change the relative size of the current screen. 13319304Speter * 13419304Speter * PUBLIC: int vs_crel __P((SCR *, long)); 13519304Speter */ 13619304Speterint 137254225Spetervs_crel(SCR *sp, long int count) 13819304Speter{ 13919304Speter sp->t_minrows = sp->t_rows = count; 14019304Speter if (sp->t_rows > sp->rows - 1) 14119304Speter sp->t_minrows = sp->t_rows = sp->rows - 1; 14219304Speter TMAP = HMAP + (sp->t_rows - 1); 14319304Speter F_SET(sp, SC_SCR_REDRAW); 14419304Speter return (0); 14519304Speter} 146