home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource3 / 158_01 / qe2 < prev    next >
Encoding:
Text File  |  1987-10-12  |  9.0 KB  |  424 lines

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