home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / EDITC80 / ED4.C < prev    next >
C/C++ Source or Header  |  2000-06-30  |  12KB  |  705 lines

  1. /*
  2.  * Screen editor:  window module
  3.  *
  4.  * Source:  ed4.c
  5.  * Version: August 21, 1981.
  6.  */
  7.  
  8. /* define global constants, variables */
  9.  
  10. #include ed1.h
  11.  
  12. /* data global to this module -----
  13.  
  14. char    editbuf[MAXLEN];    the edit buffer
  15. int    editp;            cursor: buffer index
  16. int    editpmax;        length of buffer
  17. int    edcflag;        buffer change flag
  18.  
  19. ----- */
  20.  
  21. /* abort any changes made to current line */
  22.  
  23. edabt()
  24. {
  25.     /* get unchanged line and reset cursor */
  26.     edgetln();
  27.     edredraw();
  28.     edbegin();
  29.     edcflag = NO;
  30. }
  31.  
  32. /* put cursor at beginning of current line */
  33.  
  34. edbegin()
  35. {
  36.     editp = 0;
  37.     outxy(0,outgety());
  38. }
  39.  
  40. /* change editbuf[editp] to c
  41.  * don't make change if line would become to long
  42.  */
  43.  
  44. edchng(c) char c;
  45. {
  46. char oldc;
  47. int k;
  48.     /* if at right margin then insert char */
  49.     if (editp >= editpmax) {
  50.         edins(c);
  51.         return;
  52.     }
  53.     /* change char and print length of line */
  54.     oldc = editbuf[editp];
  55.     editbuf[editp] = c;
  56.     fmtadj(editbuf,editp,editpmax);
  57.     k = fmtlen(editbuf,editpmax);
  58.     if (k > SCRNW1) {
  59.         /* line would become too long */
  60.         /* undo the change */
  61.         editbuf[editp] = oldc;
  62.         fmtadj(editbuf,editp,editpmax);
  63.     }
  64.     else {
  65.         /* set change flag, redraw line */
  66.         edcflag = YES;
  67.         editp++;
  68.         edredraw();
  69.     }
  70. }
  71.  
  72. /* delete the char to left of cursor if it exists */
  73.  
  74. eddel()
  75. {
  76. int k;
  77.     /* just move left one column if past end of line */
  78.     if (edxpos() < outgetx()) {
  79.         outxy(outgetx()-1, outgety());
  80.         return;
  81.     }
  82.     /* do nothing if cursor is at left margin */
  83.     if (editp == 0) {
  84.         return;
  85.     }
  86.     edcflag = YES;
  87.     /* compress buffer (delete char) */
  88.     k = editp;
  89.     while (k < editpmax) {
  90.         editbuf[k-1] = editbuf[k];
  91.         k++;
  92.     }
  93.     /* update pointers, redraw line */
  94.     editp--;
  95.     editpmax--;
  96.     edredraw();
  97. }
  98.  
  99. /* edit the next line.  do not go to end of buffer */
  100.  
  101. eddn()
  102. {
  103. int oldx;
  104.     /* save visual position of cursor */
  105.     oldx = outgetx();
  106.     /* replace current edit line */
  107.     if (edrepl() != OK) {
  108.         return(ERR);
  109.     }
  110.     /* do not go past last non-null line */
  111.     if (bufnrbot()) {
  112.         return(OK);
  113.     }
  114.     /* move down one line in buffer */
  115.     if (bufdn() != OK) {
  116.         return(ERR);
  117.     }
  118.     edgetln();
  119.     /* put cursor as close as possible on this
  120.      * new line to where it was on the old line.
  121.      */
  122.     editp = edscan(oldx);
  123.     /* update screen */
  124.     if (edatbot()) {
  125.         edsup(bufln()-SCRNL2);
  126.         outxy(oldx, SCRNL1);
  127.     }
  128.     else {
  129.         outxy(oldx, outgety()+1);
  130.     }
  131.     return(OK);
  132. }
  133.  
  134. /* put cursor at the end of the current line */
  135.  
  136. edend()
  137. {
  138.     editp = editpmax;
  139.     outxy(edxpos(),outgety());
  140.     
  141.     /* comment out ----- put cursor at end of screen
  142.     outxy(SCRNW1, outgety());
  143.     ----- end comment out */
  144. }
  145.  
  146. /* start editing line n
  147.  * redraw the screen with cursor at position p
  148.  */
  149.  
  150. edgo(n, p) int n, p;
  151. {
  152.     /* replace current line */
  153.     if (edrepl() == ERR) {
  154.         return(ERR);
  155.     }
  156.     /* go to new line */
  157.     if (bufgo(n) == ERR) {
  158.         return(ERR);
  159.     }
  160.     /* prevent going past end of buffer */
  161.     if (bufatbot()) {
  162.         if (bufup() == ERR) {
  163.             return(ERR);
  164.         }
  165.     }
  166.     /* redraw the screen */
  167.     bufout(bufln(),1,SCRNL1);
  168.     edgetln();
  169.     editp = min(p, editpmax);
  170.     outxy(edxpos(), 1);
  171.     return(OK);
  172. }
  173.  
  174. /* insert c into the buffer if possible */
  175.  
  176. edins(c) char c;
  177. {
  178. int k;
  179.  
  180.     /* do nothing if edit buffer is full */
  181.     if (editpmax >= MAXLEN) {
  182.         return;
  183.     }
  184.     /* fill out line if we are past its end */
  185.     if (editp == editpmax ff edxpos() < outgetx()) {
  186.         k = outgetx() - edxpos();
  187.         editpmax = editpmax + k;
  188.         while (k-- > 0) {
  189.             editbuf [editp++] = ' ';
  190.         }
  191.         editp = editpmax;
  192.     }
  193.     /* make room for inserted character */
  194.     k = editpmax;
  195.     while (k > editp) {
  196.         editbuf[k] = editbuf[k-1];
  197.         k--;
  198.     }
  199.     /* insert character. update pointers */
  200.     editbuf[editp] = c;
  201.     editp++;
  202.     editpmax++;
  203.     /* recalculate print length of line  */
  204.     fmtadj(editbuf,editp-1,editpmax);
  205.     k = fmtlen(editbuf,editpmax);
  206.     if (k > SCRNW1) {
  207.         /* line would become too long */
  208.         /* delete what we just inserted */
  209.         eddel();
  210.     }
  211.     else {
  212.         /* set change flag, redraw line */
  213.         edcflag = YES;
  214.         edredraw();
  215.     }
  216. }
  217.  
  218. /* join (concatenate) the current line with the one above it */
  219.  
  220. edjoin()
  221. {
  222. int k;
  223.  
  224.     /* do nothing if at top of file */
  225.     if (bufattop()) {
  226.         return;
  227.     }
  228.     /* replace lower line temporarily */
  229.     if (edrepl() != OK) {
  230.         return;
  231.     }
  232.     /* get upper line into buffer */
  233.     if (bufup() != OK) {
  234.         return;
  235.     }
  236.     k = bufgetln(editbuf, MAXLEN);
  237.     /* append lower line to buffer */
  238.     if (bufdn() != OK) {
  239.         return;
  240.     }
  241.     k = k + bufgetln(editbuf+k, MAXLEN-k);
  242.     /* abort if the screen isn't wide enough */
  243.     if (k > SCRNW1) {
  244.         /* bug fix */
  245.         bufgetln(editbuf,MAXLEN);
  246.         return;
  247.     }
  248.     /* replace upper line */
  249.     if (bufup() != OK) {
  250.         return;
  251.     }
  252.     editpmax = k;
  253.     edcflag = YES;
  254.     if (edrepl() != OK) {
  255.         return;
  256.     }
  257.     /* delete the lower line */
  258.     if (bufdn() != OK) {
  259.         return;
  260.     }
  261.     if (bufdel() != OK) {
  262.         return;
  263.     }
  264.     if (bufup() != OK) {
  265.         return;
  266.     }
  267.     /* update the screen */
  268.     if (edattop()) {
  269.          edredraw();
  270.     }
  271.     else {
  272.         k = outgety() - 1;
  273.         bufout(bufln(),k,SCRNL-k);
  274.         outxy(0,k);
  275.         edredraw();
  276.     }
  277. }
  278.  
  279. /* delete chars until end of line or c found */
  280.  
  281. edkill(c) char c;
  282. {
  283. int k,p;
  284.     /* do nothing if at right margin */
  285.     if (editp == editpmax) {
  286.         return;
  287.     }
  288.     edcflag = YES;
  289.     /* count number of deleted chars */
  290.     k = 1;
  291.     while ((editp+k) < editpmax) {
  292.         if (editbuf[editp+k] == c) {
  293.             break;
  294.         }
  295.         else {
  296.             k++;
  297.         }
  298.     }
  299.     /* compress buffer (delete chars) */
  300.     p = editp+k;
  301.     while (p < editpmax) {
  302.         editbuf[p-k] = editbuf[p];
  303.         p++;
  304.     }
  305.     /* update buffer size, redraw line */
  306.     editpmax = editpmax-k;
  307.     edredraw();
  308. }
  309.  
  310. /* move cursor left one column.
  311.  * never move the cursor off the current line.
  312.  */
  313.  
  314. edleft()
  315. {
  316. int k;
  317.  
  318.     /* if past right margin, move left one column */
  319.     if (edxpos() < outgetx()) {
  320.         outxy(max(0, outgetx()-1), outgety());
  321.     }
  322.     /* inside the line.  move left one character */
  323.     else if (editp != 0) {
  324.         editp--;
  325.         outxy(edxpos(),outgety());
  326.     }
  327. }
  328.  
  329. /* insert a new blank line below the current line */
  330.  
  331. ednewdn()
  332. {
  333. int k;
  334.     /* make sure there is a current line and 
  335.      * put the current line back into the buffer.
  336.      */
  337.     if (bufatbot()) {
  338.         if (bufins(editbuf,editpmax) != OK) {
  339.             return;
  340.         }
  341.     }
  342.     else if (edrepl() != OK) {
  343.             return;
  344.     }
  345.     /* move past current line */
  346.     if (bufdn() != OK) {
  347.         return;
  348.     }
  349.     /* insert place holder:  zero length line */
  350.     if (bufins(editbuf,0) != OK) {
  351.         return;
  352.     }
  353.     /* start editing the zero length line */
  354.     edgetln();
  355.     /* update the screen */
  356.     if (edatbot()) {
  357.         /* note: bufln()  >= SCRNL */
  358.         edsup(bufln()-SCRNL2);
  359.         outxy(edxpos(),SCRNL1);
  360.     }
  361.     else {
  362.         k = outgety();
  363.         bufout(bufln(),k+1,SCRNL1-k);
  364.         outxy(edxpos(),k+1);
  365.     }
  366. }
  367.  
  368. /* insert a new blank line above the current line */
  369.  
  370. ednewup()
  371. {
  372. int k;
  373.     /* put current line back in buffer */
  374.     if (edrepl() != OK) {
  375.         return;
  376.     }
  377.     /* insert zero length line at current line */
  378.     if (bufins(editbuf,0) != OK) {
  379.         return;
  380.     }
  381.     /* start editing the zero length line */
  382.     edgetln();
  383.     /* update the screen */
  384.     if (edattop()) {
  385.         edsdn(bufln());
  386.         outxy(edxpos(),1);
  387.     }
  388.     else {
  389.         k = outgety();
  390.         bufout(bufln(),k,SCRNL-k);
  391.         outxy(edxpos(),k);
  392.     }
  393. }
  394.  
  395. /* move cursor right one character.
  396.  * never move the cursor off the current line.
  397.  */
  398.  
  399. edright()
  400. {
  401.     /* if we are outside the line move right one column */
  402.     if (edxpos() < outgetx()) {
  403.         outxy (min(SCRNW1, outgetx()+1), outgety());
  404.     }
  405.     /* if we are inside a tab move to the end of it */
  406.     else if (edxpos() > outgetx()) {
  407.         outxy (edxpos(), outgety());
  408.     }
  409.     /* move right one character if inside line */
  410.     else if (editp < editpmax) {
  411.         editp++;
  412.         outxy(edxpos(),outgety());
  413.     }
  414.     /* else move past end of line */
  415.     else {
  416.         outxy (min(SCRNW1, outgetx()+1), outgety());
  417.     }
  418. }
  419.  
  420. /* split the current line into two parts.
  421.  * scroll the first half of the old line up.
  422.  */
  423.  
  424. edsplit()
  425. {
  426. int p, q;
  427. int k;
  428.  
  429.     /* indicate that edit buffer has been saved */
  430.     edcflag = NO;
  431.     /* replace current line by the first half of line */
  432.     if (bufatbot()) {
  433.         if (bufins(editbuf, editp) != OK) {
  434.             return;
  435.         }
  436.     }
  437.     else {
  438.         if (bufrepl(editbuf, editp) != OK) {
  439.             return;
  440.         }
  441.     }
  442.     /* redraw the first half of the line */
  443.     p = editpmax;
  444.     q = editp;
  445.     editpmax = editp;
  446.     editp = 0;
  447.     edredraw();
  448.     /* move the second half of the line down */
  449.     editp = 0;
  450.     while (q < p) {
  451.         editbuf [editp++] = editbuf [q++];
  452.     }
  453.     editpmax = editp;
  454.     editp = 0;
  455.     /* insert second half of the line below the first */
  456.     if (bufdn() != OK) {
  457.         return;
  458.     }
  459.     if (bufins(editbuf, editpmax) != OK) {
  460.         return;
  461.     }
  462.     /* scroll the screen up and draw the second half */
  463.     if (edatbot()) {
  464.         edsup(bufln()-SCRNL2);
  465.         outxy(1,SCRNL1);
  466.         edredraw();
  467.     }
  468.     else {
  469.         k = outgety();
  470.         bufout(bufln(), k+1, SCRNL1-k);
  471.         outxy(1, k+1);
  472.         edredraw();
  473.     }
  474. }
  475.  
  476. /* move cursor right until end of line or
  477.  * character c found.
  478.  */
  479.  
  480. edsrch(c) char c;
  481. {
  482.     /* do nothing if at right margin */
  483.     if (editp == editpmax) {
  484.         return;
  485.     }
  486.     /* scan for search character */
  487.     editp++;
  488.     while (editp < editpmax) {
  489.         if (editbuf[editp] == c) {
  490.             break;
  491.         }
  492.         else {
  493.             editp++;
  494.         }
  495.     }
  496.     /* reset cursor */
  497.     outxy(edxpos(),outgety());
  498. }
  499.  
  500. /* move cursor up one line if possible */
  501.  
  502. edup()
  503. {
  504. int oldx;
  505.     /* save visual position of cursor */
  506.     oldx = outgetx();
  507.     /* put current line back in buffer */
  508.     if (edrepl() != OK) {
  509.         return(ERR);
  510.     }
  511.     /* done if at top of buffer */
  512.     if (bufattop()) {
  513.         return(OK);
  514.     }
  515.     /* start editing the previous line */
  516.     if (bufup() != OK) {
  517.         return(ERR);
  518.     }
  519.     edgetln();
  520.     /* put cursor on this new line as close as
  521.      * possible to where it was on the old line.
  522.      */
  523.     editp = edscan(oldx);
  524.     /* update screen */
  525.     if (edattop()) {
  526.         edsdn(bufln());
  527.         outxy(oldx, 1);
  528.     }
  529.     else {
  530.         outxy(oldx, outgety()-1);
  531.     }
  532.     return(OK);
  533. }
  534.  
  535. /* delete the current line */
  536.  
  537. edzap()
  538. {
  539. int k;
  540.     /* delete the line in the buffer */
  541.     if (bufdel() != OK) {
  542.         return;
  543.     }
  544.     /* move up one line if now at bottom */
  545.     if (bufatbot()) {
  546.         if (bufup() != OK) {
  547.             return;
  548.         }
  549.         edgetln();
  550.         /* update screen */
  551.         if (edattop()) {
  552.             edredraw();
  553.         }
  554.         else {
  555.             outdelln();
  556.             outxy(0,outgety()-1);
  557.         }
  558.         return;
  559.     }
  560.     /* start editing new line */
  561.     edgetln();
  562.     /* update screen */
  563.     if (edattop()) {
  564.         edsup(bufln());
  565.         outxy(0,1);
  566.     }
  567.     else {
  568.         k = outgety();
  569.         bufout(bufln(),k,SCRNL-k);
  570.         outxy(0,k);
  571.     }
  572. }
  573.  
  574. /* return true if the current edit line is being
  575.  * displayed on the bottom line of the screen.
  576.  */
  577.  
  578. edatbot()
  579. {
  580.     return(outgety() == SCRNL1);
  581. }
  582.  
  583. /* return true if the current edit line is being
  584.  * displayed on the bottom line of the screen.
  585.  */
  586.  
  587. edattop()
  588. {
  589.     return(outgety() == 1);
  590. }
  591.  
  592. /* redraw edit line from index to end of line */
  593. /* reposition cursor */
  594.  
  595. edredraw()
  596. {
  597.     fmtadj(editbuf,0,editpmax);
  598.     fmtsubs(editbuf,max(0,editp-1),editpmax);
  599.     outxy(edxpos(),outgety());
  600. }
  601.  
  602. /* return the x position of the cursor on screen */
  603.  
  604. edxpos()
  605. {
  606.     return(min(SCRNW1,fmtlen(editbuf,editp)));
  607. }
  608.  
  609.  
  610. /* fill edit buffer from current main buffer line.
  611.  * the caller must check to make sure the main
  612.  * buffer is available.
  613.  */
  614.  
  615. edgetln()
  616. {
  617. int k;
  618.     /* put cursor on left margin, reset flag */
  619.     editp = 0;
  620.     edcflag = NO;
  621.     /* get edit line from main buffer */
  622.     k = bufgetln(editbuf,MAXLEN);
  623.     if (k > MAXLEN) {
  624.         error("line truncated");
  625.         editpmax = MAXLEN;
  626.     }
  627.     else {
  628.         editpmax = k;
  629.     }
  630.     fmtadj(editbuf,0,editpmax);
  631. }
  632.  
  633. /* replace current main buffer line by edit buffer.
  634.  * the edit buffer is NOT changed or cleared.
  635.  * return ERR is something goes wrong.
  636.  */
  637.  
  638. edrepl()
  639. {
  640.     /* do nothing if nothing has changed */
  641.     if (edcflag == NO) {
  642.         return(OK);
  643.     }
  644.     /* make sure we don't replace the line twice */
  645.     edcflag = NO;
  646.     /* insert instead of replace if at bottom of file */
  647.     if (bufatbot()) {
  648.         return(bufins(editbuf,editpmax));
  649.     }
  650.     else {
  651.         return(bufrepl(editbuf,editpmax));
  652.     }
  653. }
  654.  
  655. /* set editp to the largest index such that
  656.  * buf[editp] will be printed <= xpos
  657.  */
  658.  
  659. edscan(xpos) int xpos;
  660. {
  661.     editp = 0;
  662.     while (editp < editpmax) {
  663.         if (fmtlen(editbuf,editp) < xpos) {
  664.             editp++;
  665.         }
  666.         else {
  667.             break;
  668.         }
  669.     }
  670.     return(editp);
  671. }
  672.  
  673. /* scroll the screen up.  topline will be new top line */
  674.  
  675. edsup(topline) int topline;
  676. {
  677.     if (outhasup() == YES) {
  678.         /* hardware scroll */
  679.         outsup();
  680.         /* redraw bottom line */
  681.         bufout(topline+SCRNL2,SCRNL1,1);
  682.     }
  683.     else {
  684.         /* redraw whole screen */
  685.         bufout(topline,1,SCRNL1);
  686.     }
  687. }
  688.  
  689. /* scroll screen down.  topline will be new top line */
  690.  
  691. edsdn(topline) int topline;
  692. {
  693.     if (outhasdn() == YES) {
  694.         /* hardware scroll */
  695.         outsdn();
  696.         /* redraw top line */
  697.         bufout(topline,1,1);
  698.     }
  699.     else {
  700.         /* redraw whole screen */
  701.         bufout(topline,1,SCRNL1);
  702.     }
  703. }
  704.  
  705.