1 /* -*- mode: C; mode: fold; -*- */
2 /* Copyright (c) 1992, 1998 John E. Davis
3  * This file is part of JED editor library source.
4  *
5  * You may distribute this file under the terms the GNU General Public
6  * License.  See the file COPYING for more information.
7  */
8 #include "config.h"
9 #include "jed-feat.h"
10 /*{{{ Include Files */
11 
12 #include <stdio.h>
13 #include <slang.h>
14 
15 #include "jdmacros.h"
16 
17 #include <string.h>
18 #include <setjmp.h>
19 
20 #include "buffer.h"
21 #include "cmds.h"
22 #include "paste.h"
23 #include "screen.h"
24 #include "window.h"
25 #include "text.h"
26 #include "ledit.h"
27 #include "keymap.h"
28 #include "sysdep.h"
29 #include "misc.h"
30 #include "display.h"
31 #include "file.h"
32 #include "undo.h"
33 #include "ins.h"
34 #include "hooks.h"
35 #include "replace.h"
36 #if JED_HAS_MENUS
37 # include "menu.h"
38 #endif
39 
40 #ifdef IBMPC_SYSTEM
41 # include "doskeys.h"
42 #endif
43 
44 /*}}}*/
45 
46 void (*X_Define_Keys_Hook)(SLKeyMap_List_Type *);
47 
48 typedef struct /*{{{*/
49 {
50    jmp_buf b;
51 }
52 
53 /*}}}*/
54 jmp_buf_struct;
55 
56 jmp_buf_struct Jump_Buffer, *Jump_Buffer_Ptr;
57 
58 FVOID_STAR Last_Key_Function;
59 int *Repeat_Factor;                    /* repeats a key sequence if non null */
60 
61 char *Read_This_Character = NULL;      /* alternate keyboard buffer */
62 
63 char Jed_Key_Buffer[SLANG_MAX_KEYMAP_KEY_SEQ + 1];
64 char Key_Buffer[SLANG_MAX_KEYMAP_KEY_SEQ + 1];
65 char *Key_Bufferp = Key_Buffer;
66 static int Last_Key_Buffer_Len;
67 
68 int Jed_Max_Hits = 300;
69 
70 
jed_beep(void)71 int jed_beep (void) /*{{{*/
72 {
73    tt_beep ();
74    flush_output ();
75    return 1;
76 }
77 
78 /*}}}*/
79 
redraw(void)80 static int redraw (void)
81 {
82    jed_redraw_screen (0);
83    return 0;
84 }
85 
86 #ifndef IBMPC_SYSTEM
xterm_mouse_cmd(void)87 static int xterm_mouse_cmd (void)
88 {
89    int b, id;
90    static int last_down = JMOUSE_BUTTON_1;
91    JMouse_Type m;
92 
93    b = my_getkey ();
94    m.x = (unsigned char) my_getkey () - 32;
95    m.y = (unsigned char) my_getkey () - 32;
96 
97    b -= 32;
98 
99    if ((b & 3) == 3)
100      {
101 	m.type = JMOUSE_UP;
102 	m.button = last_down;
103 	m.state = last_down;
104      }
105    else
106      {
107 	m.type = JMOUSE_DOWN;
108 	if ((b & 3) == 0)
109 	  m.button = JMOUSE_BUTTON_1;
110 	else if (b & 1)
111 	  m.button = JMOUSE_BUTTON_2;
112 	else if (b & 2)
113 	  m.button = JMOUSE_BUTTON_3;
114 	m.state = 0;
115      }
116    last_down = m.button;
117 
118    if (-1 == (id = jed_mouse_add_event (&m)))
119      return -1;
120 
121    ungetkey (&id);
122    jed_mouse_cmd ();
123    return 1;
124 }
125 #endif
126 
127 SLKeymap_Function_Type Jed_Functions[] = /*{{{*/
128 {
129      {"backward_delete_char", backward_delete_char_cmd},
130      {"backward_delete_char_untabify", backward_delete_char_untabify},
131      {"beep", jed_beep},
132      {"begin_macro", begin_keyboard_macro},
133      {"beg_of_buffer", bob},
134      {"beg_of_line", bol},
135      {"center_line", center_line},
136      {"copy_region", copy_to_pastebuffer},
137 #if defined(__MSDOS__) && !defined(__WIN32__)
138      {"coreleft", show_memory},
139 #endif
140      {"delete_char_cmd", delete_char_cmd},
141      {"delete_window", delete_window},
142      {"digit_arg", digit_arg},
143 /*      {"double_line", double_line}, */
144      {"end_macro", end_keyboard_macro},
145      {"enlarge_window", enlarge_window},
146      {"end_of_buffer", eob},
147      {"eol_cmd", eol_cmd},
148      {"evaluate_cmd", evaluate_cmd},
149      {"execute_macro", execute_keyboard_macro},
150      {"exchange",exchange_point_mark},
151      {"exit_jed", exit_jed},
152      {"exit_mini", exit_minibuffer},
153      {"find_file", find_file},
154      {"format_paragraph", text_format_paragraph},
155      {"goto_match", goto_match},
156      {"indent_line", indent_line},
157      {"insert_file", insert_file_cmd},
158 #ifdef HAS_MOUSE
159      {"mouse_cmd", jed_mouse_cmd},
160 #endif
161      {"kbd_quit", kbd_quit},
162      {"kill_buffer", kill_buffer},
163      {"kill_line", kill_line},
164      {"kill_region", kill_region},
165      {"macro_query", macro_query},
166      {"mark_spot", mark_spot},
167      {"mini_complete", mini_complete},
168      {"narrow", narrow_to_lines},
169      {"narrow_paragraph", narrow_paragraph},
170      {"narrow_to_region", narrow_to_region},
171      {"newline", newline_cmd},
172      {"newline_and_indent", newline_and_indent},
173      {"next_char_cmd", next_char_cmd},
174      {"next_line_cmd", next_line_cmd},
175      {"one_window", one_window},
176      {"other_window", other_window},
177      {"page_down", pagedown_cmd},
178      {"page_up", pageup_cmd},
179      {"pop_spot", pop_spot},
180      {"previous_char_cmd", previous_char_cmd},
181      {"previous_line_cmd", previous_line_cmd},
182      {"quoted_insert", quoted_insert},
183      {"redraw", redraw},
184       /* {"replace", replace}, */
185      {"save_buffers", save_some_buffers},
186      {"scroll_left", scroll_left},
187      {"scroll_right", scroll_right},
188        /* {"search_backward", search_backward_cmd},
189 	  {"search_forward", search_forward_cmd}, */
190      {"self_insert_cmd", ins_char_cmd},
191      {"set_mark_cmd", set_mark_cmd},
192      {"split_window", split_window},
193      {"switch_to_buffer", get_buffer},
194      {"sys_spawn_cmd", sys_spawn_cmd},
195      {"text_smart_quote", text_smart_quote},
196 /*       {"transpose_lines", transpose_lines}, */
197      {"trim_whitespace", trim_whitespace},
198      {"undo", undo},
199      {"widen", widen},
200      {"widen_region", widen_region},
201      {"write_buffer", write_buffer},
202      {"yank", yank},
203 #if JED_HAS_MENUS
204      {"select_menubar", jed_select_menu_bar},
205 #endif
206      {(char *) NULL, NULL}
207 };
208 
209 /*}}}*/
210 
211 SLKeyMap_List_Type *Global_Map;
212 SLKeyMap_List_Type *Mini_Map;
213 
kbd_quit(void)214 int kbd_quit(void) /*{{{*/
215 {
216    int sle = SLang_Error;
217    SLKeyBoard_Quit = 1;
218 
219    msg_error("Quit!");
220    if (CBuf->user_abort != -1)
221      {
222 	if (CBuf->user_abort) SLang_Error = sle;
223      }
224    else if (Ignore_User_Abort) SLang_Error = sle;
225 #ifdef UNDO_HAS_REDO
226    set_current_undo ();
227 #endif
228    return(1);
229 }
230 
231 /*}}}*/
232 
init_keymaps(void)233 void init_keymaps(void) /*{{{*/
234 {
235    int ch;
236    char simple[2];
237    simple[1] = 0;
238 
239    if (NULL == (Global_Map = SLang_create_keymap ("global", NULL)))
240      exit_error ("Malloc error creating keymap.", 0);
241 
242    Global_Map->functions = Jed_Functions;
243 
244    /* This breaks under some DEC ALPHA compilers (scary!) */
245 #ifndef __DECC
246    for (ch = ' '; ch < 256; ch++)
247      {
248 	simple[0] = (char) ch;
249 	SLkm_define_key (simple, (FVOID_STAR) ins_char_cmd, Global_Map);
250      }
251 #else
252    ch = ' ';
253    while (1)
254      {
255 	simple[0] = (char) ch;
256 	SLkm_define_key (simple, (FVOID_STAR) ins_char_cmd, Global_Map);
257 	ch = ch + 1;
258 	if (ch == 256) break;
259      }
260 #endif
261 
262    SLkm_define_key ("^[1", (FVOID_STAR) digit_arg, Global_Map);
263    SLkm_define_key ("^[2", (FVOID_STAR) digit_arg, Global_Map);
264    SLkm_define_key ("^[3", (FVOID_STAR) digit_arg, Global_Map);
265    SLkm_define_key ("^[4", (FVOID_STAR) digit_arg, Global_Map);
266    SLkm_define_key ("^[5", (FVOID_STAR) digit_arg, Global_Map);
267    SLkm_define_key ("^[6", (FVOID_STAR) digit_arg, Global_Map);
268    SLkm_define_key ("^[7", (FVOID_STAR) digit_arg, Global_Map);
269    SLkm_define_key ("^[8", (FVOID_STAR) digit_arg, Global_Map);
270    SLkm_define_key ("^[9", (FVOID_STAR) digit_arg, Global_Map);
271    SLkm_define_key ("^[0", (FVOID_STAR) digit_arg, Global_Map);
272 
273 #ifdef IBMPC_SYSTEM
274    SLkm_define_key (PC_DEL, (FVOID_STAR) delete_char_cmd, Global_Map);
275    SLkm_define_key (PC_DEL1, (FVOID_STAR) delete_char_cmd, Global_Map);
276    SLkm_define_key (PC_NULL, (FVOID_STAR) set_mark_cmd, Global_Map);
277    SLkm_define_key (PC_LT, (FVOID_STAR) previous_char_cmd, Global_Map);
278    SLkm_define_key (PC_LT1, (FVOID_STAR) previous_char_cmd, Global_Map);
279    SLkm_define_key (PC_UP, (FVOID_STAR) previous_line_cmd, Global_Map);
280    SLkm_define_key (PC_UP1, (FVOID_STAR) previous_line_cmd, Global_Map);
281    SLkm_define_key (PC_DN, (FVOID_STAR) next_line_cmd, Global_Map);
282    SLkm_define_key (PC_DN1, (FVOID_STAR) next_line_cmd, Global_Map);
283    SLkm_define_key (PC_RT, (FVOID_STAR) next_char_cmd, Global_Map);
284    SLkm_define_key (PC_RT1, (FVOID_STAR) next_char_cmd, Global_Map);
285    SLkm_define_key (PC_PGUP, (FVOID_STAR) pageup_cmd, Global_Map);
286    SLkm_define_key (PC_PGUP1, (FVOID_STAR) pageup_cmd, Global_Map);
287    SLkm_define_key (PC_PGDN, (FVOID_STAR) pagedown_cmd, Global_Map);
288    SLkm_define_key (PC_PGDN1, (FVOID_STAR) pagedown_cmd, Global_Map);
289    SLkm_define_key (PC_HOME, (FVOID_STAR) bol, Global_Map);
290    SLkm_define_key (PC_HOME1, (FVOID_STAR) bol, Global_Map);
291    SLkm_define_key (PC_END, (FVOID_STAR) eol_cmd, Global_Map);
292    SLkm_define_key (PC_END1, (FVOID_STAR) eol_cmd, Global_Map);
293 
294    /* Now special keypad stuff */
295    SLkm_define_key (PC_ENTER, (FVOID_STAR) newline_cmd, Global_Map);
296 
297    /* wordperfect type stuff */
298    SLkm_define_key (PC_F1, (FVOID_STAR) kbd_quit, Global_Map);
299    /* SLkm_define_key (PC_F2, (FVOID_STAR) search_forward_cmd, Global_Map);
300     SLkm_define_key (PC_SHIFT_F2, (FVOID_STAR) search_backward_cmd, Global_Map); */
301    SLkm_define_key (PC_F4, (FVOID_STAR) indent_line, Global_Map);
302    SLkm_define_key (PC_ALT_F5, (FVOID_STAR) set_mark_cmd, Global_Map);
303    SLkm_define_key (PC_SHIFT_F4, (FVOID_STAR) narrow_paragraph, Global_Map);
304    SLkm_define_key (PC_SHIFT_F6, (FVOID_STAR) center_line, Global_Map);
305    SLkm_define_key (PC_F7, (FVOID_STAR) exit_jed, Global_Map);
306 #else
307 
308    /* give vtxxx arrow keys */
309    SLkm_define_key ("^[[D", (FVOID_STAR) previous_char_cmd, Global_Map);
310    SLkm_define_key ("^[OD", (FVOID_STAR) previous_char_cmd, Global_Map);
311    SLkm_define_key ("^[[A", (FVOID_STAR) previous_line_cmd, Global_Map);
312    SLkm_define_key ("^[OA", (FVOID_STAR) previous_line_cmd, Global_Map);
313    SLkm_define_key ("^[[B", (FVOID_STAR) next_line_cmd, Global_Map);
314    SLkm_define_key ("^[OB", (FVOID_STAR) next_line_cmd, Global_Map);
315    SLkm_define_key ("^[[C", (FVOID_STAR) next_char_cmd, Global_Map);
316    SLkm_define_key ("^[OC", (FVOID_STAR) next_char_cmd, Global_Map);
317    SLkm_define_key ("^[[6~", (FVOID_STAR) pagedown_cmd, Global_Map);
318    SLkm_define_key ("^[[5~", (FVOID_STAR) pageup_cmd, Global_Map);
319    SLkm_define_key ("^K^[[C", (FVOID_STAR) scroll_left, Global_Map);
320    SLkm_define_key ("^K^[[D", (FVOID_STAR) scroll_right, Global_Map);
321    SLkm_define_key ("^K^[[A", (FVOID_STAR) bob, Global_Map);
322    SLkm_define_key ("^K^[[B", (FVOID_STAR)eob, Global_Map);
323 #if HAS_MOUSE
324    SLkm_define_key ("\033[M", (FVOID_STAR)xterm_mouse_cmd, Global_Map);
325 #endif
326 #ifdef sun
327    SLkm_define_key ("\033[216z", (FVOID_STAR) pageup_cmd, Global_Map);
328    SLkm_define_key ("\033[222z", (FVOID_STAR) pagedown_cmd, Global_Map);
329    SLkm_define_key ("\033[214z", (FVOID_STAR) bol, Global_Map);
330    SLkm_define_key ("\033[220z", (FVOID_STAR) eol_cmd, Global_Map);
331 #endif
332 #endif
333 
334    SLkm_define_key ("'", (FVOID_STAR) text_smart_quote, Global_Map);
335    SLkm_define_key ("\"", (FVOID_STAR) text_smart_quote, Global_Map);
336    SLkm_define_key ("^_", (FVOID_STAR) undo, Global_Map);
337    SLkm_define_key ("^?", (FVOID_STAR) backward_delete_char_untabify, Global_Map);
338 #ifndef IBMPC_SYSTEM
339    SLkm_define_key ("^H", (FVOID_STAR) backward_delete_char_untabify, Global_Map);
340 #endif
341    SLkm_define_key ("^B", (FVOID_STAR) bol, Global_Map);
342    SLkm_define_key ("^D", (FVOID_STAR) pagedown_cmd, Global_Map);
343    SLkm_define_key ("^E", (FVOID_STAR) eol_cmd, Global_Map);
344 /*
345  SLkm_define_key ("^FB", (FVOID_STAR) search_backward_cmd, Global_Map);
346  SLkm_define_key ("^FF", (FVOID_STAR) search_forward_cmd, Global_Map);
347 */
348    SLkm_define_key ("^G", (FVOID_STAR) kbd_quit, Global_Map);
349    SLkm_define_key ("^I", (FVOID_STAR) indent_line, Global_Map);
350    SLkm_define_key ("^K(", (FVOID_STAR) begin_keyboard_macro, Global_Map);
351    SLkm_define_key ("^K)", (FVOID_STAR) end_keyboard_macro, Global_Map);
352    SLkm_define_key ("^KD", (FVOID_STAR) evaluate_cmd, Global_Map);
353    SLkm_define_key ("^KE", (FVOID_STAR) exit_jed, Global_Map);
354    SLkm_define_key ("^KG", (FVOID_STAR) find_file, Global_Map);
355    SLkm_define_key ("^KK", (FVOID_STAR) copy_to_pastebuffer, Global_Map);
356    SLkm_define_key ("^KM", (FVOID_STAR) mark_spot, Global_Map);
357    SLkm_define_key ("^KX", (FVOID_STAR) execute_keyboard_macro, Global_Map);
358    SLkm_define_key ("^K^B", (FVOID_STAR) set_mark_cmd, Global_Map);
359    SLkm_define_key ("^K^I", (FVOID_STAR) insert_file_cmd, Global_Map);
360 /*     SLang_define_key1("^K^L", (VOID_STAR) double_line, SLKEY_F_INTRINSIC, Global_Map); */
361    SLkm_define_key ("^K^M", (FVOID_STAR) pop_spot, Global_Map);
362    SLkm_define_key ("^K^P", (FVOID_STAR) yank, Global_Map);
363 /*     SLang_define_key1("^K^R", (VOID_STAR) replace, SLKEY_F_INTRINSIC, Global_Map); */
364    SLkm_define_key ("^K^V", (FVOID_STAR) kill_region, Global_Map);
365    SLkm_define_key ("^K^W", (FVOID_STAR) write_buffer, Global_Map);
366    SLkm_define_key ("^L", (FVOID_STAR) kill_line, Global_Map);
367    SLkm_define_key ("^M", (FVOID_STAR) newline_and_indent, Global_Map);
368    SLkm_define_key ("^R", (FVOID_STAR) redraw, Global_Map);
369    SLkm_define_key ("^U", (FVOID_STAR) pageup_cmd, Global_Map);
370    SLkm_define_key ("^V", (FVOID_STAR) delete_char_cmd, Global_Map);
371    SLkm_define_key ("^W0", (FVOID_STAR) delete_window, Global_Map);
372    SLkm_define_key ("^W1", (FVOID_STAR) one_window, Global_Map);
373    SLkm_define_key ("^W2", (FVOID_STAR) split_window, Global_Map);
374    SLkm_define_key ("^WO", (FVOID_STAR) other_window, Global_Map);
375    SLkm_define_key ("^XB", (FVOID_STAR) get_buffer, Global_Map);
376    SLkm_define_key ("^XK", (FVOID_STAR) kill_buffer, Global_Map);
377    SLkm_define_key ("^XN", (FVOID_STAR) narrow_to_region, Global_Map);
378    SLkm_define_key ("^XQ", (FVOID_STAR) macro_query, Global_Map);
379    SLkm_define_key ("^XS", (FVOID_STAR) save_some_buffers, Global_Map);
380    SLkm_define_key ("^XW", (FVOID_STAR) widen_region, Global_Map);
381    SLkm_define_key ("^X^", (FVOID_STAR) enlarge_window, Global_Map);
382 /*     SLang_define_key1("^X^T", (VOID_STAR) transpose_lines, SLKEY_F_INTRINSIC, Global_Map); */
383    SLkm_define_key ("^X^[", (FVOID_STAR) evaluate_cmd, Global_Map);
384    SLkm_define_key ("^X^X", (FVOID_STAR) exchange_point_mark, Global_Map);
385    SLkm_define_key ("^Z", (FVOID_STAR) sys_spawn_cmd, Global_Map);
386    SLkm_define_key ("^[<", (FVOID_STAR) bob, Global_Map);
387    SLkm_define_key ("^[>", (FVOID_STAR) eob, Global_Map);
388    SLkm_define_key ("^[N", (FVOID_STAR) narrow_paragraph, Global_Map);
389    SLkm_define_key ("^[Q", (FVOID_STAR) text_format_paragraph, Global_Map);
390    SLkm_define_key ("^[S", (FVOID_STAR) center_line, Global_Map);
391    SLkm_define_key ("^[X", (FVOID_STAR) evaluate_cmd, Global_Map);
392    SLkm_define_key ("^[\\", (FVOID_STAR) trim_whitespace, Global_Map);
393    SLkm_define_key ("^\\", (FVOID_STAR) goto_match, Global_Map);
394    SLkm_define_key ("`", (FVOID_STAR) quoted_insert, Global_Map);
395 
396    if (X_Define_Keys_Hook != NULL)  (*X_Define_Keys_Hook)(Global_Map);
397 }
398 
399 /*}}}*/
400 
401 char Last_Kbd_Command_String[32];
402 char Current_Kbd_Command_String[32];
403 
set_current_kbd_command(char * s)404 void set_current_kbd_command (char *s) /*{{{*/
405 {
406    strncpy (Current_Kbd_Command_String, s, 31);
407    Current_Kbd_Command_String[31] = 0;
408 }
409 
410 /*}}}*/
411 
key_interpret(SLang_Key_Type * key)412 static int key_interpret(SLang_Key_Type *key) /*{{{*/
413 {
414    char *rtc_save;
415    char *str;
416    int ret;
417    static int macro_depth;
418 
419    strcpy (Last_Kbd_Command_String, Current_Kbd_Command_String);
420 
421    if (key->type == SLKEY_F_INTRINSIC)
422      {
423 	set_current_kbd_command (Jed_Key_Buffer);
424 	Current_Kbd_Command_String[31] = 0;
425 	ret = (key->f.f)();
426      }
427    else
428      {
429 	str = key->f.s;
430 	set_current_kbd_command (str);
431 	if (*str == ' ')
432 	  {
433 	     /* string to insert */
434 	     insert_string(str + 1);
435 	  }
436 	else if ((*str == '@') && (0 != *(str + 1)))
437 	  {
438 	     int repeat;
439 
440 	     if (Repeat_Factor != NULL)
441 	       {
442 		  repeat = *Repeat_Factor;
443 		  Repeat_Factor = NULL;
444 	       }
445 	     else repeat = 1;
446 
447 	     if (macro_depth > 10)
448 	       {
449 		  macro_depth = 0;
450 		  msg_error ("Possible runaway macro aborted.");
451 		  return 1;
452 	       }
453 
454 	     macro_depth++;
455 	     rtc_save = Read_This_Character;
456 
457 	     while (repeat-- > 0)
458 	       {
459 		  Read_This_Character = str + 1;
460 		  do
461 		    {
462 		       do_key();
463 		    }
464 		  while ((Read_This_Character != NULL)
465 			 && (SLKeyBoard_Quit  == 0)
466 			 && (SLang_Error == 0));
467 
468 		  if (SLKeyBoard_Quit || SLang_Error)
469 		    break;
470 	       }
471 
472 	     Read_This_Character = rtc_save;
473 	     macro_depth--;
474 	  }
475 	else if ((*str == '.')
476 		 || !SLang_execute_function(str))
477 	  SLang_load_string(str);
478 
479 	ret = 1;
480      }
481 
482    Last_Key_Function = key->f.f;
483    return(ret);
484 }
485 
486 /*}}}*/
487 
update_jed_keybuffer(void)488 static void update_jed_keybuffer (void) /*{{{*/
489 {
490    Last_Key_Buffer_Len = (int) (Key_Bufferp - Key_Buffer);
491    if (Last_Key_Buffer_Len == 1)
492      {
493 	*Jed_Key_Buffer = *Key_Buffer;
494 	*(Jed_Key_Buffer + 1) = 0;
495      }
496    else
497      {
498         *Key_Bufferp = 0;
499 	strcpy (Jed_Key_Buffer, Key_Buffer);
500      }
501 
502    Key_Bufferp = Key_Buffer;
503 }
504 
505 /*}}}*/
506 
507 
508 #define XKEY(key)  key_interpret((key))
509 
do_key(void)510 int do_key (void) /*{{{*/
511 {
512    SLang_Key_Type *key;
513    int repeat;
514 
515    if (SLang_Key_TimeOut_Flag == 0)
516      {
517 	Key_Bufferp = Key_Buffer;
518 	*Key_Bufferp = 0;
519      }
520 
521 #if JED_HAS_MENUS
522    if (Jed_Menus_Active)
523      key = jed_menu_do_key ();
524    else
525 #endif
526      key = SLang_do_key (CBuf->keymap, jed_getkey);
527 
528    update_jed_keybuffer ();
529 
530    if ((key != NULL) && (key->f.f != NULL))
531      {
532 	if (Repeat_Factor == NULL) return XKEY(key);
533 	repeat = *Repeat_Factor;
534 	Suspend_Screen_Update = 1;
535 
536 	/* some routines may use the repeat factor as a prefix argument */
537 	while (repeat-- > 0)
538 	  {
539 	     if (SLKeyBoard_Quit || SLang_Error ||
540 		 (Repeat_Factor == NULL)) break;
541 	 /* (!Executing_Keyboard_Macro && (Repeat_Factor == NULL))) break; */
542 	     XKEY(key);
543 	  }
544 	Repeat_Factor = NULL;
545 
546 	return(1);
547      }
548    else if (!Executing_Keyboard_Macro && !SLKeyBoard_Quit)
549      {
550 	jed_beep ();
551 	flush_input ();
552      }
553    if (SLKeyBoard_Quit) kbd_quit();
554    return(0);
555 }
556 
557 /*}}}*/
558 
do_jed(void)559 void do_jed(void) /*{{{*/
560 {
561    char *mode;
562    Buffer *tthis = CBuf;
563 
564    /* Mark Undo boundary now because this might not be valid later */
565    mark_undo_boundary (tthis);
566    mode = CBuf->mode_string;
567 
568    Repeat_Factor = NULL;
569    Replace_Preserve_Case = 0;
570    if (do_key()) JWindow->trashed = 1;
571 
572     /* internal editing commands may have selected a different buffer
573      * so put it back to the one associated with the window.
574      */
575    if (CBuf != JWindow->buffer)
576      {
577 	char *name;
578 	if (buffer_exists(JWindow->buffer)) name = JWindow->buffer->name; else name = "*scratch*";
579 	switch_to_buffer_cmd(name);
580      }
581 
582 #if JED_HAS_MENUS
583    if ((tthis != CBuf) || (CBuf->mode_string != mode))
584      jed_notify_menu_buffer_changed ();
585 #endif
586 }
587 
588 /*}}}*/
589 
jed(void)590 void jed(void) /*{{{*/
591 {
592    /* This routine is called from main.  So before actually strting, check
593       one more hook to just to make sure  all things are go. */
594    char *startup = ".()jed_startup_hook";
595 
596 #if JED_HAS_MENUS
597    jed_notify_menu_buffer_changed ();
598 #endif
599 
600    if (2 == SLang_is_defined(startup + 3))
601      {
602 	SLang_run_hooks(startup + 3, 0);
603 	/* remove its definition from memory */
604 	SLang_load_string (startup);
605      }
606 
607 
608    Jump_Buffer_Ptr = &Jump_Buffer;
609 
610    if (setjmp(Jump_Buffer.b) != 0)
611      {
612 	SLang_restart(1);   /* just in case */
613      }
614 
615    if (CBuf != JWindow->buffer)
616      {
617 	switch_to_buffer(JWindow->buffer);
618 	window_buffer(CBuf);
619      }
620 
621 #if JED_HAS_MENUS
622    jed_notify_menu_buffer_changed ();
623 #endif
624 
625    JWindow->trashed = 1;
626    update((Line *) NULL, 0, 0);
627    Read_This_Character = NULL;
628    while(1)
629      {
630 	Suspend_Screen_Update = 0;
631 	do_jed();
632 	if (!SLKeyBoard_Quit && (CBuf->flags & BUFFER_MODIFIED) && (!Cursor_Motion))
633 	  {
634 	     CBuf->hits += 1;
635 	     if(SLang_Last_Key_Char & 0xff00) CBuf->hits += 1;
636 	  }
637 	if (CBuf->hits > Jed_Max_Hits && !input_pending(&Number_One))
638 	  {
639 	     auto_save_buffer(CBuf);
640 	     check_buffers();   /* check files on disk to see if they are recent */
641 	  }
642 
643 	if ((Last_Key_Function != (FVOID_STAR) ins_char_cmd)
644 	    || (JWindow->trashed) || (JWindow != JWindow->next)
645 	    || Suspend_Screen_Update ||
646 	    (Mini_Ghost) || (*Message_Buffer) || (*Error_Buffer))
647 	  {
648 	     update((Line *) NULL, 0, 0);
649 	  }
650      }
651 }
652 
653 /*}}}*/
654 
digit_arg(void)655 int digit_arg(void) /*{{{*/
656 {
657    static int repeat;
658    char buf[20];
659    int key;
660    int i;
661 
662    i = 0;
663    buf[i++] = (char) SLang_Last_Key_Char;
664 
665    /* After do_key (what called this), Key_Bufferp is reset.  However, I want
666     * to keep it for echoing subsequent characters.  I restore its previous
667     * value so that echoing will continue.
668     */
669 
670    Key_Bufferp = Key_Buffer + Last_Key_Buffer_Len;
671 
672    SLang_Key_TimeOut_Flag = 1;
673    while(1)
674      {
675 	buf[i] = 0;
676 	key = jed_getkey();
677 	if ((key < '0') || (key > '9')) break;
678 	buf[i++] = (char) key;
679      }
680    repeat = atoi(buf);
681    Repeat_Factor = &repeat;
682    if (Executing_Keyboard_Macro) Macro_Buffer_Ptr--;
683    else
684      {
685 	ungetkey (&key);
686 	if (Defining_Keyboard_Macro) Macro_Buffer_Ptr--;
687      }
688 
689    if (Key_Bufferp != Key_Buffer) Key_Bufferp--;
690 
691    /* Key_Timeout is still active and is only reset after this call. */
692    do_key();
693    return(1);
694 }
695 
696 /*}}}*/
697 
which_key(char * f)698 int which_key (char *f) /*{{{*/
699 {
700    int num = 0, i;
701    SLang_Key_Type *key, *key_root;
702    FVOID_STAR fp;
703    unsigned char type;
704    unsigned char buf[5];
705 
706    if (NULL == (fp = (FVOID_STAR) SLang_find_key_function(f, CBuf->keymap)))
707      type = SLKEY_F_INTERPRET;
708    else type = SLKEY_F_INTRINSIC;
709 
710    i = 256;
711    key_root = CBuf->keymap->keymap;
712    while (i--)
713      {
714 	key = key_root->next;
715 	if ((key == NULL) && (type == key_root->type) &&
716 	    (((type == SLKEY_F_INTERPRET) && (!strcmp((char *) f, key_root->f.s)))
717 	     || ((type == SLKEY_F_INTRINSIC) && (fp == key_root->f.f))))
718 	  {
719 	     buf[0] = 2;
720 	     buf[1] = 256 - 1 - i;
721 	     buf[2] = 0;
722 	     SLang_push_string(SLang_make_keystring(buf));
723 	     num++;
724 	  }
725 
726 	while (key != NULL)
727 	  {
728 	     if ((key->type == type) &&
729 		 (((type == SLKEY_F_INTERPRET) && (!strcmp((char *) f, key->f.s)))
730 		  || ((type == SLKEY_F_INTRINSIC) && (fp == key->f.f))))
731 	       {
732 		  SLang_push_string(SLang_make_keystring(key->str));
733 		  num++;
734 	       }
735 	     key = key->next;
736 	  }
737 	key_root++;
738      }
739    return(num);
740 }
741 
742 /*}}}*/
743 
find_function_string(FVOID_STAR f)744 static char *find_function_string (FVOID_STAR f) /*{{{*/
745 {
746    SLKeymap_Function_Type *fp;
747 
748    fp = Jed_Functions;
749 
750    if (f == (FVOID_STAR) ins_char_cmd) return "self_insert_cmd";
751 
752    while ((fp != NULL) && (fp->name != NULL))
753      {
754 	if ((FVOID_STAR) fp->f == f) return fp->name;
755 	fp++;
756      }
757    return NULL;
758 }
759 
760 /*}}}*/
761 
dump_this_binding(SLang_Key_Type * key)762 static void dump_this_binding (SLang_Key_Type *key) /*{{{*/
763 {
764    unsigned char ch, *s;
765    char *str,  ctrl[2];
766    char *fun;
767    int n, len;
768 
769    s = key->str;
770 
771    ctrl[0] = '^';
772    len = *s++ - 1;;
773 
774    while (len-- > 0)
775      {
776 	n = 1;
777         ch = *s++;
778 	if (ch == 127)
779 	  {
780 	     str = "DEL"; n = 3;
781 	  }
782 	else if (ch > ' ') str = (char *) &ch;
783 	else if (ch == 27)
784 	  {
785 	     str = "ESC";
786 	     n = 3;
787 	  }
788 	else if (ch == ' ')
789 	  {
790 	     str = "SPACE";
791 	     n = 5;
792 	  }
793 	else if (ch == '\t')
794 	  {
795 	     str = "TAB"; n = 3;
796 	  }
797 	else
798 	  {
799 	     str = ctrl;
800 	     *(str + 1) = ch + '@';
801 	     n = 2;
802 	  }
803 	quick_insert((unsigned char *) str, n);
804 	ins(' ');
805      }
806    ins_char_n_times('\t', 3);
807 
808    if (key->type == SLKEY_F_INTRINSIC)
809      {
810    	fun = find_function_string (key->f.f);
811      }
812    else fun = key->f.s;
813 
814    if (fun == NULL) fun = "** Unknown **";
815    insert_string (fun);
816    newline();
817 }
818 
819 /*}}}*/
820 
dump_bindings(char * map)821 void dump_bindings(char *map) /*{{{*/
822 {
823    int i;
824    SLang_Key_Type *next, *key_root;
825    SLKeyMap_List_Type *kml;
826 
827    CHECK_READ_ONLY_VOID
828 
829    if (NULL == (kml = SLang_find_keymap(map)))
830      {
831 	msg_error("Keymap undefined.");
832 	return;
833      }
834    key_root = kml->keymap;
835 
836    for (i = 0; i < 256; i++)
837      {
838 	next = key_root->next;
839 	if (next != NULL)
840 	  {
841 	     while (next != NULL)
842 	       {
843 		  dump_this_binding (next);
844 		  next = next->next;
845 	       }
846 	  }
847 	else if (key_root->f.f != NULL) dump_this_binding (key_root);
848 	key_root++;
849      }
850 }
851 
852 /*}}}*/
853 
find_key(int * ret)854 char *find_key(int *ret) /*{{{*/
855 {
856    char *fstr = NULL;
857    SLang_Key_Type *key;
858 
859    *ret = 0;
860 
861    SLang_Key_TimeOut_Flag = 0;
862    Key_Bufferp = Key_Buffer;
863    key = SLang_do_key (CBuf->keymap, jed_getkey);
864    update_jed_keybuffer ();
865 
866    if (key == NULL) return(NULL);
867    if (key->type == SLKEY_F_INTRINSIC)
868      {
869 	*ret = 1;
870 	fstr = find_function_string (key->f.f);
871      }
872    else fstr = key->f.s;
873 
874    return fstr;
875 }
876 
877 /*}}}*/
878 
use_keymap(char * name)879 void use_keymap(char *name) /*{{{*/
880 {
881    SLKeyMap_List_Type *map;
882 
883    if ((name == NULL) || (*name == 0)
884        || (NULL == (map = SLang_find_keymap(name))))
885      {
886 	msg_error("Unknown keymap.");
887      }
888    else CBuf->keymap = map;
889 }
890 
891 /*}}}*/
892 
what_keymap()893 char *what_keymap() /*{{{*/
894 {
895    return CBuf->keymap->name;
896 }
897 
898 /*}}}*/
899 
set_abort_char(int * c)900 void set_abort_char(int *c) /*{{{*/
901 {
902    char str[2];
903    int i;
904 #ifdef IBMPC_SYSTEM
905    char ch, *s, *scan = "@#$%^&*()_+?IQWERTYUIOP[]!!ASDFGHJKL!!!!\\ZXCVBNM";
906 
907    ch = 64 + (char) *c;
908    s = scan; while (*s && (*s != ch)) s++;
909    if (*s == 0) return;
910    Abort_Char = (int) (s - scan) + 0x03;
911 #else
912    Abort_Char = *c;
913 #endif
914 #ifndef MSWINDOWS
915    reset_tty();
916    init_tty();
917 #endif
918    str[0] = *c; str[1] = 0;
919 
920    for (i = 0; i < SLANG_MAX_KEYMAPS; i++)
921      {
922 	if (SLKeyMap_List[i].keymap == NULL) continue;
923 	SLang_undefine_key(str, &SLKeyMap_List[i]);
924 	SLkm_define_key (str, (FVOID_STAR) kbd_quit, &SLKeyMap_List[i]);
925      }
926 }
927 
928 /*}}}*/
929 
930 #if 0
931 void set_abort_char_in_keymap(int *c, char *map) /*{{{*/
932 {
933    char str[2];
934    SLKeyMap_List_Type *kmap;
935 
936 #ifndef MSWINDOWS
937    reset_tty();
938    init_tty();
939 #endif
940    str[0] = *c; str[1] = 0;
941 
942    if (NULL == (kmap = SLang_find_keymap(map)))
943      {
944 	msg_error("Unknown Keymap");
945 	return;
946      }
947 
948    SLang_undefine_key(str, kmap);
949    SLkm_define_key (str, (FVOID_STAR) kbd_quit, kmap);
950 }
951 #endif
952 
953 /*}}}*/
954 
955 static SLKeymap_Function_Type *Flist_Context;
956 static int Flist_Context_Len;
957 
958 #define MAX_USER_FLIST 100
959 static char *Slang_Functions[MAX_USER_FLIST];
960 static char **Slang_Flist_Context;
961 
next_function_list(char * buf)962 int next_function_list(char *buf) /*{{{*/
963 {
964    SLKeymap_Function_Type *tthis = Jed_Functions;
965    register char *name;
966    char **max;
967 
968    /* Convert '-' to '_' */
969 
970    name = buf;
971    while (*name != 0)
972      {
973 	if (*name == '-') *name = '_';
974 	name++;
975      }
976 
977    while (1)
978      {
979 	tthis = Flist_Context;
980 	name = tthis->name;
981 	if (name == NULL) break;
982 	Flist_Context++;
983 	if (!Flist_Context_Len || !strncmp(buf, name, Flist_Context_Len))
984 	  {
985 	     strcpy(buf, name);
986 	     return(1);
987 	  }
988      }
989 
990    max = Slang_Functions + MAX_USER_FLIST;
991    while (Slang_Flist_Context < max)
992      {
993 	name = *Slang_Flist_Context;
994 	if (name == NULL) return(0);
995 #if 0
996 	name++;  /* skip past hash mark */
997 #endif
998 	Slang_Flist_Context++;
999 	if (!Flist_Context_Len || !strncmp(buf, name, Flist_Context_Len))
1000 	  {
1001 	     strcpy(buf, name);
1002 	     return(1);
1003 	  }
1004      }
1005    return(0);
1006 }
1007 
1008 /*}}}*/
1009 
open_function_list(char * buf)1010 int open_function_list(char *buf) /*{{{*/
1011 {
1012    Flist_Context = Jed_Functions;
1013    Slang_Flist_Context = Slang_Functions;
1014    Flist_Context_Len = strlen(buf);
1015    return next_function_list(buf);
1016 }
1017 
1018 /*}}}*/
1019 
add_to_completion(char * name)1020 void add_to_completion(char *name) /*{{{*/
1021 {
1022    char **p, *n;
1023    static char **last = Slang_Functions;
1024 
1025    if (0 == SLang_is_defined (name))
1026      {
1027 	jed_verror ("add_completion: %s undefined", name);
1028 	return;
1029      }
1030 
1031    n = SLang_create_slstring (name);
1032    if (n == NULL)
1033      return;
1034 
1035    p = last;  /* Slang_Functions; */
1036 
1037    while (p < Slang_Functions + MAX_USER_FLIST)
1038      {
1039 	if (*p == NULL)
1040 	  {
1041 	     *p = n;
1042 	     last = p + 1;
1043 	     return;
1044 	  }
1045 	p++;
1046      }
1047 
1048    SLang_free_slstring (n);
1049    /* msg_error("Completion Quota Exceeded."); */
1050 }
1051 
1052 /*}}}*/
1053 
is_internal(char * f)1054 int is_internal(char *f) /*{{{*/
1055 {
1056    if (NULL == SLang_find_key_function(f, CBuf->keymap)) return(0);
1057    return 1;
1058 }
1059 
1060 /*}}}*/
1061 
1062 #if 0 /*k-yosino*/
1063 #if 0 /*k-yosino*/
1064 void jed_copy_keymap (char *name) /*{{{*/
1065 {
1066    if (NULL == SLang_create_keymap (name, CBuf->keymap))
1067      {
1068 	msg_error ("Unable to copy keymap.");
1069      }
1070 }
1071 
1072 /*}}}*/
1073 #else
1074 /* create and copy keymap */
1075 void jed_copy_keymap (char *neewname, char *basename) /*{{{*/
1076 {
1077    if (NULL == SLang_create_keymap (neewname, SLang_find_keymap(basename)))
1078      {
1079 	msg_error ("Unable to copy keymap.");
1080      }
1081 }
1082 
1083 #endif
1084 #else
1085 /* copy only */
jed_copy_keymap(char * neewname,char * basename)1086 void jed_copy_keymap (char *neewname, char *basename) /*{{{*/
1087 {
1088    SLKeyMap_List_Type *neewkml, *oldkml;
1089 
1090    if(NULL == (neewkml = SLang_find_keymap(neewname)) || NULL == (oldkml = SLang_find_keymap(basename)))
1091      {
1092 	msg_error ("Unable to copy keymap.");
1093 	return ;
1094      }
1095    SLang_copy_keymap (neewkml->keymap, oldkml->keymap);
1096 }
1097 
1098 /*}}}*/
1099 #endif
1100 
create_keymap(char * name)1101 void create_keymap (char *name) /*{{{*/
1102 {
1103    if (NULL == SLang_create_keymap (name, Global_Map))
1104      {
1105 	msg_error ("Unable to create keymap.");
1106      }
1107 }
1108 
1109 /*}}}*/
1110