home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 223 / emacssrc / random.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-17  |  11.0 KB  |  508 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 sure.
  6.  */
  7. #include    <stdio.h>
  8. #include    "ed.h"
  9.  
  10. extern int    kused;
  11. extern int    gotobuf();
  12.  
  13. /* mb: added function to toggle insert/overstrike */
  14.  
  15. int instog(f,n)
  16.     {
  17.     if (ovrstrk)
  18.         mlwrite("[insert]");
  19.     else
  20.         mlwrite("[overstrike]");
  21.     ovrstrk = !ovrstrk;
  22. #if AtST
  23.     Cursconf(ovrstrk?3:2,0);    /* dal: non-blink cursor in ovrstrk */
  24. #endif
  25.     return (TRUE);
  26.     }
  27.  
  28. /*
  29.  * Set fill column to n.   mb: added the ifs.
  30.  */
  31. setfillcol(f, n)
  32.     {
  33.     if (n==1)  n=0;
  34.     if ( (n!=0) && (n < lmargin + tabsize) ) 
  35.         {
  36.         mlwrite("fillcol must be >= leftmargin + tabsize");
  37.         return(ABORT);
  38.         }
  39.     fillcol = n;
  40.     mlwrite(( n ? "[right margin: %d]" : "[wrap off]" ), n );
  41.     return(TRUE);
  42.     }
  43.  
  44. /*
  45.  * Set lmargin to n. mb: added.
  46.  */
  47. setlmargin(f, n)
  48.     {
  49.     if (n==1)  n=0;
  50.     if ( (n!=0) && (n > fillcol - tabsize) ) 
  51.         {
  52.         mlwrite("lmargin must be <= fillcol - tabsize");
  53.         return(ABORT);
  54.         }
  55.     lmargin = n;
  56.     mlwrite( "[left margin: %d]", n );
  57.     return(TRUE);
  58.     }
  59.  
  60. /*
  61.  * Display the current position of the cursor,
  62.  * in origin 1 X-Y coordinates, the character that is
  63.  * under the cursor (in hex), and the fraction of the
  64.  * text that is before the cursor. The displayed column
  65.  * is not the current column, but the column that would
  66.  * be used on an infinite width display. Normally this
  67.  * is bound to "C-X =".
  68.  * dal: added buffer space available display.
  69.  */
  70. showcpos(f, n)
  71.     {
  72.     register LINE    *clp;
  73.     register int    cbo;
  74.     register long    nch;
  75.     register long    nbc;
  76.     register int    nli;     /* mb: line-no. counter */
  77.     int    cac, ratio, col;  /* mb: were register */
  78.     /* mb: deleted i,c; */
  79.  
  80.     clp = lforw(curbp->b_linep);        /* Grovel the data.    */
  81.     cbo = 0;
  82.     nch = 0;
  83.     nbc = -1;        /* mb: not-at-cursor-yet flag */
  84.     nli = 0;        /* mb: */
  85.     for (;;) 
  86.         {
  87.         if (clp==curwp->w_dotp && cbo==curwp->w_doto) 
  88.             {
  89.             nbc = nch;
  90.             if (cbo == llength(clp))
  91.                 cac = '\n';
  92.             else
  93.                 cac = lgetc(clp, cbo);
  94.             }
  95.         if (cbo == llength(clp)) 
  96.             {
  97.             if (clp == curbp->b_linep)
  98.                 break;
  99.             clp = lforw(clp);
  100.             cbo = 0;
  101.             if (nbc == -1) ++nli;  /* mb: */
  102.             }
  103.         else
  104.             ++cbo;
  105.         ++nch;
  106.         }
  107.     col = getccol(FALSE);            /* Get real column.    */
  108.     ratio = 0;                /* Ratio before dot.    */
  109.     if (nch != 0)
  110.         ratio = (100L*nbc) / nch;
  111. #ifdef AtST
  112.     mlwrite("\
  113. X=%d Y=%d CH=0x%x .=%ld (%d%% of %ld) %ld bytes free, mouse dx=%d dy=%d",
  114.     col+1, nli+1, cac, nbc, ratio, nch, memavail(), mcur_dx, mcur_dy);
  115. #else
  116.     mlwrite("X=%d Y=%d CH=0x%x .=%ld (%d%% of %ld)",
  117.         col+1, nli+1, cac, nbc, ratio, nch );
  118. #endif
  119.     return (TRUE);
  120.     }
  121.  
  122. /*
  123.  * Return current column.  Stop at first non-blank given TRUE argument.
  124.  */
  125. getccol(bflg)
  126. int bflg;
  127.     {
  128.     register int c, i, col;
  129.     col = 0;
  130.     for (i=0; i<curwp->w_doto; ++i) 
  131.         {
  132.         c = lgetc(curwp->w_dotp, i);
  133.         if (c!=' ' && c!='\t' && bflg)
  134.             break;
  135.         if (c == '\t')
  136.             col += tabsize-(col%tabsize)-1; /* mb: */
  137.         else if (iscntrl(c))    /* (c<0x20 || c==0x7F) */
  138.             ++col;
  139.         ++col;
  140.         }
  141.     return(col);
  142.     }
  143.  
  144. /*
  145.  * Twiddle the two characters on either side of
  146.  * dot. If dot is at the end of the line twiddle the
  147.  * two characters before it. Return with an error if dot
  148.  * is at the beginning of line; it seems to be a bit
  149.  * pointless to make this work. This fixes up a very
  150.  * common typo with a single stroke. Normally bound
  151.  * to "C-T". This always works within a line, so
  152.  * "WFEDIT" is good enough.
  153.  */
  154. twiddle(f, n)
  155.     {
  156.     register LINE    *dotp;
  157.     register int    doto;
  158.     register int    cl;
  159.     register int    cr;
  160.  
  161.     dotp = curwp->w_dotp;
  162.     doto = curwp->w_doto;
  163.     if (doto==llength(dotp) && --doto<0)
  164.         return (FALSE);
  165.     cr = lgetc(dotp, doto);
  166.     if (--doto < 0)
  167.         return (FALSE);
  168.     cl = lgetc(dotp, doto);
  169.     lputc(dotp, doto+0, cr);
  170.     lputc(dotp, doto+1, cl);
  171.     lchange(WFEDIT);
  172.     return (TRUE);
  173.     }
  174.  
  175. /*
  176.  * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
  177.  * tab into file.  If given argument, n, of zero, change to true tabs.
  178.  * This has to be done in this slightly funny way because the
  179.  * tab (in ASCII) has been turned into "C-I" (in 10
  180.  * bit code) already. Bound to "C-I".
  181.  */
  182. tab(f, n)        /* mb: simplified */
  183.     register int n; 
  184.     {
  185.     if (n < 1)
  186.         return (FALSE);
  187.     if (n > 1) 
  188.         {
  189.         if (n != tabsize) 
  190.             {
  191.             tabsize = n;
  192.             sgarbf = TRUE;
  193.             update();
  194.             }
  195.         mlwrite("[tabsize: %d]", n);
  196.         return(TRUE);
  197.         }
  198.     /* if (n==1) */
  199.         return(linsert(1, '\t', 0));
  200.     }
  201.  
  202. /*
  203.  * Open up some blank space. The basic plan
  204.  * is to insert a bunch of newlines, and then back
  205.  * up over them. Everything is done by the subcommand
  206.  * procerssors. They even handle the looping. Normally
  207.  * this is bound to "C-O".
  208.  */
  209. openline(f, n)
  210.     {
  211.     register int    i;
  212.     register int    s;
  213.  
  214.     if (n < 0)
  215.         return (FALSE);
  216.     if (n == 0)
  217.         return (TRUE);
  218.     i = n;            /* Insert newlines. */
  219.     do 
  220.         {
  221.         s = lnewline();
  222.         }
  223.         while ((s==TRUE) && (--i));
  224.     if (s == TRUE)                /* Then back up overtop    */
  225.         s = backchar(f, n);        /* of them all.        */
  226.     return (s);
  227.     }
  228.  
  229. /*
  230.  * dal: The following two functions handle swapping bindings for
  231.  * ^M and ^J when in autoindent mode.  The underlying functions
  232.  * left untouched since they are called from places other than
  233.  * just the key bindings.
  234.  */
  235. ctrlm(f, n)
  236.     int f, n;
  237.     {
  238.     return(autoindent ? indent(f, n) : newline(f, n));
  239.     }
  240.  
  241. ctrlj(f, n)
  242.     int f, n;
  243.     {
  244.     return(autoindent ? newline(f, n) : indent(f, n));
  245.     }
  246.  
  247. /*
  248.  * Insert a newline. Bound to "C-M".
  249.  * If you are at the end of the line and the
  250.  * next line is a blank line, just move into the
  251.  * blank line. This makes "C-O" and "C-X C-O" work
  252.  * nicely, and reduces the amount of screen
  253.  * update that has to be done. This would not be
  254.  * as critical if screen update were a lot
  255.  * more efficient.
  256.  */
  257. newline(f, n)
  258.     int f, n;
  259.     {
  260.     register int    nicol;
  261.     register LINE    *lp;
  262.     register int    s;
  263.  
  264.     if (n < 0)
  265.         return (FALSE);
  266.     while (n--) 
  267.         {
  268.         lp = curwp->w_dotp;
  269.         if ((llength(lp) == curwp->w_doto)
  270.          && (lp != curbp->b_linep)
  271.          && (llength(lforw(lp)) == 0)) 
  272.             {
  273.             if ((s=forwchar(FALSE, 1)) != TRUE)
  274.                 return (s);
  275.             }
  276.         else if ((s=lnewline()) != TRUE)
  277.             return (s);
  278.         }
  279.     return (TRUE);
  280.     }
  281.  
  282. #if EXTRA
  283. /*
  284.  * Delete blank lines around dot.
  285.  * What this command does depends if dot is
  286.  * sitting on a blank line. If dot is sitting on a
  287.  * blank line, this command deletes all the blank lines
  288.  * above and below the current line. If it is sitting
  289.  * on a non blank line then it deletes all of the
  290.  * blank lines after the line. Normally this command
  291.  * is bound to "C-X C-O". Any argument is ignored.
  292.  */
  293. deblank(f, n)
  294.     {
  295.     register LINE    *lp1;
  296.     register LINE    *lp2;
  297.     register int    nld;
  298.  
  299.     lp1 = curwp->w_dotp;
  300.     while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep)
  301.         lp1 = lp2;
  302.     lp2 = lp1;
  303.     nld = 0;
  304.     while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0)
  305.         ++nld;
  306.     if (nld == 0)
  307.         return (TRUE);
  308.     curwp->w_dotp = lforw(lp1);
  309.     curwp->w_doto = 0;
  310.     return (ldelete(nld, TRUE));
  311.     }
  312. #endif
  313.  
  314. /*
  315.  * Insert a newline, then enough
  316.  * tabs and spaces to duplicate the indentation
  317.  * of the previous line. Figure out the indentation
  318.  * of the current line. Insert a newline by calling
  319.  * the standard routine. Insert the indentation by
  320.  * inserting the right number of tabs and spaces.
  321.  * Return TRUE if all ok. Return FALSE if one
  322.  * of the subcomands failed. Normally bound
  323.  * to "C-J".
  324.  */
  325. indent(f, n)
  326.     int f, n;
  327.     {
  328.     register int    nicol;
  329.     register int    c;
  330.     register int    i;
  331.  
  332.     if (n < 0)
  333.         return (FALSE);
  334.     while (n--) 
  335.         {
  336.         nicol = getccol(TRUE);     /* mb: instead of doing it here */
  337.         /* mb: 'real' tabs always: */
  338.         if (lnewline() == FALSE
  339.         || ((i=nicol/tabsize)!=0 && linsert(i, '\t', 0)==FALSE)
  340.         || ((i=nicol%tabsize)!=0 && linsert(i,  ' ', 0)==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.  * mb: generalized for n<0.
  355.  */
  356. forwdel(f, n)
  357.     {
  358.     int s;
  359.  
  360.     if (n < 0) 
  361.         {
  362.         n = -n;
  363.         if ((s=backchar(f, n)) != TRUE)
  364.             return (s);
  365.         }
  366.     return (ldelete(n, f));
  367.     }
  368.  
  369. /*
  370.  * mb: simplified.
  371.  * Bound to both "RUBOUT" and "C-H".
  372.  */
  373. backdel(f, n)
  374.     {
  375.     return (forwdel(f, -n));
  376.     }
  377.  
  378. /*
  379.  * Kill text. If called without an argument,
  380.  * it kills from dot to the end of the line, unless it
  381.  * is at the end of the line, when it kills the newline.
  382.  * If called with an argument of 0, it kills from the
  383.  * start of the line to dot. If called with a positive
  384.  * argument, it kills from dot forward over that number
  385.  * of newlines. If called with a negative argument it
  386.  * kills backwards that number of newlines. Normally
  387.  * bound to "C-K".
  388.  */
  389. kill(f, n)
  390.     {
  391.     register int    chunk;
  392.     register LINE    *nextp;
  393.  
  394.     if (f == FALSE) 
  395.         {
  396.         chunk = llength(curwp->w_dotp)-curwp->w_doto;
  397.         if (chunk <= 0)
  398.             chunk = 1;
  399.         }
  400.     else if (n == 0) 
  401.         {
  402.         chunk = curwp->w_doto;
  403.         curwp->w_doto = 0;
  404.         }
  405.     else if (n > 0) 
  406.         {
  407.         chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
  408.         nextp = lforw(curwp->w_dotp);
  409.         while (--n) 
  410.             {
  411.             if (nextp == curbp->b_linep)
  412.                 return (FALSE);
  413.             chunk += llength(nextp)+1;
  414.             nextp = lforw(nextp);
  415.             }
  416.         }
  417.     else 
  418.         {
  419.         mlwrite("neg kill?");
  420.         return (FALSE);
  421.         }
  422.     return (ldelete(chunk, TRUE));
  423.     }
  424.  
  425. /* mb: added.
  426.  */
  427. bkill(f, n)
  428.     {
  429.     return (kill(TRUE, 0));
  430.     }
  431.  
  432. /*
  433.  * Yank text back from the kill buffer. This
  434.  * is really easy. All of the work is done by the
  435.  * standard insert routines. All you do is run the loop,
  436.  * and check for errors. Bound to "C-Y". The blank
  437.  * lines are inserted with a call to "newline"
  438.  * instead of a call to "lnewline" so that the magic
  439.  * stuff that happens when you type a carriage
  440.  * return also happens when a carriage return is
  441.  * yanked back from the kill buffer.
  442.  */
  443. yank(f, n)
  444.     {
  445.     register int    c;
  446.     register int    i;
  447.  
  448.     if (n <= 0)
  449.         return (FALSE);
  450.     if( kused > 512 )
  451.         mlwrite("[yanking...]");    /* mb: added */
  452.     while (n--) 
  453.         {
  454.         i = 0;
  455.         while ((c=kremove(i++)) >= 0) 
  456.             {
  457.             if (c == '\n') 
  458.                 {
  459.                 if (newline(FALSE, 1) != TRUE)
  460.                     return (FALSE);
  461.                 }
  462.             else 
  463.                 {
  464.                 if (linsert(1, c, 0) != TRUE)
  465.                     return (FALSE);
  466.                 }
  467.             }
  468.         }
  469.     thisflag |= CFYANK;
  470.     if( kused > 512 )
  471.             mlerase();
  472.     return (TRUE);
  473.     }
  474.  
  475. /* mb: added.
  476.  * Deletes backwards kused chars.
  477.  * Bound to C-X C-Y.
  478.  */
  479. unyank(f, n)
  480.     {
  481.     if ((lastflag&CFYANK) == 0)    /* If last command wasn't Yank */
  482.         return (FALSE);
  483.     return (backdel(TRUE, kused));
  484.     }
  485.  
  486. /* mb: added.
  487.  * Bound to E-Y.
  488.  */
  489. flush_kbuf(f, n)
  490.     {
  491.     BUFFER   *bp;
  492.     BUFFER   *tbp;
  493.     int      s;
  494.  
  495.     if ((bp=bfind("[]", TRUE, (BFTEMP|BFEDIT|BFCHG))) == NULL)
  496.         return (FALSE);
  497.     tbp = curbp;
  498.     gotobuf(bp);
  499.     s = yank(FALSE, 1);
  500.     gotobuf(tbp);
  501.     if (s == TRUE) 
  502.         {
  503.         kdelete();
  504.         mlwrite("[flushed]");
  505.         }
  506.     return (s);
  507.     }
  508.