home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 May / W2KPRK.iso / apps / posix / source / ELVIS / MOVE4.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-17  |  3.8 KB  |  214 lines

  1. /* move4.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    14407 SW Teal Blvd. #C
  6.  *    Beaverton, OR 97005
  7.  *    kirkenda@cs.pdx.edu
  8.  */
  9.  
  10.  
  11. /* This file contains movement functions which are screen-relative */
  12.  
  13. #include "config.h"
  14. #include "vi.h"
  15.  
  16. /* This moves the cursor to a particular row on the screen */
  17. /*ARGSUSED*/
  18. MARK m_row(m, cnt, key)
  19.     MARK    m;    /* the cursor position */
  20.     long    cnt;    /* the row we'll move to */
  21.     int    key;    /* the keystroke of this move - H/L/M */
  22. {
  23.     DEFAULT(1);
  24.  
  25.     /* calculate destination line based on key */
  26.     cnt--;
  27.     switch (key)
  28.     {
  29.       case 'H':
  30.         cnt = topline + cnt;
  31.         break;
  32.  
  33.       case 'M':
  34.         cnt = topline + (LINES - 1) / 2;
  35.         break;
  36.  
  37.       case 'L':
  38.         cnt = botline - cnt;
  39.         break;
  40.     }
  41.  
  42.     /* return the mark of the destination line */
  43.     return MARK_AT_LINE(cnt);
  44. }
  45.  
  46.  
  47. /* This function repositions the current line to show on a given row */
  48. /*ARGSUSED*/
  49. MARK m_z(m, cnt, key)
  50.     MARK    m;    /* the cursor */
  51.     long    cnt;    /* the line number we're repositioning */
  52.     int    key;    /* key struck after the z */
  53. {
  54.     long    newtop;
  55.  
  56.     /* Which line are we talking about? */
  57.     if (cnt < 0 || cnt > nlines)
  58.     {
  59.         return MARK_UNSET;
  60.     }
  61.     if (cnt)
  62.     {
  63.         m = MARK_AT_LINE(cnt);
  64.         newtop = cnt;
  65.     }
  66.     else
  67.     {
  68.         newtop = markline(m);
  69.     }
  70.  
  71.     /* allow a "window size" number to be entered, but ignore it */
  72.     while (key >= '0' && key <= '9')
  73.     {
  74.         key = getkey(0);
  75.     }
  76.  
  77.     /* figure out which line will have to be at the top of the screen */
  78.     switch (key)
  79.     {
  80.       case '\n':
  81. #if OSK
  82.       case '\l':
  83. #else
  84.       case '\r':
  85. #endif
  86.       case '+':
  87.         break;
  88.  
  89.       case '.':
  90.       case 'z':
  91.         newtop -= LINES / 2;
  92.         break;
  93.  
  94.       case '-':
  95.         newtop -= LINES - 1;
  96.         break;
  97.  
  98.       default:
  99.         return MARK_UNSET;
  100.     }
  101.  
  102.     /* make the new topline take effect */
  103.     if (newtop >= 1)
  104.     {
  105.         topline = newtop;
  106.     }
  107.     else
  108.     {
  109.         topline = 1L;
  110.     }
  111.     mustredraw = TRUE;
  112.  
  113.     /* The cursor doesn't move */
  114.     return m;
  115. }
  116.  
  117.  
  118. /* This function scrolls the screen.  It does this by calling redraw() with
  119.  * an off-screen line as the argument.  It will move the cursor if necessary
  120.  * so that the cursor is on the new screen.
  121.  */
  122. /*ARGSUSED*/
  123. MARK m_scroll(m, cnt, key)
  124.     MARK    m;    /* the cursor position */
  125.     long    cnt;    /* for some keys: the number of lines to scroll */
  126.     int    key;    /* keystroke that causes this movement */
  127. {
  128.     MARK    tmp;    /* a temporary mark, used as arg to redraw() */
  129.  
  130.     /* adjust cnt, and maybe *o_scroll, depending of key */
  131.     switch (key)
  132.     {
  133.       case ctrl('F'):
  134.       case ctrl('B'):
  135.         DEFAULT(1);
  136.         mustredraw = TRUE;
  137.         cnt = cnt * (LINES - 1) - 1; /* keeps one old line on screen */
  138.         break;
  139.  
  140.       case ctrl('E'):
  141.       case ctrl('Y'):
  142.         DEFAULT(1);
  143.         break;
  144.  
  145.       case ctrl('U'):
  146.       case ctrl('D'):
  147.         if (cnt == 0) /* default */
  148.         {
  149.             cnt = *o_scroll;
  150.         }
  151.         else
  152.         {
  153.             if (cnt > LINES - 1)
  154.             {
  155.                 cnt = LINES - 1;
  156.             }
  157.             *o_scroll = cnt;
  158.         }
  159.         break;
  160.     }
  161.  
  162.     /* scroll up or down, depending on key */
  163.     switch (key)
  164.     {
  165.       case ctrl('B'):
  166.       case ctrl('Y'):
  167.       case ctrl('U'):
  168.         cnt = topline - cnt;
  169.         if (cnt < 1L)
  170.         {
  171.             cnt = 1L;
  172.             m = MARK_FIRST;
  173.         }
  174.         tmp = MARK_AT_LINE(cnt) + markidx(m);
  175.         redraw(tmp, FALSE);
  176.         if (markline(m) > botline)
  177.         {
  178.             m = MARK_AT_LINE(botline);
  179.         }
  180.         break;
  181.  
  182.       case ctrl('F'):
  183.       case ctrl('E'):
  184.       case ctrl('D'):
  185.         cnt = botline + cnt;
  186.         if (cnt > nlines)
  187.         {
  188.             cnt = nlines;
  189.             m = MARK_LAST;
  190.         }
  191.         tmp = MARK_AT_LINE(cnt) + markidx(m);
  192.         redraw(tmp, FALSE);
  193.         if (markline(m) < topline)
  194.         {
  195.             m = MARK_AT_LINE(topline);
  196.         }
  197.         break;
  198.     }
  199.  
  200.     /* arrange for ctrl-B and ctrl-F to redraw the smart line */
  201.     if (key == ctrl('B') || key == ctrl('F'))
  202.     {
  203.         changes++;
  204.  
  205.         /* also, erase the statusline.  This happens naturally for
  206.          * the scrolling commands, but the paging commands need to
  207.          * explicitly clear the statusline.
  208.          */
  209.         msg("");
  210.     }
  211.  
  212.     return m;
  213. }
  214.