home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3877 < prev    next >
Text File  |  1991-08-22  |  29KB  |  2,019 lines

  1. Path: wupost!decwrl!amdcad!pyramid!oliveb!olivea!samsung!crackers!m2c!wpi.WPI.EDU!rcarter
  2. From: rcarter@wpi.WPI.EDU (Randolph Carter (nee. Joseph H. Allen))
  3. Newsgroups: alt.sources
  4. Subject: J (Joe's Editor) - Part 2 of 3
  5. Message-ID: <1991Aug22.043404.193@wpi.WPI.EDU>
  6. Date: 22 Aug 91 04:34:04 GMT
  7. Sender: rcarter@wpi.WPI.EDU (Randolph Carter (nee. Joseph H. Allen))
  8. Organization: Kadath Tours, Inc.
  9. Lines: 2008
  10.  
  11.  
  12. -- Cut here; take text between this line and the last 'cut' line
  13.    from+=helpwidth-width+1;
  14.    break;
  15.    }
  16.   if(*from!=*too)
  17.    {
  18.    cpos(i,j);
  19.    tputcc((unsigned char)(*too= *from));
  20.    oxpos++;
  21.    }
  22.   from++;
  23.   too++;
  24.   }
  25.  for(;j!=width-1;j++)
  26.   {
  27.   if(have) return;
  28.   if(' '!=*too)
  29.    {
  30.    cpos(i,j);
  31.    tputcc((unsigned char)(*too= ' '));
  32.    oxpos++;
  33.    }
  34.   too++;
  35.   }
  36.  too++;
  37.  }
  38. hupd=0;
  39. }
  40.  
  41. int updall=0;
  42.  
  43. dupdate()
  44. {
  45. int xp,yp;
  46.  
  47. aflush();
  48. if(hupd) dupdatehelp();
  49. if(upd)
  50.  {
  51.  int total=height-wind;
  52.  struct window *x;
  53.  dupdate1(1);
  54.  stwin(curwin);
  55.  x=curwin;
  56.  curwin=topwin;
  57.  xp=xpos; yp=ypos;
  58.  do
  59.   {
  60.   if((curbuf==x->buffer || updall) && curwin!=x)
  61.    {
  62.    if(total<=0) break;
  63.    ldwin(curwin);
  64.    total-=curwin->height;
  65.    newy=1;
  66.    dupdate1(0);
  67.    stwin(curwin);
  68.    }
  69.   else if(curwin==x)
  70.    total-=curwin->height;
  71.   }
  72.   while(curwin=curwin->next,curwin!=topwin);
  73.  updall=0;
  74.  ldwin(x);
  75.  curwin=x;
  76.  cpos(ypos=yp,xpos=xp);
  77.  }
  78. }
  79.  
  80. invalidate(line)
  81. {
  82. int x;
  83. for(x=0;x<width;x++) scrn[width*line+x]= -1;
  84. }
  85.  
  86. int tattrib(c)
  87. unsigned char c;
  88. {
  89. int mmode=0;
  90. if(c>=128)
  91.  {
  92.  mmode|=INVERSE;
  93.  c-=128;
  94.  }
  95. if(c==127)
  96.  {
  97.  mmode|=UNDERLINE;
  98.  c='?';
  99.  }
  100. else if(c<32)
  101.  {
  102.  mmode|=UNDERLINE;
  103.  c+='@';
  104.  }
  105. attrib(mmode);
  106. return c;
  107. }
  108.  
  109. tputcc(c)
  110. unsigned char c;
  111. {
  112. eputc(tattrib(c));
  113. }
  114.  
  115. tputss(s)
  116. unsigned char *s;
  117. {
  118. while(*s) tputcc(*(s++));
  119. }
  120.  
  121. int backup=0;
  122. FILE *handle;
  123. unsigned char gfnam[PATHSIZE];
  124.  
  125. TXTSIZ bufsiz;        /* Size of buffer */
  126. TXTPTR point;            /* The point */
  127. TXTPTR buffer;           /* The buffer */
  128. TXTPTR filend;           /* First character not in buffer */
  129. TXTPTR hole;             /* Beginning of hole */
  130. TXTPTR ehole;            /* First character not in hole */
  131. int changed=0;          /* Set when file has been changed */
  132.  
  133. fmopen()
  134. {
  135. buffer=(unsigned char *)TXTMALLOC(bufsiz=HOLESIZE);
  136. point=buffer;
  137. hole=buffer;
  138. ehole=buffer+HOLESIZE;
  139. filend=ehole;
  140. changed=0;
  141. }
  142.  
  143. fmexpand(amount)
  144. unsigned amount;
  145. {
  146. if(filend+amount-buffer>bufsiz)
  147.  {
  148.  unsigned char *old=buffer;
  149.  buffer=(TXTPTR)TXTREALLOC(buffer,bufsiz=(filend+amount+HOLESIZE-buffer));
  150.  point+=buffer-old;
  151.  filend+=buffer-old;
  152.  hole+=buffer-old;
  153.  ehole+=buffer-old;
  154.  }
  155. }
  156.  
  157. fmhole()
  158. {
  159. if(point==hole) return;
  160. if(point==ehole)
  161.  {
  162.  point=hole;
  163.  return;
  164.  }
  165. if(point<hole)
  166.  {
  167.  bmove(ehole-(hole-point),point,hole-point);
  168.  ehole-=(hole-point);
  169.  hole=point;
  170.  }
  171. else
  172.  {
  173.  bmove(hole,ehole,point-ehole);
  174.  hole+=point-ehole;
  175.  ehole=point;
  176.  point=hole;
  177.  }
  178. }
  179.  
  180. fmbig(size)
  181. TXTSIZ size;
  182. {
  183. if(size>fmholesize())
  184.  {
  185.  size+=HOLESIZE;
  186.  fmexpand(size);
  187.  bmove(ehole+size,ehole,filend-ehole);
  188.  ehole+=size;
  189.  filend+=size;
  190.  }
  191. }
  192.  
  193. int fmfnl()
  194. {
  195. while(((point==hole)?(point=ehole):point)!=filend)
  196.  if(*point==NL) return 1;
  197.  else point++;
  198. return 0;
  199. }
  200.  
  201. int fmrnl()
  202. {
  203. if(fmrc()==NL) return 1;
  204. while((point==ehole?point=hole:point)!=buffer)
  205.  if(*(--point)==NL) return 1;
  206. return 0;
  207. }
  208.  
  209.  
  210. int nundorecs=0;
  211. struct undorec
  212.  {
  213.  struct undorec *next;
  214.  TXTSIZ size;
  215.  TXTSIZ where;
  216.  struct buffer *buf;
  217.  unsigned char *buffer;
  218.  }
  219.  *undorecs=0;
  220.  
  221. fminsu(size)
  222. TXTSIZ size;
  223. {
  224. struct window *z;
  225. if(undorecs) undorecs->buf=0;
  226. if(curbuf==markbuf)
  227.  {
  228.  if(fmnote()<markb) markb+=size;
  229.  if(fmnote()<marke) marke+=size;
  230.  }
  231. z=topwin;
  232. do
  233.  {
  234.  if(z->buffer==curbuf)
  235.   {
  236.   if(z==curwin)
  237.    {
  238.    if(fmnote()<saddr) saddr+=size;
  239.    }
  240.   else
  241.    {
  242.    if(fmnote()<z->saddr) z->saddr+=size;
  243.    if(fmnote()<z->cursor) z->cursor+=size;
  244.    }
  245.   }
  246.  z=z->next;
  247.  }
  248.  while(z!=topwin);
  249. }
  250.  
  251. struct undorec *undoptr=0;
  252. int undoflag=1;
  253.  
  254. undo()
  255. {
  256. extend=0;
  257. if(undoptr)
  258.  {
  259.  undoflag=0;
  260.  fmdel(undoptr->size);
  261.  undoflag=1;
  262.  undoptr=undoptr->next;
  263.  if(!undoptr)
  264.   {
  265.   marke=markb;
  266.   return;
  267.   }
  268.  }
  269. else undoptr=undorecs;
  270. fminss(undoptr->buffer,undoptr->size);
  271. markbuf=curbuf;
  272. markb=fmnote();
  273. marke=markb+undoptr->size;
  274. }
  275.  
  276. redo()
  277. {
  278. extend=0;
  279. if(undoptr)
  280.  {
  281.  undoflag=0;
  282.  fmdel(undoptr->size);
  283.  undoflag=1;
  284.  if(undoptr==undorecs)
  285.   {
  286.   undoptr=0;
  287.   marke=markb;
  288.   return;
  289.   }
  290.  else
  291.   {
  292.   struct undorec *p;
  293.   for(p=undorecs;p->next!=undoptr;p=p->next);
  294.   undoptr=p;
  295.   }
  296.  }
  297. else for(undoptr=undorecs;undoptr->next;undoptr=undoptr->next);
  298. fminss(undoptr->buffer,undoptr->size);
  299. markbuf=curbuf;
  300. markb=fmnote();
  301. marke=markb+undoptr->size;
  302. }
  303.  
  304. fmdelu(size)
  305. TXTSIZ size;
  306. {
  307. struct window *z;
  308. struct undorec *it;
  309. if(undoflag)
  310.  {
  311.  if(undorecs)
  312.   if(undorecs->buf==curbuf && (undorecs->where==fmnote()))
  313.    {
  314.    /* Add to end */
  315.    undorecs->buffer=(unsigned char *)realloc(undorecs->buffer,
  316.    undorecs->size+size);
  317.    fmcpy(undorecs->buffer+undorecs->size,size);
  318.    undorecs->size+=size;
  319.    }
  320.   else if(undorecs->buf==curbuf && (undorecs->where==fmnote()+size))
  321.    {
  322.    /* Add to beginning */
  323.    undorecs->buffer=(unsigned char *)realloc(
  324.    undorecs->buffer,undorecs->size+size);
  325.    bbkwd(undorecs->buffer+size,undorecs->buffer,undorecs->size);
  326.    fmcpy(undorecs->buffer,size);
  327.    undorecs->size+=size;
  328.    undorecs->where-=size;
  329.    }
  330.   else goto in;
  331.  else
  332.   {
  333.   in:
  334.   /* New record */
  335.   it=(struct undorec *)malloc(sizeof(struct undorec));
  336.   it->next=undorecs;
  337.   undorecs=it;
  338.   it->buf=curbuf;
  339.   it->size=size;
  340.   it->where=fmnote();
  341.   it->buffer=(unsigned char *)malloc(size);
  342.   fmcpy(it->buffer,size);
  343.   ++nundorecs;
  344.   if(nundorecs==20)
  345.    {
  346.    struct undorec *p;
  347.    for(it=undorecs;it->next;p=it,it=it->next);
  348.    free(it->buffer);
  349.    free(it);
  350.    p->next=0;
  351.    }
  352.   }
  353.  }
  354. if(markbuf==curbuf)
  355.  {
  356.  if(fmnote()<markb) markb-=umin(size,markb-fmnote());
  357.  if(fmnote()<marke) marke-=umin(size,marke-fmnote());
  358.  }
  359. z=topwin;
  360. do
  361.  {
  362.  if(curbuf==z->buffer)
  363.   {
  364.   if(z==curwin)
  365.    {
  366.    if(fmnote()<saddr) saddr-=umin(size,saddr-fmnote());
  367.    }
  368.   else
  369.    {
  370.    if(fmnote()<z->saddr) z->saddr-=umin(size,z->saddr-fmnote());
  371.    if(fmnote()<z->cursor) z->cursor-=umin(size,z->cursor-fmnote());
  372.    }
  373.   }
  374.  z=z->next;
  375.  }
  376.  while(z!=topwin);
  377. }
  378.  
  379. fmdel(x)
  380. TXTSIZ x;
  381. {
  382. fmhole();
  383. fmdelu(x);
  384. ehole+=x;
  385. changed=1;
  386. }
  387.  
  388. fminss(string,size)
  389. unsigned char *string;
  390. unsigned size;
  391. {
  392. fminsu(size);
  393. fmhole();
  394. if(size>fmholesize()) fmbig(size);
  395. bmove(hole,string,size);
  396. hole+=size;
  397. changed=1;
  398. }
  399.  
  400. fmcpy(string,size)
  401. unsigned char *string;
  402. {
  403. fmhole();
  404. bbkwd(string,ehole,size);
  405. }
  406.  
  407. int fmcmp(string,size)
  408. unsigned char *string;
  409. int size;
  410. {
  411. unsigned char *x;
  412. if(point==hole) point=ehole;
  413. if(hole>point && hole<point+size && hole!=ehole)
  414.  {
  415.  if(fmcmp(string,hole-point)) return 1;
  416.  else
  417.   {
  418.   x=point;
  419.   point=ehole;
  420.   if(fmcmp(string+(hole-x),size-(hole-x)))
  421.    {
  422.    point=x;
  423.    return 1;
  424.    }
  425.   else
  426.    {
  427.    point=x;
  428.    return 0;
  429.    }
  430.   }
  431.  }
  432. else
  433.  {
  434.  x=point;
  435.  do
  436.   if(*(x++)!=*(string++)) return 1;
  437.   while(--size);
  438.  return 0;
  439.  }
  440. }
  441.  
  442. int tupp(c)
  443. unsigned char c;
  444. {
  445. if(c>='a' && c<='z') return c+'A'-'a';
  446. else return c;
  447. }
  448.  
  449. int fmicmp(string,size)
  450. unsigned char *string;
  451. int size;
  452. {
  453. unsigned char *x;
  454. if(point==hole) point=ehole;
  455. if(hole>point && hole<point+size && hole!=ehole)
  456.  {
  457.  if(fmcmp(string,hole-point)) return 1;
  458.  else
  459.   {
  460.   x=point;
  461.   point=ehole;
  462.   if(fmcmp(string+(hole-x),size-(hole-x)))
  463.    {
  464.    point=x;
  465.    return 1;
  466.    }
  467.   else
  468.    {
  469.    point=x;
  470.    return 0;
  471.    }
  472.   }
  473.  }
  474. else
  475.  {
  476.  x=point;
  477.  do
  478.   if(tupp(*(x++))!=tupp(*(string++))) return 1;
  479.   while(--size);
  480.  return 0;
  481.  }
  482. }
  483.  
  484. int fmsave(file,size)
  485. FILE *file;
  486. TXTSIZ size;
  487. {
  488. if(!size) return 1;
  489. if(point==hole) point=ehole;
  490. if(hole>point && hole<point+size && hole!=ehole)
  491.  {
  492.  if(hole-point!=fwrite(point,1,hole-point,file)) return 0;
  493.  if(size-(hole-point)!=fwrite(ehole,1,size-(hole-point),file)) return 0;
  494.  return 1;
  495.  }
  496. else
  497.  return size==fwrite(point,1,size,file);
  498. }
  499.  
  500. int fminsfil(file)
  501. FILE *file;
  502. {
  503. struct stat buf;
  504. TXTSIZ amount;
  505. fstat(fileno(file),&buf);
  506. if(buf.st_size==0) return 1;
  507. fminsu(buf.st_size);
  508. changed=1;
  509. fmhole();
  510. fmbig(buf.st_size);
  511. amount=fread(hole,1,buf.st_size,file);
  512. hole+=amount;
  513. return amount==buf.st_size;
  514. }
  515.  
  516. int getl(prompt,dat)
  517. unsigned char *prompt;
  518. unsigned char *dat;
  519. {
  520. int ch,x;
  521. cpos(height-1,0);
  522. tattrib(' ');
  523. eputs(prompt);
  524. eputs(" (^C to abort): ");
  525. eputs(dat);
  526. eputs("\033[K");
  527. x=strlen(dat);
  528. oxpos=strlen(prompt)+x+21;
  529. while(1)
  530.  {
  531.  ch=anext();
  532.  if(ch=='L'-'@')
  533.   {
  534.   ch= -1;
  535.   break;
  536.   }
  537.  if(ch==13 || ch==10)
  538.   {
  539.   ch=1;
  540.   break;
  541.   }
  542.  if(ch>=32 && ch<127)
  543.   {
  544.   dat[x+1]=0;
  545.   dat[x++]=ch;
  546.   tputcc(ch);
  547.   oxpos++;
  548.   continue;
  549.   }
  550.  if((ch==8 || ch==127) && x)
  551.   {
  552.   x--;
  553.   dat[x]=0;
  554.   eputs("\010 \010");
  555.   oxpos--;
  556.   continue;
  557.   }
  558.  if(ch==3)
  559.   {
  560.   ch=0;
  561.   break;
  562.   }
  563.  }
  564. invalidate(height-1);
  565. return ch;
  566. }
  567.  
  568. msg(ms)
  569. unsigned char *ms;
  570. {
  571. cpos(height-1,0);
  572. tattrib(' ');
  573. eputs(ms);
  574. eputc(' ');
  575. eputs("\033[K");
  576. oxpos=1+strlen(ms);
  577. if(ms[0]=='\033') oxpos-=7;
  578. eputs("\033[K");
  579. invalidate(height-1);
  580. anext();
  581. }
  582.  
  583. int askyn(ms)
  584. unsigned char *ms;
  585. {
  586. int ch;
  587. cpos(height-1,0);
  588. tattrib(' ');
  589. eputs(ms);
  590. oxpos=strlen(ms);
  591. if(ms[0]=='\033') oxpos-=7;
  592. eputs("\033[K");
  593. invalidate(height-1);
  594. up:
  595. ch=anext();
  596. switch(ch)
  597.  {
  598. case 'y':
  599. case 'n':
  600.  eputc(ch);
  601.  ch&=0x5f;
  602.  break;
  603. case 'Y':
  604. case 'N':
  605.  eputc(ch);
  606.  break;
  607. case 3:
  608.  ch= -1;
  609.  break;
  610. default:
  611.  goto up;
  612.  }
  613. return ch;
  614. }
  615.  
  616. int query(ms)
  617. unsigned char *ms;
  618. {
  619. cpos(height-1,0);
  620. tattrib(' ');
  621. eputs(ms);
  622. oxpos=strlen(ms);
  623. if(ms[0]=='\033') oxpos-=7;
  624. eputs("\033[K");
  625. invalidate(height-1);
  626. return anext();
  627. }
  628.  
  629. int nquery(ms)
  630. unsigned char *ms;
  631. {
  632. cpos(height-1,0);
  633. tattrib(' ');
  634. eputs(ms);
  635. oxpos=strlen(ms);
  636. if(ms[0]=='\033') oxpos-=7;
  637. eputs("\033[K");
  638. cpos(ypos,xpos);
  639. invalidate(height-1);
  640. return anext();
  641. }
  642.  
  643. imsg()
  644. {
  645. unsigned char s[PATHSIZE];
  646. tattrib(' ');
  647. if(omsg)
  648.  {
  649.  eputs(omsg);
  650.  invalidate(1);
  651.  }
  652. sprintf(s,"\033[%d;1H\033[7m** Joe's Editor version 0.0.0 (1991) **          \
  653.                               \033[m\033[2H",height);
  654. eputs(s);
  655. invalidate(height-1);
  656. upd=1;
  657. }
  658.  
  659. int pic;
  660. int autoind;
  661. int overwrite;
  662. int wrap;
  663. int tabmagic;
  664. TXTSIZ rmargin;
  665.  
  666. int options=0;
  667. unsigned char sstring[PATHSIZE];
  668. unsigned char rstring[PATHSIZE];
  669. int len;
  670.  
  671. TXTSIZ markb=0;
  672. TXTSIZ marke=0;
  673.  
  674. TXTSIZ added;
  675. TXTSIZ extend;
  676. int leave;       /* set if editor should now exit */
  677.  
  678. TXTSIZ getrcol()
  679. {
  680. TXTSIZ x,y;
  681. unsigned char ch;
  682. x=fmnote();
  683. if(fmnrnl()) fmgetc();
  684. y=0;
  685. while(fmnote()!=x)
  686.  {
  687.  ch=fmgetc();
  688.  if(ch==TAB)
  689.   while((++y)&7);
  690.  else
  691.   y++;
  692.  }
  693. return y;
  694. }
  695.  
  696. gocol(x)
  697. TXTSIZ x;
  698. {
  699. TXTSIZ y;
  700. int ch;
  701. if(fmnrnl()) fmgetc();
  702. extend=0;
  703. for(y=0;y!=x;y++)
  704.  {
  705.  if(fmeof()) goto dn;
  706.  ch=fmgetc();
  707.  if(ch==NL)
  708.   {
  709.   fmpoint(fmnote()-1);
  710.   extend=x;
  711.   return;
  712.   }
  713.  if(ch==TAB)
  714.   {
  715.   while((++y)&7)
  716.    {
  717.    if(y==x)
  718.     {
  719.     fmpoint(fmnote()-1);
  720. dn:
  721.     extend=x;
  722.     return;
  723.     }
  724.    }
  725.   y--;
  726.   }
  727.  }
  728. }
  729.  
  730. TXTSIZ calcs()
  731. {
  732. TXTSIZ y=0;
  733. if(fmnrnl()) fmgetc();
  734. extend=0;
  735. while(! (fmeof()?1:fmrc()==NL))
  736.  if(fmrc()==' ')
  737.   {
  738.   ++y;
  739.   fmgetc();
  740.   }
  741.  else if(fmrc()==TAB)
  742.   {
  743.   do ++y; while(y%TABWIDTH);
  744.   fmgetc();
  745.   }
  746.  else break;
  747. return y;
  748. }
  749.  
  750. unfill()
  751. {
  752. fmfnl();
  753. extend=0;
  754. while(fmnote())
  755.  {
  756.  unsigned char x=fmrgetc();
  757.  if(x==' ' || x==TAB) fmdel(1);
  758.  else
  759.   {
  760.   fmgetc();
  761.   break;
  762.   }
  763.  }
  764. }
  765.  
  766. /* Fill from end of line to extend position */
  767.  
  768. fillup()
  769. {
  770. TXTSIZ x;
  771. if(extend && pic)
  772.  {
  773.  x=getrcol();
  774.  while(extend>x)
  775.   {
  776.   fminsc(' ');
  777.   fmgetc();
  778.   ++x;
  779.   }
  780.  }
  781. extend=0;
  782. }
  783.  
  784. /* Save current buffer in named file.  Returns 0 on error.  Clears 'changed'
  785.  * variable if sucessfull
  786.  */
  787.  
  788. int saveit1(tos)
  789. unsigned char *tos;
  790. {
  791. unsigned char sting[PATHSIZE];
  792. TXTSIZ temp=fmnote();
  793. fmpoint(0);
  794. handle=fopen(tos,"w+");
  795. if(handle)
  796.  {
  797.  if(!fmsave(handle,fmsize()))
  798.   {
  799.   sprintf(sting,"\033[7mError writing to file %s\033[m",tos);
  800.   msg(sting);
  801.   fmpoint(temp);
  802.   return(0);
  803.   }
  804.  fmpoint(temp);
  805.  if(fclose(handle)==EOF)
  806.   {
  807.   sprintf(sting,"\033[7mError closing file %s\033[m",tos);
  808.   msg(sting);
  809.   fmpoint(temp);
  810.   return(0);
  811.   }
  812.  changed=0;
  813.  curbuf->changed=0;
  814.  return(1);
  815.  }
  816. else
  817.  {
  818.  sprintf(sting,"\033[7mError opening file %s\033[m",tos);
  819.  msg(sting);
  820.  fmpoint(temp);
  821.  return(0);
  822.  }
  823. }
  824.  
  825. rewrite()
  826. {
  827. unsigned char s[25];
  828. int *t,c;
  829. oxpos= 0;
  830. oypos= 0;
  831. tops= 0;
  832. bots= height-1;
  833. if(scroll) sprintf(s,"\033[m\033[1;%dr\033[H\033[J",height);
  834. else sprintf(s,"\033[m\033[H\033[J");
  835. eputs(s);
  836. t=scrn;
  837. c=width*height;
  838. do *(t++)= ' '; while(--c);
  839. upd=1;
  840. newy=1;
  841. updall=1;
  842. if(helpon) hupd=1;
  843. }
  844.  
  845. /* Toggle help text */
  846.  
  847. thelp()
  848. {
  849. struct window *x;
  850. newy=1;
  851. upd=1;
  852. if(helpon)
  853.  {
  854.  x=topwin;
  855.  do
  856.   {
  857.   if(x->hheight) x->height=x->hheight;
  858.   else x->height*=height, x->height/=height-wind;
  859.   x=x->next;
  860.   }
  861.   while(x!=topwin);
  862.  wind=0, hupd=0;
  863.  }
  864. else
  865.  {
  866.  hupd=1, wind=helplines;
  867.  x=topwin;
  868.  do
  869.   {
  870.   x->hheight=x->height;
  871.   x->height*=height-wind;
  872.   x->height/=height;
  873.   x=x->next;
  874.   }
  875.   while(x!=topwin);
  876.  }
  877. helpon= !helpon;
  878. wfit();
  879. }
  880.  
  881. /* Move cursor to beginning of file */
  882.  
  883. bof()
  884. {
  885. extend=0;
  886. fmpoint(0);
  887. newy=1;
  888. }
  889.  
  890. /* Move cursor to beginning of line */
  891.  
  892. bol()
  893. {
  894. if(fmnrnl()) fmgetc();
  895. extend=0;
  896. }
  897.  
  898. /* Move cursor to end of line */
  899.  
  900. eol()
  901. {
  902. extend=0;
  903. fmfnl();
  904. }
  905.  
  906. /* Move cursor to end of file */
  907.  
  908. eof()
  909. {
  910. extend=0;
  911. fmpoint(fmsize());
  912. newy=1;
  913. }
  914.  
  915. /* Move cursor right */
  916.  
  917. urtarw()
  918. {
  919. fillup();
  920. extend=0;
  921. if(fmeof())
  922.  {
  923.  if(pic)
  924.   {
  925.   into:
  926.   fminsc(' ');
  927.   fmgetc();
  928.   }
  929.  return;
  930.  }
  931. else if(fmrc()==NL)
  932.  {
  933.  if(pic) goto into;
  934.  bol();
  935.  udnarw();
  936.  return;
  937.  }
  938. fmgetc();
  939. }
  940.  
  941. rtarw()
  942. {
  943. fillup();
  944. extend=0;
  945. if(fmeof())
  946.  {
  947.  if(pic)
  948.   {
  949.   into:
  950.   fminsc(' ');
  951.   fmgetc();
  952.   }
  953.  return;
  954.  }
  955. else if(fmrc()==NL)
  956.  {
  957.  if(pic) goto into;
  958.  newy=1;
  959.  }
  960. fmgetc();
  961. }
  962.  
  963. ultarw()
  964. {
  965. fillup();
  966. if(extend) extend=0;
  967. else if(fmnote())
  968.  {
  969.  fmpoint(fmnote()-1);
  970.  if(fmrc()==NL)
  971.   {
  972.   fmgetc();
  973.   uuparw();
  974.   eol();
  975.   }
  976.  }
  977. }
  978.  
  979. ltarw()
  980. {
  981. fillup();
  982. if(extend) extend=0;
  983. else
  984.  {
  985.  if(fmnote())
  986.   fmpoint(fmnote()-1);
  987.  if(fmrc()==NL) newy=1;
  988.  }
  989. }
  990.  
  991. /* Move cursor up */
  992.  
  993. uparw()
  994. {
  995. TXTSIZ x;
  996. x=getcol();
  997. bol();
  998. if(fmnote())
  999.  {
  1000.  fmpoint(fmnote()-1);
  1001.  if(fmnrnl())
  1002.   fmgetc();
  1003.  }
  1004. gocol(x);
  1005. newy=1;
  1006. }
  1007.  
  1008. /* user's cursor up routine (uses scrolling regions) */
  1009.  
  1010. uuparw()
  1011. {
  1012. TXTSIZ sve=fmnote();
  1013. int y=(curwin->wind+1)*width;
  1014. int x;
  1015. if(scroll)
  1016.  {
  1017.  if(fmnrnl())
  1018.   {
  1019.   if(fmnote()+1==saddr)
  1020.    {
  1021.    if(fmnrnl()) fmgetc();
  1022.    saddr=fmnote();
  1023.    setregn(curwin->wind+1,curwin->wind+(curwin->height-1));
  1024.    cpos(curwin->wind+1,oxpos);
  1025.    tattrib(' ');
  1026.    eputs("\033M");
  1027.    for(x=(curwin->wind+curwin->height)*width-1;x>=y+width;x--)
  1028.     scrn[x]=scrn[x-width];
  1029.    for(x=y;x<y+width;x++) scrn[x]= ' ';
  1030.    }
  1031.   fmpoint(sve);
  1032.   }
  1033.  else
  1034.   fmpoint(sve);
  1035.  }
  1036. uparw();
  1037. }
  1038.  
  1039. /* Move cursor down */
  1040.  
  1041. dnarw()
  1042. {
  1043. TXTSIZ x;
  1044. newy=1;
  1045. x=getcol();
  1046. if(!fmfnl())
  1047.  bol();
  1048. else
  1049.  fmgetc();
  1050. gocol(x);
  1051. }
  1052.  
  1053. /* user's down arrow function */
  1054.  
  1055. udnarw()
  1056. {
  1057. TXTSIZ sve=fmnote();
  1058. int x;
  1059. if(!fmfnl())
  1060.  {
  1061.  if(pic)
  1062.   {
  1063.   fminsc(NL);
  1064.   fmpoint(sve);
  1065.   udnarw();
  1066.   return;
  1067.   }
  1068.  else
  1069.   {
  1070.   goto cant;
  1071.   }
  1072.  }
  1073. if(scroll)
  1074.  {
  1075.  if(ypos!=curwin->height+curwin->wind-1) goto cant;
  1076.  for(x=0;x!=curwin->height-2;x++) fmnrnl();
  1077.  fmfnl();
  1078.  fmgetc();
  1079.  saddr=fmnote();
  1080.  setregn(curwin->wind+1,curwin->wind+curwin->height-1);
  1081.  cpos((curwin->wind+curwin->height-1),oxpos);
  1082.  tattrib(' ');
  1083.  eputc(10);
  1084.  for(x=(curwin->wind+1)*width;x!=(curwin->wind+curwin->height-1)*width;x++)
  1085.   scrn[x]=scrn[x+width];
  1086.  for(x=(curwin->wind+curwin->height-1)*width;
  1087.      x!=(curwin->wind+curwin->height)*width;x++)
  1088.   scrn[x]= ' ';
  1089.  }
  1090. cant:
  1091. fmpoint(sve);
  1092. dnarw();
  1093. }
  1094.  
  1095. /* Magic Tabs (tm) */
  1096.  
  1097. TXTSIZ tabcol;    /* Original column of text preceeded by tab stops */
  1098.  
  1099. tabmark()
  1100. {
  1101. TXTSIZ cur=fmnote();
  1102. unsigned char c;
  1103. tabcol=0;
  1104. if(!tabmagic) return;
  1105. while(!fmeof())
  1106.  {
  1107.  c=fmgetc();
  1108.  if(c=='\t')
  1109.   {
  1110.   while(!fmeof())
  1111.    {
  1112.    c=fmgetc();
  1113.    if(c=='\n') break;
  1114.    if(c!='\t')
  1115.     {
  1116.     fmrgetc();
  1117.     tabcol=getrcol();
  1118.     break;
  1119.     }
  1120.    }
  1121.   fmpoint(cur); return;
  1122.   }
  1123.  if(c=='\n') break;
  1124.  }
  1125. fmpoint(cur); return;
  1126. }
  1127.  
  1128. tabfix()
  1129. {
  1130. TXTSIZ cur=fmnote(),newcol;
  1131. unsigned char c;
  1132. if(!tabcol) return;
  1133. while(!fmeof())
  1134.  {
  1135.  c=fmgetc();
  1136.  if(c=='\t')
  1137.   {
  1138.   while(!fmeof())
  1139.    {
  1140.    c=fmgetc();
  1141.    if(c=='\n') break;
  1142.    if(c!='\t')
  1143.     {
  1144.     fmrgetc();
  1145.     newcol=getrcol();
  1146.     while(newcol<tabcol)
  1147.      {
  1148.      fminsc('\t');
  1149.      newcol+=8;
  1150.      }
  1151.     fmrgetc();
  1152.     while(newcol>tabcol)
  1153.      {
  1154.      if(fmrgetc()=='\t')
  1155.       {
  1156.       fmdel(1);
  1157.       newcol-=8;
  1158.       }
  1159.      else break;
  1160.      }
  1161.     break;
  1162.     }
  1163.    }
  1164.   fmpoint(cur); return;
  1165.   }
  1166.  if(c=='\n') break;
  1167.  }
  1168. fmpoint(cur); return;
  1169. }
  1170.  
  1171. /* Delete character under cursor */
  1172.  
  1173. delch()
  1174. {
  1175. unsigned char c;
  1176. int x;
  1177. if(extend && pic) return;
  1178. if(extend)
  1179.  {
  1180.  extend=0;
  1181.  return;
  1182.  }
  1183. if(!fmeof())
  1184.  {
  1185.  if((c=fmrc())==NL && scroll)
  1186.   {
  1187.   if(ypos<curwin->wind+curwin->height-2)
  1188.    {
  1189.    for(x=(ypos+1)*width;x<width*(curwin->wind+curwin->height-1);x++)
  1190.     scrn[x]=scrn[x+width];
  1191.    for(x=(curwin->wind+curwin->height-1)*width;
  1192.    x<(curwin->wind+curwin->height)*width;x++) scrn[x]= ' ';
  1193.    setregn(ypos+1,(curwin->wind+curwin->height-1));
  1194.    cpos((curwin->wind+curwin->height-1),oxpos);
  1195.    tattrib(' ');
  1196.    eputc(10);
  1197.    }
  1198.   fmdel(1);
  1199.   }
  1200.  else if(c==TAB) fmdel(1);
  1201.  else
  1202.   {
  1203.   tabmark();
  1204.   fmdel(1);
  1205.   tabfix();
  1206.   }
  1207.  }
  1208. }
  1209.  
  1210. type(ch)
  1211. unsigned char ch;
  1212. {
  1213. int ox=oxpos;
  1214. int x,y;
  1215. TXTSIZ temp, temp1;
  1216. int eflag=0;
  1217. if(quote8th)
  1218.  {
  1219.  quote8th=0;
  1220.  ch|=128;
  1221.  }
  1222. ypos=oypos;
  1223. if(extend)
  1224.  {
  1225.  if(ch!=NL) fillup();
  1226.  else extend=0;
  1227.  eflag=1;
  1228.  }
  1229. if(ch==NL)
  1230.  {
  1231.  if(overwrite && !tabmagic && !fmeof()) fmdel(1);
  1232.  fminsc(ch);
  1233.  fmgetc();
  1234.  newy=1;
  1235.  if(ypos!=(curwin->wind+curwin->height-1))
  1236.   {
  1237.   if(!fmeof())
  1238.    {
  1239.    if(ypos<curwin->wind+curwin->height-2 && scroll)
  1240.     {
  1241.     setregn(ypos+1,(curwin->wind+curwin->height-1));
  1242.     cpos(ypos+1,oxpos);
  1243.     tattrib(' ');
  1244.     eputs("\033M");
  1245.     cpos(ypos+1,0);
  1246.     for(x=(curwin->wind+curwin->height)*width-1;x>=(ypos+2)*width;x--)
  1247.      scrn[x]=scrn[x-width];
  1248.     for(x=(ypos+1)*width;x<(ypos+2)*width;x++) scrn[x]=' ';
  1249.     }
  1250.    else cpos(ypos+1,0);
  1251.    }
  1252.   else
  1253.    cpos(ypos+1,0);
  1254.   }
  1255.  else if(scroll)
  1256.    {
  1257.    setregn(curwin->wind+1,(curwin->wind+curwin->height-1));
  1258.    cpos((curwin->height+curwin->wind-1),0);
  1259.    tattrib(' ');
  1260.    eputc(10);
  1261.    for(x=curwin->wind*width;x<(curwin->wind+curwin->height-1)*width;x++)
  1262.     scrn[x]=scrn[x+width];
  1263.    for(x=(curwin->wind+curwin->height-1)*width;
  1264.        x<(curwin->wind+curwin->height)*width;x++) scrn[x]= ' ';
  1265.    temp=fmnote();
  1266.    fmpoint(saddr);
  1267.    fmfnl();
  1268.    fmgetc();
  1269.    saddr=fmnote();
  1270.    fmpoint(temp);
  1271.    }
  1272.  if(ox<(width-2) && (fmeof()) && scroll) uuu=1;
  1273.  if(autoind)
  1274.   {
  1275.   temp=fmnote();
  1276.   uparw();
  1277.   for(x=0;1;x++)
  1278.    {
  1279.    ch=fmgetc();
  1280.    if(!(ch==' ' || ch==TAB)) break;
  1281.    temp1=fmnote();
  1282.    fmpoint(temp);
  1283.    fminsc(ch);
  1284.    uuu=0;
  1285.    added++;
  1286.    fmpoint(temp1);
  1287.    temp++;
  1288.    }
  1289.   fmpoint(fmnote()-(x+1));
  1290.   dnarw();
  1291.   y=overwrite, overwrite=0;
  1292.   for(;x;x--) rtarw();
  1293.   overwrite=y;
  1294.   }
  1295.  }
  1296. else
  1297.  {
  1298.  if(overwrite)
  1299.   {
  1300.   if(!tabmagic)
  1301.    {
  1302.    if(!fmeof())
  1303.     {
  1304.     unsigned char c=fmrc();
  1305.     fmdel(1);
  1306.     if(ch!=TAB && c!=TAB && c!=NL && ox<(width-2)) uuu=1;
  1307.     }
  1308.    else if(ch!=TAB && ox<(width-2)) uuu=1;
  1309.    }
  1310.   else
  1311.    if(fmrc()!=NL && !fmeof())
  1312.     if(ch==TAB && fmrc()!=TAB)
  1313.      {
  1314.      TXTSIZ foo=getrcol();
  1315.      do
  1316.       {
  1317.       if(fmeof()) break;
  1318.       if(fmrc()==NL) break;
  1319.       if(fmrc()==TAB)
  1320.        {
  1321.        fmdel(1);
  1322.        break;
  1323.        }
  1324.       else fmdel(1);
  1325.       ++foo;
  1326.       }
  1327.       while(foo&7);
  1328.      }
  1329.     else if(ch!=TAB && fmrc()==TAB)
  1330.      {
  1331.      TXTSIZ tt;
  1332.      tabmark();
  1333.      if(tt=tabcol)
  1334.       {
  1335.       fminsc(ch);
  1336.       tabmark();
  1337.       fmdel(1);
  1338.       if(tabcol!=tt) fmdel(1);
  1339.       }
  1340.      }
  1341.     else
  1342.      {
  1343.      fmdel(1);
  1344.      if(ch!=TAB && ox<(width-2)) uuu=1;
  1345.      }
  1346.    else if(ox<(width-2) && ch!=TAB) uuu=1;
  1347.   }
  1348.  if(wrap)
  1349.   {
  1350.   unsigned char xx;
  1351.   if(getrcol()<rmargin) goto skip;
  1352.   if(ch==' ')
  1353.    type(NL);
  1354.   else
  1355.    {
  1356.    temp=fmnote();
  1357.    while(1)
  1358.     {
  1359.     if(fmnote())
  1360.      {
  1361.      fmpoint(fmnote()-1);
  1362.      xx=fmrc();
  1363.      if(xx==NL) break;
  1364.      if(xx==' ' || x==TAB)
  1365.       {
  1366.       fmdel(1);
  1367.       added=0;
  1368.       type(NL);
  1369.       temp+=added;
  1370.       break;
  1371.       }
  1372.      }
  1373.     else break;
  1374.     }
  1375.    fmpoint(temp);
  1376.    fminsc(ch);
  1377.    rtarw();
  1378.    uuu=0;
  1379.    }
  1380.   }
  1381.  else
  1382.   {
  1383. skip:
  1384.   if(overwrite || ch==TAB) fminsc(ch);
  1385.   else
  1386.    {
  1387.    tabmark();
  1388.    fminsc(ch);
  1389.    tabfix();
  1390.    }
  1391.   if(ch!=TAB && ch!=NL)
  1392.    {
  1393.    if(fmnote()>=markb && fmnote()<marke) ch^=128;
  1394.    fmgetc();
  1395.    tputcc(ch);
  1396.    scrn[ypos*width+oxpos]=ch;
  1397.    oxpos++;
  1398.    if(fmeof()) { if(!eflag && ox<width-2) uuu=1; }
  1399.    else if(fmrc()==NL && !eflag && ox<width-2) uuu=1;
  1400.    }
  1401.   else fmgetc();
  1402.   }
  1403.  }
  1404. }
  1405.  
  1406. itype(ch)
  1407. unsigned char ch;
  1408. {
  1409. int x,y;
  1410. TXTSIZ temp,temp1;
  1411. if(extend)
  1412.  {
  1413.  if(ch!= NL) fillup();
  1414.  else extend=0;
  1415.  }
  1416. if(ch==NL)
  1417.  {
  1418.  fminsc(ch);
  1419.  fmgetc();
  1420.  newy=1;
  1421.  if(autoind)
  1422.   {
  1423.   temp=fmnote();
  1424.   uparw();
  1425.   for(x=0;1;x++)
  1426.    {
  1427.    ch=fmgetc();
  1428.    if(!(ch==' ' || ch==TAB)) break;
  1429.    temp1=fmnote();
  1430.    fmpoint(temp);
  1431.    fminsc(ch);
  1432.    added++;
  1433.    fmpoint(temp1);
  1434.    temp++;
  1435.    }
  1436.   fmpoint(fmnote()-(x+1));
  1437.   dnarw();
  1438.   y=overwrite, overwrite=0;
  1439.   for(;x;x--) rtarw();
  1440.   overwrite=y;
  1441.   }
  1442.  }
  1443. else
  1444.  {
  1445.  if(overwrite)
  1446.   if(!fmeof()) fmdel(1);
  1447.  if(wrap)
  1448.   {
  1449.   if(getrcol()<rmargin) goto skip;
  1450.   if(ch==' ')
  1451.    itype(NL);
  1452.   else
  1453.    {
  1454.    temp=fmnote();
  1455.    while(1)
  1456.     {
  1457.     if(fmnote())
  1458.      {
  1459.      fmpoint(fmnote()-1);
  1460.      x=fmrc();
  1461.      if(x==NL) break;
  1462.      if(x==' ' || x==TAB)
  1463.       {
  1464.       fmdel(1);
  1465.       added=0;
  1466.       itype(NL);
  1467.       temp+=added;
  1468.       break;
  1469.       }
  1470.      }
  1471.     else break;
  1472.     }
  1473.    fmpoint(temp);
  1474.    fminsc(ch);
  1475.    rtarw();
  1476.    }
  1477.   }
  1478.  else
  1479.   {
  1480. skip:
  1481.   fminsc(ch);
  1482.   rtarw();
  1483.   }
  1484.  }
  1485. }
  1486.  
  1487. /* Insert space */
  1488.  
  1489. inss()
  1490. {
  1491. int t=overwrite;
  1492. if(extend)
  1493.  {
  1494.  extend=0;
  1495.  return;
  1496.  }
  1497. overwrite=0;
  1498. type(' ');
  1499. ltarw();
  1500. overwrite=t;
  1501. }
  1502.  
  1503. /* Deleting backspace */
  1504.  
  1505. backs()
  1506. {
  1507. int flag=0,c;
  1508. if(extend)
  1509.  {
  1510.  extend=0;
  1511.  return;
  1512.  }
  1513. if(fmeof()) c=1;
  1514. else if(fmrc()==NL) c=1;
  1515. if(fmnote())
  1516.  {
  1517.  ultarw();
  1518.  if(fmrc()==TAB) flag=1;
  1519.  if(overwrite && !tabmagic)
  1520.   {
  1521.   itype(' ');
  1522.   ultarw();
  1523.   }
  1524.  else if(overwrite && tabmagic)
  1525.   {
  1526.   if(c) delch();
  1527.   else if(!flag)
  1528.    {
  1529.    itype(' ');
  1530.    ltarw();
  1531.    }
  1532.   }
  1533.  else delch();
  1534.  if(oxpos && !flag)
  1535.   {
  1536.   eputc(8), tputcc(32), eputc(8), oxpos--,scrn[oypos*width+oxpos]=32;
  1537.   if(fmeof()) uuu=1;
  1538.   else if(fmrc()==NL || overwrite) uuu=1;
  1539.   }
  1540.  }
  1541. }
  1542.  
  1543. /* quit: exit without saving */
  1544.  
  1545. eexit()
  1546. {
  1547. int c;
  1548. if(curwin->next==curwin)
  1549.  {
  1550.  if(changed)
  1551.   {
  1552.   c=askyn("Do you really want to throw away this file?"); 
  1553.   if(c=='N') return;
  1554.   if(c== -1) return;
  1555.   dclose("File not saved.");
  1556.   }
  1557.  else
  1558.   {
  1559.   dclose("File not changed so no update needed");
  1560.   }
  1561.  leave=1;
  1562.  }
  1563. else
  1564.  {
  1565.  struct window *t=curwin;
  1566.  if(changed && curbuf->count==1)
  1567.   {
  1568.   c=askyn("Do you really want to throw away this file?");
  1569.   if(c=='N') return;
  1570.   if(c== -1) return;
  1571.   }
  1572.  if(curbuf->count==1)
  1573.   {
  1574.   struct undorec *u;
  1575.   for(u=undorecs;u;u=u->next) if(u->buf==curbuf) u->buf=0;
  1576.   free(curbuf->buf), free(curbuf);
  1577.   if(curbuf==markbuf) markbuf=0;
  1578.   }                           
  1579.  else curbuf->count--;
  1580.  curwin->next->prev=curwin->prev;
  1581.  curwin->prev->next=curwin->next;
  1582.  curwin=curwin->prev;
  1583.  free(t);
  1584.  ldwin(curwin);
  1585.  if(topwin==t) topwin=curwin;
  1586.  wfit();
  1587.  }
  1588. }
  1589.  
  1590. pgup()
  1591. {
  1592. int nlins=curwin->height-1;
  1593. int hlins=nlins/2;
  1594. int x,y;
  1595. TXTSIZ curpos,z;
  1596. if(!hlins) hlins=1;
  1597. z=getcol();
  1598. curpos=fmnote();
  1599. fmpoint(saddr);
  1600. for(x=0;x<hlins;x++)
  1601.  {
  1602.  if(!fmnrnl())
  1603.   {
  1604.   if(!x)
  1605.    {
  1606.    gocol(z);
  1607.    newy=1;
  1608.    return;
  1609.    }
  1610.   else
  1611.    break;
  1612.   }
  1613.  }
  1614. if(fmnrnl()) fmgetc();
  1615. saddr=fmnote();
  1616. fmpoint(curpos);
  1617. setregn(curwin->wind+1,(curwin->wind+curwin->height-1));
  1618. cpos(curwin->wind+1,oxpos);
  1619. tattrib(' ');
  1620. for(y=0;y<x;y++)
  1621.  {
  1622.  if(scroll) eputs("\033M");
  1623.  fmnrnl();
  1624.  }
  1625. if(fmnrnl()) fmgetc();
  1626. cpos(oypos,oxpos);
  1627. gocol(z);
  1628. x*=width;
  1629. if(scroll) for(y=(curwin->wind+1)*width;y<x+(curwin->wind+1)*width;y++)
  1630.  {
  1631.  scrn[y+x]=scrn[y];
  1632.  scrn[y]= ' ';
  1633.  }
  1634. }
  1635.  
  1636. pgdn()
  1637. {
  1638. int nlins=curwin->height-1;
  1639. int hlins=nlins/2;
  1640. TXTSIZ curpos,z;
  1641. int x,y;
  1642. z=getcol();
  1643. curpos=fmnote();
  1644. x=nlins;
  1645. fmpoint(saddr);
  1646. do
  1647.  {
  1648.  if(fmfnl()) fmgetc();
  1649.  else
  1650.   {
  1651.   newy=1;
  1652.   gocol(z);
  1653.   return;
  1654.   }
  1655.  }
  1656.  while(--x);
  1657. for(x=1;x<hlins;x++)
  1658.  {
  1659.  if(fmfnl()) fmgetc();
  1660.  else break;
  1661.  }
  1662.  
  1663. fmpoint(saddr);
  1664. for(y=0;y<x;y++)
  1665.  {
  1666.  fmfnl();
  1667.  fmgetc();
  1668.  }
  1669. saddr=fmnote();
  1670.  
  1671. setregn(curwin->wind+1,(curwin->wind+curwin->height-1));
  1672. cpos((curwin->wind+curwin->height-1),oxpos);
  1673. fmpoint(curpos);
  1674. tattrib(' ');
  1675. for(y=0;y<x;y++)
  1676.  {
  1677.  fmfnl();
  1678.  fmgetc();
  1679.  if(scroll) eputc(10);
  1680.  }
  1681.  
  1682. gocol(z);
  1683. cpos(ypos,xpos);
  1684. if(scroll)
  1685.  {
  1686.  y=width*x;
  1687.  for(curpos=(curwin->wind+1)*width+y;curpos<(curwin->wind+curwin->height)*
  1688.      width;curpos++)
  1689.   scrn[curpos-y]=scrn[curpos];
  1690.  for(curpos=(curwin->wind+curwin->height)*width-width*x;
  1691.      curpos<(curwin->wind+curwin->height)*width;curpos++)
  1692.   scrn[curpos]= ' ';
  1693.  }
  1694. }
  1695.  
  1696. deleol()
  1697. {
  1698. TXTSIZ temp=fmnote();
  1699. TXTSIZ temp1;
  1700. if(extend && pic) return;
  1701. extend=0;
  1702. fmfnl();
  1703. temp1=fmnote()-temp;
  1704. fmpoint(temp);
  1705. if(temp1) fmdel(temp1);
  1706. }
  1707.  
  1708. dellin()
  1709. {
  1710. bol();
  1711. deleol();
  1712. delch();
  1713. }
  1714.  
  1715. fixpath(s)
  1716. unsigned char *s;
  1717. {
  1718. unsigned char tmp[PATHSIZE], *p, c;
  1719. struct passwd *passwd;
  1720. if(*s=='~')
  1721.  {
  1722.  p=s+1;
  1723.  while(*p!='/' && *p) ++p;
  1724.  if(c= *p)
  1725.   {
  1726.   *p=0;
  1727.   if(passwd=getpwnam(s+1))
  1728.    {
  1729.    *p=c;
  1730.    strcpy(tmp,passwd->pw_dir);
  1731.    strcat(tmp,p);
  1732.    strcpy(s,tmp);
  1733.    }
  1734.   }
  1735.  }
  1736. }
  1737.  
  1738. exsave()
  1739. {
  1740. unsigned char sting[PATHSIZE];
  1741. if(!changed)
  1742.  {
  1743.  eexit();
  1744.  return;
  1745.  }
  1746. if(gfnam[0]==0)
  1747.  {
  1748.  if(!getl("Save file",gfnam))
  1749.   return;
  1750.  fixpath(gfnam);
  1751.  }
  1752. else if(!backup)
  1753.  {
  1754.  sprintf(sting,"/bin/cp %s %s~",gfnam,gfnam);
  1755.  cpos(height-2,0);
  1756.  system(sting);
  1757.  cpos(ypos,xpos);
  1758.  }
  1759. if(saveit1(gfnam))
  1760.  {
  1761.  sprintf(sting,"File %s saved.",gfnam);
  1762.  if(curwin->next==curwin)
  1763.   {
  1764.   dclose(sting);
  1765.   leave=1;
  1766.   }
  1767.  else
  1768.   eexit();
  1769.  }
  1770. }
  1771.  
  1772. saveit()
  1773. {
  1774. unsigned char gfnam1[PATHSIZE];
  1775. unsigned char sting[PATHSIZE];
  1776. strcpy(gfnam1,gfnam);
  1777. if(!getl("Save file",gfnam1))
  1778.  return;
  1779. fixpath(gfnam1);
  1780. if(!backup && !strcmp(gfnam1,gfnam))
  1781.  {
  1782.  sprintf(sting,"/bin/cp %s %s~",gfnam,gfnam);
  1783.  cpos(height-2,0);
  1784.  system(sting);
  1785.  cpos(ypos,xpos);
  1786.  }
  1787. saveit1(gfnam1);
  1788. }
  1789.  
  1790. findline()
  1791. {
  1792. unsigned char sting[PATHSIZE];
  1793. TXTSIZ x;
  1794. sting[0]=0;
  1795. if(!getl("Goto line",sting))
  1796.  return;
  1797. x=atol(sting);
  1798. if(!x)
  1799.  {
  1800.  msg("\033[7mBad line number\033[m");
  1801.  return;
  1802.  }
  1803. x--;
  1804. bof();
  1805. for(;x;x--)
  1806.  {
  1807.  if(!fmfnl()) break;
  1808.  fmgetc();
  1809.  }
  1810. newy=1;
  1811. cntr=1;
  1812. return;
  1813. }
  1814.  
  1815. int search()
  1816. {
  1817. if(options&s_backwards)
  1818.  {
  1819.  while(fmnote())
  1820.   {
  1821.   fmrgetc();
  1822.   if(options&s_ignore) { if(!fmicmp(sstring,len)) return 1; }
  1823.   else if(!fmcmp(sstring,len)) return 1;
  1824.   }
  1825.  return 0;
  1826.  }
  1827. else
  1828.  {
  1829.  while(fmnote()+len<=fmsize())
  1830.   {
  1831.   if(!(options&s_ignore)) { if(!fmcmp(sstring,len)) return 1; }
  1832.   else if(!fmicmp(sstring,len)) return 1;
  1833.   fmgetc();
  1834.   }
  1835.  return 0;
  1836.  }
  1837. }
  1838.  
  1839. find(c)
  1840. {
  1841. int x;
  1842. int opts=0;
  1843. int n=0;
  1844. int rest=0;
  1845. int rlen;
  1846. TXTSIZ p;
  1847. unsigned char ss[80];
  1848. extend=0;
  1849. if(c=='L'-'@' && sstring[0]) goto srch;
  1850. ss[0]=0;
  1851. if(!(x=getl("Search string",ss))) return;
  1852. if(x== -1)
  1853.  {
  1854.  if(ss[0])
  1855.   strcpy(sstring,ss);
  1856.  goto srch;
  1857.  }
  1858. if(!ss[0]) return;
  1859. strcpy(sstring,ss);
  1860. ss[0]=0;
  1861. if(!getl("(I)gnore case (B)ackwards (R)eplace n",ss)) return;
  1862. for(x=0;ss[x];x++)
  1863.  {
  1864.  if(ss[x]=='i' || ss[x]=='I') opts|=s_ignore;
  1865.  if(ss[x]=='b' || ss[x]=='B') opts|=s_backwards;
  1866.  if(ss[x]=='r' || ss[x]=='R') opts|=s_replace;
  1867.  if(ss[x]=='x' || ss[x]=='X') opts|=s_regex;
  1868.  if(ss[x]>='0' && ss[x]<='9') n*=10, n+=ss[x]-'0';
  1869.  }
  1870. options=opts;
  1871. if(options&s_replace)
  1872.  {
  1873.  ss[0]=0;
  1874.  if(!(x=getl("Replace with",ss))) return;
  1875.  if(x!= -1)
  1876.   strcpy(rstring,ss);
  1877.  }
  1878. srch:
  1879. if(!sstring[0]) return;
  1880. len=strlen(sstring);
  1881. rlen=strlen(rstring);
  1882. rpt:
  1883. p=fmnote();
  1884. if(search())
  1885.  {
  1886.  if(!(options&s_backwards)) fmpoint(fmnote()+len);
  1887.  if(options&s_replace)
  1888.   {
  1889.   if(rest) goto dn;
  1890.   newy=1;
  1891.   upd=1;
  1892.   cntr=1;
  1893.   extend=0;
  1894.   dupdate();
  1895. again:
  1896.   x=nquery(
  1897.   "Replace? (Yes, No, ^C to abort or R to replace rest without asking)");
  1898.   if(x=='n' || x=='N') goto rpt;
  1899.   if(x== 3) return;
  1900.   if(x=='y' || x=='Y') goto dn;
  1901.   if(x=='r' || x=='R')
  1902.    {
  1903.    rest=1;
  1904.    goto dn;
  1905.    }
  1906.   goto again;
  1907. dn:
  1908.   if(options&s_backwards)
  1909.    {
  1910.    fmdel(len);
  1911.    fminss(rstring,rlen);
  1912.    }
  1913.   else
  1914.    {
  1915.    fmpoint(fmnote()-len);
  1916.    fmdel(len);
  1917.    fminss(rstring,rlen);
  1918.    fmpoint(fmnote()+rlen);
  1919.    }
  1920.   if(n)
  1921.    if(n==1) goto exi;
  1922.    else n--;
  1923.   goto rpt;
  1924.   }
  1925.  else if(n)
  1926.   {
  1927.   if(n==1) goto exi;
  1928.   n--;
  1929.   goto rpt;
  1930.   }
  1931.  }
  1932. else
  1933.  {
  1934.  if(!(options&s_replace) || n>1)
  1935.   msg("Not found");
  1936.  fmpoint(p);
  1937.  return;
  1938.  }
  1939. exi:
  1940. cntr=1;
  1941. newy=1;
  1942. }
  1943.  
  1944. findnext()
  1945. {
  1946. find('L'-'@');
  1947. }
  1948.  
  1949. findfirst()
  1950. {
  1951. find(0);
  1952. }
  1953.  
  1954. struct buffer *markbuf;
  1955.  
  1956. setbeg()
  1957. {
  1958. markb=fmnote();
  1959. if(markbuf!=curbuf)
  1960.  {
  1961.  markbuf=curbuf;
  1962.  marke=0;
  1963.  }
  1964. }
  1965.  
  1966. setend()
  1967. {
  1968. marke=fmnote();
  1969. if(markbuf!=curbuf)
  1970.  {
  1971.  markbuf=curbuf;
  1972.  markb=0;
  1973.  }
  1974. }
  1975.  
  1976. writeblk()
  1977. {
  1978. unsigned char gfnam1[PATHSIZE];
  1979. unsigned char sting[PATHSIZE];
  1980. TXTSIZ sv=fmnote();
  1981. struct buffer *bt=curbuf;
  1982. if(markbuf)
  1983.  {
  1984.  stbuf(curbuf);
  1985.  ldbuf(markbuf);
  1986.  }
  1987. if(markb>=marke || marke>fmsize() || !markbuf)
  1988.  {
  1989.  msg("\033[7mThe block is not marked properly\033[m  Mark it with ^KB & ^KK");
  1990.  if(markbuf)
  1991.   ldbuf(bt);
  1992.  return;
  1993.  }
  1994. gfnam1[0]=0;
  1995. if(!getl("File to write block to",gfnam1))
  1996.  {
  1997.  ldbuf(bt);
  1998.  return;
  1999.  }
  2000. fixpath(gfnam1);
  2001. handle=fopen(gfnam1,"w+");
  2002. if(handle)
  2003.  {
  2004.  fmpoint(markb);
  2005.  if(!fmsave(handle,marke-markb))
  2006.   {
  2007.   sprintf(sting,"\033[7mError writting to file %s\033[m",gfnam1);
  2008.   msg(sting);
  2009.   }
  2010.  stbuf(markbuf);
  2011.  ldbuf(bt);
  2012.  fmpoint(sv);
  2013. -- Cut here
  2014. -- 
  2015. /*  rcarter@wpi.wpi.edu */      /* Amazing */             /* Joseph H. Allen */
  2016. int a[1817];main(z,p,q,r){for(p=80;q+p-80;p-=2*a[p])for(z=9;z--;)q=3&(r=time(0)
  2017. +r*57)/7,q=q?q-1?q-2?1-p%79?-1:0:p%79-77?1:0:p<1659?79:0:p>158?-79:0,q?!a[p+q*2
  2018. ]?a[p+=a[p+=q]=q]=q:0:0;for(;q++-1817;)printf(q%79?"%c":"%c\n"," #"[!a[q-1]]);}
  2019.