home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 157_01 / qed2 < prev    next >
Text File  |  1987-10-12  |  10KB  |  438 lines

  1. /*  VERSION 0006  (DATE: 03/03/87)  (TIME: 14:44)  */
  2. /*
  3.     e (qed) screen editor
  4.  
  5.     (C) G. Nigel Gilbert, MICROLOGY, 1981
  6.  
  7.     August-December 1981
  8.  
  9.     Modified: Aug-Dec    1984:    BDS-C 'e'(vers 4.6a) to 'qe' (J.W. Haefner)
  10.               March        1985:    BDS-C 'qe' to DeSmet-C 'qed' (J.W. Haefner)
  11.  
  12.     FILE: qed2
  13.  
  14.     FUNCTIONS: movechar,moveline, maovepage, moveword, insertchar,
  15.             deletechar,crdelete,deleteword,crinsert,firstwhite,adjustc,
  16.             sync.
  17.  
  18.     PURPOSE: perform text changing commands
  19.  
  20. */
  21.  
  22. #include "qed.h"
  23.  
  24. movechar(move)    /*move cursor by 'move' columns to the right
  25.           return YES unless going off text*/
  26. int move;
  27. {
  28.     int cp, len, result;
  29.  
  30.     cp=charn+move;
  31.     result=YES;
  32.     if (cp < 0) {
  33.         result=moveline(-1); 
  34.         if (result) {
  35.             cursorx=adjustc(LLIM); 
  36.             movechar(cp+1);
  37.             }
  38.         else sync(0);
  39.         }
  40.     else if (cp > (len=strlen(text))) {
  41.         result=moveline(1); 
  42.         if (result) {
  43.             sync(0);
  44.             movechar(cp-len-1);            
  45.             }
  46.         else cursorx=adjustc(LLIM);
  47.         }
  48.     else sync(cp);
  49.     return result;
  50. }
  51.  
  52. moveline(move)    /*move cursor by 'move' lines down 
  53.          return YES if Ok, NO if going off text*/
  54. int move;
  55. {
  56.     int line;
  57.  
  58.     puttext();
  59.     if ( (move<0?-move:move) > SHEIGHT) gotoxy(WAITPOS,0);
  60.     line=cline;
  61.     if ((cline=loc(cline,move)) == line) return NO;
  62.     gettext(cline);
  63.     if (cline < pfirst || cline > plast) {
  64.         if (move == 1 || move == -1) scroll(move);
  65.         else putpage();
  66.         }
  67.     else {
  68. #if SCRNDIMMD
  69.         putline(line,cursory);
  70.         cursory+=cline-line;
  71.         cursorx=adjustc(cursorx);
  72.         putline(cline,cursory);
  73. #else                                /* screen is brite, just move cursor */
  74.         if ((!blocking) && (!offset)) {
  75.             cursory+=cline-line;
  76.             cursorx=adjustc(cursorx);
  77.             gotoxy(cursorx,cursory);
  78.             }
  79.         else {
  80.             putline(line,cursory);
  81.             cursory+=cline-line;
  82.             cursorx=adjustc(cursorx);
  83.             putline(cline,cursory);
  84.             }
  85. #endif
  86.         }
  87.     return YES;
  88. }
  89.  
  90. scroll(move)    /*scroll up (move==1) or down 1 line*/
  91. int move;
  92. {
  93.     if (move == 1) {
  94.         linedelete(topline);
  95.         putline(cline-1,SHEIGHT-1);
  96.         }
  97.     else {
  98.         insertline();
  99.         putline(cline+1,topline+1);
  100.         }
  101.     cursorx=adjustc(cursorx);
  102.     putline(cline,cursory);
  103.     if (plast-pfirst == (SHEIGHT-topline)) plast+=move;
  104.     pfirst+=move;
  105. }
  106.  
  107. calcjmp()          /* calc number of lines to jump */
  108. {
  109. int to;
  110.     jmpto = 1;              /* reset jmpto for repeat incrmtl jumps*/
  111.     if (ans[0] == '+')
  112.         if ((to=atoi(ans+1))) jumpline(to);
  113.     if (ans[0] == '-')
  114.         if ((to=atoi(ans))) jumpline((to));
  115.     if (ans[0] >= '0') {
  116.         if ((to=atoi(ans))) jumpline(to-cline);
  117.         jmpto = to;
  118.         }
  119. }
  120.  
  121. jumpline(move)    /*move current line by move lines down, checking for
  122.             interrupt from user (if interrupted, do nothing,
  123.             and return NO) */
  124. int move;
  125. {
  126.     int line, dest;
  127.  
  128.     puttext();
  129.     dest=cline+move;
  130.     dest-=dest%100;
  131.     if (dest > lastread) {
  132.         gotoxy(WAITPOS,0);
  133.         line=cline;
  134.         while (line < dest && loc(line,100) != line) {
  135.             line+=100;
  136.             if (testkey() == ESCKEY) {
  137.                 error("Interrupted");
  138.                 return NO;
  139.                 }
  140.             }
  141.         }
  142.     moveline(move);
  143.     return YES;
  144. }
  145.  
  146. movepage(dir)    /*move current line by a page down (dir==0) or up (-1)*/
  147. int dir;
  148. {
  149.     int move, line;
  150.  
  151.     puttext();
  152.     move=(SHEIGHT-topline)/2 - PAGEOVERLAP;
  153.     if (dir) move=pfirst-cline-move;
  154.     else move=plast-cline+move;
  155.     if ( (cline=loc((line=cline),move) ) != line) {
  156.            /*exit for split*/
  157.         if(inbufp && (inbuf[inbufp-1]==tran[BOFKEY])) return;
  158.         gettext(cline);
  159.         putpage();
  160.         }
  161. }
  162.  
  163. moveword(move)    /*move 1 word to the right (move -ve: left)*/
  164. int move;
  165. {
  166.     if (charn+move < 0) {
  167.         moveline(-1); 
  168.         charn=strlen(text);
  169.         goto cratend;    /* leave cursor at end of line */
  170.         }
  171.     else if (charn+move >= strlen(text)) {
  172.         moveline(1); 
  173.         sync(0);
  174.         if (inword(text[0])) return;
  175.         }
  176.         /* ORIGINAL>> while (move<0 && text[charn] && inword(text[charn])
  177.         && !inword(text[--charn]) && (charn+=move));*/
  178.         /* move off of 1st character of word */
  179.     if (move<0) charn--;    /*replacement*/
  180.         /* span all chars in word */
  181.     while (move>=0 && text[charn] && inword(text[charn]) && (charn+=move));
  182.         /* ORIGINAL>>> while ((move<0 || text[charn]) */
  183.         /* span all non-word chars */
  184.     while (( (move<0 && charn) || move>=0) && text[charn]
  185.         && !inword(text[charn]) && (charn+=move));
  186.     if (move < 0) {
  187.         if (charn) {    /*span all chars in word */
  188.         while(inword(text[charn]) && --charn);  {
  189.             if (charn || !inword(text[charn]) ) charn++; /*backup if nec.*/
  190.             }
  191.         }
  192.         else    /* charn == 0: go to end of previous line */
  193.             if (!inword(text[0])) {
  194.                 moveline(-1);
  195.                 charn=strlen(text);
  196.                 }
  197.         }
  198. cratend:
  199.     sync(charn);
  200. }
  201.  
  202. #if (WWRAP)        /*do word wrap on char insert*/
  203. insertchar(c)    /*inserts 'c' at charn, moves cursor up  one */
  204. char c;
  205. {
  206.     int cp;
  207.     /*char *t;*/
  208.     int diffn,ncharn;
  209.     char *txtp,*posp;
  210.     char *firstwhite();
  211.     
  212.     if ( (cp=strlen(text)+1) >= (LLIM-1))
  213.         error("Line too long");
  214.     else {
  215.         for (; cp >= charn; cp--) text[cp+1]=text[cp];
  216.         text[charn]=c;
  217.         altered=YES;
  218.         rewrite(charn,cursorx);
  219.         sync(charn+1);
  220.             /*word wrap*/
  221.         if  ((cursorx>=rtmarg) && c!=' ' && c!='\t') {
  222.             txtp=posp=&text[charn];
  223.             /*if ((ncharn=firstwhite(text,cursorx,charn)) == 0) ncharn=charn;*/
  224.             if ((posp=firstwhite(text,cursorx,txtp)) == text) ncharn=charn;
  225.             else ncharn=posp-text;
  226.             diffn=charn-ncharn;
  227.             sync(ncharn);
  228.             resetcursor();
  229.             crinsert(0);
  230.             sync(charn+diffn);
  231.             resetcursor();
  232.             }
  233.         }
  234. }
  235.  
  236. char *firstwhite(s,cp,tp)    /*find first prev. white*/
  237. char s[];                    /*string to search*/
  238. int cp;                        /*cursor pos and string (text) pos */
  239. char *tp;
  240. {
  241.     int cpos;
  242.     char *posp,*lastnwht;
  243.     char c;
  244.  
  245. /* original
  246.     for (cpos=cp,posp=tp;posp>=s && (((c=(*posp & 0x7f) != ' ') && c!='\t')
  247.         || cpos>rtmarg);cpos--)
  248.         if (c!='\t') posp--;
  249.         else
  250.            if (!((cpos-1)%tabwidth)) posp--;
  251.     return (++posp);
  252. */
  253.     lastnwht=tp;
  254.     posp=tp-1;
  255.     while ( ( ((c=*posp)!=' ' && c!='\t') || cp>rtmarg) && posp>=s)
  256.     {
  257.         switch(c) {
  258.         case '\t' :
  259.             if (!(cp-1)%tabwidth) posp--;
  260.             break;
  261.         case ' ' :
  262.             posp--;
  263.             break;
  264.         default  :
  265.             lastnwht=posp--;
  266.             break;
  267.         }
  268.         cp--;
  269.     }
  270.     return (lastnwht);
  271. }
  272.  
  273. #else        /*no wwrap*/
  274.  
  275. insertchar(c)    /*inserts 'c' at charn, moves cursor up  one */
  276. char c;
  277. {
  278.         int cx,cp,temp;
  279.     char *t;
  280.  
  281.     if ( (cp=strlen(text)+1) >= (LLIM-1))
  282.         error("Line to long");
  283.     else {
  284.         for (; cp >= charn; cp--) text[cp+1]=text[cp];
  285.         text[charn]=c;
  286.         altered=YES;
  287.         rewrite(charn,cursorx);
  288.         sync(charn+1);
  289.         }
  290. }
  291. #endif
  292.  
  293. deletechar(dir)    /*deletes char before (dir=-1) or at (dir=0) cursor */
  294. int dir;
  295. {
  296.     char c;
  297.     int cp;
  298.  
  299.     cp=charn+dir;
  300.     if (cp < 0) {
  301.         if (cline > 1) crdelete(-1);
  302.         }
  303.     else if (text[cp] == '\0') {
  304.         if (cline < lastl) crdelete(0);
  305.         }
  306.     else {
  307.         do { 
  308.             c=text[cp]=text[cp+1]; 
  309.             cp++; 
  310.             } 
  311.         while(c);
  312.         altered=YES;
  313.         sync(charn+dir);
  314.         if (calcoffset() != lastoff)rewrite(0,0);
  315.         else rewrite(charn,cursorx);
  316.         }
  317. }
  318.  
  319. crdelete(dir)    /*delete a [CR] before (dir==-1)or at (dir==0) cursor */
  320. int dir;
  321. {
  322.     int delline, len, *t;
  323.     char textb[LLIM];
  324.  
  325.     altered=YES;
  326.     if (dir == 0) {
  327.         delline=cline+1;
  328.         strcpy(textb,getline(delline));
  329.         cursory++;
  330.         }
  331.     else {
  332.         delline=cline;
  333.         strcpy(textb,text);
  334.         if (cline > 1) gettext(cline-1);
  335.         else puttext();
  336.         }
  337.     sync((len=strlen(text)));
  338.     if (len+strlen(textb) >= LLIM) {
  339.         textb[LLIM-len]='\0';
  340.         error("Line too long - cut short");
  341.         }
  342.     strcat(text,textb);
  343.     deltp(delline,1);
  344.     if (delline > plast || delline <= pfirst) {
  345.         puttext(); 
  346.         putpage();
  347.         }
  348.     else {
  349.         linedelete(cursory--);
  350.         rewrite(0,0);
  351.         if (plast <= lastl && lastl-pfirst > SHEIGHT - topline)
  352.             putline(plast, SHEIGHT);
  353.         else plast=lastl;
  354.         }
  355. }
  356.  
  357. deleteword()
  358. {
  359.     int pend, cp;
  360.     char c;
  361.  
  362. /*
  363.     for (pend=charn; (c=text[pend]) && ( inword(c)); pend++);
  364.     while ( (c=text[pend]) && !inword(c)) pend++;
  365. */
  366.     for (pend=charn; (c=text[pend]) && ( !inword(c)); pend++);
  367.     while ( (c=text[pend]) && inword(c)) pend++;
  368.     for (cp=charn; (text[cp]=text[pend]); pend++, cp++);
  369.     rewrite(charn,cursorx);
  370.     altered=YES;
  371. }
  372.  
  373. crinsert(dir)    /*insert a [CR] behind (dir==0) or in front of (-1) cursor*/
  374. {
  375.     char textb[LLIM], c;
  376.     int charnb;
  377.  
  378.     charnb=0;
  379.     if (autoin && !isspace(text[charn]))
  380.         while(isspace( (c=text[charnb]) )) textb[charnb++]=c;
  381.     strcpy(&textb[charnb],&text[charn]);
  382.     text[charn]='\0';
  383.     altered=YES; 
  384.     if (dir == 0) puttext();
  385.     if ((cline=inject(cline,textb)+dir) == FAIL) return;
  386.     if (dir == 0) {
  387.         gettext(cline); 
  388.         sync(charnb); 
  389.         }
  390.     if (cursory >= SHEIGHT) { 
  391.         puttext(); 
  392.         /*putpage();*/  /*<== original code*/
  393.         linedelete(topline); /*<==new code to next "}"*/
  394.         pfirst++;             /*   scrolls with newline*/
  395.         gotoxy(cursorx,--cursory);
  396.     }
  397.     /*else {*/   /*<==original*/
  398.     if (cursory < SHEIGHT) {
  399.         gotoxy(0,cursory+1);
  400.         insertline();
  401.         if (dir == 0) putline(cline-1,cursory++);
  402.         else putline(cline+1,cursory+1);
  403.         rewrite(0,0);
  404.         if (plast-pfirst < SHEIGHT-topline)plast++;
  405.     }
  406. }
  407.  
  408. oops()    /*undoes edits on current line*/
  409. {
  410.     if (altered) {
  411.         if (cline <= lastl) gettext(cline);
  412.         else text[0]='\0';
  413.         altered=NO;
  414.         cursorx=adjustc(cursorx);
  415.         rewrite(0,0);
  416.         }
  417. }
  418.  
  419. adjustc(x)    /*return x coord. for cursor nearest to col. 'x' so that
  420.           cursor isn't in the middle of a tab or off the end of the
  421.           current line*/
  422. int x;
  423. {
  424.     int cpos;
  425.     char c;
  426.  
  427.     for(charn=0, cpos=0; cpos < x && (c=text[charn]); charn++, cpos++)
  428.         if (c == '\t') cpos=cpos+tabwidth-1-(cpos%tabwidth);
  429.     return cpos;
  430. }
  431.  
  432. sync(cp)    /*put cursorx and charn onto character 'cp' of current line*/
  433. int cp;
  434. {
  435.     for(charn=0, cursorx=0; charn < cp; cursorx++, charn++)
  436.         if (text[charn] == '\t') cursorx=cursorx+tabwidth-1-(cursorx%tabwidth);
  437. }
  438.