home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 133_01 / e2 < prev    next >
Text File  |  1985-03-10  |  8KB  |  372 lines

  1. /*
  2.     e screen editor
  3.  
  4.     (C) G. Nigel Gilbert, MICROLOGY, 1981
  5.  
  6.     August-December 1981
  7.  
  8.     FILE: e2
  9.  
  10.     FUNCTIONS: movechar,moveline, movepage, moveword, insertchar,
  11.             deletechar,crdelete,deleteword,crinsert,adjustc,
  12.             sync, pointtobrack.
  13.  
  14.     PURPOSE: perform text changing commands
  15.  
  16. */
  17.  
  18. #include "e.h"
  19.  
  20. movechar(move)    /*move cursor by 'move' columns to the right
  21.           return YES unless going off text*/
  22. int move;
  23. {
  24.     int cp, len, result;
  25.  
  26.     cp=charn+move;
  27.     result=YES;
  28.     if (cp < 0) {
  29.         result=moveline(-1);
  30.         if (result) {
  31.             adjustc(LLIM);
  32.             movechar(cp+1);
  33.             }
  34.         else sync(0);
  35.         }
  36.     else if (cp > (len=strlen(text))) {
  37.         result=moveline(1);
  38.         if (result) {
  39.             sync(0);
  40.             movechar(cp-len-1);
  41.             }
  42.         else adjustc(LLIM);
  43.         }
  44.     else sync(cp);
  45.     return result;
  46. }
  47.  
  48. moveline(move)    /*move cursor by 'move' lines down
  49.          return YES if Ok, NO if going off text*/
  50. int move;
  51. {
  52.     int line;
  53.  
  54.     puttext();
  55.     if ( (move<0?-move:move) > SHEIGHT) gotoxy(WAITPOS,0);
  56.     line=cline;
  57.     if ((cline=loc(cline,move)) != line) {
  58.         gettext(cline);
  59.         if (cline < pfirst || cline > plast) {
  60.             if (move == 1 || move == -1) scroll(move);
  61.             else putpage();
  62.             }
  63.         else {
  64.             if (hilight) putline(line,cursory);
  65.             cursory+=cline-line;
  66.             adjustc(cursorx);
  67.             if (hilight) putline(cline,cursory);
  68.             }
  69.         return YES;
  70.         }
  71.     else return NO;
  72. }
  73.  
  74. scroll(move)    /*scroll up (move==1) or down 1 line*/
  75. int move;
  76. {
  77.     if (move == 1) {
  78.         linedelete(topline);
  79.         putline(cline-1,SHEIGHT-1);
  80.         }
  81.     else {
  82.         insertline();
  83.         putline(cline+1,topline+1);
  84.         }
  85.     adjustc(cursorx);
  86.     putline(cline,cursory);
  87.     if (plast-pfirst == (SHEIGHT-topline)) plast+=move;
  88.     pfirst+=move;
  89. }
  90.  
  91. jumpline(move)    /*move current line by move lines down, checking for
  92.             interrupt from user (if interrupted, do nothing,
  93.             and return NO) */
  94. int move;
  95. {
  96.     int line, dest;
  97.     char testkey();
  98.  
  99.     puttext();
  100.     dest=cline+move;
  101.     dest-=dest%100;
  102.     if (dest > lastread) {
  103.         gotoxy(WAITPOS,0);
  104.         line=cline;
  105.         while (line < dest && loc(line,100) != line) {
  106.             line+=100;
  107.             if (testkey() == ESCKEY) {
  108.                 error("Interrupted");
  109.                 return NO;
  110.                 }
  111.             }
  112.         }
  113.     moveline(move);
  114.     return YES;
  115. }
  116.  
  117. movepage(dir)    /*move current line by a page down (dir==0) or up (-1)*/
  118. int dir;
  119. {
  120.     int move, line;
  121.  
  122.     puttext();
  123.     move=(SHEIGHT-topline)/2 - PAGEOVERLAP;
  124.     if (dir) move=pfirst-cline-move;
  125.     else move=plast-cline+move;
  126.     if ( (cline=loc((line=cline),move) ) != line) {
  127.         gettext(cline);
  128.         putpage();
  129.         }
  130. }
  131.  
  132. moveword(move)    /*move 1 word to the right (move -ve: left)*/
  133. int move;
  134. {
  135.     if (charn+move < 0) {
  136.         moveline(-1);
  137.         charn=strlen(text);
  138.         }
  139.     else if (charn+move >= strlen(text)) {
  140.         moveline(1);
  141.         sync(0);
  142.         if (inword(text[0])) return;
  143.         }
  144.     while ((move<0 || text[charn]) && inword(text[charn]) && (charn+=move));
  145.     while ((move<0 || text[charn]) && !inword(text[charn]) && (charn+=move));
  146.     if (move < 0 && charn) {
  147.         while(inword(text[charn]) && --charn);
  148.         if (charn || !inword(text[charn]) ) charn++;
  149.         }
  150.     sync(charn);
  151. }
  152.  
  153. insertchar(c)    /*inserts 'c' at charn, moves cursor up  one */
  154. char c;
  155. {
  156.     int cp;
  157.  
  158.     if ( (cp=strlen(text)+1) >= (LLIM-1))
  159.         error("Line too long");
  160.     else {
  161.         for (; cp >= charn; cp--) text[cp+1]=text[cp];
  162.         text[charn]=c;
  163.         altered=YES;
  164.         rewrite(charn,cursorx);
  165.         if (c == ')' || c == '}' || c == ']') pointtobrack(c);
  166.         sync(charn+1);
  167.         }
  168. }
  169.  
  170. pointtobrack(closebr)    /*momentarily put cursor on matching opening
  171.             bracket */
  172. char closebr;
  173. {
  174.     int chn, chna, i, l, brackline, brackcount, cx;
  175.     char openbr, *t, c, *getline();
  176.  
  177.     if (closebr == ')') openbr='(';
  178.     else if (closebr == '}') openbr='{';
  179.     else openbr='[';
  180.  
  181.     for (chn=charn, t=text, l=cline, brackcount=0, brackline=cursory;
  182.         l >= pfirst; brackline--) {
  183.         for (; chn >= 0; chn--) {
  184.             if ((c=*(t+chn)) == closebr) brackcount++;
  185.             if (c == openbr) brackcount--;
  186.             if (brackcount == 0) {
  187.                 for (chna=0, cx=0; chna < chn; chna++, cx++)
  188.                     if (*(t+chna) == '\t') cx+= tabwidth-1-(cx%tabwidth);
  189.                 if (l == cline || blockscroll) cx+= (lastoff>0)-lastoff;
  190.                 if (cx < 0|| cx >= SWIDTH) return;
  191.                 gotoxy(cx,brackline);
  192.                 for (i=0; i < (3 * CURSORWAIT); i++);
  193.                 return;
  194.                 }
  195.             }
  196.         chn=strlen( (t=getline(--l) ))-1;
  197.         }
  198. }
  199.  
  200. deletechar(dir)    /*deletes char before (dir=-1) or at (dir=0) cursor */
  201. int dir;
  202. {
  203.     char c;
  204.     int cp;
  205.  
  206.     cp=charn+dir;
  207.     if (cp < 0) {
  208.         if (cline > 1) crdelete(-1);
  209.         }
  210.     else if (text[cp] == '\0') {
  211.         if (cline < lastl) crdelete(0);
  212.         }
  213.     else {
  214.         do {
  215.             c=text[cp]=text[cp+1];
  216.             cp++;
  217.             }
  218.         while(c);
  219.         altered=YES;
  220.         sync(charn+dir);
  221.         if (calcoffset() != lastoff)rewrite(0,0);
  222.         else rewrite(charn,cursorx);
  223.         }
  224. }
  225.  
  226. crdelete(dir)    /*delete a [CR] before (dir==-1)or at (dir==0) cursor */
  227. int dir;
  228. {
  229.     int delline, len, *t;
  230.     char textb[LLIM], *getline();
  231.  
  232.     altered=YES;
  233.     if (dir == 0) {
  234.         delline=cline+1;
  235.         strcpy(textb,getline(delline));
  236.         cursory++;
  237.         }
  238.     else {
  239.         delline=cline;
  240.         strcpy(textb,text);
  241.         if (cline > 1) gettext(cline-1);
  242.         else puttext();
  243.         }
  244.     sync((len=strlen(text)));
  245.     if (len+strlen(textb) >= LLIM) {
  246.         textb[LLIM-len]='\0';
  247.         error("Line too long - cut short");
  248.         }
  249.     strcat(text,textb);
  250.     puttext();
  251.     delete(delline);
  252.     if (delline > plast || delline <= pfirst) putpage();
  253.     else {
  254.         linedelete(cursory--);
  255.         rewrite(0,0);
  256.         if (plast <= lastl && lastl-pfirst > SHEIGHT - topline)
  257.             putline(plast, SHEIGHT);
  258.         else plast=lastl;
  259.         }
  260. }
  261.  
  262. deleteword()    /*delete rest of word if in word, else up to next word */
  263. {
  264.     int pend, cp, in;
  265.     char c;
  266.  
  267.     for (in=inword(text[pend=charn]);
  268.         (c=text[pend]) && (in ? inword(c): !inword(c)); pend++);
  269.     for (cp=charn; (text[cp]=text[pend]); pend++, cp++);
  270.     rewrite(charn,cursorx);
  271.     altered=YES;
  272. }
  273.  
  274. crinsert(dir)    /*insert a [CR] behind (dir==0) or in front of (-1) cursor*/
  275. {
  276.     char textb[LLIM], c;
  277.     int charnb;
  278.  
  279.     charnb=0;
  280.     if (autoin && !isspace(text[charn])) while(isspace( (c=text[charnb]) ))
  281.         textb[charnb++]=c;
  282.     strcpy(&textb[charnb],&text[charn]);
  283.     text[charn]='\0';
  284.     altered=YES;
  285.     if (dir == 0) {
  286.         puttext();
  287.         strcpy(text,textb);
  288.         altered=YES;
  289.         sync(charnb);
  290.         if ((cline=inject(cline,textb)) == FAIL) return;
  291.         }
  292.     else if (inject(cline,textb) == FAIL) return;
  293.     if (cursory >= SHEIGHT) {
  294.         puttext();
  295.         putpage();
  296.         }
  297.     else {
  298.         insertline();
  299.         if (dir == 0) putline(cline-1,cursory++);
  300.         else putline(cline+1,cursory+1);
  301.         if (plast-pfirst < SHEIGHT-topline)plast++;
  302.         rewrite(0,0);
  303.         }
  304. }
  305.  
  306. undo()    /*undoes edits on current line and then from history*/
  307. {
  308.     struct histstep *step;
  309.     sint onpage;
  310.     int l, slot;
  311.     char textb[LLIM];
  312.  
  313.     if (altered) {
  314.         if (cline <= lastl) gettext(cline);
  315.         else text[0]='\0';
  316.         altered=NO;
  317.         adjustc(cursorx);
  318.         rewrite(0,0);
  319.         }
  320.     else {
  321.         if (histcnt == 0) {
  322.             error("Nothing to undo");
  323.             return;
  324.             }
  325.         onpage=NO;
  326.         do {
  327.             if (--histptr < 0) histptr= (HISTLEN-1);
  328.             histcnt--;
  329.             step=history[histptr];
  330.             l=step->histline;
  331.             onpage= onpage || (l >= pfirst && l <= plast);
  332.             storehist=NO;
  333.             switch (step->histtype) {
  334.             case HISTINSERT:
  335.                 delete(l+1);
  336.                 break;
  337.             case HISTDELETE:
  338.                 if ((slot=pageloc[step->histp.page]) <= 0)
  339.                     slot=swapin(step->histp.page);
  340.                 strcpy(textb,slotaddr[slot] + step->histp.moffset);
  341.                 inject(l-1,textb);
  342.                 break;
  343.             case HISTREPLACE:
  344.                 tp[l].page=step->histp.page;
  345.                 tp[l].moffset=step->histp.moffset;
  346.                 break;
  347.                 }
  348.             } while (histcnt && step->histcomm ==
  349.                     history[(histptr-1 < 0 ? HISTLEN-1 : histptr-1)].histcomm);
  350.         if (onpage) putpage();
  351.     }
  352. }
  353.  
  354. adjustc(x)    /*set cursorx to col. cursor nearest to col. 'x' so that
  355.           cursor isn't in the middle of a tab or off the end of the
  356.           current line*/
  357. int x;
  358. {
  359.     char c;
  360.  
  361.     for(charn=0, cursorx=0; cursorx < x && (c=text[charn]);
  362.                         charn++, cursorx++)
  363.         if (c == '\t') cursorx+=tabwidth-1-(cursorx%tabwidth);
  364. }
  365.  
  366. sync(cp)    /*put cursorx and charn onto character 'cp' of current line*/
  367. int cp;
  368. {
  369.     for(charn=0, cursorx=0; charn < cp; cursorx++, charn++)
  370.         if (text[charn] == '\t') cursorx=cursorx+tabwidth-1-(cursorx%tabwidth);
  371. }
  372. );