home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / micrognu / part02 / basic.c next >
Encoding:
C/C++ Source or Header  |  1987-01-26  |  7.8 KB  |  363 lines

  1. /*
  2.  *        Basic cursor motion commands.
  3.  * 
  4.  * The routines in this file are the basic
  5.  * command functions for moving the cursor around on
  6.  * the screen, setting mark, and swapping dot with
  7.  * mark. Only moves between lines, which might make the
  8.  * current buffer framing bad, are hard.
  9.  */
  10. #include    "def.h"
  11.  
  12. /*
  13.  * Go to beginning of line.
  14.  */
  15. /*ARGSUSED*/
  16. gotobol(f, n, k) {
  17.     curwp->w_doto  = 0;
  18.     return (TRUE);
  19. }
  20.  
  21. /*
  22.  * Move cursor backwards. Do the
  23.  * right thing if the count is less than
  24.  * 0. Error if you try to move back from
  25.  * the beginning of the buffer.
  26.  */
  27. /*ARGSUSED*/
  28. backchar(f, n, k) register int n; {
  29.     register LINE    *lp;
  30.  
  31.     if (n < 0)
  32.         return (forwchar(f, -n, k));
  33.     while (n--) {
  34.         if (curwp->w_doto == 0) {
  35.             if ((lp=lback(curwp->w_dotp)) == curbp->b_linep) {
  36.                 if (k != KRANDOM)
  37.                     ewprintf("Beginning of buffer");
  38.                 return (FALSE);
  39.             }
  40.             curwp->w_dotp  = lp;
  41.             curwp->w_doto  = llength(lp);
  42.             curwp->w_flag |= WFMOVE;
  43.         } else
  44.             curwp->w_doto--;
  45.     }
  46.     return (TRUE);
  47. }
  48.  
  49. /*
  50.  * Go to end of line.
  51.  */
  52. /*ARGSUSED*/
  53. gotoeol(f, n, k) {
  54.     curwp->w_doto  = llength(curwp->w_dotp);
  55.     return (TRUE);
  56. }
  57.  
  58. /*
  59.  * Move cursor forwards. Do the
  60.  * right thing if the count is less than
  61.  * 0. Error if you try to move forward
  62.  * from the end of the buffer.
  63.  */
  64. /*ARGSUSED*/
  65. forwchar(f, n, k) register int n; {
  66.     if (n < 0)
  67.         return (backchar(f, -n, k));
  68.     while (n--) {
  69.         if (curwp->w_doto == llength(curwp->w_dotp)) {
  70.             if (curwp->w_dotp == curbp->b_linep) {
  71.                 if (k != KRANDOM)
  72.                     ewprintf("End of buffer");
  73.                 return (FALSE);
  74.             }
  75.             curwp->w_dotp  = lforw(curwp->w_dotp);
  76.             curwp->w_doto  = 0;
  77.             curwp->w_flag |= WFMOVE;
  78.         } else
  79.             curwp->w_doto++;
  80.     }
  81.     return (TRUE);
  82. }
  83.  
  84. /*
  85.  * Go to the beginning of the
  86.  * buffer. Setting WFHARD is conservative,
  87.  * but almost always the case.
  88.  */
  89. gotobob(f, n, k) {
  90.     (VOID) setmark(f, n, k) ;
  91.     curwp->w_dotp  = lforw(curbp->b_linep);
  92.     curwp->w_doto  = 0;
  93.     curwp->w_flag |= WFHARD;
  94.     return (TRUE);
  95. }
  96.  
  97. /*
  98.  * Go to the end of the buffer.
  99.  * Setting WFHARD is conservative, but
  100.  * almost always the case.
  101.  */
  102. gotoeob(f, n, k) {
  103.     (VOID) setmark(f, n, k) ;
  104.     curwp->w_dotp  = curbp->b_linep;
  105.     curwp->w_doto  = 0;
  106.     curwp->w_flag |= WFHARD;
  107.     return (TRUE);
  108. }
  109.  
  110. /*
  111.  * Move forward by full lines.
  112.  * If the number of lines to move is less
  113.  * than zero, call the backward line function to
  114.  * actually do it. The last command controls how
  115.  * the goal column is set.
  116.  */
  117. /*ARGSUSED*/
  118. forwline(f, n, k) {
  119.     register LINE    *dlp;
  120.  
  121.     if (n < 0)
  122.         return (backline(f, -n, KRANDOM));
  123.     if ((lastflag&CFCPCN) == 0)        /* Fix goal.        */
  124.         setgoal();
  125.     thisflag |= CFCPCN;
  126.     dlp = curwp->w_dotp;
  127.     while (n-- && dlp!=curbp->b_linep)
  128.         dlp = lforw(dlp);
  129.     curwp->w_dotp  = dlp;
  130.     curwp->w_doto  = getgoal(dlp);
  131.     curwp->w_flag |= WFMOVE;
  132.     return (TRUE);
  133. }
  134.  
  135. /*
  136.  * This function is like "forwline", but
  137.  * goes backwards. The scheme is exactly the same.
  138.  * Check for arguments that are less than zero and
  139.  * call your alternate. Figure out the new line and
  140.  * call "movedot" to perform the motion.
  141.  */
  142. /*ARGSUSED*/
  143. backline(f, n, k) {
  144.     register LINE    *dlp;
  145.  
  146.     if (n < 0)
  147.         return (forwline(f, -n, KRANDOM));
  148.     if ((lastflag&CFCPCN) == 0)        /* Fix goal.        */
  149.         setgoal();
  150.     thisflag |= CFCPCN;
  151.     dlp = curwp->w_dotp;
  152.     while (n-- && lback(dlp)!=curbp->b_linep)
  153.         dlp = lback(dlp);
  154.     curwp->w_dotp  = dlp;
  155.     curwp->w_doto  = getgoal(dlp);
  156.     curwp->w_flag |= WFMOVE;
  157.     return (TRUE);
  158. }
  159.  
  160. /*
  161.  * Set the current goal column,
  162.  * which is saved in the external variable "curgoal",
  163.  * to the current cursor column. The column is never off
  164.  * the edge of the screen; it's more like display then
  165.  * show position.
  166.  */
  167. setgoal() {
  168.  
  169.     curgoal = getcolpos() - 1;        /* Get the position.    */
  170.     if (curgoal >= ncol)            /* Chop to tty width.    */
  171.         curgoal = ncol-1;
  172. }
  173.  
  174. /*
  175.  * This routine looks at a line (pointed
  176.  * to by the LINE pointer "dlp") and the current
  177.  * vertical motion goal column (set by the "setgoal"
  178.  * routine above) and returns the best offset to use
  179.  * when a vertical motion is made into the line.
  180.  */
  181. getgoal(dlp) register LINE *dlp; {
  182.     register int    c;
  183.     register int    col;
  184.     register int    newcol;
  185.     register int    dbo;
  186.  
  187.     col = 0;
  188.     dbo = 0;
  189.     while (dbo != llength(dlp)) {
  190.         c = lgetc(dlp, dbo);
  191.         newcol = col;
  192.         if (c == '\t')
  193.             newcol |= 0x07;
  194.         else if (ISCTRL(c) != FALSE)
  195.             ++newcol;
  196.         ++newcol;
  197.         if (newcol > curgoal)
  198.             break;
  199.         col = newcol;
  200.         ++dbo;
  201.     }
  202.     return (dbo);
  203. }
  204.  
  205. /*
  206.  * Scroll forward by a specified number
  207.  * of lines, or by a full page if no argument.
  208.  * The "2" is the window overlap (this is the default
  209.  * value from ITS EMACS). Because the top line in
  210.  * the window is zapped, we have to do a hard
  211.  * update and get it back.
  212.  */
  213. /*ARGSUSED*/
  214. forwpage(f, n, k) register int n; {
  215.     register LINE    *lp;
  216.  
  217.     if (f == FALSE) {
  218.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  219.         if (n <= 0)            /* Forget the overlap    */
  220.             n = 1;            /* if tiny window.    */
  221.     } else if (n < 0)
  222.         return (backpage(f, -n, KRANDOM));
  223. #ifdef    CVMVAS
  224.     else                    /* Convert from pages    */
  225.         n *= curwp->w_ntrows;        /* to lines.        */
  226. #endif
  227.     lp = curwp->w_linep;
  228.     while (n-- && lp!=curbp->b_linep)
  229.         lp = lforw(lp);
  230.     curwp->w_linep = lp;
  231.     curwp->w_dotp  = lp;
  232.     curwp->w_doto  = 0;
  233.     curwp->w_flag |= WFHARD;
  234.     return (TRUE);
  235. }
  236.  
  237. /*
  238.  * This command is like "forwpage",
  239.  * but it goes backwards. The "2", like above,
  240.  * is the overlap between the two windows. The
  241.  * value is from the ITS EMACS manual. The
  242.  * hard update is done because the top line in
  243.  * the window is zapped.
  244.  */
  245. /*ARGSUSED*/
  246. backpage(f, n, k) register int n; {
  247.     register LINE    *lp;
  248.  
  249.     if (f == FALSE) {
  250.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  251.         if (n <= 0)            /* Don't blow up if the    */
  252.             n = 1;            /* window is tiny.    */
  253.     } else if (n < 0)
  254.         return (forwpage(f, -n, KRANDOM));
  255. #ifdef    CVMVAS
  256.     else                    /* Convert from pages    */
  257.         n *= curwp->w_ntrows;        /* to lines.        */
  258. #endif
  259.     lp = curwp->w_linep;
  260.     while (n-- && lback(lp)!=curbp->b_linep)
  261.         lp = lback(lp);
  262.     curwp->w_linep = lp;
  263.     curwp->w_dotp  = lp;
  264.     curwp->w_doto  = 0;
  265.     curwp->w_flag |= WFHARD;
  266.     return (TRUE);
  267. }
  268.  
  269. /*
  270.  * Page the other window. Check to make sure it exists, then
  271.  * nextwind, forwpage and prevwind.
  272.  */
  273. pagenext(f, n, k) {
  274.     if (wheadp->w_wndp == NULL) {
  275.         ewprintf("No other window");
  276.         return FALSE;
  277.     }
  278.     (VOID) nextwind(f, n, k);
  279.     (VOID) forwpage(f, n, k);
  280.     (VOID) prevwind(f, n, k);
  281.     return TRUE;
  282. }
  283.  
  284. /*
  285.  * Set the mark in the current window
  286.  * to the value of dot. A message is written to
  287.  * the echo line unless we are running in a keyboard
  288.  * macro, when it would be silly.
  289.  */
  290. /*ARGSUSED*/
  291. setmark(f, n, k) {
  292.     isetmark();
  293.     if (kbdmop == NULL)
  294.         ewprintf("Mark set");
  295.     return (TRUE);
  296. }
  297.  
  298. /* 
  299.  * Internal set mark routine, used by other functions (daveb).
  300.  */
  301. isetmark()
  302. {
  303.     curwp->w_markp = curwp->w_dotp;
  304.     curwp->w_marko = curwp->w_doto;
  305. }
  306.  
  307. /*
  308.  * Swap the values of "dot" and "mark" in
  309.  * the current window. This is pretty easy, because
  310.  * all of the hard work gets done by the standard routine
  311.  * that moves the mark about. The only possible
  312.  * error is "no mark".
  313.  */
  314. /*ARGSUSED*/
  315. swapmark(f, n, k) {
  316.     register LINE    *odotp;
  317.     register int    odoto;
  318.  
  319.     if (curwp->w_markp == NULL) {
  320.         ewprintf("No mark in this window");
  321.         return (FALSE);
  322.     }
  323.     odotp = curwp->w_dotp;
  324.     odoto = curwp->w_doto;
  325.     curwp->w_dotp  = curwp->w_markp;
  326.     curwp->w_doto  = curwp->w_marko;
  327.     curwp->w_markp = odotp;
  328.     curwp->w_marko = odoto;
  329.     curwp->w_flag |= WFMOVE;
  330.     return (TRUE);
  331. }
  332.  
  333. /*
  334.  * Go to a specific line, mostly for
  335.  * looking up errors in C programs, which give the
  336.  * error a line number. If an argument is present, then
  337.  * it is the line number, else prompt for a line number
  338.  * to use.
  339.  */
  340. /*ARGSUSED*/
  341. gotoline(f, n, k) register int n; {
  342.     register LINE    *clp;
  343.     register int    s;
  344.     char        buf[32];
  345.  
  346.     if (f == FALSE) {
  347.         if ((s=ereply("Goto line: ", buf, sizeof(buf))) != TRUE)
  348.             return (s);
  349.         n = atoi(buf);
  350.     }
  351.  
  352.     clp = lforw(curbp->b_linep);        /* "clp" is first line    */
  353.     while (n > 1) {
  354.         if (lforw(clp) == curbp->b_linep) break;
  355.         clp = lforw(clp);
  356.         --n;
  357.     }
  358.     curwp->w_dotp = clp;
  359.     curwp->w_doto = 0;
  360.     curwp->w_flag |= WFMOVE;
  361.     return (TRUE);
  362. }
  363.