home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / shell / csh531s.lha / rawcon.c < prev    next >
C/C++ Source or Header  |  1993-06-15  |  20KB  |  942 lines

  1. /* rawcon.c
  2.  *
  3.  * Shell 2.07M  17-Jun-87
  4.  * console handling, command line editing support for Shell
  5.  * using new console packets from 1.2.
  6.  * Written by Steve Drew. (c) 14-Oct-86.
  7.  * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
  8.  *
  9.  * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  10.  * Version 5.00L by Urban Mueller 17-Feb-91
  11.  * Version 5.20L by Andreas M. Kirchwitz (Fri, 13 Mar 1992)
  12.  *
  13.  */
  14.  
  15. #include "shell.h"
  16.  
  17. void setrawcon( long flag, int ievent );
  18.  
  19. #define LINELEN 255
  20.  
  21. int w_width=80, w_height=24;
  22.  
  23. #if RAW_CONSOLE
  24.  
  25. static int myget( void );
  26. static void myunget(int c);
  27. static int get_seq( long *param );
  28.  
  29. static void back( int n );
  30. static void left( int n );
  31. static void right( int n );
  32. static int  leftwordlen( void );
  33. static int  rightwordlen( void );
  34. static void delete( int i );
  35. static void history( int hnum );
  36. static void display( char *str );
  37. static void redraw( void );
  38. static void abbrev( char *buf, char **eav, int eac );
  39. static void quote( char *buf, char *sep );
  40. static void getword( char *buf );
  41. static void delword( void );
  42. static int  getkey(void);
  43.  
  44. static char *tyahdptr;
  45. static int unget;
  46.  
  47. #define SETRAW setrawcon(-1,1);
  48. #define SETCON setrawcon( 0,1);
  49.  
  50. extern char *MenuCommand[MAXMENUS][MAXMENUITEMS];
  51.  
  52. #define CTRL  -64
  53. #define SHIFT 512
  54. #define ESC   1024
  55.  
  56. #define CUP   256
  57. #define CDN   257
  58. #define CRT   258
  59. #define CLT   259
  60. #define TAB   9
  61.  
  62. static int Curmap;
  63. static USHORT *Keymap[8];
  64. static USHORT DefKeymap0[]={
  65.        CLT,  0, /* CursLt = Move.Left  */
  66.        CRT,  1, /* CursRt = Move.Right */
  67.  SHIFT+CLT,  2, /* SCursLt= Move.WordL */
  68.  SHIFT+CRT,  3, /* SCursRt= Move.WordR */
  69.    ESC+CLT,  4, /* ESC-CLt= Move.SOL   */
  70.    ESC+CRT,  5, /* ESC-CRt= Move.EOL   */
  71.   CTRL+'A',  4, /* ^A     = Move.SOL   */
  72.   CTRL+'E',  5, /* ^E     = Move.EOL   */
  73.   CTRL+'Z',  4, /* ^Z     = Move.SOL   */
  74.          8, 10, /* BackSp = Del.BackSp */
  75.        127, 11, /* Delete = Del.Delete */
  76.    ESC+  8, 12, /* ESC-BkS= Del.WordL  */
  77.    ESC+127, 13, /* ESC-Del= Del.WordR  */
  78.   CTRL+'W', 12, /* ^W     = Del.WordL  */
  79.   CTRL+'B', 14, /* ^B     = Del.SOL    */
  80.   CTRL+'K', 15, /* ^K     = Del.EOL    */
  81.    ESC+'x',513, /* ESC-x  = Setmap 1   */
  82.    ESC+'d', 16, /* ESC-d  = Del.Line   */
  83.   CTRL+'X', 16, /* ^X     = Del.Line   */
  84.        CUP, 20, /* CursUp = Hist.Back  */
  85.        CDN, 21, /* CursDn = Hist.Forw  */
  86.    ESC+CUP, 22, /* ECursUp= Hist.Beg   */
  87.    ESC+CDN, 23, /* ECursDn= Hist.End   */
  88.  SHIFT+CUP, 24, /* SCursUp= Hist.Compl */
  89.    ESC+'!', 24, /* ESC-!  = Hist.Compl */
  90.    ESC+ 13, 25, /* ESC-Ret= Hist.Exec  */
  91.   CTRL+'T', 26, /* ^T     = Hist.Tail  */
  92.  SHIFT+CDN, 27, /* SCursDn= Hist.Clr   */
  93.   CTRL+'P', 28, /* ^P     = Hist.DupWrd*/
  94.        TAB, 30, /* Tab    = Comp.Norm  */
  95.  SHIFT+TAB, 31, /* STab   = Comp.Part  */
  96.    ESC+TAB, 32, /* ESC-TAB= Comp.All   */
  97.    ESC+'*', 32, /* ESC-*  = Comp.All   */
  98.    ESC+'c', 33, /* ESC-c  = Comp.CD    */
  99.    ESC+'~', 34, /* ESC-~  = Comp.LastCD*/
  100.   CTRL+'D', 35, /* CTRL-D = Comp.Dir   */
  101.    ESC+'=', 35, /* ESC-=  = Comp.Dir   */
  102.    ESC+'i', 40, /* ESC-i  = Spec.Insert*/
  103.   CTRL+'L', 43, /* ^L     = Spec.Refr  */
  104.         10, 44, /* Enter  = Spec.Accept*/
  105.         13, 44, /* ^Enter = Spec.Accept*/
  106.   CTRL+'N', 45, /* ^N     = Spec.Next  */
  107.   CTRL+'O', 48, /* ^O     = Spec.EchoO */
  108.  CTRL+'\\', 46, /* ^\     = Spec.EOF   */
  109.        260, 42, /* Help   = Spec.Help  */
  110.        271, 51, /* Menu   = Misc.Menu  */
  111.   CTRL+'U', 52, /* ^U     = Misc.Undo  */
  112.   CTRL+'R', 53, /* ^R     = Misc.Repeat*/
  113.    ESC+'s', 54, /* ESC-s  = Misc.Swap  */
  114.          0,  0
  115. };
  116.  
  117. static USHORT DefKeymap1[]={
  118.          8, 14,
  119.        127, 15
  120. };
  121.  
  122. static int  Pos, Len;
  123. static char *Line, *Prompt;
  124. static char LastDir[128];
  125. static char Undo[256];
  126. static int  LastFn=-99, LastKey=-99;
  127. long   Param[10];
  128.  
  129. void
  130. initmap(void)
  131. {
  132.     if( !Keymap[0] )
  133.         Keymap[0]=DefKeymap0, Keymap[1]=DefKeymap1;
  134. }
  135.  
  136. char *
  137. rawgets( char line[], char prompt[] )
  138. {
  139.     static int HNum=-1;
  140.  
  141.     int  key, fn, old, hnum=-1, olen=0, inslen=0;
  142.     int  insert, undo_pos=0, undo_len=0;
  143.     int  eac, eactr=0;
  144.     char typeahd[LINELEN], **eav=NULL, *ret=line;
  145.     
  146.     char *prio_set;
  147.     long oldprio,prio;
  148.  
  149.     if ( o_noraw || !isconsole(Input()) ) {
  150.         if( isconsole(Input())) {
  151.             printf("%s",prompt);
  152.             fflush(stdout);
  153.         }
  154.         return gets(line);
  155.     }
  156.  
  157.     if (WaitForChar(Input(), 100L) || CHARSWAIT(stdin)) /* don't switch to 1 */
  158.         return gets(line);
  159.  
  160.     SETRAW;
  161.  
  162.     if (prio_set = get_var(LEVEL_SET,v_clipri)) {
  163.         prio=atol(prio_set);
  164.         if (!isnum(prio_set)) {
  165.             printf("error: variable _clipri (%s) is not a number\n",prio_set);
  166.             prio_set = NULL;
  167.         }
  168.         else if (prio<-128 || prio>127) {
  169.             printf("error: variable _clipri (%s) is out of range (-128,127)\n",prio_set);
  170.             prio_set = NULL;
  171.         }
  172.         else {
  173.             oldprio = SetTaskPri((struct Task *)Myprocess,prio);
  174.         }
  175.     }
  176.  
  177.     tyahdptr=typeahd;
  178.     typeahd[0]=0;
  179.     Flush(Output());
  180.     printf("\015\033[ p%s",prompt);
  181.  
  182.     Line= line; Prompt= prompt;
  183.     line[ Len=Pos=0 ]=0;
  184.     insert= o_insert;
  185.  
  186.     if( LastFn!=25 )
  187.         LastFn=-1;
  188.  
  189.     if( HNum>=0 ) {
  190.         history( hnum=HNum );
  191.         HNum=-1;
  192.     }
  193.  
  194.     while( (key=getkey()) != -1) {
  195.         USHORT *p;
  196.         int    t;
  197.         char   c, *s, *src, *sep;
  198.  
  199.         for( fn=-1, p=Keymap[Curmap]; *p; p+=2 )
  200.             if( *p==key )
  201.                 { fn=p[1]; break; }
  202.         if( fn==-1 && (key>=261 && key<=270 || key>=261+SHIFT && key<=270+SHIFT))
  203.             fn=50;
  204.         if( fn==-1 && tyahdptr )
  205.             fn=-2;
  206.         if( fn!=52 && fn!=-2 ) {
  207.             memcpy( Undo, line, Len+1 );
  208.             undo_pos=Pos; undo_len=Len;
  209.         }
  210.  
  211.         switch( fn/512 ) {
  212.         case 1:
  213.             fn&=511;
  214.             if( fn<8 && Keymap[fn] ) Curmap=fn;
  215.             fn=-3;
  216.             break;
  217.         case 2:
  218.             key=fn&511, fn=-1;
  219.             break;
  220.         }
  221.  
  222.         if( fn!=-3 )
  223.             Curmap=0;
  224.  
  225.         if( fn==53 )
  226.             fn=LastFn, key=LastKey;
  227.  
  228.         switch( fn ) {
  229.         case -3:                                /* change keymap */
  230.             break;
  231.         case -2:                                /* auto insert   */
  232.         case -1:                                /* insert key    */
  233.             key&=255;
  234.             if (key < 31 || (insert?Len:Pos) >= LINELEN-1 )
  235.                 break;
  236.             putchar(key);
  237.             if (Pos < Len && insert) {
  238.                 memmove( line+Pos+1, line+Pos, Len-Pos+1);
  239.                 printf("%s",line+Pos+1);
  240.                 back(Len-Pos);
  241.                 Len++;
  242.             }
  243.             line[Pos++] = key;
  244.             if (Len < Pos) Len = Pos;
  245.             line[Len] = 0;
  246.             break;
  247.  
  248.         case 0:                                 /* cursor left  */
  249.             left(1);
  250.             break;
  251.         case 1:                                 /* cursor right */
  252.             right(1);
  253.             break;
  254.         case 2:                                 /* word left    */
  255.             left( leftwordlen() );
  256.             break;
  257.         case 3:                                 /* word right   */
  258.             right( rightwordlen() );
  259.             break;
  260.         case 4:                                 /* beg of line  */
  261.             left(Pos);
  262.             break;
  263.         case 5:                                 /* end of line  */
  264.             right(Len-Pos);
  265.             break;
  266.  
  267.         case 10:                                /* backspace    */
  268.             if (Pos==0)
  269.                 break;
  270.             left(1);
  271.         case 11:                                /* delete       */
  272.             if (Pos==Len)
  273.                 break;
  274.             delete(1);
  275.             break;
  276.         case 12:                                /* bkspc word     */
  277.             if( !leftwordlen() )
  278.                 break;
  279.             left( leftwordlen() );
  280.         case 13:                                /* del word       */
  281.             delete( rightwordlen() );
  282.             break;
  283.         case 14:                                /* del to SOL     */
  284.             left( old=Pos );
  285.             delete( old );
  286.             break;
  287.         case 16:                                /* delete line    */
  288.             left( Pos );
  289.         case 15:                                /* delete to EOL  */
  290.             delete( Len-Pos );
  291.             break;
  292.  
  293.         case 17:                                /* clear screen + refresh */
  294.             fprintf(stdout,"\033c\017");
  295.             fflush(stdout);
  296.             redraw();
  297.             break;
  298.  
  299.         case 20:                                /* history up   */
  300.             if( hnum>=H_len-1 )
  301.                 hnum=H_len-1;
  302.             history( ++hnum );
  303.             break;
  304.         case 21:                                /* history down */
  305.             if( hnum<=0 )
  306.                 hnum=0;
  307.             history( --hnum );
  308.             break;
  309.         case 22:                                /* beg of hist */
  310.             history( hnum=H_len-1 );
  311.             break;
  312.         case 23:                                /* end of hist */
  313.             history( hnum=0 );
  314.             break;
  315.         case 24:                                /* complete hist */
  316.             if( LastFn!=fn )
  317.                 hnum=-1, olen=Len;
  318.             line[Len=olen]=0;
  319.             if((hnum=find_history( line, ++hnum ))==-1)
  320.                 display(line);
  321.             else
  322.                 history(hnum);
  323.             break;
  324.         case 25:                                /* exec hist  */
  325.             HNum= hnum;
  326.             LastFn= fn;
  327.             goto done;
  328.         case 26:                                /* tail of prev */
  329.             if( H_head && (s=H_head->line) && (s=index(s,' ')))
  330.                 tyahdptr=s;
  331.             break;
  332.         case 27:                                /* bottom   */
  333.             history( hnum=-1 );
  334.             break;
  335.         case 28:                                /* duplicate word */
  336.             for( s=line+Pos,t=0; s>line && s[-1]==' '; s--,t++ ) ;
  337.             left(t);
  338.             *(tyahdptr=typeahd)=' ';
  339.             getword( typeahd+(t?0:1) );
  340.             right(t);
  341.             break;
  342.  
  343.         case 32:                                /* complete all  */
  344.         case 35: LastFn=-1;                     /* show files    */
  345.         case 30:                                /* complete      */
  346.         case 31:                                /* complete part */
  347.         case 33:                                /* qcd           */
  348.             sep=" ";
  349.             if( fn!=LastFn ) {
  350.                 getword( typeahd );
  351.                 filemap( typeahd, 1 );
  352.                 if( eav    ) free_expand( eav ), eav=NULL;
  353.                 eac=0;
  354.                 breakreset();
  355.                 if( fn==35 ) {
  356.                     int tmp=o_scroll;
  357.                     int old_Pos=Pos;
  358.                     right(Len-Pos);
  359.                     putchar('\n');
  360.                     memmove( typeahd+8, typeahd, strlen(typeahd)+1);
  361.                     /*
  362.                        we need to escape "dir" here in
  363.                        such a way that it works even if
  364.                        a user aliased "dir" to something
  365.                        completely else
  366.                     */
  367.                     memcpy ( typeahd, "\\dir -s ", 8);
  368.                     o_scroll=0;
  369.                     execute( typeahd );
  370.                     o_scroll=tmp;
  371.                     printf("\033[J%s%s",Prompt,Line);
  372.                     back(Len-old_Pos);
  373.                     Pos = old_Pos;
  374.                     break;
  375.                 }
  376.                 if( fn!=33 ) {
  377.                     strcat(  typeahd, "*");
  378.                     if( !index(typeahd,'&' ))
  379.                         eav =expand(typeahd,&eac);
  380.                     if( eac==0 ) {
  381.                         putchar(7);
  382.                         break;
  383.                     }
  384.                 }
  385.                 if( fn==30 )
  386.                     s=eav[ eactr=0 ];
  387.                 else if( fn==31 )
  388.                     abbrev(s=typeahd,eav,eac), eactr=-1, sep= eac==1?" ":"";
  389.                 else if( fn==32 ) {
  390.                     strncpy(s=typeahd, src=compile_av(eav,0,eac,' ',1),LINELEN);
  391.                     typeahd[LINELEN-1]=0;
  392.                     free(src);
  393.                 } else if( fn==33 ) {     /* 33 */
  394.                     strncpy(LastDir,typeahd,128);
  395.                     if( !quick_cd( s=typeahd+128, LastDir, 0)) {
  396.                         putchar(7);
  397.                         break;
  398.                     }
  399.                 }
  400.                 delword();
  401.             } else {
  402.                 if( fn==33 )
  403.                     quick_cd( s=typeahd+128, LastDir, 1);
  404.                 else { /* 30,31 */
  405.                     if( eac==0 ) {
  406.                         putchar(7);
  407.                         break;
  408.                     }
  409.                     s=eav[eactr=++eactr % eac];
  410.                 }
  411.                 left(inslen);
  412.                 delete(inslen);
  413.             }
  414.             strcpy( tyahdptr=typeahd, s );
  415.             if( fn!=32 )
  416.                 quote( typeahd, sep );
  417.             inslen=strlen(typeahd);
  418.             break;
  419.         case 34:                      /* last CD */
  420.             strncpy(typeahd,get_var( LEVEL_SET, v_lcd ),230);
  421.             appendslash(tyahdptr=typeahd);
  422.             break;
  423.  
  424.         case 40:                      /* ins/ovr */
  425.             insert ^= 1;
  426.             break;
  427.         case 41:                      /* quit    */
  428.             strcpy(line,"quit");
  429.             goto done;
  430.         case 42:                      /* help    */
  431.             strcpy(line,"help");
  432.             goto done;
  433.         case 43:                      /* refresh */
  434.             redraw();
  435.             break;
  436.         case 44:                      /* exec    */
  437.             goto done;
  438.         case 45:                      /* leave   */
  439.             add_history( line );
  440.             right(Len-Pos);
  441.             putchar('\n');
  442.             line[Len=Pos=0]=0;
  443.             update_sys_var(v_prompt);
  444.             update_sys_var(v_titlebar);
  445.             redraw();
  446.             hnum=-1;
  447.             break;
  448.         case 46:                      /* EOF */
  449.             ret=NULL;
  450.             goto done;
  451.         case 47:                      /* NOP */
  452.             break;
  453.         case 48:                      /* ^O  */
  454.             /*putchar( CTRL+'O' );*/
  455.             putchar( '\017' );
  456.             redraw();
  457.             break;
  458.         case 49:                      /* ^G  */
  459.             /*putchar( CTRL+'G' );*/
  460.             putchar( '\007' );
  461.             break;
  462.  
  463.         case 50:                      /* FKey */
  464.             sprintf(typeahd,"%c%d",Param[0]>=10?'F':'f',Param[0]%10+1);
  465.             if (s = get_var(LEVEL_SET, typeahd)) {
  466.                 tyahdptr = strcpy(typeahd,s);
  467.                 a0tospace( tyahdptr );
  468.             }
  469.             break;
  470.         case 51:                      /* RawRaw */
  471.             if( Param[0]==10 ) {   /* P0=class P2=code */
  472.                 int num=MENUNUM( Param[2] ), item=ITEMNUM( Param[2] );
  473.                 tyahdptr="";
  474.                 if( num>=0 && num<MAXMENUS && item>=0 && item<MAXMENUITEMS )
  475.                     tyahdptr=MenuCommand[num][item];                                 
  476.             }
  477.             if( Param[0]==11 ) {
  478.                 strcpy(line,"quit");
  479.                 goto done;
  480.             }
  481.             break;
  482.         case 52:                      /* Undo   */
  483.             back(Pos);
  484.             t=Len; Len=undo_len; undo_len=t;
  485.             t=Pos; Pos=undo_pos; undo_pos=t;
  486.             swapmem( Undo, line, MAX( Len, undo_len)+1 );
  487.             printf("\033[J%s",line);
  488.             back(Len-Pos);
  489.             break;
  490.         case 53:                      /* repeat */
  491.             break;
  492.         case 54:                      /* swap   */
  493.             if( (t=Pos==Len?Pos-1:Pos)>0 )
  494.                 c=line[t-1], line[t-1]=line[t], line[t]=c;
  495.             redraw();
  496.             break;
  497.         }
  498.         if( fn!=-2 )
  499.             LastFn=fn, LastKey=key;
  500.     }
  501.     ret=NULL;
  502. done:
  503.     if( ret )
  504.         printf("\033[%dC\n", Len-Pos );
  505.     newwidth();
  506.     if( eav ) free_expand(eav);
  507.     SETCON;
  508.  
  509.     if (prio_set)
  510.         SetTaskPri((struct Task *)Myprocess,oldprio);
  511.  
  512.     return ret;
  513. }
  514.  
  515. static int
  516. getkey(void)
  517. {
  518.     int   esc=0, key, c;
  519.     long *par;
  520.  
  521.     key=-1;
  522.     if( (c=myget())==27 ) {
  523.         esc=ESC;
  524.         if((c=myget())=='[')
  525.             c=155, esc=0;
  526.     }
  527.  
  528.     if(c!=155)
  529.         key=c;
  530.     else {
  531.         switch(c=myget()) {
  532.         case 'A': key=256;       break; /* CursUp */
  533.         case 'B': key=257;       break; /* CursDn */
  534.         case 'C': key=258;       break; /* CursRt */
  535.         case 'D': key=259;       break; /* CursLt */
  536.         case 'T': key=256+SHIFT; break; /* SCursUp */
  537.         case 'S': key=257+SHIFT; break; /* SCursDn */
  538.         case ' ':
  539.             switch( myget() ) {
  540.             case '@': key=258+SHIFT; break; /* SCursRt */
  541.             case 'A': key=259+SHIFT; break; /* SCursLt */
  542.             }
  543.             break;
  544.         case 'Z': key= 9+SHIFT;       break; /* STab    */
  545.         case '?': key= 260; myget();  break; /* Help    */
  546.         case -1 : return -99;
  547.         default :
  548.             if( c>='0' && c<='9' ) {
  549.                 myunget(c);
  550.                 par=Param;
  551.                 do {
  552.                     for( *par=0; (c=myget())>='0' && c<='9';  )
  553.                         *par=10* *par + c-'0';
  554.                     par++;
  555.                 } while( c==';' );
  556.                 if( c=='~' ) {
  557.                     key=Param[0]+261;
  558.                     if( key>270 ) key+=SHIFT-10;
  559.                 }
  560.                 if( c=='|' ) key=271;
  561.             } else
  562.                 key=c;
  563.         }
  564.     }
  565.  
  566.     return key+esc;
  567. }
  568.  
  569. static void
  570. back(int n)
  571. {
  572.     if( n>0 ) printf("\033[%dD",n);
  573. }
  574.  
  575. static void
  576. left(int n)
  577. {
  578.     if( n>Pos ) n=Pos;
  579.     if( n<=0  ) return;
  580.     back(n);
  581.     Pos-=n;
  582. }
  583.  
  584. static void
  585. right(int n)
  586. {
  587.     if( n+Pos>Len ) n=Len-Pos;
  588.     if( n<=0      ) return;
  589.     printf("\033[%dC",n);
  590.     Pos+=n;
  591. }
  592.  
  593. static int
  594. leftwordlen( void )
  595. {
  596.     char  *ptr= Line+Pos;
  597.     while( ptr>Line && *(ptr-1) == ' ' ) ptr--;
  598.     while( ptr>Line && *(ptr-1) != ' ' ) ptr--;
  599.     return (Line+Pos)-ptr;
  600. }
  601.  
  602. static int
  603. rightwordlen( void )
  604. {
  605.     char  *ptr= Line+Pos;
  606.     while( ptr<Line+Len && *ptr != ' ' ) ptr++;
  607.     while( ptr<Line+Len && *ptr == ' ' ) ptr++;
  608.     return ptr-(Line+Pos);
  609. }
  610.  
  611. static void
  612. delete( int cnt )
  613. {
  614.     if( !cnt ) return;
  615.     memmove( Line+Pos, Line+Pos+cnt, Len-Pos-cnt );
  616.     memset ( Line+Len-cnt, ' ', cnt );
  617.     printf("%s",Line+Pos);
  618.     back(Len-Pos);
  619.     Line[ Len-=cnt ]=0;
  620. }
  621.  
  622. static void
  623. history( int hnum )
  624. {
  625.     HIST *hist;
  626.  
  627.     for( hist=H_head; hist && hnum--; hist=hist->next) ;
  628.     display( hist ? hist->line : "");
  629. }
  630.  
  631. static void 
  632. display( char *str )
  633. {
  634.     left(Pos);
  635.     strcpy(Line,str);
  636.     printf("\033[J%s",str);
  637.     Pos= Len= strlen(str);
  638. }
  639.  
  640. static void
  641. redraw( void )
  642. {
  643.     back(Pos);
  644.     printf("\015\033[J%s%s",Prompt,Line);
  645.     back(Len-Pos);
  646. }
  647.  
  648. static int wleft, wdel;
  649.  
  650. static void
  651. getword( char *buf )
  652. {
  653.     char *beg, *end, *l=Line;
  654.  
  655.     for( end=l+Pos; *end  && *end!=' '; ++end ) ;
  656.     for( beg=l+Pos; beg>l && !index(" <>;",*(beg-1)) ; beg-- ) ;
  657.     memcpy( buf, beg, end-beg );
  658.     buf[end-beg]=0;
  659.     wleft= (l+Pos)-beg;
  660.     wdel = end-beg;
  661. }
  662.  
  663. static void
  664. delword()
  665. {
  666.     left( wleft);
  667.     delete( wdel );
  668. }
  669.  
  670.  
  671.  
  672. static void
  673. abbrev( char *buf, char **eav, int eac )
  674. {
  675.     int i, j, radlen=9999;
  676.  
  677.     /*if( eac>1 ) putchar( CTRL+'G' );*/
  678.     if( eac>1 ) putchar( '\007' );    /* ^G */
  679.  
  680.     strcpy( buf, eav[0] );
  681.     for( i=0; i<eac; i++ ) {
  682.         if ( (j=strlen(eav[i])) < radlen ) radlen=j;
  683.         for( j=0; j<radlen && tolower(eav[0][j])==tolower(eav[i][j]); j++ ) ;
  684.         if ( j<radlen ) radlen=j;
  685.     }
  686.     buf[radlen]=0;
  687. }
  688.  
  689.  
  690.  
  691. static int must_be_quoted(char *s)
  692. {
  693.     if (!*s)
  694.         return 1;
  695.     for ( ; *s; s++)
  696.         if (ISSPACE(*s) || *s==';' || *s=='|' || *s=='#' || *s=='^'
  697.              || *s=='?' || *s=='*' || *s=='&' || *s=='$' || *s=='!'
  698.              || *s=='~' || *s=='`' || *s=='\'')
  699.            return 1;
  700.     return 0;
  701. }
  702.  
  703. static void quote( char *buf, char *sep )
  704. {
  705.     int len=strlen(buf), dir=isdir(buf);
  706.  
  707.     if (must_be_quoted(buf)) {
  708.         memmove(buf+1,buf,len);
  709.         buf[0]=buf[++len]='\"';
  710.         buf[++len]=0;
  711.     }
  712.     strcat(buf,dir?"/":sep);
  713. }
  714.  
  715.  
  716.  
  717. void
  718. setrawcon( long flag, int ievent ) /* -1L=RAW:, 0L=CON: */
  719. {
  720.     static char menuon, button;
  721.  
  722.     if( !o_nowindow && ievent && flag==0 && menuon)
  723.         printf("\033[10}"), menuon=0;
  724.  
  725.     DoPkt( (void *)Myprocess->pr_ConsoleTask, ACTION_SCREEN_MODE, flag,  NULL,NULL,NULL,NULL );
  726.  
  727.     if( !o_nowindow && ievent && flag==-1 ) {
  728.         if( !menuon )
  729.             printf("\033[10{"), menuon=1;
  730.         if( !button )
  731.             printf("\033[11{"), button=1;
  732.     }
  733.     fflush(stdout);
  734. }
  735.  
  736.  
  737. static int row, height, cnt;
  738. static char scrollstr[10];
  739. static int noquick=1;
  740.  
  741.  
  742. extern BPTR OldCin;
  743.  
  744. static int FromTee;
  745.  
  746. static UBYTE
  747. mygetchar(void)
  748. {
  749.     UBYTE c;
  750.     Read( Input(), &c, 1 );
  751.     return c;
  752. }
  753.  
  754. void
  755. prepscroll( int fromtee )
  756. {
  757.     BPTR truecin=0;
  758.     long param[8];
  759.  
  760.     row=height=0;
  761.     FromTee=fromtee;
  762.  
  763.     if(( noquick=!o_scroll || o_noraw || o_nofastscr))
  764.         return;
  765.     if(( noquick=!isconsole(Myprocess->pr_COS) && !fromtee ))
  766.         return;
  767.     if( !isconsole(Myprocess->pr_CIS)) {
  768.         truecin=Myprocess->pr_CIS;
  769.  
  770.         if( noquick=!isconsole(OldCin) )
  771.             return;
  772.  
  773.         Myprocess->pr_CIS = DEVTAB(stdin) = OldCin;
  774.     }
  775.  
  776.     if( !CHARSWAIT(stdin) ) {
  777.         SETRAW;
  778.         Write(OldCin,"\033[ q",4);
  779.         get_seq( param );
  780.         height=param[2];
  781.         while( mygetchar()!='r') ;
  782.  
  783.         Write(OldCin,"\033[6n",4);
  784.         get_seq( param );
  785.         row=param[0];
  786.  
  787.         SETCON;
  788.  
  789.         cnt= height-row+1;
  790.         noquick= height<o_minrows;
  791.     }
  792.  
  793.     sprintf(scrollstr,"\033[%cS\033[%cA", o_scroll+'0', o_scroll+'0');
  794.  
  795.     if( truecin )
  796.         Myprocess->pr_CIS = DEVTAB(stdin) = truecin;
  797. }
  798.  
  799. static int
  800. get_seq( long *param )
  801. {
  802.     int c;
  803.  
  804.     while( (c=mygetchar())!=155 ) ;
  805.     do {
  806.         *param=0;
  807.         while( (c=mygetchar())>='0' && c<='9' )
  808.             *param=10* *param + c-'0';
  809.         param++;
  810.     } while( c==';' );
  811.  
  812.     return c;
  813. }
  814.  
  815.  
  816. void
  817. quickscroll( void )
  818. {
  819.     if( noquick ) return;
  820.  
  821.     if( --cnt<=0 ) {
  822.         cnt=o_scroll;
  823.         fprintf( FromTee ? stderr : stdout, "%s",scrollstr);
  824.     }
  825. }
  826.  
  827. int
  828. do_keymap( void )
  829. {
  830.     int i, n, len;
  831.     USHORT *tmp, *put, *get, *map;
  832.     char   *ind;
  833.  
  834. #if 0
  835.     if( ac==1 ) {
  836.         for( get=Keymap[0]; *get; get+=2 )
  837.             printf("%4d %4d\n",get[0],get[1]);
  838.         return 0;
  839.     }
  840. #endif
  841.  
  842.     n=myatoi(av[1],0,7);
  843.     if( atoierr ) return 20;
  844.  
  845.     map=Keymap[n]; len=0;
  846.     if( map )
  847.         for( len=0; map[2*len]; len++ ) ;
  848.  
  849.     put=tmp=salloc((len+ac)*2*sizeof(USHORT));
  850.     for( i=2; i<ac; i++ ) {
  851.         if( !(ind=index(av[i],'='))) {
  852.             ierror( av[i],500);
  853.             free( tmp );
  854.             return 20;
  855.         }
  856.         *put++=atoi(av[i]);
  857.         *put++=atoi(ind+1);
  858.     }
  859.  
  860.     for( i=0; i<len; i++ ) {
  861.         for( get=tmp; get<put; get+=2 )
  862.             if( *get==map[2*i] )
  863.                 break;
  864.         if( get==put ) {
  865.             *put++=map[2*i];
  866.             *put++=map[2*i+1];
  867.         }
  868.     }
  869.     *put++=0;
  870.     *put  =0;
  871.  
  872.     if( map && map!=DefKeymap0 && map!=DefKeymap1 )
  873.         free( map );
  874.     Keymap[n]=tmp;
  875.     Curmap=0;
  876.  
  877.     return 0;
  878. }
  879.  
  880. static int
  881. myget( void )
  882. {
  883.     int c;
  884.  
  885.     if( unget )
  886.         c=unget, unget=0;
  887.     else if( tyahdptr && *tyahdptr ) {
  888.         c=*tyahdptr++;
  889.     } else {
  890.         tyahdptr=NULL;
  891.         fflush(stdout);
  892.         c=getchar();
  893.     }
  894.  
  895.     return c;
  896. }
  897.  
  898. static void
  899. myunget(int c)
  900. {
  901.     unget=c;
  902. }
  903.  
  904. int
  905. newwidth( void )
  906. {
  907.     extern struct Window *Win;
  908.  
  909.     w_width = 80;
  910.     w_height= 24;
  911.     if( !o_nowindow && Win ) {
  912.         w_width =(Win->Width - Win->BorderLeft - Win->BorderRight)/
  913.                   Win->RPort->TxWidth;
  914.         w_height=(Win->Height- Win->BorderTop  - Win->BorderBottom)/
  915.                   Win->RPort->TxHeight;
  916.     }
  917.     if( w_width<1 ) w_width=1;          /* crash after resizing was reported */
  918.     return w_width;
  919. }
  920.  
  921.  
  922.  
  923. #else
  924.  
  925. void prepscroll(int fromtee) {}
  926. void quickscroll(void) {}
  927. int  do_keymap( void ) {}
  928. void setrawcon( long flag, int ievent ) {}
  929. int  newwidth( void ) {}
  930. void initmap(void) {}
  931.  
  932. #endif
  933.  
  934. extern struct MsgPort *Console;
  935.  
  936. int
  937. isconsole( BPTR fh )
  938. {
  939.     return ((struct FileHandle *)(4*fh))->fh_Type==Console &&
  940.         IsInteractive(fh);
  941. }
  942.