home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / d / ed / !Ed / c / EdKeys < prev    next >
Encoding:
Text File  |  1990-06-21  |  9.3 KB  |  382 lines

  1. /* key processor for Ed
  2.    Copyright C.T.Stretch 1990
  3.    Thu,21 Jun 1990
  4. */
  5.  
  6. #include "Edhdr.h"
  7. #include "wkey.h"
  8. #include <ctype.h>
  9.  
  10. #define MF CKMOD(CD);break
  11. #define MFL if(cline->col<NCOL||CF) CKMOD(CD);break
  12. #define NOCARET (1<<25);
  13. #define HEX(k) (k-(k>'9'?(k>'Z'?('a'-10):('A'-10)):'0'))
  14.  
  15. static int hexch[]={ '\\','x','0','0',0 };
  16.  
  17. void keys_checkcp()
  18. { wimp_wstate state;
  19.   wimp_openstr *o=&state.o;
  20.   wimpt_noerr(wimp_get_wind_state(cwind->hand,&state));
  21.   if(clinen<cwind->over+(OFFSET-o->y+LINEHT-1)/LINEHT)
  22.   { o->y=OFFSET+LINEHT*(cwind->over-clinen);
  23.     wimpt_noerr(wimp_open_wind(o));
  24.   }
  25.   else
  26.   if(clinen>cwind->over+(OFFSET-o->y+o->box.y1-o->box.y0-LINEHT+1)/LINEHT)
  27.   { o->y=OFFSET+LINEHT*(cwind->over-clinen-1)+o->box.y1-o->box.y0;
  28.     wimpt_noerr(wimp_open_wind(o));
  29.   }
  30.   if(cpos<((o->x+CHWIDTH-1)/CHWIDTH))
  31.   { o->x=CHWIDTH*cpos;
  32.     wimpt_noerr(wimp_open_wind(o));
  33.   }
  34.   else
  35.   if(cpos>((o->x+o->box.x1-o->box.x0-CHWIDTH+1)/CHWIDTH))
  36.   { o->x=CHWIDTH*(cpos+1)+o->box.x0-o->box.x1;
  37.     wimpt_noerr(wimp_open_wind(o));
  38.   }
  39. }
  40.  
  41. static void indent(line *l)
  42. { int n=0,m,s=0;
  43.   line *pl=l->prev;
  44.   char *t=l->text,*p=pl->text;
  45.   while(l->len>0&&t[l->len-1]==' ') l->len--;
  46.   if(pl&&!pl->fold&&l->col<NCOL)
  47.   { for(;(n<pl->len)&&(p[n]==' ');n++);
  48.     if(n>=pl->len) n=0;
  49.     for(m=n;m<pl->len;m++)
  50.     { if(p[m]=='{') { n+=2;s++;}
  51.       if(p[m]=='}'&&s>0) { n-=2;s--;}
  52.       if(m<pl->len-1&&!strncmp(p+m,"/*",2))
  53.                      { m=find_skipcomm(pl,m+2);continue;}
  54.       if(p[m]=='\'') { m=find_skipchar(pl,m+1);continue;}
  55.       if(p[m]=='\"') { m=find_skipstr(pl,m+1);continue;}
  56.     }
  57.     if(n<0) n=0;
  58.   }
  59.   if(l==cline) cpos=n;
  60.   if(!l->len) return;
  61.   for(m=0;(m<l->len)&&(t[m]==' ');m++);
  62.   if(t[m]=='}'&&n>=2) n-=2;
  63.   if(l->len+n-m>MAXC)
  64.   { n=MAXC-l->len+m;
  65.     BEEP;
  66.   }
  67.   if(m==n) return;
  68.   memmove(t+n,t+m,l->len-m);
  69.   if(n>m) memset(t+m,' ',n-m);
  70.   l->len+=(n-m);
  71. }
  72.  
  73. static void nl(BOOL split)
  74. { wimp_wstate state;
  75.   wimp_openstr *o=&state.o;
  76.   int n=CL-cpos;
  77.   wind *w;
  78.   wimp_box sou[1];
  79.   wimp_caretstr cs[1];
  80.   if(!mem_getline(cline)) return;
  81.   CD->len+=1;
  82.   if(n>0&&split)
  83.   { memcpy(CN->text,CT+cpos,n);
  84.     memset(CT+cpos,' ',n);
  85.     CL=cpos;CN->len=n;
  86.   }
  87.   cline=CN;clinen++;cpos=0;
  88.   if(split&&CP->col>=NCOL) cline->col=NCOL;
  89.   indent(cline);
  90.   wimpt_noerr(wimp_get_caret_pos(cs));
  91.   cs->height=NOCARET;
  92.   wimpt_noerr(wimp_set_caret_pos(cs));
  93.   w=CD->list;
  94.   while(w)
  95.   { wimpt_noerr(wimp_get_wind_state(w->hand,&state));
  96.     if(clinen<=w->over+(OFFSET-o->y)/LINEHT)
  97.     { w->over+=1;
  98.       disp_sete(w);
  99.     }
  100.     else
  101.     { disp_sete(w);
  102.       if(clinen<=w->over+(OFFSET-o->y+o->box.y1-o->box.y0)/LINEHT)
  103.       { sou->x0=0;sou->y0=LBASE(CD->len-1);
  104.         sou->x1=WWIDTH;sou->y1=LBASE(clinen)+4;
  105.         wimpt_noerr(wimp_blockcopy(w->hand,sou,0,LBASE(CD->len)));
  106.         disp_update(0,MAXC);
  107.         if(split) disp_updatel(CP);
  108.       }
  109.     }
  110.     w=w->next;
  111.   }
  112.   cs->height=CARHT;
  113.   wimpt_noerr(wimp_set_caret_pos(cs));
  114. }
  115.  
  116. static void tidy(void)
  117. { line *l;
  118.   for(l=cline;l&&!l->fold&&l->len;l=l->next) indent(l);
  119.   disp_fred(CD);
  120. }
  121.  
  122. static void del()
  123. { if(cpos<=0) return;
  124.   if(cpos>CL) {cpos--;return;}
  125.   if(cpos==CL){CT[--cpos]=32;disp_update(cpos,CL--);return;}
  126.   memcpy(CT+cpos-1,CT+cpos,CL-cpos);
  127.   disp_update(--cpos,CL--);
  128.   CT[CL]=32;
  129. }
  130.  
  131. static void dline()
  132. { wimp_wstate state;
  133.   wimp_openstr *o=&state.o;
  134.   wimp_box sou[1];
  135.   wimp_caretstr cs[1];
  136.   wind *w;
  137.   line **l;
  138.   int nextln=clinen+1;
  139.   if(CF) for(l=&(CF);*l;mem_unlink(l)) if(*l==MARK) MARK=0;
  140.   if(!CN&&!CP) { mem_clear(cline);cpos=0;disp_update(0,MAXC);return;}
  141.   if(MARK==cline) MARK=0;
  142.   CD->len-=1;
  143.   if(CP)
  144.   { cline=CP;clinen--;cpos=CL;mem_unlink(cline);
  145.   }
  146.   else
  147.   { cline=CN;cpos=0;mem_unlink(&(CD->line));
  148.   }
  149.   wimpt_noerr(wimp_get_caret_pos(cs));
  150.   cs->height=NOCARET;
  151.   wimpt_noerr(wimp_set_caret_pos(cs));
  152.   w=CD->list;
  153.   while(w)
  154.   { disp_sete(w);
  155.     wimpt_noerr(wimp_get_wind_state(w->hand,&state));
  156.     if(clinen>=w->over+(OFFSET-o->y)/LINEHT-1
  157.       && clinen<=w->over+(OFFSET-o->y+o->box.y1-o->box.y0)/LINEHT)
  158.     { sou->x0=0;sou->y0=LBASE(CD->len+2);
  159.       sou->x1=WWIDTH;sou->y1=LBASE(nextln)+4;
  160.       wimpt_noerr(wimp_blockcopy(w->hand,sou,0,LBASE(CD->len+1)));
  161.     }
  162.     w=w->next;
  163.   }
  164.   cs->height=CARHT;
  165.   wimpt_noerr(wimp_set_caret_pos(cs));
  166. }
  167.  
  168. static void clearleft()
  169. { int n=CL;
  170.   if(!cpos) return;
  171.   if(cpos>n) cpos=n;
  172.   if(n>cpos) memmove(CT,CT+cpos,n-cpos);
  173.   memset(CT+n-cpos,' ',cpos);
  174.   CL-=cpos;
  175.   disp_update(0,n);
  176.   cpos=0;
  177. }
  178.  
  179. static void clearright()
  180. { int n=CL;
  181.   if(cpos>=n) return;
  182.   memset(CT+cpos,' ',n-cpos);
  183.   CL=cpos;
  184.   disp_update(cpos,n);
  185. }
  186.  
  187. static void up() {if(CP) {cline=CP;clinen--;} }
  188.  
  189. static void down()
  190. { if(!CN) if(!mem_getline(cline)) return;
  191.   cline=CN;clinen++;
  192. }
  193.  
  194. static void left()
  195. { if(cpos>0) cpos--;
  196.   else if(CP)
  197.   { cline=CP;clinen--;cpos=CL;
  198.   }
  199. }
  200.  
  201. static void right() { if(cpos<MAXC) cpos++;}
  202.  
  203. static void upgo()
  204. { wimp_wstate state;
  205.   wimp_openstr *o=&state.o;
  206.   cline=CD->line;
  207.   clinen=0;
  208.   wimpt_noerr(wimp_get_wind_state(cwind->hand,&state));
  209.   o->x=0;o->y=(cwind->over)*LINEHT;
  210.   cpos=0;
  211.   wimpt_noerr(wimp_open_wind(o));
  212. }
  213.  
  214. static void downgo()
  215. { int x;
  216.   wimp_wstate state;
  217.   wimp_openstr *o=&state.o;
  218.   wimpt_noerr(wimp_get_wind_state(cwind->hand,&state));
  219.   o->y=(cwind->over-CD->len-2)*LINEHT+o->box.y1-o->box.y0;
  220.   cline=CD->line;clinen=0;
  221.   while(CN) {cline=CN;clinen++;}
  222.   cpos=CL;
  223.   x=cpos*16-(o->box.x1-o->box.x0);
  224.   o->x=(x<0)?0:x;
  225.   wimpt_noerr(wimp_open_wind(o));
  226. }
  227.  
  228. static void pgmove(int d)
  229. { wimp_wstate state;
  230.   wimp_openstr *o=&state.o;
  231.   wimpt_noerr(wimp_get_wind_state(cwind->hand,&state));
  232.   o->y+=d*(o->box.y1-o->box.y0);
  233.   clinen=cwind->over+1+(OFFSET-o->y)/LINEHT;
  234.   if(clinen>=CD->len) clinen=CD->len-1;
  235.   cline=disp_find(clinen,CD);
  236.   wimpt_noerr(wimp_open_wind(o));
  237. }
  238.  
  239. static void join(void)
  240. { int n;
  241.   if(!CP||CF||CP->fold) return;
  242.   cpos=CP->len;
  243.   for(n=0;n<CL&&CT[n]==' ';n++);
  244.   if(CL+CP->len-n>MAXC) return;
  245.   memcpy(CP->text+CP->len,CT+n,CL-n);
  246.   CP->len+=CL-n;
  247.   mem_unlink(CP);
  248.   cline=CP;clinen--;
  249.   disp_fred(CD);
  250. }         
  251.  
  252. void keys_add(int k)
  253. { char *t=CT;
  254.   int l=CL;
  255.   if(!cline || cpos>=MAXC || l>=MAXC) { BEEP;return;}
  256.   if(cpos<l) memmove(t+cpos+1,t+cpos,l-cpos);
  257.   if(cpos>l) CL=cpos;
  258.   CT[cpos++]=(char)k;
  259.   CL++;
  260.   disp_update(cpos-1,CL);
  261.   disp_setcaret();
  262.   if(cline->col<NCOL) CKMOD(CD);
  263. }     
  264.  
  265. static void insfkey(int n)
  266. { char v[10],s[MAXC],*w;
  267.   sprintf(v,"Key$%d",n);
  268.   os_read_var_val(v,s,MAXC);
  269.   for(w=s;*w;w++) keys_add(*w);
  270. }
  271.  
  272. static BOOL insedx(int n)
  273. { char v[10];
  274.   char s[257];
  275.   char *m;
  276.   int a,b,c;
  277.   sprintf(v,"Ed$%c",(char)n);
  278.   os_read_var_val(v,s,256);
  279.   if(!*s) return FALSE;
  280.   for(m=s;*m;m++)
  281.   { if(*m=='&')
  282.     { a=m[1];
  283.       if(a=='&') { keys_add('&');m++;continue;}
  284.       b=m[2];
  285.       c=m[3];
  286.       if(!(isxdigit(a)&&isxdigit(b)&&isxdigit(c))) 
  287.       { werr(0,"Bad Ed$%c char %d",(char)n,m-s);
  288.         return TRUE;
  289.       }
  290.       keys_key((HEX(a)<<8)+(HEX(b)<<4)+HEX(c));
  291.       m+=3;
  292.     }
  293.     else keys_key(*m);
  294.   }
  295.   return TRUE;
  296. }
  297.  
  298. static void setfkey(int n)
  299. { char v[MAXC+12];
  300.   sprintf(v,"Set Key$%d %*.*s",n,CL,CL,CT);
  301.   system(v);
  302. }
  303.  
  304. static void topset(int n)
  305. { int *m;
  306.   hexch[2]='0'+(n>>4);
  307.   if(hexch[2]>'9') hexch[2]+='A'-'9'-1;
  308.   hexch[3]='0'+(n&0xF);
  309.   if(hexch[3]>'9') hexch[3]+='A'-'9'-1;
  310.   for(m=hexch;*m;m++) keys_add(*m);
  311. }
  312.  
  313. static void other(int k)
  314. { if(k>=wkey_CF(1)&&k<=wkey_CF(9)) { insfkey(k-wkey_CF(0));return;}
  315.   if(k>=wkey_CSF(1)&&k<=wkey_CSF(9)) { setfkey(k-wkey_CSF(0));return;}
  316.   if(k>=128&&k<=255) { topset(k);return;}
  317.   if(k>=wkey_C('A')&&k<=wkey_C('_')) if(insedx(k+'A'-wkey_C('A'))) return;
  318.   wimp_processkey(k);
  319. }
  320.  
  321. #ifdef SHOWBUG
  322. static void showbug(void)
  323. { werr(0,"emptyn %d empty %p ",emptyn,empty);
  324.   werr(0,"cwind %p cline %p cdoc %p cdoc->wind %p",cwind,cline,CD,CD->list);
  325. }
  326. #endif
  327.  
  328. static void keyop(int k)
  329. { switch(k)
  330.   {
  331. #ifdef SHOWBUG
  332.     case wkey_C('Q'):showbug();break;
  333. #endif
  334.     case wkey_DEL:   del();MFL;
  335.     case wkey_INS:   nl(FALSE);MFL;
  336.     case wkey_RIGHT: right();break;
  337.     case wkey_DOWN:  down();break;
  338.     case wkey_LEFT:  left();break;
  339.     case wkey_UP:    up();break;
  340.     case wkey_CLEFT: cpos=0;break;
  341.     case wkey_CRIGHT:cpos=CL;break;
  342.     case wkey_CDOWN: downgo();break;
  343.     case wkey_CUP:   upgo();break;
  344.     case wkey_SDOWN: pgmove(-1);break;
  345.     case wkey_SUP:   pgmove(1);break;
  346.     case wkey_F(0):  file_savedoc("printer:",CD);break;
  347.     case wkey_SF(0): if(CD->mark) file_saveline("printer:",CD->mark);break;
  348.     case wkey_F(1):  fold_mark();break;
  349.     case wkey_SF(1): fold_unmark();break;
  350.     case wkey_F(2):  fold_gomark();break;
  351.     case wkey_SF(2): fold_note();MFL;
  352.     case wkey_F(3):  nl(FALSE);cline->col=NCOL;break;
  353.     case wkey_SF(3): fold_unnote();MF;
  354.     case wkey_F(4):  fold_gonote();break;
  355.     case wkey_SF(4): fold_comnote();MF;
  356.     case wkey_F(5):  fold_copy();MFL;
  357.     case wkey_SF(5): fold_movel();MFL;
  358.     case wkey_F(6):  clearleft();MFL;
  359.     case wkey_SF(6): clearright();MFL;
  360.     case wkey_F(7):  nl(TRUE);MFL;
  361.     case wkey_SF(7): join();MF;
  362.     case wkey_F(8):  dline();MFL;
  363.     case wkey_SF(8): tidy();MF;
  364.     case wkey_F(9):  fold_fold();break;
  365.     case wkey_SF(9): fold_unfoldall();break;
  366.     case wkey_F(10): fold_unfold1();break;
  367.     case wkey_SF(10):fold_fold1();break;
  368.     case wkey_F(11): fold_foldmark();break;
  369.     case wkey_SF(11):file_runline(FALSE);break;
  370.     case wkey_SF(12):file_runline(TRUE);break;
  371.     default:other(k);
  372.   }
  373.   while(CL>0&&CT[CL-1]==' ') CL--;
  374.   keys_checkcp();
  375.   disp_setcaret();
  376. }
  377.  
  378. void keys_key(int k)
  379. { if(k>31 && k<127) keys_add(k);
  380.   else keyop(k);
  381. }
  382.