home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  10.7 KB  |  501 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 "screen.h"
  12. #include "window.h"
  13. #include "display.h"
  14. #include "sysdep.h"
  15. #include "file.h"
  16. #include "keymap.h"
  17. #include "ledit.h"
  18. #include "misc.h"
  19. #include "ins.h"
  20. #include "slang.h"
  21. #include "paste.h"
  22.  
  23. char Error_Buffer[256];
  24. char Message_Buffer[256];
  25. volatile int SLKeyBoard_Quit;
  26. int Exit_From_MiniBuffer;
  27.  
  28.  
  29. typedef struct
  30. {
  31.    jmp_buf b;
  32. } jmp_buf_struct;
  33.  
  34. extern jmp_buf_struct Jump_Buffer, *Jump_Buffer_Ptr;
  35.  
  36. #define MACRO_SIZE 256
  37. char Macro_Buffer[MACRO_SIZE];
  38. char *Macro_Buffer_Ptr = Macro_Buffer;
  39. char *Macro_Ptr_Max = Macro_Buffer;
  40. int Defining_Keyboard_Macro = 0;
  41. int Executing_Keyboard_Macro = 0;
  42.  
  43. static struct
  44. {
  45.    int def;
  46.    int exe;
  47. } Macro_State;
  48.  
  49. MiniInfo_Type Mini_Info;
  50.  
  51. void macro_store_key(char ch)
  52. {
  53.    /* I need to put something here to increase the size of the Macro_Buffer
  54.       in case of overflow */
  55.  
  56.    if (Macro_Buffer_Ptr - Macro_Buffer >= MACRO_SIZE) msg_error("Macro Size exceeded.");
  57.    else *Macro_Buffer_Ptr++ = ch;
  58. }
  59.  
  60. void restore_macro_state(void)
  61. {
  62.    Defining_Keyboard_Macro = Macro_State.def;
  63.    Executing_Keyboard_Macro = Macro_State.exe;
  64. }
  65.  
  66. void set_macro_state(void)
  67. {
  68.    Macro_State.def = Defining_Keyboard_Macro;
  69.    Macro_State.exe = Executing_Keyboard_Macro;
  70. }
  71.  
  72. /* if not in the mini buffer and if during keyboard macro, allow user to enter
  73.    different text each time macro is executed */
  74.  
  75. int macro_query()
  76. {
  77.    char *s;
  78.    int n;
  79.    
  80.    /* macro state is already set */
  81.    Defining_Keyboard_Macro = 0;
  82.    Executing_Keyboard_Macro = 0;
  83.  
  84.    if (!IS_MINIBUFFER)
  85.      {
  86.     if (NULL == (s = read_from_minibuffer("Enter String:", (char *) NULL, NULL, &n))) return(0);
  87.     ins_chars((unsigned char *) s, n);
  88.     SLFREE(s);
  89.      }
  90.  
  91.    /* exit from mini restores the state */
  92.    return(1);
  93. }
  94.  
  95. int jed_getkey()
  96. {
  97.    int ch, diff, ch1;
  98.    static int mini_flag = 0;
  99.    int *srf;
  100.    
  101.    if (Read_This_Character != NULL)
  102.      {
  103.     ch = *Read_This_Character++;
  104.     if (ch == 0) Read_This_Character = NULL;
  105.     else
  106.       {
  107.          if ((ch1 = *Read_This_Character) == 0) 
  108.            {
  109.           Read_This_Character = NULL;
  110.           return (ch);
  111.            }
  112.          
  113.          
  114.          if (ch == '^')
  115.            {
  116.           if (ch1 == '?') ch = 127; 
  117.           else ch = ch1 - '@';
  118.           Read_This_Character++;
  119.            }
  120.          else if (ch == '\\') 
  121.            {
  122.           ch = ch1;
  123.           Read_This_Character++;
  124.            }
  125.          if (*Read_This_Character == 0) Read_This_Character = NULL;
  126.          return(ch);
  127.       }
  128.     
  129.      }
  130.    
  131.    if (Executing_Keyboard_Macro)
  132.      {
  133.     if (Macro_Buffer_Ptr < Macro_Ptr_Max) return (*Macro_Buffer_Ptr++);
  134.     Executing_Keyboard_Macro = 0;
  135.     update((Line *) NULL, 0, 0);
  136.      }
  137.  
  138.    diff = (int) (Key_Bufferp - Key_Buffer);
  139.    if (!SLang_Error && SLang_Key_TimeOut_Flag && 
  140.        ((mini_flag && (diff > 0))
  141.     || !input_pending(&Number_Ten)))
  142.      {
  143.     message(Key_Buffer);
  144.     strcat(Message_Buffer, "-");
  145.     
  146.     /* This ensures that the update is performed if we are echoing from 
  147.      * digit argument */
  148.     srf = Repeat_Factor; Repeat_Factor = NULL;
  149.     update((Line *)NULL, 0, 0);
  150.     Repeat_Factor = srf;
  151.     message(" ");           /* ensures that previous message will 
  152.                 get erased. */
  153.     mini_flag = 1;
  154.      }
  155.    else (mini_flag = 0);
  156.    
  157.    ch = my_getkey();
  158.    if (diff < 13) 
  159.      {
  160.     *Key_Bufferp++ = (char) ch;
  161.     *Key_Bufferp = 0;
  162.      }
  163.    else 
  164.      {
  165.     /* msg_error("KeyBuffer overflow!"); */
  166.     Key_Bufferp = Key_Buffer;
  167.      }
  168.    
  169.    
  170.    if (Defining_Keyboard_Macro) 
  171.      {
  172.     /* starting a new keysequence to save this point */
  173.     if (diff == 0)
  174.       {
  175.          Macro_Ptr_Max = Macro_Buffer_Ptr;
  176.       }
  177.     
  178.     macro_store_key(ch);
  179.      }
  180.    return(ch);
  181. }
  182.  
  183.  
  184. void msg_error(char *msg)
  185. {
  186.    flush_input();
  187.    JWindow->trashed = 1;
  188.    Defining_Keyboard_Macro = Executing_Keyboard_Macro = 0;
  189.    Read_This_Character = NULL;
  190.    Repeat_Factor = NULL;
  191.    set_macro_state();
  192.    if (Batch) fprintf(stderr, "%s\n", msg);
  193.  
  194.    if (!SLang_Error) SLang_Error = INTRINSIC_ERROR;
  195.    if (Error_Buffer[0] == 0) strcpy(Error_Buffer, msg);
  196. }
  197.  
  198. /* later I will do more with this-- for now, keep last one */
  199. void message(char *msg)
  200. {
  201.    if (Executing_Keyboard_Macro) return;
  202.    if (Batch || (JScreen[0].old == NULL)) fprintf(stderr, "%s\n", msg);
  203.     
  204.    if (msg == NULL) *Message_Buffer = 0; 
  205.    else 
  206.      {
  207.     if (*msg == 0) msg = " ";
  208.     strncpy(Message_Buffer, msg, 255);
  209.     Message_Buffer[255] = 0;
  210.      }
  211. }
  212.  
  213. /* read from minibuffer using prompt providing a default, and stuffing
  214.    the minibuffer with init if necessary */
  215. /* I should make recursive mini buffers */
  216. char *read_from_minibuffer(char *prompt, char *deflt, char *what, int *n)
  217. {
  218.    char buf[256];
  219.    jmp_buf_struct *mini_jmp_save, mini_jmp_buf;
  220.    unsigned char *ps;
  221.    unsigned char *p, ch;
  222.    
  223.    static Window_Type *current_window;
  224.    /* may get changed if user leaves minibuffer and returns from other
  225.       window which means that the new window becomes target of minibuffer action */
  226.    Window_Type *w;
  227.    char *ret;
  228.    int len, save_point;
  229.  
  230.    if (!IS_MINIBUFFER) current_window = JWindow;
  231.    if (select_minibuffer()) return(NULL);   /* we should be on a new line of mini buffer */
  232.  
  233.    ps = Mini_Info.prompt;
  234.    p = (unsigned char *) prompt;
  235.    len = 0;
  236.    
  237.    if (p != NULL) 
  238.      {
  239.     while (0 != (ch = *p++))
  240.       {
  241.          *ps++ = ch;
  242.          len++;
  243.       }
  244.     *ps++ =  ' ';
  245.     len++;
  246.      }
  247.  
  248.    if ((deflt != NULL) && (*deflt != 0))
  249.      {
  250.     sprintf(buf,"(default: %s) ", deflt);
  251.     p = (unsigned char *) buf;
  252.     
  253.     while (0 != (ch = *p++))
  254.       {
  255.          *ps++ = ch;
  256.          len++;
  257.       }
  258.      }
  259.    *ps = 0;
  260.  
  261.    /* Use calculate column to find effective length */
  262.    
  263.    Mini_Info.prompt_len = len;
  264.    p = CLine->data; save_point = Point;
  265.    CLine->data = Mini_Info.prompt;  Point = len;
  266.    Mini_Info.effective_prompt_len = 0;
  267.    Mini_Info.effective_prompt_len = calculate_column() - 1;
  268.    CLine->data = p;  Point = save_point;
  269.  
  270.    touch_window();
  271.    if (what != NULL) insert_string(what);
  272.    update((Line *) NULL, 0, 0);
  273.    
  274.    mini_jmp_save = Jump_Buffer_Ptr;
  275.    Jump_Buffer_Ptr = &mini_jmp_buf;
  276.    
  277.    if (setjmp(mini_jmp_buf.b) != 0)
  278.      {
  279.     SLang_restart(1);   /* just in case */
  280.     update((Line *) NULL, 0, 0);
  281.      }
  282.  
  283.    while(!Exit_From_MiniBuffer)
  284.      {
  285.     do_jed();
  286.     /* if (setjmp(Jump_Buffer) != 0)
  287.      * {
  288.      * Exit_From_MiniBuffer = 1;
  289.      * }  */
  290.  
  291.     if (SLKeyBoard_Quit && IS_MINIBUFFER) break;
  292.     update((Line *) NULL, 0, 0);
  293.      }
  294.    
  295.    if (Exit_From_MiniBuffer && !Executing_Keyboard_Macro 
  296.        && (Repeat_Factor == NULL) && !JWindow->trashed && !input_pending(&Number_Zero))
  297.      {
  298.     tt_goto_rc (*tt_Screen_Rows - 1, 0);
  299.     flush_output ();
  300.      }
  301.  
  302.    Jump_Buffer_Ptr = mini_jmp_save;
  303.    
  304.    exit_minibuffer ();               /* be graceful */
  305.    
  306.    Exit_From_MiniBuffer = 0;
  307.    MiniBuffer_Active = 0;
  308.    restore_macro_state();
  309.    
  310.    if (!SLKeyBoard_Quit)
  311.      {
  312.     if (CLine->len == 0)
  313.       {
  314.          if (deflt != NULL) insert_string(deflt);
  315.       }
  316.     bob();
  317.     push_mark();
  318.     eob();
  319.     ret = make_buffer_substring(n);
  320.      }
  321.    else ret = NULL;
  322.    
  323.    /* we should be in minibuffer so delete marks and spots */
  324.    while (CBuf->spots) pop_spot();
  325.    while (CBuf->marks) pop_mark(&Number_Zero);
  326.    erase_buffer();
  327.  
  328.    /* Remove MiniWindow from the ring */
  329.    w = JWindow;
  330.    while (w->next != JWindow) w = w->next;
  331.    other_window();
  332.    w->next = JWindow;
  333.    
  334.    /* Note that by this time, current_window might be history. */
  335.    while((JWindow != current_window) && (JWindow != w)) other_window();
  336.    JWindow->trashed = 1;
  337.  
  338.    /* delete_buffer(MiniBuffer); */
  339.    MiniBuffer = NULL;
  340.    return(ret);
  341. }
  342.  
  343. void exit_error(char *str, int severity)
  344. {
  345.    reset_display();
  346.    reset_tty(); 
  347.    fprintf(stderr,"\007\rJED: Fatal Error: %s!\n", str);
  348.    if (CBuf != NULL) 
  349.      {
  350.     fprintf(stderr, "CBuf: %p, CLine: %p, Point %d\n", CBuf, CLine, Point);
  351.     if (CLine != NULL) fprintf(stderr, "CLine: data: %p, len = %d, next: %p, prev %p\n",
  352.                    CLine->data, CLine->len, CLine->next, CLine->prev);
  353.     fprintf(stderr, "Max_LineNum: %d, LineNum: %d\n", Max_LineNum, LineNum);
  354.     if (JWindow != NULL) fprintf(stderr, "JWindow: %p, top: %d, rows: %d, buffer: %p\n",
  355.                      JWindow, JWindow->top, JWindow->rows, JWindow->buffer);
  356.     auto_save_all();
  357.      }
  358.    if (severity)
  359.      {
  360. #ifdef unix
  361.    fprintf(stderr, "Dumping Core.");
  362.    abort ();
  363. #endif
  364.      }
  365.    exit(-1);
  366. }
  367.  
  368. static int Macro_Illegal_Now = 0;
  369. static int check_macro_legality(void)
  370. {
  371.    if (Macro_Illegal_Now) 
  372.      {
  373.     msg_error("Illegal context for Macro definition.");
  374.     return (0);
  375.      }
  376.    return (1);
  377. }
  378.  
  379.  
  380. int begin_keyboard_macro()
  381. {
  382.    if (!check_macro_legality()) return (0);
  383.    
  384.    Macro_Buffer_Ptr = Macro_Buffer;
  385.    message("Defining Macro.");
  386.    Defining_Keyboard_Macro = 1;
  387.    set_macro_state();
  388.    return(1);
  389. }
  390.  
  391. int end_keyboard_macro()
  392. {
  393.  
  394.     if (Defining_Keyboard_Macro) message("Macro Defined.");
  395.     else
  396.       {
  397.       if (!Executing_Keyboard_Macro) msg_error("Not defining Macro!");
  398.       Executing_Keyboard_Macro = 0;
  399.       return(1);
  400.       }
  401.  
  402.    /* Macro_Ptr_Max = Macro_Buffer_Ptr; */
  403.    Defining_Keyboard_Macro = 0;
  404.    set_macro_state();
  405.    return(1);
  406. }
  407.  
  408. int execute_keyboard_macro()
  409. {
  410.     int repeat = 0, *repeat_ptr;
  411.  
  412.    if (!check_macro_legality()) return (0);
  413.  
  414.     if (Defining_Keyboard_Macro)
  415.       {
  416.       msg_error("Can't execute a macro while defining one.");
  417.       return(0);
  418.       }
  419.  
  420.    Executing_Keyboard_Macro = 1;
  421.    set_macro_state();
  422.    Macro_Buffer_Ptr = Macro_Buffer;
  423.  
  424.    /* save the repeat context */
  425.    repeat_ptr = Repeat_Factor;
  426.    if (repeat_ptr != NULL) repeat = *repeat_ptr;
  427.  
  428.    JWindow->trashed = 1;
  429.    Macro_Illegal_Now = 1;
  430.    while ((Macro_Buffer_Ptr < Macro_Ptr_Max) 
  431.       && Executing_Keyboard_Macro) /* since we might enter minibuffer 
  432.                       and stop macro before returning 
  433.                       here */
  434.      {
  435.     Repeat_Factor = NULL;
  436.     /* ch = *Macro_Buffer_Ptr++; */
  437.     do_key();
  438.     if (SLKeyBoard_Quit || (*Error_Buffer)) break;
  439.      }
  440.    Macro_Illegal_Now = 0;
  441.  
  442.    /* restore context */
  443.    Repeat_Factor = repeat_ptr;
  444.    if (repeat_ptr != NULL) *repeat_ptr = repeat;
  445.    Executing_Keyboard_Macro = 0;
  446.    set_macro_state();
  447.    return(1);
  448. }
  449. /*
  450.    before this can be of any real use, I need strings without the NULL 
  451.    chars! */
  452. /*      
  453. int get_macro()
  454. {
  455.    if ((Defining_Keyboard_Macro) || (Executing_Keyboard_Macro))
  456.      {
  457.     msg_error("Macro Buffer locked!");
  458.     return(0);
  459.      }
  460.    if (Macro_Ptr_Max == Macro_Buffer) return (0);
  461. }
  462. */
  463.  
  464. void get_last_macro ()
  465. {
  466.    register char *m, *s, ch;
  467.    char buf[2 * MACRO_SIZE + 1];
  468.    
  469.    if (Defining_Keyboard_Macro) 
  470.      {
  471.     msg_error("Complete Macro first!");
  472.     return;
  473.      }
  474.    
  475.    m = Macro_Buffer;
  476.    if (m == Macro_Ptr_Max)
  477.      {
  478.     msg_error("Macro not defined.");
  479.     return;
  480.      }
  481.    
  482.    s = buf;
  483.    while (m < Macro_Ptr_Max)
  484.      {
  485.     ch = *m++;
  486.     if ((ch < ' ') || (ch == 127))
  487.       {
  488.          *s++ = '^';
  489.          if (ch == 127) ch = '?'; else ch = '@' + ch;
  490.       }
  491.     else if ((ch == '^') || (ch == '\\'))
  492.       {
  493.          *s++ = '\\';
  494.       }
  495.     
  496.     *s++ = ch;
  497.      }
  498.    *s = 0;
  499.    SLang_push_string(buf);
  500. }
  501.