home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1820.lha / XDME / cursor.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  21KB  |  1,217 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     cursor.c
  5.  
  6.     DESCRIPTION
  7.     All routines that only move the cursor.
  8.  
  9.     NOTES
  10.  
  11.     BUGS
  12.  
  13.     TODO
  14.  
  15.     EXAMPLES
  16.  
  17.     SEE ALSO
  18.  
  19.     INDEX
  20.  
  21.     HISTORY
  22.     04. Oct 1992    ada created
  23.  
  24. ******************************************************************************/
  25.  
  26. /**************************************
  27.         Includes
  28. **************************************/
  29. #include <defs.h>
  30.  
  31.  
  32. /**************************************
  33.         Globale Variable
  34. **************************************/
  35. Prototype void do_up              (void);
  36. Prototype void do_scrolldown          (void);
  37. Prototype void do_scrollup          (void);
  38. Prototype void do_down              (void);
  39. Prototype void do_page              (void);
  40. Prototype void do_downadd          (void);
  41. Prototype void do_left              (void);
  42. Prototype void do_right           (void);
  43. Prototype void do_tab              (void);
  44. Prototype void do_backtab          (void);
  45. Prototype void do_top              (void);
  46. Prototype void do_bottom          (void);
  47. Prototype void do_firstcolumn          (void);
  48. Prototype void do_firstnb          (void);
  49. Prototype void do_lastcolumn          (void);
  50. Prototype void do_goto              (void);
  51. Prototype void do_screentop          (void);
  52. Prototype void do_screenbottom          (void);
  53. Prototype void do_wleft           (void);
  54. Prototype void do_wright          (void);
  55. Prototype void do_col              (void);
  56. Prototype void do_scroll          (int);
  57. Prototype void do_match           (void);
  58. Prototype void do_ping              (void);
  59. Prototype void do_pong              (void);
  60. Prototype void do_undo              (void);
  61. Prototype int  get_pong           (int);
  62. Prototype void escapecomlinemode      (void);
  63. Prototype void do_esc              (void);
  64. Prototype void do_recall          (void);
  65. Prototype void markerkill          (ED *);
  66.  
  67. Prototype char    * HistoBuff[];
  68. Prototype short   NumHistoLines;
  69. Prototype short   HistoLine;
  70.  
  71.  
  72. /**************************************
  73.       Interne Defines & Strukturen
  74. **************************************/
  75.  
  76.  
  77. /**************************************
  78.         Interne Variable
  79. **************************************/
  80. static struct TextMarker marker[PINGDEPTH];
  81.  
  82. /* TODO: replace define by function for infinite history */
  83.  
  84. #define MaxHistoLines        40
  85.  
  86. /* HistoBuff is filled [0..NumHistoLines-1], NumHistoLines is in
  87.    [0..MaxHistoLines], HistoLine is in [0..NumHistoLines]. If NumHistoLines
  88.    is 0, then the HistoryBuffer is empty. */
  89.  
  90. char * HistoBuff[MaxHistoLines];
  91. short  NumHistoLines;
  92. short  HistoLine;
  93.  
  94.  
  95. /**************************************
  96.        Interne Prototypes
  97. **************************************/
  98.  
  99.  
  100.  
  101. void do_up (void)
  102. {
  103.     ED * ep = Ep;
  104.     RP * rp = ep->win->RPort;
  105.  
  106.     if (!globalflags.Comlinemode)
  107.     {
  108.     if (ep->line)
  109.     {
  110.         text_sync ();
  111.         ep->line --;
  112.         text_load ();
  113.  
  114.         if (Ep->line < Ep->topline)
  115.         {
  116.         ep->topline --;
  117.  
  118.         scroll_display (0, -1, ep->topcolumn, ep->topline,
  119.             ep->topcolumn + Columns, ep->topline + Lines);
  120.         }
  121.     } else
  122.     {
  123.         globalflags.Abortcommand = 1;
  124.     }
  125.     } else
  126.     {
  127.     if (HistoLine)
  128.     {
  129.         HistoLine --;
  130.  
  131.         strcpy (Current, HistoBuff[HistoLine]);
  132.  
  133.         ep->column = Clen = strlen (Current);
  134.  
  135.         text_redisplaycurrline ();
  136.     }
  137.     }
  138. } /* do_up */
  139.  
  140.  
  141. void do_scrolldown (void)
  142. {
  143.     ED * ep = Ep;
  144.     RP * rp = ep->win->RPort;
  145.  
  146.     if (ep->topline + Lines < ep->lines)
  147.     {
  148.     text_sync ();
  149.  
  150.     ep->topline ++;
  151.     ep->line ++;
  152.  
  153.     text_load ();
  154.  
  155.     scroll_display (0, 1, ep->topcolumn, ep->topline,
  156.             ep->topcolumn + Columns - 1, ep->topline + Lines - 1);
  157.     } else
  158.     globalflags.Abortcommand = 1;
  159. } /* do_scrolldown */
  160.  
  161.  
  162. void do_scrollup (void)
  163. {
  164.     ED * ep = Ep;
  165.     RP * rp = ep->win->RPort;
  166.  
  167.     if (ep->topline)
  168.     {
  169.     text_sync ();
  170.  
  171.     ep->topline --;
  172.     ep->line --;
  173.  
  174.     text_load ();
  175.  
  176.     scroll_display (0, -1, ep->topcolumn, ep->topline,
  177.             ep->topcolumn + Columns - 1, ep->topline + Lines - 1);
  178.     } else
  179.     globalflags.Abortcommand = 1;
  180. } /* do_scrollup */
  181.  
  182.  
  183. void do_down (void)
  184. {
  185.     ED * ep = Ep;
  186.     RP * rp = ep->win->RPort;
  187.  
  188.     if (!globalflags.Comlinemode)
  189.     {
  190.     if (ep->line + 1 < ep->lines)
  191.     {
  192.         text_sync ();
  193.  
  194.         ep->line ++;
  195.  
  196.         text_load ();
  197.  
  198.         if (ep->line - ep->topline >= Lines)
  199.         {
  200.         ep->topline ++;
  201.  
  202.         scroll_display (0, 1, ep->topcolumn, ep->topline,
  203.                 ep->topcolumn + Columns, ep->topline + Lines);
  204.         }
  205.     } else
  206.         globalflags.Abortcommand = 1;
  207.     } else
  208.     { /* Comlinemode */
  209.     if (HistoLine < NumHistoLines)
  210.     {
  211.         HistoLine ++;
  212.  
  213.         if (HistoLine != NumHistoLines)
  214.         strcpy (Current, HistoBuff[HistoLine]);
  215.         else
  216.         *Current = 0;
  217.  
  218.         ep->column = Clen = strlen (Current);
  219.  
  220.         text_redisplaycurrline ();
  221.     }
  222.     } /* if (!Comlinemode) */
  223. } /* do_down */
  224.  
  225.  
  226. /*
  227.     PAGEUP
  228.     PAGEDOWN
  229.     PAGELEFT
  230.     PAGERIGHT
  231.     PAGESET n    (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
  232.         can be > 100.
  233. */
  234.  
  235. void do_page (void)
  236. {
  237.     ED     * ep = Ep;
  238.     ushort n,
  239.        t;
  240.  
  241.     switch(av[0][4])
  242.     {
  243.     case 'u':
  244.         if (!ep->topline && !ep->line) return;
  245.  
  246.         text_sync ();
  247.  
  248.         if (ep->line != ep->topline)
  249.         {
  250.         ep->line = ep->topline;
  251.  
  252.         text_load ();
  253.         return;
  254.         }
  255.  
  256.         n = Lines * PageJump / 100;
  257.  
  258.         if (ep->topline < n)
  259.         n = ep->topline;
  260.  
  261.         ep->line -= n;
  262.         ep->topline -= n;
  263.  
  264.         text_load ();
  265.  
  266.         if (!Nsu)
  267.         scroll_display (0, -n, 0, ep->topline, MAXLINELEN,
  268.             ep->topline + Lines);
  269.         break;
  270.  
  271.     case 'd':
  272.         if (ep->topline + Lines >= ep->lines &&
  273.             ep->line == ep->lines -1)
  274.         return;
  275.  
  276.         text_sync ();
  277.  
  278.         if (ep->line != ep->topline + Lines -1)
  279.         {
  280.         ep->line = ep->topline + Lines -1;
  281.  
  282.         if (ep->line >= ep->lines)
  283.             ep->line = ep->lines -1;
  284.  
  285.         text_load ();
  286.         return;
  287.         }
  288.  
  289.         n = Lines * PageJump / 100;
  290.  
  291.         ep->line    += n;
  292.         ep->topline += n;
  293.  
  294.         if (ep->line >= ep->lines)
  295.         ep->line = ep->lines - 1;
  296.  
  297.         text_load ();
  298.  
  299.         if (!Nsu)
  300.         scroll_display (0, n, 0, ep->topline, MAXLINELEN,
  301.             ep->topline + Lines);
  302.         break;
  303.  
  304.     case 'l':
  305.         if (!ep->topcolumn && !ep->column) return;
  306.  
  307.         t = firstns (Current);
  308.  
  309.         if (ep->column != ep->topcolumn)
  310.         {
  311.         if (t > ep->topcolumn && ep->column != t)
  312.             ep->column = t;
  313.         else
  314.             ep->column = ep->topcolumn;
  315.  
  316.         text_sync ();
  317.         return;
  318.         }
  319.  
  320.         n = Columns * PageJump / 100;
  321.  
  322.         if (ep->topcolumn < n)
  323.         n = ep->topcolumn;
  324.  
  325.         if (t < ep->column && t > ep->column - n)
  326.         ep->column = t;
  327.         else
  328.         ep->column -= n;
  329.         ep->topcolumn -= n;
  330.  
  331.         text_sync ();
  332.  
  333.         if (!Nsu)
  334.         scroll_display (-n, 0, 0, ep->topline, MAXLINELEN,
  335.             ep->topline + Lines);
  336.         break;
  337.  
  338.     case 'r':
  339.         if (ep->topcolumn + Columns >= MAXLINELEN &&
  340.             ep->column == MAXLINELEN-1)
  341.         return;
  342.  
  343.         text_sync ();
  344.  
  345.         t = LINELEN(ep,ep->line);
  346.  
  347.         if (ep->column != ep->topcolumn + Columns -1)
  348.         {
  349.         if (t < ep->topcolumn + Columns && t != ep->column)
  350.             ep->column = t;
  351.         else
  352.             ep->column = ep->topcolumn + Columns -1;
  353.  
  354.         if (ep->column >= MAXLINELEN)
  355.             ep->column = MAXLINELEN - 1;
  356.  
  357.         text_sync ();
  358.         return;
  359.         }
  360.  
  361.         n = Columns * PageJump / 100;
  362.  
  363.         if (t > ep->column && t < ep->column + n)
  364.         ep->column = t;
  365.         else
  366.         ep->column    += n;
  367.         ep->topcolumn += n;
  368.  
  369.         if (ep->column >= MAXLINELEN)
  370.         ep->column = MAXLINELEN - 1;
  371.  
  372.         text_sync ();
  373.  
  374.         if (!Nsu)
  375.         scroll_display (n, 0, 0, ep->topline, MAXLINELEN,
  376.             ep->topline + Lines);
  377.         break;
  378.  
  379.     case 's':
  380.         PageJump = atoi ((char *)av[1]);
  381.  
  382.         if (PageJump > 100)
  383.         PageJump = 100;
  384.         else if (PageJump < 1)
  385.         PageJump = 1;
  386.  
  387.         break;
  388.     }
  389. } /* do_page */
  390.  
  391.  
  392. void do_downadd (void)
  393. {
  394.     ED      * ep = Ep;
  395.     ubyte * ptr;
  396.  
  397.     if (ep->line + 1 == ep->lines)
  398.     {
  399.     ep->modified = 1;
  400.  
  401.     if (makeroom (32))
  402.     {
  403.         ptr = allocline (1);
  404.  
  405.         SETLINE(ep,ep->lines) = ptr;
  406.         ep->lines ++;
  407.     } else
  408.     {
  409.         nomemory ();
  410.     }
  411.     }
  412.  
  413.     do_down ();
  414. } /* do_downadd */
  415.  
  416.  
  417. void do_left (void)
  418. {
  419.     ED * ep = Ep;
  420.  
  421.     if (ep->column)
  422.     {
  423.     ep->column --;
  424.  
  425.     if (ep->column < ep->topcolumn)
  426.         text_adjust (FALSE);
  427.     } else
  428.     globalflags.Abortcommand = 1;
  429. } /* do_left */
  430.  
  431.  
  432. void do_right (void)
  433. {
  434.     ED * ep = Ep;
  435.  
  436.     if (ep->column != 254)
  437.     {
  438.     if (Current[ep->column] == 0)
  439.     {
  440.         Current[ep->column] = ' ';
  441.         Current[ep->column+1]= '\0';
  442.  
  443.         Clen ++;
  444.     }
  445.  
  446.     ep->column ++;
  447.  
  448.     if (ep->column - ep->topcolumn >= Columns)
  449.         text_adjust (FALSE);
  450.     } else
  451.     globalflags.Abortcommand = 1;
  452. } /* do_right */
  453.  
  454.  
  455. void do_tab (void)
  456. {
  457.     short n;
  458.     ED    * ep = Ep;
  459.  
  460.     /* TODO */
  461.     for (n=ep->config.tabstop-(ep->column % ep->config.tabstop); n>0; n--)
  462.     do_right ();
  463. } /* do_tab */
  464.  
  465.  
  466. void do_backtab (void)
  467. {
  468.     short n;
  469.     ED    * ep = Ep;
  470.  
  471.     n = ep->column % ep->config.tabstop;
  472.     if (!n)
  473.     n = ep->config.tabstop;
  474.  
  475.     /* TODO */
  476.     for (; n > 0; --n)
  477.     do_left ();
  478. } /* do_backtab */
  479.  
  480.  
  481. void do_top (void)
  482. {
  483.     text_sync ();
  484.  
  485.     Ep->line = 0;
  486.  
  487.     text_load ();
  488.     text_adjust (FALSE);
  489. } /* do_top */
  490.  
  491.  
  492. void do_bottom (void)
  493. {
  494.     text_sync ();
  495.  
  496.     Ep->line = Ep->lines - 1;
  497.  
  498.     text_load ();
  499.     text_adjust (FALSE);
  500. } /* do_bottom */
  501.  
  502.  
  503. void do_firstcolumn (void)
  504. {
  505.     if (Ep->column)
  506.     {
  507.     Ep->column = 0;
  508.     text_adjust (FALSE);
  509.     }
  510. } /* do_firstcolumn */
  511.  
  512.  
  513. void do_firstnb (void)
  514. {
  515.     for (Ep->column = 0; Current[Ep->column] == ' '; Ep->column ++);
  516.  
  517.     if (Current[Ep->column] == 0)
  518.     Ep->column = 0;
  519.  
  520.     text_adjust (FALSE);
  521. } /* do_firstnb */
  522.  
  523.  
  524. void do_lastcolumn (void)
  525. {
  526.     short i;
  527.  
  528.     text_sync ();
  529.  
  530.     i = (globalflags.Comlinemode) ? Clen : LINELEN(Ep,Ep->line);
  531.  
  532.     if (i != Ep->column)
  533.     {
  534.     Ep->column = i;
  535.     text_adjust (FALSE);
  536.     }
  537. } /* do_lastcolumn */
  538.  
  539.  
  540. /*
  541.  * GOTO [+/-]N
  542.  * GOTO BLOCK    start of block
  543.  * GOTO START    start of block
  544.  * GOTO END    end of block
  545.  */
  546.  
  547. void do_goto (void)
  548. {
  549.     long   n,
  550.        i;
  551.     char * ptr = (char *)av[1];
  552.  
  553.     i = 0;
  554.     n = -1;
  555.  
  556.     switch (*ptr)
  557.     {
  558.     case 'b':
  559.     case 's':
  560.         n = -1;
  561.  
  562.         if (ActualBlock.type != BT_NONE && Ep == ActualBlock.ep)
  563.         n = ActualBlock.start_line;
  564.     break;
  565.  
  566.     case 'e':
  567.         n = -1;
  568.  
  569.         if (ActualBlock.type != BT_NONE && Ep == ActualBlock.ep)
  570.         n = ActualBlock.end_line;
  571.     break;
  572.  
  573.     case '+':
  574.         i = 1;
  575.  
  576.     case '-':
  577.         n = Ep->line;
  578.  
  579.     default:
  580.         n += atoi(ptr+i);
  581.     } /* switch (*ptr) */
  582.  
  583.     if (n >= Ep->lines)
  584.     n = Ep->lines - 1;
  585.  
  586.     if (n < 0)
  587.     {
  588.     error ("goto:\nCannot go to\nline `%s'", av[1]);
  589.     } else
  590.     {
  591.     text_sync ();
  592.  
  593.     Ep->line = n;
  594.  
  595.     text_load ();
  596.     text_adjust (FALSE);
  597.     }
  598. } /* do_goto */
  599.  
  600.  
  601. void do_screentop (void)
  602. {
  603.     text_sync ();
  604.  
  605.     Ep->line = Ep->topline;
  606.  
  607.     text_load ();
  608.     text_adjust (FALSE);
  609. } /* do_screentop */
  610.  
  611.  
  612. void do_screenbottom (void)
  613. {
  614.     text_sync ();
  615.  
  616.     Ep->line = Ep->topline + Lines - 1;
  617.  
  618.     if (Ep->line < 0 || Ep->line >= Ep->lines)
  619.     Ep->line = Ep->lines - 1;
  620.  
  621.     text_load ();
  622.     text_adjust (FALSE);
  623. } /* do_screenbottom */
  624.  
  625.  
  626. void do_wleft ()
  627. {
  628.     ED * ep = Ep;
  629.     int  i;
  630.  
  631.     for (;;)
  632.     {
  633.     i = ep->column;
  634.  
  635.     if (i == 0)
  636.         goto prevline;
  637.  
  638.     i --;
  639.  
  640.     while (i && Current[i] == ' ')
  641.         i --;
  642.  
  643.     if (i == 0 && Current[0] == ' ')
  644.     {
  645. prevline:
  646.         if (globalflags.Comlinemode || ep->line == 0)
  647.         {
  648.         i = ep->column;
  649.         break;
  650.         }
  651.  
  652.         text_sync ();
  653.  
  654.         ep->line --;
  655.  
  656.         text_load ();
  657.  
  658.         ep->column = Clen;
  659.         continue;
  660.     } /* while !SOL && isspace(Current[i]) */
  661.  
  662.     while (i && Current[i] != ' ')
  663.         i --;
  664.  
  665.     if (Current[i] == ' ')
  666.         i ++;
  667.  
  668.     break;
  669.     } /* forever */
  670.  
  671.     ep->column = i;
  672.  
  673.     text_adjust (FALSE);
  674. } /* do_wleft */
  675.  
  676.  
  677. void do_wright()
  678. {
  679.     ED * ep = Ep;
  680.     int  i;
  681.  
  682.     for (;;)
  683.     {
  684.     i = ep->column;
  685.  
  686.     if (i == Clen)
  687.         goto nextline;
  688.  
  689.     while (i != Clen && Current[i] != ' ')  /* skip past current word */
  690.         i ++;
  691.  
  692.     while (i != Clen && Current[i] == ' ')  /* to beg. of next word   */
  693.         i ++;
  694.  
  695.     if (i == Clen)
  696.     {
  697. nextline:
  698.         if (globalflags.Comlinemode || ep->line == ep->lines - 1)
  699.         {
  700.         i = ep->column;
  701.         break;
  702.         }
  703.  
  704.         text_sync ();
  705.  
  706.         ep->line ++;
  707.  
  708.         text_load ();
  709.  
  710.         ep->column = i = 0;
  711.  
  712.         if (Current[0] != ' ')
  713.         break;
  714.  
  715.         continue;
  716.     }
  717.  
  718.     break;
  719.     } /* forever */
  720.  
  721.     ep->column = i;
  722.  
  723.     text_adjust (FALSE);
  724. } /* do_wright() */
  725.  
  726.  
  727. void do_col (void)
  728. {
  729.     int    col;
  730.     char * ptr = (char *)av[1];
  731.  
  732.     switch(*ptr)
  733.     {
  734.     case '+':
  735.         col = text_colno() + atoi(ptr + 1);
  736.         if (col > 254)
  737.         col = 254;
  738.     break;
  739.  
  740.     case '-':
  741.         col = text_colno() + atoi(ptr);
  742.         if (col < 0)
  743.         col = 0;
  744.     break;
  745.  
  746.     default:
  747.         col = atoi(ptr) - 1;
  748.     break;
  749.     }
  750.  
  751.     if (col > 254 || col < 0)
  752.     {
  753.     globalflags.Abortcommand = 1;
  754.     return;
  755.     }
  756.  
  757.     while (Clen < col)
  758.     Current[Clen ++] = ' ';
  759.  
  760.     Current[Clen] = 0;
  761.  
  762.     Ep->column = col;
  763.  
  764.     text_adjust (FALSE);
  765. } /* do_col */
  766.  
  767.  
  768. void do_scroll (int dir) /* SCROLLLEFT SCROLLRIGHT */
  769. {
  770.     ED     * ep = Ep;
  771.     ushort step    = 4;
  772.  
  773.     if (Nsu)
  774.     return;
  775.  
  776.     if (dir == -1)
  777.     if (av[0][6] == 'l')
  778.         dir = SCROLL_LEFT;
  779.     else
  780.         dir = SCROLL_RIGHT;
  781.  
  782.     if (dir == SCROLL_LEFT)
  783.     {
  784.     if (!ep->topcolumn)
  785.     {
  786.         globalflags.Abortcommand = 1;
  787.         return;
  788.     }
  789.  
  790.     if (ep->topcolumn < step)
  791.         step = ep->topcolumn;
  792.     } else if (dir == SCROLL_RIGHT)
  793.     {
  794.     if ((ep->topcolumn + Columns) >= MAXLINELEN)
  795.     {
  796.         globalflags.Abortcommand = 1;
  797.         return;
  798.     }
  799.  
  800.     if ((ep->topcolumn + Columns + step) >= MAXLINELEN)
  801.         step = MAXLINELEN - (ep->topcolumn + Columns);
  802.     }
  803.  
  804.     if (dir == SCROLL_LEFT)
  805.     {
  806.     ep->topcolumn -= step;
  807.     ep->column    -= step;
  808.     } else
  809.     {
  810.     ushort end;
  811.  
  812.     /* fill Current with spaces */
  813.     end = ep->column + step;
  814.  
  815.     for ( ; Clen<end; Clen++)
  816.         Current[Clen] = ' ';
  817.  
  818.     Current[Clen] = 0;
  819.  
  820.     ep->topcolumn += step;
  821.     ep->column    += step;
  822.     }
  823.  
  824.     scroll_display ((dir == SCROLL_LEFT ? -step : step), 0,
  825.         ep->topcolumn, ep->topline,
  826.         ep->topcolumn + Columns, ep->topline + Lines);
  827. } /* do_scroll */
  828.  
  829.  
  830. void do_match (void)
  831. {
  832.     char   dec,     /* char that indicates a "level_down"   */
  833.        inc;     /*        -""-         "level_up"     */
  834.     char * line;    /* contents of the actual line        */
  835.     short  pos;     /* position in that line        */
  836.     short  dir;     /* direction of search            */
  837.     long   linnr;    /* actual line-number            */
  838.     short  level;    /* "level"                              */
  839.  
  840.     /* set start values */
  841.     pos   = Ep->column;
  842.     line  = Current;
  843.     linnr = Ep->line;
  844.     inc   = line[pos];
  845.  
  846.     /* Check for a known paren and select the search-direction accordingly. */
  847.     switch (inc)
  848.     {
  849.     case '{':
  850.         dir = 1;
  851.         dec = '}';
  852.     break;
  853.  
  854.     case '}':
  855.         dir = -1;
  856.         dec = '{';
  857.     break;
  858.  
  859.     case '[':
  860.         dir = 1;
  861.         dec = ']';
  862.     break;
  863.  
  864.     case ']':
  865.         dir = -1;
  866.         dec = '[';
  867.     break;
  868.  
  869.     case '(':
  870.         dir = 1;
  871.         dec = ')';
  872.     break;
  873.  
  874.     case ')':
  875.         dir = -1;
  876.         dec = '(';
  877.     break;
  878.  
  879.     case '`':
  880.         dir = 1;
  881.         dec = '\'';
  882.     break;
  883.  
  884.     case '\'':
  885.         dir = -1;
  886.         dec = '`';
  887.     break;
  888.  
  889.     default:
  890.         dir = 0;
  891.     break;
  892.     }
  893.  
  894.     /* if there is no known paren, return */
  895.     if (!dir)
  896.     return;
  897.  
  898.     /* we start with level 0. Since we ARE on a paren, this is increased soon */
  899.     level = 0;
  900.  
  901.     for (;;)
  902.     {
  903.     if (line[pos] == inc)
  904.     { /* check for "inc-char" */
  905.         level ++;
  906.     } else
  907.     {
  908.         if (line[pos] == dec)
  909.         { /* dito */
  910.         level --;
  911.  
  912.         /* if we have reached the start-level, we are through */
  913.         if (!level)
  914.             break;
  915.         }
  916.     }
  917.  
  918.     /* next pos */
  919.     pos += dir;
  920.  
  921.     if (pos <= 0)
  922.     {
  923.         do
  924.         {
  925.         if (!linnr)
  926.         {
  927.             warn ("match: No matching paren");
  928.             return;
  929.         }
  930.  
  931.         linnr --;
  932.  
  933.         line = GETTEXT(Ep,linnr);
  934.         pos = strlen (line);
  935.  
  936.         if (pos)
  937.         {
  938.             pos --;
  939.  
  940.             break;
  941.         }
  942.         } while (!pos);
  943.     } else if (!line[pos])
  944.     {
  945.         linnr ++;
  946.  
  947.         if (linnr >= Ep->lines)
  948.         {
  949.         warn ("match: No matching paren");
  950.         return;
  951.         }
  952.  
  953.         line = GETTEXT(Ep,linnr);
  954.         pos = 0;
  955.     }
  956.     }
  957.  
  958.     text_sync ();
  959.  
  960.     if (linnr >= Ep->lines)
  961.     linnr = Ep->lines - 1;
  962.  
  963.     Ep->line   = linnr;
  964.     Ep->column = pos;
  965.  
  966.     text_load ();
  967.     text_adjust (FALSE);
  968. } /* do_match */
  969.  
  970.  
  971. void do_ping (void)
  972. {
  973.     uword num = atoi (av[1]);
  974.  
  975.     if (num >= PINGDEPTH)
  976.     {
  977.     error ("ping:\n%ld out of range\n(max %ld)", num, PINGDEPTH);
  978.     return;
  979.     }
  980.  
  981.     marker[num].ep     = Ep;
  982.     marker[num].column = Ep->column;
  983.     marker[num].line   = Ep->line;
  984.  
  985.     title ("Position marked");
  986. } /* do_ping */
  987.  
  988.  
  989. void do_pong (void)
  990. {
  991.     short num = atoi (av[1]);
  992.  
  993.     text_sync ();
  994.  
  995.     if (num < 0 || num >= PINGDEPTH || !marker[num].ep)
  996.     {
  997.     error ("pong:\nrange error or\nyet nothing marked");
  998.     return;
  999.     }
  1000.  
  1001.     text_cursor (1);
  1002.     switch_ed (marker[num].ep);
  1003.     text_cursor (0);
  1004.  
  1005.     if (IntuitionBase->ActiveWindow != Ep->win)
  1006.     {
  1007.     WindowToFront (Ep->win);
  1008.     ActivateWindow (Ep->win);
  1009.     }
  1010.  
  1011.     if ((Ep->line = marker[num].line) >= Ep->lines)
  1012.     {
  1013.     marker[num].line = Ep->line = Ep->lines - 1;
  1014.     }
  1015.  
  1016.     Ep->column = marker[num].column;
  1017.  
  1018.     text_load ();
  1019.     text_adjust (FALSE);
  1020. } /* do_pong */
  1021.  
  1022.  
  1023. int get_pong (int num)
  1024. {
  1025.      if (num < 0 || num >= PINGDEPTH || !marker[num].ep)
  1026.      {
  1027.       return (-1);
  1028.      }
  1029.  
  1030.      if (marker[num].line >= Ep->lines)
  1031.       return (marker[num].line = Ep->lines-1);
  1032.  
  1033.      return (marker[num].line);
  1034. } /* get_pong */
  1035.  
  1036.  
  1037. /*
  1038.  * esc, escimm
  1039.  */
  1040.  
  1041. int Savetopline, Savecolumn, Savetopcolumn;
  1042.  
  1043. void do_recall (void)
  1044. {
  1045.     av[0] = "escimm";
  1046.  
  1047.     /* Copy last Histoline if possible */
  1048.     if (NumHistoLines)
  1049.     av[1] = HistoBuff[NumHistoLines - 1];
  1050.     else
  1051.     av[1] = "";
  1052.  
  1053.     do_esc ();
  1054.  
  1055.     if (NumHistoLines)
  1056.     HistoLine --;
  1057. } /* do_recall */
  1058.  
  1059.  
  1060. void do_esc (void)
  1061. {
  1062.     ED    * ep = Ep;
  1063.     RP    * rp = ep->win->RPort;
  1064.     short y;
  1065.  
  1066.     if (globalflags.Comlinemode)
  1067.     {
  1068.     escapecomlinemode ();
  1069.     return;
  1070.     } else
  1071.     {             /* PATCH_NULL added */
  1072.     esc_partial = Partial;    /* PATCH_NULL added */
  1073.     Partial = NULL;     /* PATCH_NULL added */
  1074.     }
  1075.  
  1076.     text_sync ();
  1077.  
  1078.     if (av[0][3] == 'i')
  1079.     strcpy ((char *)Current, (char *)av[1]);
  1080.     else
  1081.     Current[0] = 0;
  1082.  
  1083.     Clen = strlen ((char *)Current);
  1084.     globalflags.Comlinemode = 1;
  1085.  
  1086.     /* returnoveride (1); */            /* PATCH_NULL [25 Jan 1993] : commented out */
  1087.  
  1088.     Savetopline   = ep->topline;
  1089.     Savecolumn      = ep->column;
  1090.     Savetopcolumn = ep->topcolumn;
  1091.  
  1092.     ep->column = Clen;
  1093.  
  1094.     if (ep->column < Lines)
  1095.     ep->topcolumn = 0;
  1096.     else
  1097.     {
  1098.     ep->topcolumn = Clen - Lines;
  1099.     }
  1100.  
  1101.     ep->topline   = ep->line - Lines + 1;
  1102.  
  1103.     y = ROW (Lines-1);
  1104.     SetAPen (rp, TEXT_BPEN);
  1105.     SetWrMsk (rp, -1);
  1106.     RectFill (rp, COL(0), y, Xpixs, Ypixs);
  1107.  
  1108.     y --;
  1109.     SetAPen (rp, TEXT_FPEN);
  1110.     RectFill (rp, COL(0), y, Xpixs, y);
  1111.  
  1112.     text_displayseg (Lines - 1, 1);
  1113.  
  1114.     HistoLine = NumHistoLines;
  1115. } /* do_esc */
  1116.  
  1117.  
  1118. void escapecomlinemode (void)
  1119. {
  1120.     ED     * ep = Ep;
  1121.     RP     * rp = ep->win->RPort;
  1122.     char * ptr;
  1123.  
  1124.     if (esc_partial)
  1125.     {       /* PATCH_NULL P -> esc_p */
  1126.     free(esc_partial);  /* PATCH_NULL P -> esc_p */
  1127.     esc_partial = NULL; /* PATCH_NULL P -> esc_p */
  1128.     }
  1129.  
  1130.     if (globalflags.Comlinemode)
  1131.     {
  1132.     /* Don't add empty lines */
  1133.     if (*Current)
  1134.     {
  1135.         ptr = Current + strlen (Current) -1;
  1136.  
  1137.         while (*ptr == ' ' && ptr != (char *)Current)
  1138.         ptr --;
  1139.  
  1140.         /* Set string-end after last char. Note that this code
  1141.            removes histo-lines with length 1 (single chars) */
  1142.         if (ptr != (char *)Current)
  1143.         ptr ++;
  1144.  
  1145.         *ptr = 0;
  1146.     }
  1147.  
  1148.     /* If we are somewhere above and we didn't change anything,
  1149.        we won't add a new history-line */
  1150.     /* If there is something to add */
  1151.     if (!(HistoLine != NumHistoLines && !strcmp (Current,
  1152.         HistoBuff[HistoLine])) && *Current)
  1153.         {
  1154.         /* Check if buffer is full */
  1155.         if (NumHistoLines == MaxHistoLines)
  1156.         {
  1157.         /* Free oldest line and shift buffer */
  1158.         free (HistoBuff[0]);
  1159.  
  1160.         movmem (HistoBuff + 1, HistoBuff,
  1161.             sizeof (char *) * (MaxHistoLines - 1));
  1162.  
  1163.         /* We have now space for one line */
  1164.         NumHistoLines --;
  1165.         }
  1166.  
  1167.         /* Allocate new line */
  1168.         ptr = malloc (strlen (Current) + 1);
  1169.  
  1170.         /* Copy new line if possible. Note that even if malloc()
  1171.            failed we don't loose information. */
  1172.         if (ptr)
  1173.         {
  1174.         strcpy (ptr, (char *)Current);
  1175.  
  1176.         /* Add line. At this point, NumHistoLines is ALWAYS
  1177.            less than MaxHistoLines ! */
  1178.         HistoBuff[NumHistoLines ++] = ptr;
  1179.         }
  1180.     }
  1181.  
  1182.     globalflags.Comlinemode = 0;
  1183.  
  1184.     /* returnoveride (0); */        /* PATCH_NULL [25 Jan 1993] : commented out */
  1185.  
  1186.     ep->topline   = Savetopline;
  1187.     ep->column    = Savecolumn;
  1188.     ep->topcolumn = Savetopcolumn;
  1189.  
  1190.     text_load ();
  1191.  
  1192.     SetAPen (rp, TEXT_BPEN);
  1193.     SetWrMsk (rp, -1);
  1194.     RectFill (rp, COL(0), ROW(Lines-1)-1, Xpixs, Ypixs);
  1195.  
  1196.     SetAPen (rp, TEXT_FPEN);
  1197.     text_displayseg (Lines - 2, 2);
  1198.     }
  1199. } /* escapecomlinemode */
  1200.  
  1201.  
  1202. void markerkill (ED * ep)
  1203. {
  1204.     short i;
  1205.  
  1206.     for (i = 0; i < PINGDEPTH; ++i)
  1207.     {        /*    remove ping-pong marks    */
  1208.     if (marker[i].ep == ep)
  1209.         marker[i].ep = NULL;
  1210.     }
  1211. } /* markerkill */
  1212.  
  1213.  
  1214. /******************************************************************************
  1215. *****  ENDE cursor.c
  1216. ******************************************************************************/
  1217.