home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / EDITOR / NVI179B / NVI179B.ZIP / vi / v_left.c < prev    next >
C/C++ Source or Header  |  1996-04-27  |  7KB  |  294 lines

  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
  13. static const char sccsid[] = "@(#)v_left.c    10.7 (Berkeley) 3/6/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_left -- [count]^H, [count]h
  29.  *    Move left by columns.
  30.  *
  31.  * PUBLIC: int v_left __P((SCR *, VICMD *));
  32.  */
  33. int
  34. v_left(sp, vp)
  35.     SCR *sp;
  36.     VICMD *vp;
  37. {
  38.     recno_t cnt;
  39.  
  40.     /*
  41.      * !!!
  42.      * The ^H and h commands always failed in the first column.
  43.      */
  44.     if (vp->m_start.cno == 0) {
  45.         v_sol(sp);
  46.         return (1);
  47.     }
  48.  
  49.     /* Find the end of the range. */
  50.     cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
  51.     if (vp->m_start.cno > cnt)
  52.         vp->m_stop.cno = vp->m_start.cno - cnt;
  53.     else
  54.         vp->m_stop.cno = 0;
  55.  
  56.     /*
  57.      * All commands move to the end of the range.  Motion commands
  58.      * adjust the starting point to the character before the current
  59.      * one.
  60.      */
  61.     if (ISMOTION(vp))
  62.         --vp->m_start.cno;
  63.     vp->m_final = vp->m_stop;
  64.     return (0);
  65. }
  66.  
  67. /*
  68.  * v_cfirst -- [count]_
  69.  *    Move to the first non-blank character in a line.
  70.  *
  71.  * PUBLIC: int v_cfirst __P((SCR *, VICMD *));
  72.  */
  73. int
  74. v_cfirst(sp, vp)
  75.     SCR *sp;
  76.     VICMD *vp;
  77. {
  78.     recno_t cnt, lno;
  79.  
  80.     /*
  81.      * !!!
  82.      * If the _ is a motion component, it makes the command a line motion
  83.      * e.g. "d_" deletes the line.  It also means that the cursor doesn't
  84.      * move.
  85.      *
  86.      * The _ command never failed in the first column.
  87.      */
  88.     if (ISMOTION(vp))
  89.         F_SET(vp, VM_LMODE);
  90.     /*
  91.      * !!!
  92.      * Historically a specified count makes _ move down count - 1
  93.      * rows, so, "3_" is the same as "2j_".
  94.      */
  95.     cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
  96.     if (cnt != 1) {
  97.         --vp->count;
  98.         return (v_down(sp, vp));
  99.     }
  100.  
  101.     /*
  102.      * Move to the first non-blank.
  103.      *
  104.      * Can't just use RCM_SET_FNB, in case _ is used as the motion
  105.      * component of another command.
  106.      */
  107.     vp->m_stop.cno = 0;
  108.     if (nonblank(sp, vp->m_stop.lno, &vp->m_stop.cno))
  109.         return (1);
  110.  
  111.     /*
  112.      * !!!
  113.      * The _ command has to fail if the file is empty and we're doing
  114.      * a delete.  If deleting line 1, and 0 is the first nonblank,
  115.      * make the check.
  116.      */
  117.     if (vp->m_stop.lno == 1 &&
  118.         vp->m_stop.cno == 0 && ISCMD(vp->rkp, 'd')) {
  119.         if (db_last(sp, &lno))
  120.             return (1);
  121.         if (lno == 0) {
  122.             v_sol(sp);
  123.             return (1);
  124.         }
  125.     }
  126.  
  127.     /*
  128.      * Delete and non-motion commands move to the end of the range,
  129.      * yank stays at the start.  Ignore others.
  130.      */
  131.     vp->m_final =
  132.         ISMOTION(vp) && ISCMD(vp->rkp, 'y') ? vp->m_start : vp->m_stop;
  133.     return (0);
  134. }
  135.  
  136. /*
  137.  * v_first -- ^
  138.  *    Move to the first non-blank character in this line.
  139.  *
  140.  * PUBLIC: int v_first __P((SCR *, VICMD *));
  141.  */
  142. int
  143. v_first(sp, vp)
  144.     SCR *sp;
  145.     VICMD *vp;
  146. {
  147.     /*
  148.      * !!!
  149.      * Yielding to none in our quest for compatibility with every
  150.      * historical blemish of vi, no matter how strange it might be,
  151.      * we permit the user to enter a count and then ignore it.
  152.      */
  153.  
  154.     /*
  155.      * Move to the first non-blank.
  156.      *
  157.      * Can't just use RCM_SET_FNB, in case ^ is used as the motion
  158.      * component of another command.
  159.      */
  160.     vp->m_stop.cno = 0;
  161.     if (nonblank(sp, vp->m_stop.lno, &vp->m_stop.cno))
  162.         return (1);
  163.  
  164.     /*
  165.      * !!!
  166.      * The ^ command succeeded if used as a command when the cursor was
  167.      * on the first non-blank in the line, but failed if used as a motion
  168.      * component in the same situation.
  169.      */
  170.     if (ISMOTION(vp) && vp->m_start.cno == vp->m_stop.cno) {
  171.         v_sol(sp);
  172.         return (1);
  173.     }
  174.  
  175.     /*
  176.      * If moving right, non-motion commands move to the end of the range.
  177.      * Delete and yank stay at the start.  Motion commands adjust the
  178.      * ending point to the character before the current ending charcter.
  179.      *
  180.      * If moving left, all commands move to the end of the range.  Motion
  181.      * commands adjust the starting point to the character before the
  182.      * current starting character.
  183.      */
  184.     if (vp->m_start.cno < vp->m_stop.cno)
  185.         if (ISMOTION(vp)) {
  186.             --vp->m_stop.cno;
  187.             vp->m_final = vp->m_start;
  188.         } else
  189.             vp->m_final = vp->m_stop;
  190.     else {
  191.         if (ISMOTION(vp))
  192.             --vp->m_start.cno;
  193.         vp->m_final = vp->m_stop;
  194.     }
  195.     return (0);
  196. }
  197.  
  198. /*
  199.  * v_ncol -- [count]|
  200.  *    Move to column count or the first column on this line.  If the
  201.  *    requested column is past EOL, move to EOL.  The nasty part is
  202.  *    that we have to know character column widths to make this work.
  203.  *
  204.  * PUBLIC: int v_ncol __P((SCR *, VICMD *));
  205.  */
  206. int
  207. v_ncol(sp, vp)
  208.     SCR *sp;
  209.     VICMD *vp;
  210. {
  211.     if (F_ISSET(vp, VC_C1SET) && vp->count > 1) {
  212.         --vp->count;
  213.         vp->m_stop.cno =
  214.             vs_colpos(sp, vp->m_start.lno, (size_t)vp->count);
  215.         /*
  216.          * !!!
  217.          * The | command succeeded if used as a command and the cursor
  218.          * didn't move, but failed if used as a motion component in the
  219.          * same situation.
  220.          */
  221.         if (ISMOTION(vp) && vp->m_stop.cno == vp->m_start.cno) {
  222.             v_nomove(sp);
  223.             return (1);
  224.         }
  225.     } else {
  226.         /*
  227.          * !!!
  228.          * The | command succeeded if used as a command in column 0
  229.          * without a count, but failed if used as a motion component
  230.          * in the same situation.
  231.          */
  232.         if (ISMOTION(vp) && vp->m_start.cno == 0) {
  233.             v_sol(sp);
  234.             return (1);
  235.         }
  236.         vp->m_stop.cno = 0;
  237.     }
  238.  
  239.     /*
  240.      * If moving right, non-motion commands move to the end of the range.
  241.      * Delete and yank stay at the start.  Motion commands adjust the
  242.      * ending point to the character before the current ending charcter.
  243.      *
  244.      * If moving left, all commands move to the end of the range.  Motion
  245.      * commands adjust the starting point to the character before the
  246.      * current starting character.
  247.      */
  248.     if (vp->m_start.cno < vp->m_stop.cno)
  249.         if (ISMOTION(vp)) {
  250.             --vp->m_stop.cno;
  251.             vp->m_final = vp->m_start;
  252.         } else
  253.             vp->m_final = vp->m_stop;
  254.     else {
  255.         if (ISMOTION(vp))
  256.             --vp->m_start.cno;
  257.         vp->m_final = vp->m_stop;
  258.     }
  259.     return (0);
  260. }
  261.  
  262. /*
  263.  * v_zero -- 0
  264.  *    Move to the first column on this line.
  265.  *
  266.  * PUBLIC: int v_zero __P((SCR *, VICMD *));
  267.  */
  268. int
  269. v_zero(sp, vp)
  270.     SCR *sp;
  271.     VICMD *vp;
  272. {
  273.     /*
  274.      * !!!
  275.      * The 0 command succeeded if used as a command in the first column
  276.      * but failed if used as a motion component in the same situation.
  277.      */
  278.     if (ISMOTION(vp) && vp->m_start.cno == 0) {
  279.         v_sol(sp);
  280.         return (1);
  281.     }
  282.  
  283.     /*
  284.      * All commands move to the end of the range.  Motion commands
  285.      * adjust the starting point to the character before the current
  286.      * one.
  287.      */
  288.     vp->m_stop.cno = 0;
  289.     if (ISMOTION(vp))
  290.         --vp->m_start.cno;
  291.     vp->m_final = vp->m_stop;
  292.     return (0);
  293. }
  294.