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 1319304Speterstatic const char sccsid[] = "@(#)v_right.c 10.7 (Berkeley) 3/6/96"; 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_right -- [count]' ', [count]l 2919304Speter * Move right by columns. 3019304Speter * 3119304Speter * PUBLIC: int v_right __P((SCR *, VICMD *)); 3219304Speter */ 3319304Speterint 3419304Speterv_right(sp, vp) 3519304Speter SCR *sp; 3619304Speter VICMD *vp; 3719304Speter{ 3819304Speter size_t len; 3919304Speter int isempty; 4019304Speter 4119304Speter if (db_eget(sp, vp->m_start.lno, NULL, &len, &isempty)) { 4219304Speter if (isempty) 4319304Speter goto eol; 4419304Speter return (1); 4519304Speter } 4619304Speter 4719304Speter /* It's always illegal to move right on empty lines. */ 4819304Speter if (len == 0) { 4919304Spetereol: v_eol(sp, NULL); 5019304Speter return (1); 5119304Speter } 5219304Speter 5319304Speter /* 5419304Speter * Non-motion commands move to the end of the range. Delete and 5519304Speter * yank stay at the start. Ignore others. Adjust the end of the 5619304Speter * range for motion commands. 5719304Speter * 5819304Speter * !!! 5919304Speter * Historically, "[cdsy]l" worked at the end of a line. Also, 6019304Speter * EOL is a count sink. 6119304Speter */ 6219304Speter vp->m_stop.cno = vp->m_start.cno + 6319304Speter (F_ISSET(vp, VC_C1SET) ? vp->count : 1); 6419304Speter if (vp->m_start.cno == len - 1 && !ISMOTION(vp)) { 6519304Speter v_eol(sp, NULL); 6619304Speter return (1); 6719304Speter } 6819304Speter if (vp->m_stop.cno >= len) { 6919304Speter vp->m_stop.cno = len - 1; 7019304Speter vp->m_final = ISMOTION(vp) ? vp->m_start : vp->m_stop; 7119304Speter } else if (ISMOTION(vp)) { 7219304Speter --vp->m_stop.cno; 7319304Speter vp->m_final = vp->m_start; 7419304Speter } else 7519304Speter vp->m_final = vp->m_stop; 7619304Speter return (0); 7719304Speter} 7819304Speter 7919304Speter/* 8019304Speter * v_dollar -- [count]$ 8119304Speter * Move to the last column. 8219304Speter * 8319304Speter * PUBLIC: int v_dollar __P((SCR *, VICMD *)); 8419304Speter */ 8519304Speterint 8619304Speterv_dollar(sp, vp) 8719304Speter SCR *sp; 8819304Speter VICMD *vp; 8919304Speter{ 9019304Speter size_t len; 9119304Speter int isempty; 9219304Speter 9319304Speter /* 9419304Speter * !!! 9519304Speter * A count moves down count - 1 rows, so, "3$" is the same as "2j$". 9619304Speter */ 9719304Speter if ((F_ISSET(vp, VC_C1SET) ? vp->count : 1) != 1) { 9819304Speter /* 9919304Speter * !!! 10019304Speter * Historically, if the $ is a motion, and deleting from 10119304Speter * at or before the first non-blank of the line, it's a 10219304Speter * line motion, and the line motion flag is set. 10319304Speter */ 10419304Speter vp->m_stop.cno = 0; 10519304Speter if (nonblank(sp, vp->m_start.lno, &vp->m_stop.cno)) 10619304Speter return (1); 10719304Speter if (ISMOTION(vp) && vp->m_start.cno <= vp->m_stop.cno) 10819304Speter F_SET(vp, VM_LMODE); 10919304Speter 11019304Speter --vp->count; 11119304Speter if (v_down(sp, vp)) 11219304Speter return (1); 11319304Speter } 11419304Speter 11519304Speter /* 11619304Speter * !!! 11719304Speter * Historically, it was illegal to use $ as a motion command on 11819304Speter * an empty line. Unfortunately, even though C was historically 11919304Speter * aliased to c$, it (and not c$) was special cased to work on 12019304Speter * empty lines. Since we alias C to c$ too, we have a problem. 12119304Speter * To fix it, we let c$ go through, on the assumption that it's 12219304Speter * not a problem for it to work. 12319304Speter */ 12419304Speter if (db_eget(sp, vp->m_stop.lno, NULL, &len, &isempty)) { 12519304Speter if (!isempty) 12619304Speter return (1); 12719304Speter len = 0; 12819304Speter } 12919304Speter 13019304Speter if (len == 0) { 13119304Speter if (ISMOTION(vp) && !ISCMD(vp->rkp, 'c')) { 13219304Speter v_eol(sp, NULL); 13319304Speter return (1); 13419304Speter } 13519304Speter return (0); 13619304Speter } 13719304Speter 13819304Speter /* 13919304Speter * Non-motion commands move to the end of the range. Delete 14019304Speter * and yank stay at the start. Ignore others. 14119304Speter */ 14219304Speter vp->m_stop.cno = len ? len - 1 : 0; 14319304Speter vp->m_final = ISMOTION(vp) ? vp->m_start : vp->m_stop; 14419304Speter return (0); 14519304Speter} 146