/[qemacs]/qemacs/shell.c
ViewVC logotype

Diff of /qemacs/shell.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.11 by chqrlie, Mon May 9 06:03:07 2005 UTC revision 1.12 by chqrlie, Mon May 9 06:21:49 2005 UTC
# Line 53  typedef struct ShellState { Line 53  typedef struct ShellState {
53      int color, def_color;      int color, def_color;
54      int cur_offset; /* current offset at position x, y */      int cur_offset; /* current offset at position x, y */
55      int esc_params[MAX_ESC_PARAMS];      int esc_params[MAX_ESC_PARAMS];
56        int has_params[MAX_ESC_PARAMS];
57      int nb_esc_params;      int nb_esc_params;
58      int state;      int state;
59      int esc1;      int esc1;
# Line 61  typedef struct ShellState { Line 62  typedef struct ShellState {
62      EditBuffer *b_color; /* color buffer, one byte per char */      EditBuffer *b_color; /* color buffer, one byte per char */
63      int is_shell; /* only used to display final message */      int is_shell; /* only used to display final message */
64      struct QEmacsState *qe_state;      struct QEmacsState *qe_state;
65        const char *ka1, *ka3, *kb2, *kc1, *kc3, *kcbt, *kspd;
66        const char *kbeg, *kbs, *kent, *kdch1, *kich1;
67        const char *kcub1, *kcud1, *kcuf1, *kcuu1;
68        const char *kf1, *kf2, *kf3, *kf4, *kf5;
69        const char *kf6, *kf7, *kf8, *kf9, *kf10;
70        const char *kf11, *kf12, *kf13, *kf14, *kf15;
71        const char *kf16, *kf17, *kf18, *kf19, *kf20;
72        const char *khome, *kend, *kmous, *knp, *kpp;
73    
74  } ShellState;  } ShellState;
75    
76  static int shell_get_colorized_line(EditState *e, unsigned int *buf, int buf_size,  static int shell_get_colorized_line(EditState *e,
77                                        unsigned int *buf, int buf_size,
78                                      int offset, int line_num);                                      int offset, int line_num);
79    
80  /* move to mode */  /* move to mode */
# Line 156  static int run_process(const char *path, Line 167  static int run_process(const char *path,
167    
168  static void tty_init(ShellState *s)  static void tty_init(ShellState *s)
169  {  {
170        char *term;
171    
172      s->state = TTY_STATE_NORM;      s->state = TTY_STATE_NORM;
173      s->cur_offset = 0;      s->cur_offset = 0;
174      s->def_color = TTY_GET_COLOR(7, 0);      s->def_color = TTY_GET_COLOR(7, 0);
175      s->color = s->def_color;      s->color = s->def_color;
176    
177        term = getenv("TERM");
178        /* vt100 terminfo definitions */
179        s->kbs = "\010";
180        s->ka1 = "\033Oq";
181        s->ka3 = "\033Os";
182        s->kb2 = "\033Or";
183        s->kc1 = "\033Op";
184        s->kc3 = "\033On";
185        s->kcub1 = "\033OD";
186        s->kcud1 = "\033OB";
187        s->kcuf1 = "\033OC";
188        s->kcuu1 = "\033OA";
189        s->kent = "\033OM";
190        s->kf1 = "\033OP";
191        s->kf2 = "\033OQ";
192        s->kf3 = "\033OR";
193        s->kf4 = "\033OS";
194        s->kf5 = "\033Ot";
195        s->kf6 = "\033Ou";
196        s->kf7 = "\033Ov";
197        s->kf8 = "\033Ol";
198        s->kf9 = "\033Ow";
199        s->kf10 = "\033Ox";
200    
201        /* ansi terminfo definitions */
202        if (strstart(term, "ansi", NULL)) {
203            s->kbs = "\010";
204            s->kcbt = "\033[Z";
205            s->kcub1 = "\033[D";
206            s->kcud1 = "\033[B";
207            s->kcuf1 = "\033[C";
208            s->kcuu1 = "\033[A";
209            s->khome = "\033[H";
210            s->kich1 = "\033[L";
211        }
212        if (strstart(term, "vt220", NULL)) {
213            s->kcub1 = "\033[D";
214            s->kcud1 = "\033[B";
215            s->kcuf1 = "\033[C";
216            s->kcuu1 = "\033[A";
217            s->kdch1 = "\033[3~";
218            s->kend = "\033[4~";
219            s->khome = "\033[1~";
220            s->kich1 = "\033[2~";
221            s->knp = "\033[6~";
222            s->kpp = "\033[5~";
223            s->kf1 = "\033OP";
224            s->kf2 = "\033OQ";
225            s->kf3 = "\033OR";
226            s->kf4 = "\033OS";
227            s->kf5 = "\033[17~";
228            s->kf6 = "\033[18~";
229            s->kf7 = "\033[19~";
230            s->kf8 = "\033[20~";
231            s->kf9 = "\033[21~";
232            s->kf10 = "\033[29~";
233        }
234        if (strstart(term, "cygwin", NULL)) {
235            s->kbs = "\10";
236            goto linux_cygwin;
237        }
238        if (strstart(term, "linux", NULL)) {
239            s->kbs = "\177";
240            s->kb2 = "\033[G";
241            s->kcbt = "\033[Z";
242            s->kspd = "\032";       // ^Z
243        linux_cygwin:
244            s->kcub1 = "\033[D";
245            s->kcud1 = "\033[B";
246            s->kcuf1 = "\033[C";
247            s->kcuu1 = "\033[A";
248            s->kdch1 = "\033[3~";
249            s->kend = "\033[4~";
250            s->khome = "\033[1~";
251            s->kich1 = "\033[2~";
252            s->knp = "\033[6~";
253            s->kpp = "\033[5~";
254            s->kf1 = "\033[[A";
255            s->kf2 = "\033[[B";
256            s->kf3 = "\033[[C";
257            s->kf4 = "\033[[D";
258            s->kf5 = "\033[[E";
259            s->kf6 = "\033[17~";
260            s->kf7 = "\033[18~";
261            s->kf8 = "\033[19~";
262            s->kf9 = "\033[20~";
263            s->kf10 = "\033[21~";
264            s->kf11 = "\033[23~";
265            s->kf12 = "\033[24~";
266            s->kf13 = "\033[25~";
267            s->kf14 = "\033[26~";
268            s->kf15 = "\033[28~";
269            s->kf16 = "\033[29~";
270            s->kf17 = "\033[31~";
271            s->kf18 = "\033[32~";
272            s->kf19 = "\033[33~";
273            s->kf20 = "\033[34~";
274        }
275        if (strstart(term, "xterm", NULL)) {
276            s->ka1 = "\033Ow";
277            s->ka3 = "\033Ou";
278            s->kb2 = "\033Oy";
279            s->kbeg = "\033OE";
280            s->kbs = "\03377";
281            s->kc1 = "\033Oq";
282            s->kc3 = "\033Os";
283            s->kcub1 = "\033OD";
284            s->kcud1 = "\033OB";
285            s->kcuf1 = "\033OC";
286            s->kcuu1 = "\033OA";
287            s->kdch1 = "\033[3~";
288            s->kend = "\033[4~";
289            s->kent = "\033OM";
290            s->khome = "\033[1~";
291            s->kich1 = "\033[2~";
292            s->kmous = "\033[M";
293            s->knp = "\033[6~";
294            s->kpp = "\033[5~";
295            s->kf1 = "\033OP";
296            s->kf2 = "\033OQ";
297            s->kf3 = "\033OR";
298            s->kf4 = "\033OS";
299            s->kf5 = "\033[15~";
300            s->kf6 = "\033[17~";
301            s->kf7 = "\033[18~";
302            s->kf8 = "\033[19~";
303            s->kf9 = "\033[20~";
304            s->kf10 = "\033[21~";
305            s->kf11 = "\033[23~";
306            s->kf12 = "\033[24~";
307            s->kf13 = "\033[25~";
308            s->kf14 = "\033[26~";
309            s->kf15 = "\033[28~";
310            s->kf16 = "\033[29~";
311            s->kf17 = "\033[31~";
312            s->kf18 = "\033[32~";
313            s->kf19 = "\033[33~";
314            s->kf20 = "\033[34~";
315        }
316  }  }
317    
318  static void tty_write(ShellState *s, const unsigned char *buf, int len)  static void tty_write(ShellState *s, const unsigned char *buf, int len)
# Line 182  static void tty_write(ShellState *s, con Line 335  static void tty_write(ShellState *s, con
335  /* compute offset the char at 'x' and 'y'. Can insert spaces or lines  /* compute offset the char at 'x' and 'y'. Can insert spaces or lines
336     if needed */     if needed */
337  /* XXX: optimize !!!!! */  /* XXX: optimize !!!!! */
338  static void tty_gotoxy(ShellState *s, int x, int y)  static void tty_gotoxy(ShellState *s, int x, int y, int relative)
339  {  {
340      int total_lines, line_num, col_num, offset, offset1, c;      int total_lines, cur_line, line_num, col_num, offset, offset1, c;
341      unsigned char buf1[10];      unsigned char buf1[10];
342    
343      /* compute offset */      /* compute offset */
# Line 192  static void tty_gotoxy(ShellState *s, in Line 345  static void tty_gotoxy(ShellState *s, in
345      line_num = total_lines - TTY_YSIZE;      line_num = total_lines - TTY_YSIZE;
346      if (line_num < 0)      if (line_num < 0)
347          line_num = 0;          line_num = 0;
348    
349        if (relative) {
350            eb_get_pos(s->b, &cur_line, &col_num, s->cur_offset);
351            cur_line -= line_num;
352            if (cur_line < 0)
353                cur_line = 0;
354            x += col_num;
355            y += line_num;
356        }
357        if (y < 0)
358            y = 0;
359        else if (y >= TTY_YSIZE)
360            y = TTY_YSIZE - 1;
361        if (x < 0)
362            x = 0;
363    
364      line_num += y;      line_num += y;
365      /* add lines if necessary */      /* add lines if necessary */
366      while (line_num >= total_lines) {      while (line_num >= total_lines) {
# Line 266  static void tty_emulate(ShellState *s, i Line 435  static void tty_emulate(ShellState *s, i
435      int i, offset, offset1, offset2, n;      int i, offset, offset1, offset2, n;
436      unsigned char buf1[10];      unsigned char buf1[10];
437            
438    #define ESC2(c1,c2)  (((c1)<<8)|((unsigned char)c2))
439      switch (s->state) {      switch (s->state) {
440      case TTY_STATE_NORM:      case TTY_STATE_NORM:
441          switch(c) {          switch(c) {
# Line 342  static void tty_emulate(ShellState *s, i Line 512  static void tty_emulate(ShellState *s, i
512          break;          break;
513      case TTY_STATE_ESC:      case TTY_STATE_ESC:
514          if (c == '[') {          if (c == '[') {
515              for (i = 0; i < MAX_ESC_PARAMS; i++)              for (i = 0; i < MAX_ESC_PARAMS; i++) {
516                  s->esc_params[i] = 0;                  s->esc_params[i] = 0;
517                    s->has_params[i] = 0;
518                }
519              s->nb_esc_params = 0;              s->nb_esc_params = 0;
520                s->esc1 = 0;
521              s->state = TTY_STATE_CSI;              s->state = TTY_STATE_CSI;
522          } else {          } else {
523              /* CG: should deal with other sequences:              /* CG: should deal with other sequences:
# Line 383  static void tty_emulate(ShellState *s, i Line 556  static void tty_emulate(ShellState *s, i
556          break;          break;
557      case TTY_STATE_ESC2:      case TTY_STATE_ESC2:
558          s->state = TTY_STATE_NORM;          s->state = TTY_STATE_NORM;
 #define ESC2(c1,c2)  (((c1)<<8)|((unsigned char)c2))  
559          switch (ESC2(s->esc1, c)) {          switch (ESC2(s->esc1, c)) {
560          case ESC2('(','B'):          case ESC2('(','B'):
561          case ESC2(')','B'):          case ESC2(')','B'):
# Line 395  static void tty_emulate(ShellState *s, i Line 567  static void tty_emulate(ShellState *s, i
567              /* XXX: ??? */              /* XXX: ??? */
568              break;              break;
569          }          }
 #undef ESC2  
570          break;          break;
571      case TTY_STATE_CSI:      case TTY_STATE_CSI:
572            if (c == '?') {
573                s->esc1 = c;
574                break;
575            }
576          if (c >= '0' && c <= '9') {          if (c >= '0' && c <= '9') {
577              if (s->nb_esc_params < MAX_ESC_PARAMS) {              if (s->nb_esc_params < MAX_ESC_PARAMS) {
578                  s->esc_params[s->nb_esc_params] =                  s->esc_params[s->nb_esc_params] =
579                      s->esc_params[s->nb_esc_params] * 10 + c - '0';                      s->esc_params[s->nb_esc_params] * 10 + c - '0';
580                    s->has_params[s->nb_esc_params] = 1;
581              }              }
582          } else {          } else {
583              s->nb_esc_params++;              s->nb_esc_params++;
584              if (c == ';')              if (c == ';')
585                  break;                  break;
586              s->state = TTY_STATE_NORM;              s->state = TTY_STATE_NORM;
587              switch(c) {              switch (ESC2(s->esc1,c)) {
588                case ESC2('?','h'): /* set terminal mode */
589                    /* 1047, 1048 -> cup mode:
590                     * should grab all keys while active!
591                     */
592                case ESC2('?','l'): /* reset terminal mode */
593                    break;
594                case 'A':
595                    /* move relative up */
596                    tty_gotoxy(s, 0, -(s->esc_params[0] + 1 - s->has_params[0]), 1);
597                    break;
598                case 'B':
599                    /* move relative down */
600                    tty_gotoxy(s, 0, (s->esc_params[0] + 1 - s->has_params[0]), 1);
601                    break;
602                case 'C':
603                    /* move relative forward */
604                    tty_gotoxy(s, -(s->esc_params[0] + 1 - s->has_params[0]), 0, 1);
605                    break;
606                case 'D':
607                    /* move relative backward */
608                    tty_gotoxy(s, (s->esc_params[0] + 1 - s->has_params[0]), 0, 1);
609                    break;
610              case 'H':              case 'H':
611                  /* goto xy */                  /* goto xy */
612                  {                  tty_gotoxy(s, s->esc_params[1] - s->has_params[1],
613                      int x, y;                             s->esc_params[0] - s->has_params[0], 0);
                     y = s->esc_params[0] - 1;  
                     x = s->esc_params[1] - 1;  
                     if (y < 0)  
                         y = 0;  
                     else if (y >= TTY_YSIZE)  
                         y = TTY_YSIZE - 1;  
                     if (x < 0)  
                         x = 0;  
                     tty_gotoxy(s, x, y);  
                 }  
614                  break;                  break;
615              case 'K':              case 'J':   /* clear to end of screen */
616                  /* clear to eol */              case 'L':   /* insert lines */
617                case 'M':   /* delete lines */
618                case 'S':   /* scroll forward P lines */
619                case 'T':   /* scroll back P lines */
620                case 'X':   /* erase P characters */
621                    break;
622                case 'K':   /* clear eol (parm=1 -> bol) */
623                  offset1 = s->cur_offset;                  offset1 = s->cur_offset;
624                  for(;;) {                  for(;;) {
625                      c = eb_nextc(s->b, offset1, &offset2);                      c = eb_nextc(s->b, offset1, &offset2);
# Line 470  static void tty_emulate(ShellState *s, i Line 664  static void tty_emulate(ShellState *s, i
664              case 'n':              case 'n':
665                  if (s->esc_params[0] == 6) {                  if (s->esc_params[0] == 6) {
666                      /* XXX: send cursor position, just to be able to                      /* XXX: send cursor position, just to be able to
667                         launch qemacs in qemacs ! */                         launch qemacs in qemacs (in 8859-1) ! */
668                      char buf2[20];                      char buf2[20];
669                      snprintf(buf2, sizeof(buf2), "\033[%d;%dR", 1, 1);                      snprintf(buf2, sizeof(buf2), "\033[%d;%dR", 1, 1);
670                      tty_write(s, buf2, -1);                      tty_write(s, buf2, -1);
# Line 482  static void tty_emulate(ShellState *s, i Line 676  static void tty_emulate(ShellState *s, i
676          }          }
677          break;          break;
678      }      }
679    #undef ESC2
680      tty_update_cursor(s);      tty_update_cursor(s);
681  }  }
682    
# Line 572  static void shell_read_cb(void *opaque) Line 767  static void shell_read_cb(void *opaque)
767      if (len <= 0)      if (len <= 0)
768          return;          return;
769            
770        if (trace_buffer)
771            eb_write(trace_buffer, trace_buffer->total_size, buf, len);
772    
773      for (i = 0; i < len; i++)      for (i = 0; i < len; i++)
774          tty_emulate(s, buf[i]);          tty_emulate(s, buf[i]);
775    
# Line 662  EditBuffer *new_shell_buffer(const char Line 860  EditBuffer *new_shell_buffer(const char
860      if (!b)      if (!b)
861          return NULL;          return NULL;
862      set_buffer_name(b, name); /* ensure that the name is unique */      set_buffer_name(b, name); /* ensure that the name is unique */
863        eb_set_charset(b, &charset_vt100);
864    
865      s = malloc(sizeof(ShellState));      s = malloc(sizeof(ShellState));
866      if (!s) {      if (!s) {
# Line 705  EditBuffer *new_shell_buffer(const char Line 904  EditBuffer *new_shell_buffer(const char
904      return b;      return b;
905  }  }
906    
907  static void do_shell(EditState *e)  static void do_shell(EditState *s, int force)
908  {  {
909        QEmacsState *qs = s->qe_state;
910        EditState *e;
911      EditBuffer *b;      EditBuffer *b;
912      const char *argv[3];      const char *argv[3];
913      const char *shell_path;      const char *shell_path;
914    
915        /* CG: Should prompt for buffer name if arg:
916         * find a syntax for optional string argument w/ prompt
917         */
918        /* find shell buffer if any */
919        if (!force || force == NO_ARG) {
920            b = eb_find("*shell*");
921            if (b) {
922                e = edit_find(b);
923                if (e)
924                    qs->active_window = e;
925                else
926                    switch_to_buffer(s, b);
927                return;
928            }
929        }
930    
931      /* find shell name */      /* find shell name */
932      shell_path = getenv("SHELL");      shell_path = getenv("SHELL");
933      if (!shell_path)      if (!shell_path)
# Line 723  static void do_shell(EditState *e) Line 940  static void do_shell(EditState *e)
940      if (!b)      if (!b)
941          return;          return;
942            
943      switch_to_buffer(e, b);      switch_to_buffer(s, b);
944      do_set_mode(e, &shell_mode, NULL);      do_set_mode(s, &shell_mode, NULL);
945    
946      put_status(e, "Press C-o to toggle between shell/edit mode");      put_status(s, "Press C-o to toggle between shell/edit mode");
947      shell_launched = 1;      shell_launched = 1;
948  }  }
949    
# Line 734  void shell_move_left_right(EditState *e, Line 951  void shell_move_left_right(EditState *e,
951  {  {
952      if (e->interactive) {      if (e->interactive) {
953          ShellState *s = e->b->priv_data;          ShellState *s = e->b->priv_data;
954          tty_write(s, dir > 0 ? "\033[C" : "\033[D", -1);          tty_write(s, dir > 0 ? s->kcuf1 : s->kcub1, -1);
955      } else {      } else {
956          text_move_left_right_visual(e, dir);          text_move_left_right_visual(e, dir);
957      }      }
# Line 754  void shell_move_up_down(EditState *e, in Line 971  void shell_move_up_down(EditState *e, in
971  {  {
972      if (e->interactive) {      if (e->interactive) {
973          ShellState *s = e->b->priv_data;          ShellState *s = e->b->priv_data;
974          tty_write(s, dir > 0 ? "\033[B" : "\033[A", -1);          tty_write(s, dir > 0 ? s->kcud1 : s->kcuu1, -1);
975      } else {      } else {
976          text_move_up_down(e, dir);          text_move_up_down(e, dir);
977      }      }
# Line 969  static void do_compile_error(EditState * Line 1186  static void do_compile_error(EditState *
1186    
1187  /* specific shell commands */  /* specific shell commands */
1188  static CmdDef shell_commands[] = {  static CmdDef shell_commands[] = {
     CMD0( KEY_NONE, KEY_NONE, "shell", do_shell)  
1189      CMD0( KEY_CTRL('o'), KEY_NONE, "shell-toggle-input", do_shell_toggle_input)      CMD0( KEY_CTRL('o'), KEY_NONE, "shell-toggle-input", do_shell_toggle_input)
1190      CMD1( '\r', KEY_NONE, "shell-return", shell_write_char, '\r')      CMD1( '\r', KEY_NONE, "shell-return", shell_write_char, '\r')
1191        /* CG: should send s->kbs */
1192      CMD1( 127, KEY_NONE, "shell-backward-delete-char", shell_write_char, 127)      CMD1( 127, KEY_NONE, "shell-backward-delete-char", shell_write_char, 127)
1193      CMD1( KEY_CTRL('d'), KEY_DELETE, "shell-delete-char", shell_write_char, 4)      CMD1( KEY_CTRL('d'), KEY_DELETE, "shell-delete-char", shell_write_char, 4)
1194      CMD1( KEY_CTRL('i'), KEY_NONE, "shell-tabulate", shell_write_char, 9)      CMD1( KEY_CTRL('i'), KEY_NONE, "shell-tabulate", shell_write_char, 9)
# Line 981  static CmdDef shell_commands[] = { Line 1198  static CmdDef shell_commands[] = {
1198    
1199  /* compilation commands */  /* compilation commands */
1200  static CmdDef compile_commands[] = {  static CmdDef compile_commands[] = {
1201        CMD_( KEY_CTRLXRET('\r'), KEY_NONE, "shell", do_shell, "i")
1202      CMD_( KEY_CTRLX(KEY_CTRL('e')), KEY_NONE, "compile", do_compile,      CMD_( KEY_CTRLX(KEY_CTRL('e')), KEY_NONE, "compile", do_compile,
1203            "s{Compile command: }|compile|")            "s{Compile command: }|compile|")
1204      CMD1( KEY_CTRLX(KEY_CTRL('p')), KEY_NONE, "previous-error",      CMD1( KEY_CTRLX(KEY_CTRL('p')), KEY_NONE, "previous-error",

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.12

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26