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