home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1992, 1994 John E. Davis (davis@amy.tch.harvard.edu)
- * All Rights Reserved.
- */
- #include <stdio.h>
- #include <string.h>
- #include <setjmp.h>
-
- #include "config.h"
- #include "buffer.h"
- #include "screen.h"
- #include "window.h"
- #include "display.h"
- #include "sysdep.h"
- #include "file.h"
- #include "keymap.h"
- #include "ledit.h"
- #include "misc.h"
- #include "ins.h"
- #include "slang.h"
- #include "paste.h"
-
- char Error_Buffer[256];
- char Message_Buffer[256];
- volatile int SLKeyBoard_Quit;
- int Exit_From_MiniBuffer;
-
-
- typedef struct
- {
- jmp_buf b;
- } jmp_buf_struct;
-
- extern jmp_buf_struct Jump_Buffer, *Jump_Buffer_Ptr;
-
- #define MACRO_SIZE 256
- char Macro_Buffer[MACRO_SIZE];
- char *Macro_Buffer_Ptr = Macro_Buffer;
- char *Macro_Ptr_Max = Macro_Buffer;
- int Defining_Keyboard_Macro = 0;
- int Executing_Keyboard_Macro = 0;
-
- static struct
- {
- int def;
- int exe;
- } Macro_State;
-
- MiniInfo_Type Mini_Info;
-
- void macro_store_key(char ch)
- {
- /* I need to put something here to increase the size of the Macro_Buffer
- in case of overflow */
-
- if (Macro_Buffer_Ptr - Macro_Buffer >= MACRO_SIZE) msg_error("Macro Size exceeded.");
- else *Macro_Buffer_Ptr++ = ch;
- }
-
- void restore_macro_state(void)
- {
- Defining_Keyboard_Macro = Macro_State.def;
- Executing_Keyboard_Macro = Macro_State.exe;
- }
-
- void set_macro_state(void)
- {
- Macro_State.def = Defining_Keyboard_Macro;
- Macro_State.exe = Executing_Keyboard_Macro;
- }
-
- /* if not in the mini buffer and if during keyboard macro, allow user to enter
- different text each time macro is executed */
-
- int macro_query()
- {
- char *s;
- int n;
-
- /* macro state is already set */
- Defining_Keyboard_Macro = 0;
- Executing_Keyboard_Macro = 0;
-
- if (!IS_MINIBUFFER)
- {
- if (NULL == (s = read_from_minibuffer("Enter String:", (char *) NULL, NULL, &n))) return(0);
- ins_chars((unsigned char *) s, n);
- SLFREE(s);
- }
-
- /* exit from mini restores the state */
- return(1);
- }
-
- int jed_getkey()
- {
- int ch, diff, ch1;
- static int mini_flag = 0;
- int *srf;
-
- if (Read_This_Character != NULL)
- {
- ch = *Read_This_Character++;
- if (ch == 0) Read_This_Character = NULL;
- else
- {
- if ((ch1 = *Read_This_Character) == 0)
- {
- Read_This_Character = NULL;
- return (ch);
- }
-
-
- if (ch == '^')
- {
- if (ch1 == '?') ch = 127;
- else ch = ch1 - '@';
- Read_This_Character++;
- }
- else if (ch == '\\')
- {
- ch = ch1;
- Read_This_Character++;
- }
- if (*Read_This_Character == 0) Read_This_Character = NULL;
- return(ch);
- }
-
- }
-
- if (Executing_Keyboard_Macro)
- {
- if (Macro_Buffer_Ptr < Macro_Ptr_Max) return (*Macro_Buffer_Ptr++);
- Executing_Keyboard_Macro = 0;
- update((Line *) NULL, 0, 0);
- }
-
- diff = (int) (Key_Bufferp - Key_Buffer);
- if (!SLang_Error && SLang_Key_TimeOut_Flag &&
- ((mini_flag && (diff > 0))
- || !input_pending(&Number_Ten)))
- {
- message(Key_Buffer);
- strcat(Message_Buffer, "-");
-
- /* This ensures that the update is performed if we are echoing from
- * digit argument */
- srf = Repeat_Factor; Repeat_Factor = NULL;
- update((Line *)NULL, 0, 0);
- Repeat_Factor = srf;
- message(" "); /* ensures that previous message will
- get erased. */
- mini_flag = 1;
- }
- else (mini_flag = 0);
-
- ch = my_getkey();
- if (diff < 13)
- {
- *Key_Bufferp++ = (char) ch;
- *Key_Bufferp = 0;
- }
- else
- {
- /* msg_error("KeyBuffer overflow!"); */
- Key_Bufferp = Key_Buffer;
- }
-
-
- if (Defining_Keyboard_Macro)
- {
- /* starting a new keysequence to save this point */
- if (diff == 0)
- {
- Macro_Ptr_Max = Macro_Buffer_Ptr;
- }
-
- macro_store_key(ch);
- }
- return(ch);
- }
-
-
- void msg_error(char *msg)
- {
- flush_input();
- JWindow->trashed = 1;
- Defining_Keyboard_Macro = Executing_Keyboard_Macro = 0;
- Read_This_Character = NULL;
- Repeat_Factor = NULL;
- set_macro_state();
- if (Batch) fprintf(stderr, "%s\n", msg);
-
- if (!SLang_Error) SLang_Error = INTRINSIC_ERROR;
- if (Error_Buffer[0] == 0) strcpy(Error_Buffer, msg);
- }
-
- /* later I will do more with this-- for now, keep last one */
- void message(char *msg)
- {
- if (Executing_Keyboard_Macro) return;
- if (Batch || (JScreen[0].old == NULL)) fprintf(stderr, "%s\n", msg);
-
- if (msg == NULL) *Message_Buffer = 0;
- else
- {
- if (*msg == 0) msg = " ";
- strncpy(Message_Buffer, msg, 255);
- Message_Buffer[255] = 0;
- }
- }
-
- /* read from minibuffer using prompt providing a default, and stuffing
- the minibuffer with init if necessary */
- /* I should make recursive mini buffers */
- char *read_from_minibuffer(char *prompt, char *deflt, char *what, int *n)
- {
- char buf[256];
- jmp_buf_struct *mini_jmp_save, mini_jmp_buf;
- unsigned char *ps;
- unsigned char *p, ch;
-
- static Window_Type *current_window;
- /* may get changed if user leaves minibuffer and returns from other
- window which means that the new window becomes target of minibuffer action */
- Window_Type *w;
- char *ret;
- int len, save_point;
-
- if (!IS_MINIBUFFER) current_window = JWindow;
- if (select_minibuffer()) return(NULL); /* we should be on a new line of mini buffer */
-
- ps = Mini_Info.prompt;
- p = (unsigned char *) prompt;
- len = 0;
-
- if (p != NULL)
- {
- while (0 != (ch = *p++))
- {
- *ps++ = ch;
- len++;
- }
- *ps++ = ' ';
- len++;
- }
-
- if ((deflt != NULL) && (*deflt != 0))
- {
- sprintf(buf,"(default: %s) ", deflt);
- p = (unsigned char *) buf;
-
- while (0 != (ch = *p++))
- {
- *ps++ = ch;
- len++;
- }
- }
- *ps = 0;
-
- /* Use calculate column to find effective length */
-
- Mini_Info.prompt_len = len;
- p = CLine->data; save_point = Point;
- CLine->data = Mini_Info.prompt; Point = len;
- Mini_Info.effective_prompt_len = 0;
- Mini_Info.effective_prompt_len = calculate_column() - 1;
- CLine->data = p; Point = save_point;
-
- touch_window();
- if (what != NULL) insert_string(what);
- update((Line *) NULL, 0, 0);
-
- mini_jmp_save = Jump_Buffer_Ptr;
- Jump_Buffer_Ptr = &mini_jmp_buf;
-
- if (setjmp(mini_jmp_buf.b) != 0)
- {
- SLang_restart(1); /* just in case */
- update((Line *) NULL, 0, 0);
- }
-
- while(!Exit_From_MiniBuffer)
- {
- do_jed();
- /* if (setjmp(Jump_Buffer) != 0)
- * {
- * Exit_From_MiniBuffer = 1;
- * } */
-
- if (SLKeyBoard_Quit && IS_MINIBUFFER) break;
- update((Line *) NULL, 0, 0);
- }
-
- if (Exit_From_MiniBuffer && !Executing_Keyboard_Macro
- && (Repeat_Factor == NULL) && !JWindow->trashed && !input_pending(&Number_Zero))
- {
- tt_goto_rc (*tt_Screen_Rows - 1, 0);
- flush_output ();
- }
-
- Jump_Buffer_Ptr = mini_jmp_save;
-
- exit_minibuffer (); /* be graceful */
-
- Exit_From_MiniBuffer = 0;
- MiniBuffer_Active = 0;
- restore_macro_state();
-
- if (!SLKeyBoard_Quit)
- {
- if (CLine->len == 0)
- {
- if (deflt != NULL) insert_string(deflt);
- }
- bob();
- push_mark();
- eob();
- ret = make_buffer_substring(n);
- }
- else ret = NULL;
-
- /* we should be in minibuffer so delete marks and spots */
- while (CBuf->spots) pop_spot();
- while (CBuf->marks) pop_mark(&Number_Zero);
- erase_buffer();
-
- /* Remove MiniWindow from the ring */
- w = JWindow;
- while (w->next != JWindow) w = w->next;
- other_window();
- w->next = JWindow;
-
- /* Note that by this time, current_window might be history. */
- while((JWindow != current_window) && (JWindow != w)) other_window();
- JWindow->trashed = 1;
-
- /* delete_buffer(MiniBuffer); */
- MiniBuffer = NULL;
- return(ret);
- }
-
- void exit_error(char *str, int severity)
- {
- reset_display();
- reset_tty();
- fprintf(stderr,"\007\rJED: Fatal Error: %s!\n", str);
- if (CBuf != NULL)
- {
- fprintf(stderr, "CBuf: %p, CLine: %p, Point %d\n", CBuf, CLine, Point);
- if (CLine != NULL) fprintf(stderr, "CLine: data: %p, len = %d, next: %p, prev %p\n",
- CLine->data, CLine->len, CLine->next, CLine->prev);
- fprintf(stderr, "Max_LineNum: %d, LineNum: %d\n", Max_LineNum, LineNum);
- if (JWindow != NULL) fprintf(stderr, "JWindow: %p, top: %d, rows: %d, buffer: %p\n",
- JWindow, JWindow->top, JWindow->rows, JWindow->buffer);
- auto_save_all();
- }
- if (severity)
- {
- #ifdef unix
- fprintf(stderr, "Dumping Core.");
- abort ();
- #endif
- }
- exit(-1);
- }
-
- static int Macro_Illegal_Now = 0;
- static int check_macro_legality(void)
- {
- if (Macro_Illegal_Now)
- {
- msg_error("Illegal context for Macro definition.");
- return (0);
- }
- return (1);
- }
-
-
- int begin_keyboard_macro()
- {
- if (!check_macro_legality()) return (0);
-
- Macro_Buffer_Ptr = Macro_Buffer;
- message("Defining Macro.");
- Defining_Keyboard_Macro = 1;
- set_macro_state();
- return(1);
- }
-
- int end_keyboard_macro()
- {
-
- if (Defining_Keyboard_Macro) message("Macro Defined.");
- else
- {
- if (!Executing_Keyboard_Macro) msg_error("Not defining Macro!");
- Executing_Keyboard_Macro = 0;
- return(1);
- }
-
- /* Macro_Ptr_Max = Macro_Buffer_Ptr; */
- Defining_Keyboard_Macro = 0;
- set_macro_state();
- return(1);
- }
-
- int execute_keyboard_macro()
- {
- int repeat = 0, *repeat_ptr;
-
- if (!check_macro_legality()) return (0);
-
- if (Defining_Keyboard_Macro)
- {
- msg_error("Can't execute a macro while defining one.");
- return(0);
- }
-
- Executing_Keyboard_Macro = 1;
- set_macro_state();
- Macro_Buffer_Ptr = Macro_Buffer;
-
- /* save the repeat context */
- repeat_ptr = Repeat_Factor;
- if (repeat_ptr != NULL) repeat = *repeat_ptr;
-
- JWindow->trashed = 1;
- Macro_Illegal_Now = 1;
- while ((Macro_Buffer_Ptr < Macro_Ptr_Max)
- && Executing_Keyboard_Macro) /* since we might enter minibuffer
- and stop macro before returning
- here */
- {
- Repeat_Factor = NULL;
- /* ch = *Macro_Buffer_Ptr++; */
- do_key();
- if (SLKeyBoard_Quit || (*Error_Buffer)) break;
- }
- Macro_Illegal_Now = 0;
-
- /* restore context */
- Repeat_Factor = repeat_ptr;
- if (repeat_ptr != NULL) *repeat_ptr = repeat;
- Executing_Keyboard_Macro = 0;
- set_macro_state();
- return(1);
- }
- /*
- before this can be of any real use, I need strings without the NULL
- chars! */
- /*
- int get_macro()
- {
- if ((Defining_Keyboard_Macro) || (Executing_Keyboard_Macro))
- {
- msg_error("Macro Buffer locked!");
- return(0);
- }
- if (Macro_Ptr_Max == Macro_Buffer) return (0);
- }
- */
-
- void get_last_macro ()
- {
- register char *m, *s, ch;
- char buf[2 * MACRO_SIZE + 1];
-
- if (Defining_Keyboard_Macro)
- {
- msg_error("Complete Macro first!");
- return;
- }
-
- m = Macro_Buffer;
- if (m == Macro_Ptr_Max)
- {
- msg_error("Macro not defined.");
- return;
- }
-
- s = buf;
- while (m < Macro_Ptr_Max)
- {
- ch = *m++;
- if ((ch < ' ') || (ch == 127))
- {
- *s++ = '^';
- if (ch == 127) ch = '?'; else ch = '@' + ch;
- }
- else if ((ch == '^') || (ch == '\\'))
- {
- *s++ = '\\';
- }
-
- *s++ = ch;
- }
- *s = 0;
- SLang_push_string(buf);
- }
-