home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 21 / emacsrc / random.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-05-14  |  12.7 KB  |  389 lines

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