home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pine / pine3.07 / pico / random.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-30  |  10.2 KB  |  365 lines

  1. /*
  2.  * Program:    Random routines
  3.  *
  4.  * Modifier:    Michael Seibel
  5.  *        Networks and Distributed Computing
  6.  *        Computing & Communications
  7.  *        University of Washington
  8.  *        Administration Building, AG-44
  9.  *        Seattle, WA  98195
  10.  *        Internet: mikes@cac.washington.edu
  11.  *
  12.  * Date:    19 Jan 1991
  13.  * Last Edited:    6 Jan 1992
  14.  *
  15.  * Copyright 1991 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35. /*
  36.  * This file contains the command processing functions for a number of random
  37.  * commands. There is no functional grouping here, for sure.
  38.  */
  39.  
  40. #include        <stdio.h>
  41. #include    "estruct.h"
  42. #include    "pico.h"
  43. #include        "edef.h"
  44.  
  45. int     tabsize;                        /* Tab size (0: use real tabs)  */
  46.  
  47. /*
  48.  * Set fill column to n.
  49.  */
  50. setfillcol(f, n)
  51. {
  52.     char    numbuf[16];
  53.     register int s;
  54.  
  55.     sprintf(numbuf,"%d",fillcol);
  56.     s = mlreplyd("Set fill column to : ", numbuf, 4, QDEFLT);
  57.     fillcol = atoi(numbuf);
  58.         return(s);
  59. }
  60.  
  61. /*
  62.  * Display the current position of the cursor, in origin 1 X-Y coordinates,
  63.  * the character that is under the cursor (in octal), and the fraction of the
  64.  * text that is before the cursor. The displayed column is not the current
  65.  * column, but the column that would be used on an infinite width display.
  66.  * Normally this is bound to "C-X =".
  67.  */
  68. showcpos(f, n)
  69. {
  70.         register LINE   *clp;
  71.         register long   nch;
  72.         register int    cbo;
  73.         register long   nbc;
  74.         register int    cac;
  75.         register int    ratio;
  76.         register int    col;
  77.         register int    lines;
  78.         register int    thisline;
  79.     char     buffer[80];
  80.  
  81.         clp = lforw(curbp->b_linep);            /* Grovel the data.     */
  82.         cbo = 0;
  83.         nch = 0;
  84.         lines = 0;
  85.         for (;;) {
  86.                 if (clp==curwp->w_dotp && cbo==curwp->w_doto) {
  87.                 thisline = lines;
  88.                         nbc = nch;
  89.                         if (cbo == llength(clp))
  90.                                 cac = '\n';
  91.                         else
  92.                                 cac = lgetc(clp, cbo);
  93.                 }
  94.                 if (cbo == llength(clp)) {
  95.                         if (clp == curbp->b_linep)
  96.                                 break;
  97.                         clp = lforw(clp);
  98.                         cbo = 0;
  99.             lines++;
  100.                 } else
  101.                         ++cbo;
  102.                 ++nch;
  103.         }
  104.     sprintf(buffer,"line %d of %d (%d%%%%), character %ld of %ld (%d%%%%)",
  105.         thisline+1, lines+1, (100L*(thisline+1))/(lines+1),
  106.         nbc, nch, (nch) ? (100L*nbc)/nch : 0);
  107.     emlwrite(buffer);
  108.         return (TRUE);
  109. }
  110.  
  111. /*
  112.  * Return current column.  Stop at first non-blank given TRUE argument.
  113.  */
  114. getccol(bflg)
  115. int bflg;
  116. {
  117.         register int c, i, col;
  118.         col = 0;
  119.         for (i=0; i<curwp->w_doto; ++i) {
  120.                 c = lgetc(curwp->w_dotp, i);
  121.                 if (c!=' ' && c!='\t' && bflg)
  122.                         break;
  123.                 if (c == '\t')
  124.                         col |= 0x07;
  125.                 else if (c<0x20 || c==0x7F)
  126.                         ++col;
  127.                 ++col;
  128.         }
  129.         return(col);
  130. }
  131.  
  132.  
  133.  
  134. /*
  135.  * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
  136.  * tab into file.  If given argument, n, of zero, change to true tabs.
  137.  * If n > 1, simulate tab stop every n-characters using spaces. This has to be
  138.  * done in this slightly funny way because the tab (in ASCII) has been turned
  139.  * into "C-I" (in 10 bit code) already. Bound to "C-I".
  140.  */
  141. tab(f, n)
  142. {
  143.         if (n < 0)
  144.                 return (FALSE);
  145.         if (n == 0 || n > 1) {
  146.                 tabsize = n;
  147.                 return(TRUE);
  148.         }
  149.         if (! tabsize)
  150.                 return(linsert(1, '\t'));
  151.         return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
  152. }
  153.  
  154.  
  155. /*
  156.  * Insert a newline. Bound to "C-M". If we are in CMODE, do automatic
  157.  * indentation as specified.
  158.  */
  159. newline(f, n)
  160. {
  161.     register int    s;
  162.  
  163.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  164.         return(rdonly());    /* we are in read only mode    */
  165.     if (n < 0)
  166.         return (FALSE);
  167.  
  168.         if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  169.         int l;
  170.  
  171.         if(worthit(&l)){
  172.         if(curwp->w_doto != 0)
  173.           l++;
  174.         scrolldown(curwp, l, n);
  175.         }
  176.     }
  177.  
  178.     /* if we are in C mode and this is a default <NL> */
  179.     /* pico's never in C mode */
  180.  
  181.     /* insert some lines */
  182.     while (n--) {
  183.         if ((s=lnewline()) != TRUE)
  184.             return (s);
  185.     }
  186.     return (TRUE);
  187. }
  188.  
  189.  
  190.  
  191. /*
  192.  * Delete forward. This is real easy, because the basic delete routine does
  193.  * all of the work. Watches for negative arguments, and does the right thing.
  194.  * If any argument is present, it kills rather than deletes, to prevent loss
  195.  * of text if typed with a big argument. Normally bound to "C-D".
  196.  */
  197. forwdel(f, n)
  198. {
  199.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  200.         return(rdonly());    /* we are in read only mode    */
  201.         if (n < 0)
  202.                 return (backdel(f, -n));
  203.  
  204.         if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  205.         int l;
  206.  
  207.         if(worthit(&l) && curwp->w_doto == llength(curwp->w_dotp))
  208.           scrollup(curwp, l+1, 1);
  209.     }
  210.  
  211.         if (f != FALSE) {                       /* Really a kill.       */
  212.                 if ((lastflag&CFKILL) == 0)
  213.                         kdelete();
  214.                 thisflag |= CFKILL;
  215.         }
  216.         return (ldelete(n, f));
  217. }
  218.  
  219.  
  220.  
  221. /*
  222.  * Delete backwards. This is quite easy too, because it's all done with other
  223.  * functions. Just move the cursor back, and delete forwards. Like delete
  224.  * forward, this actually does a kill if presented with an argument. Bound to
  225.  * both "RUBOUT" and "C-H".
  226.  */
  227. backdel(f, n)
  228. {
  229.         register int    s;
  230.  
  231.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  232.         return(rdonly());    /* we are in read only mode    */
  233.         if (n < 0)
  234.                 return (forwdel(f, -n));
  235.  
  236.     if(optimize && curwp->w_dotp != curwp->w_bufp->b_linep){
  237.         int l;
  238.  
  239.         if(worthit(&l) && curwp->w_doto == 0 &&
  240.            lback(curwp->w_dotp) != curwp->w_bufp->b_linep){
  241.         if(l == curwp->w_toprow)
  242.           scrollup(curwp, l+1, 1);
  243.         else if(llength(lback(curwp->w_dotp)) == 0)
  244.           scrollup(curwp, l-1, 1);
  245.         else
  246.           scrollup(curwp, l, 1);
  247.         }
  248.     }
  249.  
  250.         if (f != FALSE) {                       /* Really a kill.       */
  251.                 if ((lastflag&CFKILL) == 0)
  252.                         kdelete();
  253.                 thisflag |= CFKILL;
  254.         }
  255.         if ((s=backchar(f, n)) == TRUE)
  256.                 s = ldelete(n, f);
  257.         return (s);
  258. }
  259.  
  260.  
  261.  
  262. /*
  263.  * killtext - delete the line that the cursor is currently in.
  264.  *          a greatly pared down version of its former self.
  265.  */
  266. killtext(f, n)
  267. {
  268.     register int    chunk;
  269.  
  270.         if (curbp->b_mode&MDVIEW)       /* don't allow this command if  */
  271.                 return(rdonly());       /* we are in read only mode     */
  272.  
  273.         if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  274.         int l;
  275.  
  276.         if(worthit(&l))
  277.           scrollup(curwp, l, 1);
  278.     }
  279.  
  280.         if ((lastflag&CFKILL) == 0)             /* Clear kill buffer if */
  281.                 kdelete();                      /* last wasn't a kill.  */
  282.         thisflag |= CFKILL;
  283.     curwp->w_doto = 0;        /* wack from the beginning of line */
  284.     chunk = llength(curwp->w_dotp) + 1;    /* for the whole length. */
  285.     return(ldelete(chunk, TRUE));
  286. }
  287.  
  288.  
  289. /*
  290.  * Yank text back from the kill buffer. This is really easy. All of the work
  291.  * is done by the standard insert routines. All you do is run the loop, and
  292.  * check for errors. Bound to "C-Y".
  293.  */
  294. yank(f, n)
  295. {
  296.         register int    c;
  297.         register int    i;
  298.         extern   int    kused;
  299.  
  300.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  301.         return(rdonly());    /* we are in read only mode    */
  302.         if (n < 0)
  303.                 return (FALSE);
  304.  
  305.         if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  306.         int l;
  307.  
  308.         if(worthit(&l) && !(lastflag&CFFILL)){
  309.         register int  t = 0; 
  310.         register int  i = 0;
  311.         register int  ch;
  312.  
  313.         while((ch=kremove(i++)) >= 0)
  314.           if(ch == '\n')
  315.             t++;
  316.         if(t+l < curwp->w_toprow+curwp->w_ntrows)
  317.           scrolldown(curwp, l, t);
  318.         }
  319.     }
  320.  
  321.     if(lastflag&CFFILL)        /* if last command was fillpara() */
  322.       gotobop(FALSE, 1);        /* then go to the top of the para */
  323.                     /* then splat out the saved buffer */
  324.         while (n--) {
  325.                 i = 0;
  326.                 while ((c=kremove(i)) >= 0) {
  327.                         if (c == '\n') {
  328.                                 if (lnewline(FALSE, 1) == FALSE)
  329.                                         return (FALSE);
  330.                         } else {
  331.                                 if (linsert(1, c) == FALSE)
  332.                                         return (FALSE);
  333.                         }
  334.                         ++i;
  335.                 }
  336.         }
  337.  
  338.     if(lastflag&CFFILL){            /* if last command was fillpara() */
  339.         register LINE *botline;     /* blast the filled paragraph */
  340.         register LINE *topline;
  341.         register int  done = 0;
  342.  
  343.         kdelete();
  344.         topline = curwp->w_dotp;
  345.         gotoeop(FALSE, 1);
  346.         botline = lforw(curwp->w_dotp);
  347.         curwp->w_dotp = topline;
  348.         if(topline != botline){
  349.         while(!done){
  350.             if(lforw(curwp->w_dotp) == botline)
  351.               done++;
  352.             curwp->w_doto = 0;
  353.             ldelete((llength(curwp->w_dotp) + 1), FALSE);
  354.         }
  355.         }
  356.         curwp->w_flag |= WFMODE;
  357.  
  358.         if(Pmaster == NULL){
  359.         sgarbk = TRUE;
  360.         emlwrite("");
  361.         }
  362.     }
  363.         return (TRUE);
  364. }
  365.