home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / newemacs / basic.c next >
C/C++ Source or Header  |  1986-02-04  |  7KB  |  304 lines

  1. /*
  2.  * The routines in this file
  3.  * move the cursor around on the screen.
  4.  * They compute a new value for the cursor, then
  5.  * adjust ".". The display code always updates the
  6.  * cursor location, so only moves between lines,
  7.  * or functions that adjust the top line in the window
  8.  * and invalidate the framing, are hard.
  9.  */
  10. #include    <stdio.h>
  11. #include    "ed.h"
  12.  
  13. /*
  14.  * Move the cursor to the
  15.  * beginning of the current line.
  16.  * Trivial.
  17.  */
  18. gotobol(f, n)
  19. {
  20.     curwp->w_doto  = 0;
  21.     return (TRUE);
  22. }
  23.  
  24. /*
  25.  * Move the cursor backwards by
  26.  * "n" characters. If "n" is less than
  27.  * zero call "forwchar" to actually do the
  28.  * move. Otherwise compute the new cursor
  29.  * location. Error if you try and move
  30.  * out of the buffer. Set the flag if the
  31.  * line pointer for dot changes.
  32.  */
  33. backchar(f, n)
  34. register int    n;
  35. {
  36.     register LINE    *lp;
  37.  
  38.     if (n < 0)
  39.         return (forwchar(f, -n));
  40.     while (n--) {
  41.         if (!curwp->w_doto) {
  42.             if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
  43.                 return (FALSE);
  44.             curwp->w_dotp  = lp;
  45.             curwp->w_doto  = llength(lp);
  46.             curwp->w_flag |= WFMOVE;
  47.         } else
  48.             curwp->w_doto--;
  49.     }
  50.     return (TRUE);
  51. }
  52.  
  53. /*
  54.  * Move the cursor to the end
  55.  * of the current line. Trivial.
  56.  * No errors.
  57.  */
  58. gotoeol(f, n)
  59. {
  60.     curwp->w_doto  = llength(curwp->w_dotp);
  61.     return (TRUE);
  62. }
  63.  
  64. /*
  65.  * Move the cursor forwwards by
  66.  * "n" characters. If "n" is less than
  67.  * zero call "backchar" to actually do the
  68.  * move. Otherwise compute the new cursor
  69.  * location, and move ".". Error if you
  70.  * try and move off the end of the
  71.  * buffer. Set the flag if the line pointer
  72.  * for dot changes.
  73.  */
  74. forwchar(f, n)
  75. register int    n;
  76. {
  77.     if (n < 0)
  78.         return (backchar(f, -n));
  79.     while (n--) {
  80.         if (curwp->w_doto == llength(curwp->w_dotp)) {
  81.             if (curwp->w_dotp == curbp->b_linep)
  82.                 return (FALSE);
  83.             curwp->w_dotp  = lforw(curwp->w_dotp);
  84.             curwp->w_doto  = 0;
  85.             curwp->w_flag |= WFMOVE;
  86.         } else
  87.             curwp->w_doto++;
  88.     }
  89.     return (TRUE);
  90. }
  91.  
  92. /*
  93.  * Goto the beginning of the buffer.
  94.  * Massive adjustment of dot. This is considered
  95.  * to be hard motion; it really isn't if the original
  96.  * value of dot is the same as the new value of dot.
  97.  * Normally bound to "M-<".
  98.  */
  99. gotobob(f, n)
  100. {
  101.     curwp->w_dotp  = lforw(curbp->b_linep);
  102.     curwp->w_doto  = 0;
  103.     curwp->w_flag |= WFHARD;
  104.     return (TRUE);
  105. }
  106.  
  107. /*
  108.  * Move to the end of the buffer.
  109.  * Dot is always put at the end of the
  110.  * file (ZJ). The standard screen code does
  111.  * most of the hard parts of update. Bound to 
  112.  * "M->".
  113.  */
  114. gotoeob(f, n)
  115. {
  116.     curwp->w_dotp  = curbp->b_linep;
  117.     curwp->w_doto  = 0;
  118.     curwp->w_flag |= WFHARD;
  119.     return (TRUE);
  120. }
  121.  
  122. /*
  123.  * Move forward by full lines.
  124.  * If the number of lines to move is less
  125.  * than zero, call the backward line function to
  126.  * actually do it. The last command controls how
  127.  * the goal column is set. Bound to "C-N". No
  128.  * errors are possible.
  129.  */
  130. forwline(f, n)
  131. {
  132.     register LINE    *dlp;
  133.  
  134.     if (n < 0)
  135.         return (backline(f, -n));
  136.     if (!(lastflag&CFCPCN))        /* Reset goal if last    */
  137.         curgoal = curcol;        /* not C-P or C-N    */
  138.     thisflag |= CFCPCN;
  139.     dlp = curwp->w_dotp;
  140.     while (n-- && dlp!=curbp->b_linep)
  141.         dlp = lforw(dlp);
  142.     curwp->w_dotp  = dlp;
  143.     curwp->w_doto  = getgoal(dlp);
  144.     curwp->w_flag |= WFMOVE;
  145.     return (TRUE);
  146. }
  147.  
  148. /*
  149.  * This function is like "forwline", but
  150.  * goes backwards. The scheme is exactly the same.
  151.  * Check for arguments that are less than zero and
  152.  * call your alternate. Figure out the new line and
  153.  * call "movedot" to perform the motion. No errors
  154.  * are possible. Bound to "C-P".
  155.  */
  156. backline(f, n)
  157. {
  158.     register LINE    *dlp;
  159.  
  160.     if (n < 0)
  161.         return (forwline(f, -n));
  162.     if (!(lastflag&CFCPCN))        /* Reset goal if the    */
  163.         curgoal = curcol;        /* last isn't C-P, C-N    */
  164.     thisflag |= CFCPCN;
  165.     dlp = curwp->w_dotp;
  166.     while (n-- && lback(dlp)!=curbp->b_linep)
  167.         dlp = lback(dlp);
  168.     curwp->w_dotp  = dlp;
  169.     curwp->w_doto  = getgoal(dlp);
  170.     curwp->w_flag |= WFMOVE;
  171.     return (TRUE);
  172. }
  173.  
  174. /*
  175.  * This routine, given a pointer to
  176.  * a LINE, and the current cursor goal
  177.  * column, return the best choice for the
  178.  * offset. The offset is returned.
  179.  * Used by "C-N" and "C-P".
  180.  */
  181. getgoal(dlp)
  182. register LINE    *dlp;
  183. {
  184.     register int    c;
  185.     register int    col;
  186.     register int    newcol;
  187.     register int    dbo;
  188.  
  189.     for (col = dbo = 0; dbo != llength(dlp); ++dbo) {
  190.         c = lgetc(dlp, dbo);
  191.         newcol = col;
  192.         if (c == '\t')
  193.             newcol |= 0x07;
  194.         else if (c<0x20 || c==0x7F)
  195.             ++newcol;
  196.         ++newcol;
  197.         if (newcol > curgoal)
  198.             break;
  199.         col = newcol;
  200.     }
  201.     return (dbo);
  202. }
  203.  
  204. /*
  205.  * Scroll forward by a specified number
  206.  * of lines, or by a full page if no argument.
  207.  * Bound to "C-V". The "2" in the arithmetic on
  208.  * the window size is the overlap; this value is
  209.  * the default overlap value in ITS EMACS.
  210.  * Because this zaps the top line in the display
  211.  * window, we have to do a hard update.
  212.  */
  213. forwpage(f, n)
  214. register int    n;
  215. {
  216.     register LINE    *lp;
  217.  
  218.     if (f == FALSE) {
  219.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  220.         if (n <= 0)            /* Forget the overlap    */
  221.             n = 1;            /* if tiny window.    */
  222.     } else if (n < 0)
  223.         return (backpage(f, -n));
  224. #if    CVMVAS
  225.     else                    /* Convert from pages    */
  226.         n *= curwp->w_ntrows;        /* to lines.        */
  227. #endif
  228.     for (lp = curwp->w_linep; n-- && lp!=curbp->b_linep; lp = lforw(lp)) {};
  229.     curwp->w_linep = curwp->w_dotp  = lp;
  230.     curwp->w_doto  = 0;
  231.     curwp->w_flag |= WFHARD;
  232.     return (TRUE);
  233. }
  234.  
  235. /*
  236.  * This command is like "forwpage",
  237.  * but it goes backwards. The "2", like above,
  238.  * is the overlap between the two windows. The
  239.  * value is from the ITS EMACS manual. Bound
  240.  * to "M-V". We do a hard update for exactly
  241.  * the same reason.
  242.  */
  243. backpage(f, n)
  244. register int    n;
  245. {
  246.     register LINE    *lp;
  247.  
  248.     if (f == FALSE) {
  249.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  250.         if (n <= 0)            /* Don't blow up if the    */
  251.             n = 1;            /* window is tiny.    */
  252.     } else if (n < 0)
  253.         return (forwpage(f, -n));
  254. #if    CVMVAS
  255.     else                    /* Convert from pages    */
  256.         n *= curwp->w_ntrows;        /* to lines.        */
  257. #endif
  258.     for (lp=curwp->w_linep; n-- && lback(lp)!=curbp->b_linep;)
  259.         lp=lback(lp);
  260.     curwp->w_linep = curwp->w_dotp  = lp;
  261.     curwp->w_doto  = 0;
  262.     curwp->w_flag |= WFHARD;
  263.     return (TRUE);
  264. }
  265.  
  266. /*
  267.  * Set the mark in the current window
  268.  * to the value of "." in the window. No errors
  269.  * are possible. Bound to "M-.".
  270.  */
  271. setmark(f, n)
  272. {
  273.     curwp->w_markp = curwp->w_dotp;
  274.     curwp->w_marko = curwp->w_doto;
  275.     mlwrite("[Mark set]");
  276.     return (TRUE);
  277. }
  278.  
  279. /*
  280.  * Swap the values of "." and "mark" in
  281.  * the current window. This is pretty easy, bacause
  282.  * all of the hard work gets done by the standard routine
  283.  * that moves the mark about. The only possible error is
  284.  * "no mark". Bound to "C-X C-X".
  285.  */
  286. swapmark(f, n)
  287. {
  288.     register LINE    *odotp;
  289.     register int    odoto;
  290.  
  291.     if (curwp->w_markp == NULL) {
  292.         mlwrite("No mark in this window");
  293.         return (FALSE);
  294.     }
  295.     odotp = curwp->w_dotp;
  296.     odoto = curwp->w_doto;
  297.     curwp->w_dotp  = curwp->w_markp;
  298.     curwp->w_doto  = curwp->w_marko;
  299.     curwp->w_markp = odotp;
  300.     curwp->w_marko = odoto;
  301.     curwp->w_flag |= WFMOVE;
  302.     return (TRUE);
  303. }
  304.