home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / newemacs / random.c < prev    next >
Text File  |  1979-12-31  |  11KB  |  480 lines

  1. /*
  2.  * This file contains the
  3.  * command processing functions for
  4.  * a number of random commands. There is
  5.  * no functional grouping here, for
  6.  * sure.
  7.  */
  8. #include    <stdio.h>
  9. #include    "ed.h"
  10.  
  11. int    tabsize;            /* Tab size (0: use real tabs)    */
  12.  
  13. /*
  14.  * Set fill column to n. 
  15.  */
  16. setfillcol(f, n)
  17. {
  18.     fillcol = n;
  19.     return(TRUE);
  20. }
  21.  
  22. /*
  23.  * Display the current position of the cursor,
  24.  * in origin 1 X-Y coordinates, the character that is
  25.  * under the cursor (in octal), and the fraction of the
  26.  * text that is before the cursor. The displayed column
  27.  * is not the current column, but the column that would
  28.  * be used on an infinite width display. Normally this
  29.  * is bound to "C-X =".
  30.  */
  31. showcpos(f, n)
  32. {
  33.     register LINE    *clp;
  34.     register long    nch;
  35.     register int    cbo;
  36.     register long    nbc;
  37.     register int    cac;
  38.     register int    ratio;
  39.     register int    col;
  40.     register int    i;
  41.     register int    c;
  42.     register long   nln;
  43.     register long   thisln;
  44.  
  45.     clp = lforw(curbp->b_linep);        /* Grovel the data.    */
  46.     nln =0;
  47.     for (cbo=nch=0;;++nch) {
  48.         if (clp==curwp->w_dotp && cbo==curwp->w_doto) {
  49.             thisln = nln+1L;
  50.             nbc = nch;
  51.             cac = (cbo==llength(clp)) ? '\n' : lgetc(clp,cbo);
  52.         }
  53.         if (cbo == llength(clp)) {
  54.             if (clp == curbp->b_linep)
  55.                 break;
  56.             clp = lforw(clp);
  57.             cbo = 0;
  58.              nln++;
  59.         } else
  60.             ++cbo;
  61.     }
  62.     col = getccol(FALSE);            /* Get real column.    */
  63.     ratio = 0;                /* Ratio before dot.    */
  64.     if (nch)
  65.         ratio = (100L*nbc) / nch;
  66.     mlwrite("X=%d Y=%d line=%D CH=0x%x .=%D (%d%% of %D)",
  67.         col+1, currow+1, thisln, cac, nbc, ratio, nch);
  68.     return (TRUE);
  69. }
  70.  
  71. /*
  72.  * Return current column.  Stop at first non-blank given TRUE argument.
  73.  */
  74. getccol(bflg)
  75. int bflg;
  76. {
  77.     register int c, i, col;
  78.     for (col=i=0; i<curwp->w_doto; ++i,col++) {
  79.         c = lgetc(curwp->w_dotp, i);
  80.         if (c!=' ' && c!='\t' && bflg)
  81.             break;
  82.         if (c == '\t')
  83.             col |= 0x07;
  84.         else if (c<0x20 || c==0x7F)
  85.             ++col;
  86.     }
  87.     return(col);
  88. }
  89.  
  90. /*
  91.  * Twiddle the two characters on either side of
  92.  * dot. If dot is at the end of the line twiddle the
  93.  * two characters before it. Return with an error if dot
  94.  * is at the beginning of line; it seems to be a bit
  95.  * pointless to make this work. This fixes up a very
  96.  * common typo with a single stroke. Normally bound
  97.  * to "C-T". This always works within a line, so
  98.  * "WFEDIT" is good enough.
  99.  */
  100. twiddle(f, n)
  101. {
  102.     register LINE    *dotp;
  103.     register int    doto;
  104.     register int    cl;
  105.     register int    cr;
  106.  
  107.     dotp = curwp->w_dotp;
  108.     doto = curwp->w_doto;
  109.     if (doto==llength(dotp) && --doto<0)
  110.         return (FALSE);
  111.     cr = lgetc(dotp, doto);
  112.     if (--doto < 0)
  113.         return (FALSE);
  114.     cl = lgetc(dotp, doto);
  115.     lputc(dotp, doto+0, cr);
  116.     lputc(dotp, doto+1, cl);
  117.     lchange(WFEDIT);
  118.     return (TRUE);
  119. }
  120.  
  121. /*
  122.  * Quote the next character, and
  123.  * insert it into the buffer. All the characters
  124.  * are taken literally, with the exception of the newline,
  125.  * which always has its line splitting meaning. The character
  126.  * is always read, even if it is inserted 0 times, for
  127.  * regularity. Bound to "M-Q" (for me) and "C-Q" (for Rich,
  128.  * and only on terminals that don't need XON-XOFF).
  129.  */
  130. quote(f, n)
  131. {
  132.     register int    s;
  133.     register int    c;
  134.  
  135.     c = scr_ci() ;
  136.     if (n < 0)
  137.         return (FALSE);
  138.     if (!n)
  139.         return (TRUE);
  140.     if (c == '\n') {
  141.         do {
  142.             s = lnewline();
  143.         } while (s==TRUE && --n);
  144.         return (s);
  145.     }
  146.     return (linsert(n, c));
  147. }
  148.  
  149. /*
  150.  * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
  151.  * tab into file.  If given argument, n, of zero, change to true tabs.
  152.  * If n > 1, simulate tab stop every n-characters using spaces.
  153.  * This has to be done in this slightly funny way because the
  154.  * tab (in ASCII) has been turned into "C-I" (in 10
  155.  * bit code) already. Bound to "C-I".
  156.  */
  157. tab(f, n)
  158. {
  159.     if (n < 0)
  160.         return (FALSE);
  161.     if (!n || n > 1) {
  162.         tabsize = n;
  163.         return(TRUE);
  164.     }
  165.     if (! tabsize)
  166.         return(linsert(1, '\t'));
  167.     return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
  168. }
  169.  
  170. /*
  171.  * Open up some blank space. The basic plan
  172.  * is to insert a bunch of newlines, and then back
  173.  * up over them. Everything is done by the subcommand
  174.  * procerssors. They even handle the looping. Normally
  175.  * this is bound to "C-O".
  176.  */
  177. openline(f, n)
  178. {
  179.     register int    i;
  180.     register int    s;
  181.  
  182.     if (n < 0)
  183.         return (FALSE);
  184.     if (!n)
  185.         return (TRUE);
  186.     i = n;                    /* Insert newlines.    */
  187.     do {
  188.         s = lnewline();
  189.     } while (s==TRUE && --i);
  190.     if (s == TRUE)                /* Then back up overtop    */
  191.         s = backchar(f, n);        /* of them all.        */
  192.     return (s);
  193. }
  194.  
  195. /*
  196.  * Insert a newline. Bound to "C-M".
  197.  * If you are at the end of the line and the
  198.  * next line is a blank line, just move into the
  199.  * blank line. This makes "C-O" and "C-X C-O" work
  200.  * nicely, and reduces the ammount of screen
  201.  * update that has to be done. This would not be
  202.  * as critical if screen update were a lot
  203.  * more efficient.
  204.  * Newline has been changed to accomodate overwrite mode.
  205.  * If not at end of buffer cursor will be moved to beginning of next
  206.  * line, otherwise newlines will be inserted at the end of the buffer.
  207.  */
  208. newline(f, n)
  209. {
  210.     
  211.     if (n < 0)
  212.         return (FALSE);
  213.     /* if in insert mode then */
  214.     if (!(curbp->b_flag & BFOVRWRITE))
  215.         {
  216.         /* insert new lines */
  217.         insmodenewlin(f,n);
  218.         }
  219.     else
  220.         /* in overwrite mode */
  221.         {
  222.         /* move to existing lines, if at end insert new lines */
  223.         ovmodenewlin(f,n);
  224.         }
  225.     
  226. }
  227.  
  228.  
  229. insmodenewlin(f,n)
  230.     {
  231.     int nicol;
  232.     register LINE    *lp;
  233.     register int    s;
  234.  
  235.     while (n--) 
  236.         {
  237.         lp = curwp->w_dotp;
  238.         if (llength(lp) == curwp->w_doto
  239.         && lp != curbp->b_linep
  240.         && !llength(lforw(lp))) 
  241.             {
  242.             if ((s=forwchar(FALSE, 1)) != TRUE)
  243.                 return (s);
  244.             } 
  245.         else if ((s=lnewline()) != TRUE)
  246.             return (s);
  247.         }
  248.     return (TRUE);
  249.     }
  250.  
  251. ovmodenewlin(f,n)
  252.     {
  253.     int nicol;
  254.     register LINE    *lp;
  255.     register int    s;
  256.  
  257.     while (n--)
  258.         {
  259.         lp = curwp->w_dotp;
  260.         /* if not at end of buffer */
  261.         if (lp != curbp->b_linep)
  262.             {
  263.             /* go to beginning of next line */
  264.             if ((s=forwline(f,1)) != TRUE)
  265.                 return(s);
  266.             curwp->w_doto = 0;
  267.             }
  268.         else
  269.         /* otherwise */
  270.             {
  271.             /* insert newline at end of buffer */
  272.             if((s=lnewline()) != TRUE)
  273.                 return(s);
  274.             }
  275.         return(TRUE);
  276.         }
  277.     }
  278.  
  279. /*
  280.  * Delete blank lines around dot.
  281.  * What this command does depends if dot is
  282.  * sitting on a blank line. If dot is sitting on a
  283.  * blank line, this command deletes all the blank lines
  284.  * above and below the current line. If it is sitting
  285.  * on a non blank line then it deletes all of the
  286.  * blank lines after the line. Normally this command
  287.  * is bound to "C-X C-O". Any argument is ignored.
  288.  */
  289. deblank(f, n)
  290. {
  291.     register LINE    *lp1;
  292.     register LINE    *lp2;
  293.     register int    nld;
  294.  
  295.     lp1 = curwp->w_dotp;
  296.     while (!llength(lp1) && (lp2=lback(lp1))!=curbp->b_linep)
  297.         lp1 = lp2;
  298.     lp2 = lp1;
  299.     nld = 0;
  300.     while ((lp2=lforw(lp2))!=curbp->b_linep && !llength(lp2))
  301.         ++nld;
  302.     if (!nld)
  303.         return (TRUE);
  304.     curwp->w_dotp = lforw(lp1);
  305.     curwp->w_doto = 0;
  306.     return (ldelete(nld));
  307. }
  308.  
  309. /*
  310.  * Insert a newline, then enough
  311.  * tabs and spaces to duplicate the indentation
  312.  * of the previous line. Assumes tabs are every eight
  313.  * characters. Quite simple. Figure out the indentation
  314.  * of the current line. Insert a newline by calling
  315.  * the standard routine. Insert the indentation by
  316.  * inserting the right number of tabs and spaces.
  317.  * Return TRUE if all ok. Return FALSE if one
  318.  * of the subcomands failed. Normally bound
  319.  * to "C-J".
  320.  */
  321. indent(f, n)
  322. {
  323.     register int    nicol;
  324.     register int    c;
  325.     register int    i;
  326.  
  327.     if (n < 0)
  328.         return (FALSE);
  329.     while (n--) {
  330.         for (nicol=i=0; i<llength(curwp->w_dotp); ++i) {
  331.             c = lgetc(curwp->w_dotp, i);
  332.             if (c!=' ' && c!='\t')
  333.                 break;
  334.             if (c == '\t')
  335.                 nicol |= 0x07;
  336.             ++nicol;
  337.         }
  338.         if (lnewline() == FALSE
  339.         || ((i=nicol/8) && linsert(i, '\t')==FALSE)
  340.         || ((i=nicol%8) && linsert(i,  ' ')==FALSE))
  341.             return (FALSE);
  342.     }
  343.     return (TRUE);
  344. }
  345.  
  346. /*
  347.  * Delete forward. This is real
  348.  * easy, because the basic delete routine does
  349.  * all of the work. Watches for negative arguments,
  350.  * and does the right thing. If any argument is
  351.  * present, it kills rather than deletes, to prevent
  352.  * loss of text if typed with a big argument.
  353.  * Normally bound to "C-D".
  354.  */
  355. forwdel(f, n)
  356. {
  357.     if (n < 0)
  358.         return (backdel(f, -n));
  359.     if (f != FALSE) {            /* Really a kill.    */
  360.         if (!(lastflag&CFKILL))
  361.             kdelete();
  362.         thisflag |= CFKILL;
  363.     }
  364.     return (ldelete(n, f));
  365. }
  366.  
  367. /*
  368.  * Delete backwards. This is quite easy too,
  369.  * because it's all done with other functions. Just
  370.  * move the cursor back, and delete forwards.
  371.  * Like delete forward, this actually does a kill
  372.  * if presented with an argument. Bound to both
  373.  * "RUBOUT" and "C-H".
  374.  */
  375. backdel(f, n)
  376. {
  377.     register int    s;
  378.  
  379.     if (n < 0)
  380.         return (forwdel(f, -n));
  381.     if (f != FALSE) {            /* Really a kill.    */
  382.         if (!(lastflag&CFKILL))
  383.             kdelete();
  384.         thisflag |= CFKILL;
  385.     }
  386.     if ((s=backchar(f, n)) == TRUE)
  387.         s = ldelete(n, f);
  388.     return (s);
  389. }
  390.  
  391. /*
  392.  * Kill text. If called without an argument,
  393.  * it kills from dot to the end of the line, unless it
  394.  * is at the end of the line, when it kills the newline.
  395.  * If called with an argument of 0, it kills from the
  396.  * start of the line to dot. If called with a positive
  397.  * argument, it kills from dot forward over that number
  398.  * of newlines. If called with a negative argument it
  399.  * kills backwards that number of newlines. Normally
  400.  * bound to "C-K".
  401.  */
  402. kill(f, n)
  403. {
  404.     register int    chunk;
  405.     register LINE    *nextp;
  406.  
  407.     if (!(lastflag&CFKILL))        /* Clear kill buffer if    */
  408.         kdelete();            /* last wasn't a kill.    */
  409.     thisflag |= CFKILL;
  410.     if (f == FALSE) {
  411.         if (!(chunk = llength(curwp->w_dotp)-curwp->w_doto)) chunk = 1;
  412.     } else if (!n) {
  413.         chunk = curwp->w_doto;
  414.         curwp->w_doto = 0;
  415.     } else if (n > 0) {
  416.         chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
  417.         nextp = lforw(curwp->w_dotp);
  418.         while (--n) {
  419.             if (nextp == curbp->b_linep)
  420.                 return (FALSE);
  421.             chunk += llength(nextp)+1;
  422.             nextp = lforw(nextp);
  423.         }
  424.     } else {
  425.         mlwrite("neg kill");
  426.         return (FALSE);
  427.     }
  428.     return (ldelete(chunk, TRUE));
  429. }
  430.  
  431. /*
  432.  * Yank text back from the kill buffer. This
  433.  * is really easy. All of the work is done by the
  434.  * standard insert routines. All you do is run the loop,
  435.  * and check for errors. Bound to "C-Y". The blank
  436.  * lines are inserted with a call to "newline"
  437.  * instead of a call to "lnewline" so that the magic
  438.  * stuff that happens when you type a carriage
  439.  * return also happens when a carriage return is
  440.  * yanked back from the kill buffer.
  441.  */
  442. yank(f, n)
  443. {
  444.     register int    c;
  445.     register int    i;
  446.     extern     int    kused;
  447.  
  448.     if (n < 0)
  449.         return (FALSE);
  450.     while (n--) {
  451.         i = 0;
  452.         while ((c=kremove(i)) >= 0) {
  453.             if (c == '\n') {
  454.                 if (insmodenewlin(FALSE, 1) == FALSE)
  455.                     return (FALSE);
  456.             } else {
  457.                 if (linsert(1, c) == FALSE)
  458.                     return (FALSE);
  459.             }
  460.             ++i;
  461.         }
  462.     }
  463.     return (TRUE);
  464. }
  465.  
  466. /* toggle between the insert and overwrite modes */
  467. togglemode()
  468.     {
  469.     /* if in overwrite mode */
  470.     if (curbp->b_flag & BFOVRWRITE)
  471.         /* change to insert mode */
  472.         curbp->b_flag &= ~BFOVRWRITE;
  473.     else
  474.         /* change from insert mode to overwrite mode */
  475.         curbp->b_flag |= BFOVRWRITE;
  476.     /* cause the mode line to be redisplayed */
  477.     curwp->w_flag |= WFMODE;
  478.     }
  479.  
  480.