home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / keymap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  21.8 KB  |  792 lines

  1. /*
  2.  *  Copyright (c) 1992, 1994 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <setjmp.h>
  8.  
  9. #include "config.h"
  10. #include "buffer.h"
  11. #include "cmds.h"
  12. #include "paste.h"
  13. #include "screen.h"
  14. #include "window.h"
  15. #include "text.h"
  16. #include "ledit.h"
  17. #include "keymap.h"
  18. #include "sysdep.h"
  19. #include "misc.h"
  20. #include "display.h"
  21. #include "file.h"
  22. #include "slang.h"
  23. #include "undo.h"
  24. #include "ins.h"
  25. #include "hooks.h"
  26.  
  27. void (*X_Define_Keys_Hook)(SLKeyMap_List_Type *);
  28.  
  29. typedef struct
  30. {
  31.    jmp_buf b;
  32. } jmp_buf_struct;
  33.  
  34. jmp_buf_struct Jump_Buffer, *Jump_Buffer_Ptr;
  35.  
  36. VOID *Last_Key_Function;
  37. int *Repeat_Factor;                    /* repeats a key sequence if non null */
  38.  
  39.  
  40. char *Read_This_Character = NULL;      /* alternate keyboard buffer */
  41.  
  42. char Jed_Key_Buffer[13];
  43. char Key_Buffer[13];
  44. char *Key_Bufferp = Key_Buffer;
  45. static int Last_Key_Buffer_Len;
  46.  
  47. #ifdef HAS_MOUSE
  48. JMouse_Type JMouse;
  49. #endif
  50.  
  51. int beep (void)
  52. {
  53.    tt_beep ();
  54.    flush_output ();
  55.    return 1;
  56. }
  57.  
  58. SLKeymap_Function_Type Jed_Functions[] =
  59.   {
  60.       {"backward_delete_char", backward_delete_char_cmd},
  61.       {"backward_delete_char_untabify", backward_delete_char_untabify},
  62.       {"beep", beep},
  63.       {"begin_macro", begin_keyboard_macro},
  64.       {"beg_of_buffer", bob},
  65.       {"beg_of_line", bol},
  66.       {"brace_bra_cmd", brace_bra_cmd},
  67.       {"brace_ket_cmd", brace_ket_cmd},
  68.       {"center_line", center_line},
  69.       {"copy_region", copy_to_pastebuffer},
  70. #if defined(msdos) || defined(__GO32__)
  71.       {"coreleft", show_memory},
  72. #endif
  73.       {"delete_char_cmd", delete_char_cmd},
  74.       {"delete_window", delete_window},
  75.       {"digit_arg", digit_arg},
  76. /*      {"double_line", double_line}, */
  77.       {"end_macro", end_keyboard_macro},
  78.       {"enlarge_window", enlarge_window},
  79.       {"end_of_buffer", eob},
  80.       {"eol_cmd", eol_cmd},
  81.       {"evaluate_cmd", evaluate_cmd},
  82.       {"execute_macro", execute_keyboard_macro},
  83.       {"exchange",exchange_point_mark},
  84.       {"exit_jed", exit_jed},
  85.       {"exit_mini", exit_minibuffer},
  86.       {"find_file", find_file},
  87.       {"format_paragraph", text_format_paragraph},
  88.       {"goto_match", goto_match},
  89.       {"indent_line", indent_line},
  90.       {"insert_file", insert_file_cmd},
  91.       {"kbd_quit", kbd_quit},
  92.       {"kill_buffer", kill_buffer},
  93.       {"kill_line", kill_line},
  94.       {"kill_region", kill_region},
  95.       {"macro_query", macro_query},
  96.       {"mark_spot", mark_spot},
  97.       {"mini_complete", mini_complete},
  98.       {"narrow", narrow_to_region},
  99.       {"narrow_paragraph", narrow_paragraph},
  100.       {"newline", newline},
  101.       {"newline_and_indent", newline_and_indent},
  102.       {"next_char_cmd", next_char_cmd},
  103.       {"next_line_cmd", next_line_cmd},
  104.       {"one_window", one_window},
  105.       {"other_window", other_window},
  106.       {"page_down", pagedown_cmd},
  107.       {"page_up", pageup_cmd},
  108.       {"pop_spot", pop_spot},
  109.       {"previous_char_cmd", previous_char_cmd},
  110.       {"previous_line_cmd", previous_line_cmd},
  111.       {"quoted_insert", quoted_insert},
  112.       {"redraw", redraw},
  113.       /* {"replace", replace}, */
  114.       {"save_buffers", save_some_buffers},
  115.       {"scroll_left", scroll_left},
  116.       {"scroll_right", scroll_right},
  117.        /* {"search_backward", search_backward_cmd},
  118.       {"search_forward", search_forward_cmd}, */
  119.       {"self_insert_cmd", ins_char_cmd},
  120.       {"set_mark_cmd", set_mark_cmd},
  121.       {"split_window", split_window},
  122.       {"switch_to_buffer", get_buffer},
  123.       {"sys_spawn_cmd", sys_spawn_cmd},
  124.       {"text_smart_quote", text_smart_quote},
  125. /*       {"transpose_lines", transpose_lines}, */
  126.       {"trim_whitespace", trim_whitespace},
  127.      {"undo", undo},
  128.       {"widen", widen},
  129.       {"write_buffer", write_buffer},
  130.       {"yank", yank},
  131.       {(char *) NULL, NULL}
  132.    };
  133.  
  134. SLKeyMap_List_Type *Global_Map;
  135. SLKeyMap_List_Type *Mini_Map;
  136.  
  137. int kbd_quit(void)
  138. {
  139.    int sle = SLang_Error;
  140.    SLKeyBoard_Quit = 1;
  141.    
  142.    /* --- never serious, testing only
  143.    if (Repeat_Factor != NULL) 
  144.      {
  145.     msg_error("Bang!");
  146.     longjmp(Jump_Buffer_Ptr->b, 1);
  147.      } */
  148.    
  149.    msg_error("Quit!");
  150.    if (Ignore_User_Abort) SLang_Error = sle;
  151.    return(1);
  152. }
  153.  
  154. void init_keymaps(void)
  155. {
  156.    int ch;
  157.    char simple[2];
  158.    simple[1] = 0;
  159.    
  160.    if (NULL == (Global_Map = SLang_create_keymap ("global", NULL)))
  161.      exit_error ("Malloc error creating keymap.", 0);
  162.    
  163.    Global_Map->functions = Jed_Functions;
  164.    
  165.    for (ch = ' '; ch < 256; ch++)
  166.      {
  167.     simple[0] = (char) ch;
  168.     SLang_define_key1(simple, (VOID *) ins_char_cmd, SLKEY_F_INTRINSIC, Global_Map);
  169.      }
  170.    
  171.  
  172.     SLang_define_key1("^[1", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  173.     SLang_define_key1("^[2", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  174.     SLang_define_key1("^[3", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  175.     SLang_define_key1("^[4", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  176.     SLang_define_key1("^[5", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  177.     SLang_define_key1("^[6", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  178.     SLang_define_key1("^[7", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  179.     SLang_define_key1("^[8", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  180.     SLang_define_key1("^[9", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  181.     SLang_define_key1("^[0", (VOID *) digit_arg, SLKEY_F_INTRINSIC, Global_Map);
  182.  
  183. #ifndef pc_system
  184.    /* give vtxxx arrow keys */
  185.     SLang_define_key1("^[[D", (VOID *) previous_char_cmd,SLKEY_F_INTRINSIC, Global_Map);
  186.     SLang_define_key1("^[OD", (VOID *) previous_char_cmd,SLKEY_F_INTRINSIC, Global_Map);
  187.     SLang_define_key1("^[[A", (VOID *) previous_line_cmd, SLKEY_F_INTRINSIC, Global_Map);
  188.     SLang_define_key1("^[OA", (VOID *) previous_line_cmd, SLKEY_F_INTRINSIC, Global_Map);
  189.     SLang_define_key1("^[[B", (VOID *) next_line_cmd, SLKEY_F_INTRINSIC, Global_Map);
  190.     SLang_define_key1("^[OB", (VOID *) next_line_cmd, SLKEY_F_INTRINSIC, Global_Map);
  191.     SLang_define_key1("^[[C", (VOID *) next_char_cmd, SLKEY_F_INTRINSIC, Global_Map);
  192.     SLang_define_key1("^[OC", (VOID *) next_char_cmd, SLKEY_F_INTRINSIC, Global_Map);
  193.     SLang_define_key1("^[[6~", (VOID *) pagedown_cmd, SLKEY_F_INTRINSIC, Global_Map);
  194.     SLang_define_key1("^[[5~", (VOID *) pageup_cmd, SLKEY_F_INTRINSIC, Global_Map);
  195.     SLang_define_key1("^K^[[C", (VOID *) scroll_left, SLKEY_F_INTRINSIC, Global_Map);
  196.     SLang_define_key1("^K^[[D", (VOID *) scroll_right, SLKEY_F_INTRINSIC, Global_Map);
  197.     SLang_define_key1("^K^[[A", (VOID *) bob, SLKEY_F_INTRINSIC, Global_Map);
  198.     SLang_define_key1("^K^[[B", (VOID *)eob, SLKEY_F_INTRINSIC, Global_Map);
  199. #else
  200. #include "doskeys.c"
  201. #endif
  202.  
  203.     SLang_define_key1("'", (VOID *) text_smart_quote, SLKEY_F_INTRINSIC, Global_Map);
  204.     SLang_define_key1("\"", (VOID *) text_smart_quote, SLKEY_F_INTRINSIC, Global_Map);
  205.     SLang_define_key1("^_", (VOID *) undo, SLKEY_F_INTRINSIC, Global_Map);
  206.     SLang_define_key1("^?", (VOID *) backward_delete_char_untabify, SLKEY_F_INTRINSIC, Global_Map);
  207.     SLang_define_key1("^B", (VOID *) bol, SLKEY_F_INTRINSIC, Global_Map);
  208.     SLang_define_key1("^D", (VOID *) pagedown_cmd, SLKEY_F_INTRINSIC, Global_Map);
  209.     SLang_define_key1("^E", (VOID *) eol_cmd, SLKEY_F_INTRINSIC, Global_Map);
  210. /*
  211.     SLang_define_key1("^FB", (VOID *) search_backward_cmd, SLKEY_F_INTRINSIC, Global_Map);
  212.     SLang_define_key1("^FF", (VOID *) search_forward_cmd, SLKEY_F_INTRINSIC, Global_Map);
  213. */
  214.     SLang_define_key1("^G", (VOID *) kbd_quit, SLKEY_F_INTRINSIC, Global_Map);
  215.     SLang_define_key1("^I", (VOID *) indent_line, SLKEY_F_INTRINSIC, Global_Map);
  216.     SLang_define_key1("^K(", (VOID *) begin_keyboard_macro, SLKEY_F_INTRINSIC, Global_Map);
  217.     SLang_define_key1("^K)", (VOID *) end_keyboard_macro, SLKEY_F_INTRINSIC, Global_Map);
  218.     SLang_define_key1("^KD", (VOID *) evaluate_cmd, SLKEY_F_INTRINSIC, Global_Map);
  219.     SLang_define_key1("^KE", (VOID *) exit_jed, SLKEY_F_INTRINSIC, Global_Map);
  220.     SLang_define_key1("^KG", (VOID *) find_file, SLKEY_F_INTRINSIC, Global_Map);
  221.     SLang_define_key1("^KK", (VOID *) copy_to_pastebuffer, SLKEY_F_INTRINSIC, Global_Map);
  222.     SLang_define_key1("^KM", (VOID *) mark_spot, SLKEY_F_INTRINSIC, Global_Map);
  223.     SLang_define_key1("^KX", (VOID *) execute_keyboard_macro, SLKEY_F_INTRINSIC, Global_Map);
  224.     SLang_define_key1("^K^B", (VOID *) set_mark_cmd, SLKEY_F_INTRINSIC, Global_Map);
  225.     SLang_define_key1("^K^I", (VOID *) insert_file_cmd, SLKEY_F_INTRINSIC, Global_Map);
  226. /*     SLang_define_key1("^K^L", (VOID *) double_line, SLKEY_F_INTRINSIC, Global_Map); */
  227.     SLang_define_key1("^K^M", (VOID *) pop_spot, SLKEY_F_INTRINSIC, Global_Map);
  228.     SLang_define_key1("^K^P", (VOID *) yank, SLKEY_F_INTRINSIC, Global_Map);
  229. /*     SLang_define_key1("^K^R", (VOID *) replace, SLKEY_F_INTRINSIC, Global_Map); */
  230.     SLang_define_key1("^K^V", (VOID *) kill_region, SLKEY_F_INTRINSIC, Global_Map);
  231.     SLang_define_key1("^K^W", (VOID *) write_buffer, SLKEY_F_INTRINSIC, Global_Map);
  232.     SLang_define_key1("^L", (VOID *) kill_line, SLKEY_F_INTRINSIC, Global_Map);
  233.     SLang_define_key1("^M", (VOID *) newline_and_indent, SLKEY_F_INTRINSIC, Global_Map);
  234.     SLang_define_key1("^R", (VOID *) redraw, SLKEY_F_INTRINSIC, Global_Map);
  235.     SLang_define_key1("^U", (VOID *) pageup_cmd, SLKEY_F_INTRINSIC, Global_Map);
  236.     SLang_define_key1("^V", (VOID *) delete_char_cmd, SLKEY_F_INTRINSIC, Global_Map);
  237.     SLang_define_key1("^W0", (VOID *) delete_window, SLKEY_F_INTRINSIC, Global_Map);
  238.     SLang_define_key1("^W1", (VOID *) one_window, SLKEY_F_INTRINSIC, Global_Map);
  239.     SLang_define_key1("^W2", (VOID *) split_window, SLKEY_F_INTRINSIC, Global_Map);
  240.     SLang_define_key1("^WO", (VOID *) other_window, SLKEY_F_INTRINSIC, Global_Map);
  241.     SLang_define_key1("^XB", (VOID *) get_buffer, SLKEY_F_INTRINSIC, Global_Map);
  242.     SLang_define_key1("^XK", (VOID *) kill_buffer, SLKEY_F_INTRINSIC, Global_Map);
  243.     SLang_define_key1("^XN", (VOID *) narrow_to_region, SLKEY_F_INTRINSIC, Global_Map);
  244.     SLang_define_key1("^XQ", (VOID *) macro_query, SLKEY_F_INTRINSIC, Global_Map);
  245.     SLang_define_key1("^XS", (VOID *) save_some_buffers, SLKEY_F_INTRINSIC, Global_Map);
  246.     SLang_define_key1("^XW", (VOID *) widen, SLKEY_F_INTRINSIC, Global_Map);
  247.     SLang_define_key1("^X^", (VOID *) enlarge_window, SLKEY_F_INTRINSIC, Global_Map);
  248. /*     SLang_define_key1("^X^T", (VOID *) transpose_lines, SLKEY_F_INTRINSIC, Global_Map); */
  249.    SLang_define_key1("^X^[", (VOID *) evaluate_cmd, SLKEY_F_INTRINSIC, Global_Map);
  250.     SLang_define_key1("^X^X", (VOID *) exchange_point_mark, SLKEY_F_INTRINSIC, Global_Map);
  251.     SLang_define_key1("^Z", (VOID *) sys_spawn_cmd, SLKEY_F_INTRINSIC, Global_Map);
  252.     SLang_define_key1("^[<", (VOID *) bob, SLKEY_F_INTRINSIC, Global_Map);
  253.     SLang_define_key1("^[>", (VOID *) eob, SLKEY_F_INTRINSIC, Global_Map);
  254.     SLang_define_key1("^[N", (VOID *) narrow_paragraph, SLKEY_F_INTRINSIC, Global_Map);
  255.     SLang_define_key1("^[Q", (VOID *) text_format_paragraph, SLKEY_F_INTRINSIC, Global_Map);
  256.     SLang_define_key1("^[S", (VOID *) center_line, SLKEY_F_INTRINSIC, Global_Map);
  257.     SLang_define_key1("^[X", (VOID *) evaluate_cmd, SLKEY_F_INTRINSIC, Global_Map);
  258.     SLang_define_key1("^[\\", (VOID *) trim_whitespace, SLKEY_F_INTRINSIC, Global_Map);
  259.     SLang_define_key1("^\\", (VOID *) goto_match, SLKEY_F_INTRINSIC, Global_Map);
  260.     SLang_define_key1("`", (VOID *) quoted_insert, SLKEY_F_INTRINSIC, Global_Map);
  261.     SLang_define_key1("{", (VOID *) brace_bra_cmd, SLKEY_F_INTRINSIC, Global_Map);
  262.     SLang_define_key1("}", (VOID *) brace_ket_cmd, SLKEY_F_INTRINSIC, Global_Map);
  263.  
  264.    if (X_Define_Keys_Hook != NULL)  (*X_Define_Keys_Hook)(Global_Map);
  265. }
  266.  
  267. static int key_interpret(SLang_Key_Type *key)
  268. {
  269.    char *rtc_save;
  270.    char *str;
  271.    int ret;
  272.    static int macro_depth;
  273.    
  274.    if (key->type == SLKEY_F_INTRINSIC)
  275.      {
  276.     ret = (int) ((int (*)(void)) key->f)();
  277.      }
  278.    else
  279.      {
  280.     str = (char *) key->f;
  281.     
  282.     if (*str == ' ')
  283.       {
  284.          /* string to insert */
  285.          insert_string(str + 1);
  286.       }
  287.     else if ((*str == '@') && (0 != *(str + 1)))
  288.       {
  289.          if (macro_depth > 10) 
  290.            {
  291.           macro_depth = 0;
  292.           msg_error ("Possible runaway macro aborted.");
  293.           return 1;
  294.            }
  295.          macro_depth++;
  296.          rtc_save = Read_This_Character;
  297.          Read_This_Character = str + 1;
  298.          do
  299.            {
  300.           do_key();
  301.            }
  302.          while (Read_This_Character != NULL);
  303.          Read_This_Character = rtc_save;
  304.          macro_depth--;
  305.       }
  306.     else if ((*str == '.')
  307.          || !SLang_execute_function(str))
  308.       SLang_load_string(str);
  309.  
  310.     ret = 1;
  311.      }
  312.    
  313.    Last_Key_Function = key->f;
  314.    return(ret);
  315. }
  316.  
  317. static void update_jed_keybuffer (void)
  318. {
  319.    Last_Key_Buffer_Len = (int) (Key_Bufferp - Key_Buffer);
  320.    if (Last_Key_Buffer_Len == 1)
  321.      {
  322.     *Jed_Key_Buffer = *Key_Buffer;
  323.     *(Jed_Key_Buffer + 1) = 0;
  324.      }
  325.    else
  326.      {
  327.         *Key_Bufferp = 0;
  328.     strcpy (Jed_Key_Buffer, Key_Buffer);
  329.      }
  330.    
  331.    Key_Bufferp = Key_Buffer;
  332. }
  333.  
  334.    
  335. #define XKEY(key)  key_interpret((key))
  336.  
  337. int do_key (void)
  338. {
  339.    SLang_Key_Type *key;
  340.    int repeat;
  341.    
  342.    if (SLang_Key_TimeOut_Flag == 0)
  343.      {
  344.     Key_Bufferp = Key_Buffer;
  345.     *Key_Bufferp = 0;
  346.      }
  347.    
  348.    key = SLang_do_key (CBuf->keymap, jed_getkey);
  349.    update_jed_keybuffer ();
  350.    
  351.    if ((key != NULL) && (key->f != NULL))
  352.      {
  353.     if (Repeat_Factor == NULL) return XKEY(key);
  354.     repeat = *Repeat_Factor;
  355.     Suspend_Screen_Update = 1;
  356.  
  357.     /* some routines may use the repeat factor as a prefix argument */
  358.     while (repeat-- > 0)
  359.       {
  360.          if (SLKeyBoard_Quit || SLang_Error ||
  361.          (Repeat_Factor == NULL)) break;
  362.      /* (!Executing_Keyboard_Macro && (Repeat_Factor == NULL))) break; */
  363.          XKEY(key);
  364.       }
  365.     Repeat_Factor = NULL;
  366.  
  367.     return(1);
  368.      }
  369.    else if (!Executing_Keyboard_Macro && !SLKeyBoard_Quit)
  370.      {
  371.     beep ();
  372.     flush_input();
  373.      }
  374.    if (SLKeyBoard_Quit) kbd_quit();
  375.    return(0);
  376. }
  377.  
  378. void do_jed(void)
  379. {
  380.    char *name;
  381.    Buffer *tthis = CBuf;
  382.    
  383.    /* Mark Undo boundary now because tthis might not be valid later */
  384.    mark_undo_boundary(tthis);
  385.    
  386.    Repeat_Factor = NULL;
  387.    
  388.    if (do_key()) JWindow->trashed = 1;
  389.  
  390.     /* internal editing commands may have selected a different buffer
  391.        so put it back. */
  392.     if (CBuf != JWindow->buffer)
  393.       {
  394.      if (buffer_exists(JWindow->buffer)) name = JWindow->buffer->name; else name = "*scratch*";
  395.      switch_to_buffer_cmd(name);
  396.       }
  397. }
  398.  
  399. void jed(void)
  400. {
  401.    /* This routine is called from main.  So before actually strting, check
  402.       one more hook to just to make sure  all things are go. */
  403.    SLang_run_hooks("jed_startup_hook", NULL, NULL);
  404.  
  405.    Jump_Buffer_Ptr = &Jump_Buffer;
  406.    
  407.    if (setjmp(Jump_Buffer.b) != 0)
  408.      {
  409.     SLang_restart(1);   /* just in case */
  410.      }
  411.  
  412.    if (CBuf != JWindow->buffer)
  413.      {
  414.     switch_to_buffer(JWindow->buffer);
  415.     window_buffer(CBuf);
  416.      }
  417.    JWindow->trashed = 1;
  418.    update((Line *) NULL, 0, 0);
  419.    Read_This_Character = NULL;
  420.    while(1)
  421.      {
  422.     Suspend_Screen_Update = 0;
  423.     do_jed();
  424.     if (!SLKeyBoard_Quit && (CBuf->flags & BUFFER_TRASHED)
  425.         && (!Cursor_Motion)) CBuf->hits += 1;
  426.     if (CBuf->hits > User_Vars.max_hits)
  427.       {
  428.          auto_save_buffer(CBuf);
  429.          check_buffers();   /* check files on disk to see if they are recent */
  430.       }
  431.     
  432.     if ((Last_Key_Function != (VOID *) ins_char_cmd)
  433.         || (JWindow->trashed) || (JWindow != JWindow->next)
  434.         || Suspend_Screen_Update ||
  435.         (Mini_Ghost) || (*Message_Buffer) || (*Error_Buffer))
  436.       {
  437.          update((Line *) NULL, 0, 0);
  438.       }
  439.      }
  440. }
  441.  
  442. int digit_arg(void)
  443. {
  444.    static int repeat;
  445.    char buf[20];
  446.    int key;
  447.    int i;
  448.    
  449.    i = 0;
  450.    buf[i++] = (char) SLang_Last_Key_Char;
  451.    
  452.    /* After do_key (what called this), Key_Bufferp is reset.  However, I want 
  453.     * to keep it for echoing subsequent characters.  I restore its previous 
  454.     * value so that echoing will continue. 
  455.     */
  456.    
  457.    Key_Bufferp = Key_Buffer + Last_Key_Buffer_Len;
  458.  
  459.    SLang_Key_TimeOut_Flag = 1;
  460.    while(1)
  461.      {
  462.     buf[i] = 0;
  463.     key = jed_getkey();
  464.     if ((key < '0') || (key > '9')) break;
  465.     buf[i++] = (char) key;
  466.      }
  467.    repeat = atoi(buf);
  468.    Repeat_Factor = &repeat;
  469.    if (Executing_Keyboard_Macro) Macro_Buffer_Ptr--;
  470.    else 
  471.      {
  472.     ungetkey (&key);
  473.     if (Defining_Keyboard_Macro) Macro_Buffer_Ptr--;
  474.      }
  475.    
  476.    if (Key_Bufferp != Key_Buffer) Key_Bufferp--;
  477.  
  478.    /* Key_Timeout is still active and is only reset after this call. */
  479.    do_key();
  480.    return(1);
  481. }
  482.  
  483. int which_key (char *f)
  484. {
  485.    int num = 0, i;
  486.    SLang_Key_Type *key, *key_root;
  487.    VOID *fp;
  488.    unsigned char type;
  489.    unsigned char buf[5];
  490.    
  491.    if (NULL == (fp = (VOID *) SLang_find_key_function(f, CBuf->keymap)))
  492.      type = SLKEY_F_INTERPRET;
  493.    else type = SLKEY_F_INTRINSIC;
  494.  
  495.    i = 256;
  496.    key_root = CBuf->keymap->keymap;
  497.    while (i--)
  498.      {
  499.     key = key_root->next;
  500.     if ((key == NULL) && (type == key_root->type) &&
  501.         (((type == SLKEY_F_INTERPRET) && (!strcmp((char *) f, (char *) key_root->f)))
  502.         || ((type == SLKEY_F_INTRINSIC) && (fp == key_root->f))))
  503.       {
  504.          *buf = 2;
  505.          *(buf + 1) = 256 - 1 - i;
  506.          SLang_push_string(SLang_make_keystring(buf));
  507.          num++;
  508.       }
  509.     while (key != NULL)
  510.       {
  511.          if ((key->type == type) &&
  512.          (((type == SLKEY_F_INTERPRET) && (!strcmp((char *) f, (char *) key->f)))
  513.          || ((type == SLKEY_F_INTRINSIC) && (fp == key->f))))
  514.            {
  515.           SLang_push_string(SLang_make_keystring(key->str));
  516.           num++;
  517.            }
  518.          key = key->next;
  519.       }
  520.     key_root++;
  521.      }
  522.    return(num);
  523. }
  524.  
  525.  
  526. static char *find_function_string (VOID *f)
  527. {
  528.    SLKeymap_Function_Type *fp;
  529.  
  530.    fp = Jed_Functions;
  531.  
  532.    if (f == (VOID *) ins_char_cmd) return "self_insert_cmd";
  533.    
  534.    while((fp != NULL) && (fp->name != NULL))
  535.      {
  536.     if ((VOID *) fp->f == f) return fp->name;
  537.     fp++;
  538.      }
  539.    return NULL;
  540. }
  541.  
  542.  
  543. static void dump_this_binding (unsigned char *s, VOID *f, int type)
  544. {
  545.    unsigned char ch;
  546.    char *str,  ctrl[2];
  547.    char *fun;
  548.    int n, len;
  549.    
  550.    ctrl[0] = '^';
  551.    len = *s++ - 1;;
  552.    
  553.    while (len-- > 0)
  554.      {
  555.     n = 1;
  556.         ch = *s++;
  557.     if (ch == 127) 
  558.       {
  559.          str = "DEL"; n = 3;
  560.       }
  561.     else if (ch > ' ') str = (char *) &ch;
  562.     else if (ch == 27) 
  563.       {
  564.          str = "ESC";
  565.          n = 3;
  566.       }
  567.     else if (ch == ' ')
  568.       {
  569.          str = "SPACE";
  570.          n = 5;
  571.       }
  572.     else if (ch == '\t')
  573.       {
  574.          str = "TAB"; n = 3;
  575.       }
  576.     else
  577.       {
  578.          str = ctrl;
  579.          *(str + 1) = ch + '@';
  580.          n = 2;
  581.       }
  582.     quick_insert((unsigned char *) str, n);
  583.     ins(' ');
  584.      }
  585.    ins_char_n_times('\t', 3);
  586.    
  587.    if (type == SLKEY_F_INTRINSIC)
  588.      {
  589.        fun = find_function_string (f);
  590.      }
  591.    else fun = (char *) f;
  592.  
  593.    insert_string (fun);
  594.    newline();
  595. }
  596.  
  597. void  dump_bindings(char *map)
  598. {
  599.    int i;
  600.    SLang_Key_Type *next, *key_root;
  601.    SLKeyMap_List_Type *kml;
  602.  
  603.    if (NULL == (kml = SLang_find_keymap(map)))
  604.      {
  605.     msg_error("Keymap undefined.");
  606.     return;
  607.      }
  608.    key_root = kml->keymap;
  609.    
  610.    for (i = 0; i < 256; i++)
  611.      {
  612.     next = key_root->next;
  613.     if (next != NULL)
  614.       {
  615.          while (next != NULL)
  616.            {
  617.           dump_this_binding (next->str, next->f, next->type);
  618.           next = next->next;
  619.            }
  620.       }
  621.     else if (key_root->f != NULL) dump_this_binding (key_root->str, key_root->f, key_root->type);
  622.     key_root++;
  623.      }
  624. }
  625.  
  626. char *find_key(int *ret)
  627. {
  628.    char *fstr = NULL;
  629.    SLang_Key_Type *key;
  630.  
  631.    *ret = 0;
  632.    
  633.    SLang_Key_TimeOut_Flag = 0;
  634.    Key_Bufferp = Key_Buffer;
  635.    key = SLang_do_key (CBuf->keymap, jed_getkey);
  636.    update_jed_keybuffer ();
  637.    
  638.    if (key == NULL) return(NULL);
  639.    if (key->type == SLKEY_F_INTRINSIC)
  640.      {
  641.     *ret = 1;
  642.     fstr = find_function_string (key->f);
  643.      }
  644.    else fstr = (char *) key->f;
  645.  
  646.    return(fstr);
  647. }
  648.  
  649.  
  650. void use_keymap(char *name)
  651. {
  652.    SLKeyMap_List_Type *map;
  653.    if (NULL == (map = SLang_find_keymap(name)))
  654.      {
  655.     msg_error("Unknown keymap.");
  656.      }
  657.    else (CBuf->keymap = map);
  658. }
  659.  
  660. char *what_keymap()
  661. {
  662.    return CBuf->keymap->name;
  663. }
  664.  
  665. void set_abort_char(int *c)
  666. {
  667.    char str[2];
  668.    int i;
  669. #ifdef pc_system
  670.    char ch, *s, *scan = "@#$%^&*()_+?IQWERTYUIOP[]!!ASDFGHJKL!!!!\\ZXCVBNM";
  671.    
  672.    ch = 64 + (char) *c;
  673.    s = scan; while (*s && (*s != ch)) s++;
  674.    if (*s == 0) return;
  675.    Abort_Char = (int) (s - scan) + 0x03;
  676. #else
  677.    Abort_Char = *c;
  678. #endif
  679.    reset_tty();
  680.    init_tty();
  681.    str[0] = *c; str[1] = 0;
  682.     
  683.    for (i = 0; i < SLANG_MAX_KEYMAPS; i++)
  684.      {
  685.     if (SLKeyMap_List[i].keymap == NULL) continue;
  686.     SLang_undefine_key(str, &SLKeyMap_List[i]);
  687.     SLang_define_key1(str, (VOID *) kbd_quit, SLKEY_F_INTRINSIC, &SLKeyMap_List[i]);
  688.      }
  689. }
  690.  
  691.  
  692. static SLKeymap_Function_Type *Flist_Context;
  693. static int Flist_Context_Len;
  694.  
  695. #define MAX_USER_FLIST 100
  696. static char *Slang_Functions[MAX_USER_FLIST];
  697. static char **Slang_Flist_Context;
  698.  
  699.  
  700. int next_function_list(char *buf)
  701. {
  702.    SLKeymap_Function_Type *tthis = Jed_Functions;
  703.    register char *name;
  704.    char **max;
  705.    
  706.    /* Convert '-' to '_' */
  707.    
  708.    name = buf;
  709.    while (*name != 0) 
  710.      {
  711.     if (*name == '-') *name = '_';
  712.     name++;
  713.      }
  714.    
  715.    while (1)
  716.      {
  717.     tthis = Flist_Context;
  718.     name = tthis->name;
  719.     if (name == NULL) break;
  720.     Flist_Context++;
  721.     if (!Flist_Context_Len || !strncmp(buf, name, Flist_Context_Len))
  722.       {
  723.          strcpy(buf, name);
  724.          return(1);
  725.       }
  726.      }
  727.    
  728.    max = Slang_Functions + MAX_USER_FLIST;
  729.    while (Slang_Flist_Context < max)
  730.      {
  731.     name = *Slang_Flist_Context;
  732.     if (name == NULL) return(0);
  733.     name++;  /* skip past hash mark */
  734.     Slang_Flist_Context++;
  735.     if (!Flist_Context_Len || !strncmp(buf, name, Flist_Context_Len))
  736.       {
  737.          strcpy(buf, name);
  738.          return(1);
  739.       }
  740.      }
  741.    return(0);
  742. }
  743.  
  744. int open_function_list(char *buf)
  745. {
  746.    Flist_Context = Jed_Functions;
  747.    Slang_Flist_Context = Slang_Functions;
  748.    Flist_Context_Len = strlen(buf);
  749.    return next_function_list(buf);
  750. }
  751.  
  752. void add_to_completion(char *name)
  753. {
  754.    char **p, *n;
  755.    static char **last = Slang_Functions;
  756.    
  757.    n = SLang_find_name(name);
  758.    if (n == NULL)
  759.      {
  760.     msg_error("Undefined Symbol.");
  761.     return;
  762.      }
  763.    
  764.    p = last;  /* Slang_Functions; */
  765.    
  766.    while (p < Slang_Functions + MAX_USER_FLIST)
  767.      {
  768.     if (*p == NULL) 
  769.       {
  770.          *p = n;
  771.          last = ++p;
  772.          return;
  773.       }
  774.     p++;
  775.      }
  776.    msg_error("Completion Quota Exceeded.");
  777. }
  778.  
  779. int is_internal(char *f)
  780. {
  781.    if (NULL == SLang_find_key_function(f, CBuf->keymap)) return(0);
  782.    return 1;
  783. }
  784.  
  785. void create_keymap (char *name)
  786. {
  787.    if (NULL == SLang_create_keymap (name, Global_Map))
  788.      {
  789.     msg_error ("Unable to create keymap.");
  790.      }
  791. }
  792.