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