Fix metadata usage
[sxemacs] / src / cmdloop.c
1 /* Editor command loop.
2    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
3    Copyright (C) 1995, 1996 Ben Wing.
4
5 This file is part of SXEmacs
6
7 SXEmacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 SXEmacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
19
20
21 /* Synched up with: Mule 2.0.  Not synched with FSF.
22    This was renamed from keyboard.c.  However, it only contains the
23    command-loop stuff from FSF's keyboard.c; all the rest is in
24    event*.c, console.c, or signal.c. */
25
26 /* #### This module purports to separate out the command-loop stuff
27    from event-stream.c, but it doesn't really.  Perhaps this file
28    should just be merged into event-stream.c, given its shortness. */
29
30 #include <config.h>
31 #include "lisp.h"
32
33 #include "buffer.h"
34 #include "commands.h"
35 #include "ui/frame.h"
36 #include "events/events.h"
37 #include "ui/window.h"
38
39 /* Current depth in recursive edits.  */
40 Fixnum command_loop_level;
41
42 #ifndef LISP_COMMAND_LOOP
43 /* Form to evaluate (if non-nil) when Emacs is started.  */
44 Lisp_Object Vtop_level;
45 #else
46 /* Function to call to evaluate to read and process events.  */
47 Lisp_Object Vcommand_loop;
48 #endif                          /* LISP_COMMAND_LOOP */
49
50 Lisp_Object Venter_window_hook, Vleave_window_hook;
51
52 /* The error handler.  */
53 Lisp_Object Qcommand_error;
54
55 /* The emergency error handler, before we're ready.  */
56 Lisp_Object Qreally_early_error_handler;
57
58 /* Variable defined in Lisp. */
59 Lisp_Object Qerrors_deactivate_region;
60
61 Lisp_Object Qtop_level;
62
63 static Lisp_Object command_loop_1(Lisp_Object dummy);
64 EXFUN(Fcommand_loop_1, 0);
65
66 /* There are two possible command loops -- one written entirely in
67    C and one written mostly in Lisp, except stuff written in C for
68    speed.  The advantage of the Lisp command loop is that the user
69    can specify their own command loop to use by changing the variable
70    `command-loop'.  Its disadvantage is that it's slow. */
71
72 static Lisp_Object default_error_handler(Lisp_Object data)
73 {
74         int speccount = specpdl_depth();
75
76         /* None of this is invoked, normally.  This code is almost identical
77            to the `command-error' function, except `command-error' does cool
78            tricks with sounds.  This function is a fallback, invoked if
79            command-error is unavailable.  */
80
81         Fding(Qnil, Qnil, Qnil);
82
83         if (!NILP(Fboundp(Qerrors_deactivate_region))
84             && !NILP(Fsymbol_value(Qerrors_deactivate_region)))
85                 zmacs_deactivate_region();
86         Fdiscard_input();
87         specbind(Qinhibit_quit, Qt);
88         Vstandard_output = Qt;
89         Vstandard_input = Qt;
90         Vexecuting_macro = Qnil;
91         Fset(intern("last-error"), data);
92         clear_echo_area(selected_frame(), Qnil, 0);
93         Fdisplay_error(data, Qt);
94         check_quit();           /* make Vquit_flag accurate */
95         Vquit_flag = Qnil;
96         return (unbind_to(speccount, Qt));
97 }
98
99 DEFUN("really-early-error-handler", Freally_early_error_handler, 1, 1, 0,       /*
100 You should almost certainly not be using this.
101 */
102       (x))
103 {
104         /* This is an error handler used when we're running temacs and when
105            we're in the early stages of SXEmacs.  No errors ought to be
106            occurring in those cases (or they ought to be trapped and
107            dealt with elsewhere), but if an error slips through, we need
108            to deal with it.  We could write this function in Lisp (and it
109            used to be this way, at the beginning of loadup.el), but we do
110            it this way in case an error occurs before we get to loading
111            loadup.el.  Note that there is also an `early-error-handler',
112            used in startup.el to catch more reasonable errors that
113            might occur during startup if the sysadmin or whoever fucked
114            up.  This function is more conservative in what it does
115            and is used only as a last resort, indicating that the
116            programmer himself fucked up somewhere. */
117         stderr_out("*** Error in SXEmacs initialization");
118         Fprint(x, Qexternal_debugging_output);
119         stderr_out("*** Backtrace\n");
120         Fbacktrace(Qexternal_debugging_output, Qt);
121         stderr_out("*** Killing SXEmacs\n");
122         return Fkill_emacs(make_int(-1));
123 }
124 \f
125 /**********************************************************************/
126 /*                     Command-loop (in C)                            */
127 /**********************************************************************/
128
129 #ifndef LISP_COMMAND_LOOP
130
131 /* The guts of the command loop are in command_loop_1().  This function
132    doesn't catch errors, though -- that's the job of command_loop_2(),
133    which is a condition-case wrapper around command_loop_1().
134    command_loop_1() never returns, but may get thrown out of.
135
136    When an error occurs, cmd_error() is called, which usually
137    invokes the Lisp error handler in `command-error'; however,
138    a default error handler is provided if `command-error' is nil
139    (e.g. during startup).  The purpose of the error handler is
140    simply to display the error message and do associated cleanup;
141    it does not need to throw anywhere.  When the error handler
142    finishes, the condition-case in command_loop_2() will finish and
143    command_loop_2() will reinvoke command_loop_1().
144
145    command_loop_2() is invoked from three places: from
146    initial_command_loop() (called from main() at the end of
147    internal initialization), from the Lisp function `recursive-edit',
148    and from call_command_loop().
149
150    call_command_loop() is called when a macro is started and when the
151    minibuffer is entered; normal termination of the macro or
152    minibuffer causes a throw out of the recursive command loop. (To
153    'execute-kbd-macro for macros and 'exit for minibuffers.  Note also
154    that the low-level minibuffer-entering function,
155    `read-minibuffer-internal', provides its own error handling and
156    does not need command_loop_2()'s error encapsulation; so it tells
157    call_command_loop() to invoke command_loop_1() directly.)
158
159    Note that both read-minibuffer-internal and recursive-edit set
160    up a catch for 'exit; this is why `abort-recursive-edit', which
161    throws to this catch, exits out of either one.
162
163    initial_command_loop(), called from main(), sets up a catch
164    for 'top-level when invoking command_loop_2(), allowing functions
165    to throw all the way to the top level if they really need to.
166    Before invoking command_loop_2(), initial_command_loop() calls
167    top_level_1(), which handles all of the startup stuff (creating
168    the initial frame, handling the command-line options, loading
169    the user's .emacs file, etc.).  The function that actually does this
170    is in Lisp and is pointed to by the variable `top-level';
171    normally this function is `normal-top-level'.  top_level_1() is
172    just an error-handling wrapper similar to command_loop_2().
173    Note also that initial_command_loop() sets up a catch for 'top-level
174    when invoking top_level_1(), just like when it invokes
175    command_loop_2(). */
176
177 static Lisp_Object cmd_error(Lisp_Object data, Lisp_Object dummy)
178 {
179         /* This function can GC */
180         check_quit();           /* make Vquit_flag accurate */
181         Vquit_flag = Qnil;
182
183         any_console_state();
184
185         if (!NILP(Ffboundp(Qcommand_error)))
186                 return call1(Qcommand_error, data);
187
188         return default_error_handler(data);
189 }
190
191 static Lisp_Object top_level_1(Lisp_Object dummy)
192 {
193         /* This function can GC */
194         /* On entry to the outer level, run the startup file */
195         if (!NILP(Vtop_level))
196                 condition_case_1(Qerror, Feval, Vtop_level, cmd_error, Qnil);
197 #if 1
198         else {
199                 message("\ntemacs can only be run in -batch mode.");
200                 noninteractive = 1;     /* prevent things under kill-emacs from blowing up */
201                 Fkill_emacs(make_int(-1));
202         }
203 #else
204         else if (purify_flag)
205                 message("Bare impure Emacs (standard Lisp code not loaded)");
206         else
207                 message("Bare Emacs (standard Lisp code not loaded)");
208 #endif
209
210         return Qnil;
211 }
212
213 /* Here we catch errors in execution of commands within the
214    editing loop, and reenter the editing loop.
215    When there is an error, cmd_error runs and the call
216    to condition_case_1() returns. */
217
218 /* Avoid confusing the compiler. A helper function for command_loop_2 */
219 static DOESNT_RETURN command_loop_3(void)
220 {
221 #ifdef LWLIB_MENUBARS_LUCID
222         extern int in_menu_callback;    /* defined in menubar-x.c */
223 #endif                          /* LWLIB_MENUBARS_LUCID */
224
225 #ifdef LWLIB_MENUBARS_LUCID
226         /*
227          * #### Fix the menu code so this isn't necessary.
228          *
229          * We cannot allow the lwmenu code to be reentered, because the
230          * code is not written to be reentrant and will crash.  Therefore
231          * paths from the menu callbacks back into the menu code have to
232          * be blocked.  Fnext_event is the normal path into the menu code,
233          * but waiting to signal an error there is too late in case where
234          * a new command loop has been started.  The error will be caught
235          * and Fnext_event will be called again, looping forever.  So we
236          * signal an error here to avoid the loop.
237          */
238         if (in_menu_callback)
239                 error("Attempt to enter command_loop_3 inside menu callback");
240 #endif                          /* LWLIB_MENUBARS_LUCID */
241         /* This function can GC */
242         for (;;) {
243                 condition_case_1(Qerror, command_loop_1, Qnil, cmd_error, Qnil);
244                 /* #### wrong with selected-console? */
245                 /* See command in initial_command_loop about why this value
246                    is 0. */
247                 reset_this_command_keys(Vselected_console, 0);
248         }
249 }
250
251 static Lisp_Object command_loop_2(Lisp_Object dummy)
252 {
253         command_loop_3();       /* doesn't return */
254         return Qnil;
255 }
256
257 /* This is called from emacs.c when it's done with initialization. */
258
259 DOESNT_RETURN initial_command_loop(Lisp_Object load_me)
260 {
261         /* This function can GC */
262         if (!NILP(load_me)) {
263                 Vtop_level = list2(Qload, load_me);
264         }
265
266         /* First deal with startup and command-line arguments.  A throw
267            to 'top-level gets us back here directly (does this ever happen?).
268            Otherwise, this function will return normally when all command-
269            line arguments have been processed, the user's initialization
270            file has been read in, and the first frame has been created. */
271         internal_catch(Qtop_level, top_level_1, Qnil, 0);
272
273         /* If an error occurred during startup and the initial console
274            wasn't created, then die now (the error was already printed out
275            on the terminal device). */
276         if (!noninteractive &&
277             (!CONSOLEP(Vselected_console) ||
278              CONSOLE_STREAM_P(XCONSOLE(Vselected_console)))) {
279                 fprintf(stderr,
280                         "\nFATAL error starting up initial console\n  "
281                         "noninteractive:%d CONSP(Vselected_console):%d "
282                         "CONSOLE_STREAM_P(XCONSOLE(...)):%d",
283                         noninteractive,
284                         CONSOLEP(Vselected_console),
285                         CONSOLE_STREAM_P(XCONSOLE(Vselected_console)));
286                 Fprin1(Vselected_console, Qnil);
287                 Fkill_emacs(make_int(-1));
288         }
289
290         /* End of -batch run causes exit here. */
291         if (noninteractive)
292                 Fkill_emacs(Qt);
293
294         for (;;) {
295                 command_loop_level = 0;
296                 MARK_MODELINE_CHANGED;
297                 /* Now invoke the command loop.  It never returns; however, a
298                    throw to 'top-level will place us at the end of this loop. */
299                 internal_catch(Qtop_level, command_loop_2, Qnil, 0);
300                 /* #### wrong with selected-console? */
301                 /* We don't actually call clear_echo_area() here, partially
302                    at least because that runs Lisp code and it may be unsafe
303                    to do so -- we are outside of the normal catches for
304                    errors and such. */
305                 reset_this_command_keys(Vselected_console, 0);
306         }
307 }
308
309 /* This function is invoked when a macro or minibuffer starts up.
310    Normal termination of the macro or minibuffer causes a throw past us.
311    See the comment above.
312
313    Note that this function never returns (but may be thrown out of). */
314
315 Lisp_Object call_command_loop(Lisp_Object catch_errors)
316 {
317         /* This function can GC */
318         if (NILP(catch_errors))
319                 return (command_loop_1(Qnil));
320         else
321                 return (command_loop_2(Qnil));
322 }
323
324 static Lisp_Object recursive_edit_unwind(Lisp_Object buffer)
325 {
326         if (!NILP(buffer))
327                 Fset_buffer(buffer);
328
329         command_loop_level--;
330         MARK_MODELINE_CHANGED;
331
332         return Qnil;
333 }
334
335 DEFUN("recursive-edit", Frecursive_edit, 0, 0, "",      /*
336 Invoke the editor command loop recursively.
337 To get out of the recursive edit, a command can do `(throw 'exit nil)';
338 that tells this function to return.
339 Alternately, `(throw 'exit t)' makes this function signal an error.
340 */
341       ())
342 {
343         /* This function can GC */
344         Lisp_Object val;
345         int speccount = specpdl_depth();
346
347         command_loop_level++;
348         MARK_MODELINE_CHANGED;
349
350         {
351                 Lisp_Object tmp = Fselected_window(Qnil);
352                 record_unwind_protect(recursive_edit_unwind,
353                                       ((current_buffer !=
354                                         XBUFFER(XWINDOW(tmp)->buffer))
355                                        ? Fcurrent_buffer()
356                                        : Qnil));
357         }
358
359         specbind(Qstandard_output, Qt);
360         specbind(Qstandard_input, Qt);
361
362         val = internal_catch(Qexit, command_loop_2, Qnil, 0);
363
364         if (EQ(val, Qt))
365                 /* Turn abort-recursive-edit into a quit. */
366                 Fsignal(Qquit, Qnil);
367
368         return unbind_to(speccount, Qnil);
369 }
370
371 #endif                          /* !LISP_COMMAND_LOOP */
372 \f
373 /**********************************************************************/
374 /*             Alternate command-loop (largely in Lisp)               */
375 /**********************************************************************/
376
377 #ifdef LISP_COMMAND_LOOP
378
379 static Lisp_Object load1(Lisp_Object name)
380 {
381         /* This function can GC */
382         call4(Qload, name, Qnil, Qt, Qnil);
383         return (Qnil);
384 }
385
386 /* emergency backups for cold-load-stream use */
387 static Lisp_Object
388 cold_load_command_error(Lisp_Object datum, Lisp_Object ignored)
389 {
390         /* This function can GC */
391         check_quit();           /* make Vquit_flag accurate */
392         Vquit_flag = Qnil;
393
394         return default_error_handler(datum);
395 }
396
397 static Lisp_Object cold_load_command_loop(Lisp_Object dummy)
398 {
399         /* This function can GC */
400         return (condition_case_1(Qt,
401                                  command_loop_1, Qnil,
402                                  cold_load_command_error, Qnil));
403 }
404
405 Lisp_Object call_command_loop(Lisp_Object catch_errors)
406 {
407         /* This function can GC */
408         reset_this_command_keys(Vselected_console, 0);  /* #### bleagh */
409
410       loop:
411         for (;;) {
412                 if (NILP(Vcommand_loop))
413                         break;
414                 call1(Vcommand_loop, catch_errors);
415         }
416
417         /* This isn't a "correct" definition, but you're pretty hosed if
418            you broke "command-loop" anyway */
419         /* #### not correct with Vselected_console */
420         XCONSOLE(Vselected_console)->prefix_arg = Qnil;
421         if (NILP(catch_errors))
422                 Fcommand_loop_1();
423         else
424                 internal_catch(Qtop_level, cold_load_command_loop, Qnil, 0);
425         goto loop;
426         return Qnil;
427 }
428
429 static Lisp_Object initial_error_handler(Lisp_Object datum, Lisp_Object ignored)
430 {
431         /* This function can GC */
432         Vcommand_loop = Qnil;
433         Fding(Qnil, Qnil, Qnil);
434
435         if (CONSP(datum) && EQ(XCAR(datum), Qquit))
436                 /* Don't bother with the message */
437                 return (Qt);
438
439         message("Error in command-loop!!");
440         Fset(intern("last-error"), datum);      /* #### Better/different name? */
441         Fsit_for(make_int(2), Qnil);
442         cold_load_command_error(datum, Qnil);
443         return (Qt);
444 }
445
446 DOESNT_RETURN initial_command_loop(Lisp_Object load_me)
447 {
448         /* This function can GC */
449         if (!NILP(load_me)) {
450                 if (!NILP(condition_case_1(Qt, load1, load_me,
451                                            initial_error_handler, Qnil)))
452                         Fkill_emacs(make_int(-1));
453         }
454
455         for (;;) {
456                 command_loop_level = 0;
457                 MARK_MODELINE_CHANGED;
458
459                 condition_case_1(Qt,
460                                  call_command_loop, Qtop_level,
461                                  initial_error_handler, Qnil);
462         }
463 }
464
465 #endif                          /* LISP_COMMAND_LOOP */
466 \f
467 /**********************************************************************/
468 /*                     Guts of command loop                           */
469 /**********************************************************************/
470
471 static Lisp_Object command_loop_1(Lisp_Object dummy)
472 {
473         /* This function can GC */
474         /* #### not correct with Vselected_console */
475         XCONSOLE(Vselected_console)->prefix_arg = Qnil;
476         return (Fcommand_loop_1());
477 }
478
479 /* This is the actual command reading loop, sans error-handling
480    encapsulation.  This is used for both the C and Lisp command
481    loops.  Originally this function was written in Lisp when
482    the Lisp command loop was used, but it was too slow that way.
483
484    Under the C command loop, this function will never return
485    (although someone might throw past it).  Under the Lisp
486    command loop, this will return only when the user specifies
487    a new command loop by changing the command-loop variable. */
488
489 DEFUN("command-loop-1", Fcommand_loop_1, 0, 0, 0,       /*
490 Invoke the internals of the canonical editor command loop.
491 Don't call this unless you know what you're doing.
492 */
493       ())
494 {
495         /* This function can GC */
496         Lisp_Object event = Fmake_event(Qnil, Qnil);
497 #if defined LISP_COMMAND_LOOP || !defined HAVE_BDWGC || !defined EF_USE_BDWGC
498         Lisp_Object old_loop = Qnil;
499 #endif
500         struct gcpro gcpro1, gcpro2;
501         int was_locked = in_single_console_state();
502         GCPRO2(event, old_loop);
503
504         /* cancel_echoing (); */
505         /* This magically makes single character keyboard macros work just
506            like the real thing.  This is slightly bogus, but it's in here for
507            compatibility with Emacs 18.  It's not even clear what the "right
508            thing" is. */
509         if (!((STRINGP(Vexecuting_macro) || VECTORP(Vexecuting_macro))
510               && XINT(Flength(Vexecuting_macro)) == 1))
511                 Vlast_command = Qt;
512
513 #ifndef LISP_COMMAND_LOOP
514         while (1)
515 #else
516         old_loop = Vcommand_loop;
517         while (EQ(Vcommand_loop, old_loop))
518 #endif                          /* LISP_COMMAND_LOOP */
519         {
520                 /* If focus_follows_mouse, make sure the frame with window manager
521                    focus is selected. */
522                 if (focus_follows_mouse)
523                         investigate_frame_change();
524
525                 /* Make sure the current window's buffer is selected.  */
526                 {
527                         Lisp_Object selected_window = Fselected_window(Qnil);
528
529                         if (!NILP(selected_window) &&
530                             (XBUFFER(XWINDOW(selected_window)->buffer) !=
531                              current_buffer)) {
532                                 set_buffer_internal(XBUFFER
533                                                     (XWINDOW(selected_window)->
534                                                      buffer));
535                         }
536                 }
537
538 #if 0                           /* What's wrong with going through ordinary procedure of quit?
539                                    quitting here leaves overriding-terminal-local-map
540                                    when you type C-u C-u C-g. */
541                 /* If ^G was typed before we got here (that is, before emacs was
542                    idle and waiting for input) then we treat that as an interrupt. */
543                 QUIT;
544 #endif
545
546                 /* If minibuffer on and echo area in use, wait 2 sec and redraw
547                    minibuffer.  Treat a ^G here as a command, not an interrupt.
548                  */
549                 if (minibuf_level > 0 && echo_area_active(selected_frame())) {
550                         /* Bind dont_check_for_quit to 1 so that C-g gets read in
551                            rather than quitting back to the minibuffer.  */
552                         int count = specpdl_depth();
553                         begin_dont_check_for_quit();
554                         Fsit_for(make_int(2), Qnil);
555                         clear_echo_area(selected_frame(), Qnil, 0);
556                         unbind_to(count, Qnil);
557                 }
558
559                 Fnext_event(event, Qnil);
560                 /* If ^G was typed while emacs was reading input from the user, then
561                    Fnext_event() will have read it as a normal event and
562                    next_event_internal() will have set Vquit_flag.  We reset this
563                    so that the ^G is treated as just another key.  This is strange,
564                    but it is what emacs 18 did.
565
566                    Do not call check_quit() here. */
567                 Vquit_flag = Qnil;
568                 Fdispatch_event(event);
569
570                 if (!was_locked)
571                         any_console_state();
572 #if (defined (__SUNPRO_C)                       \
573      || defined (__SUNPRO_CC)                   \
574      || (defined(DEC_ALPHA) && defined(OSF1)))
575         if (0)
576                 return Qnil;    /* Shut up compiler */
577 #endif
578         }
579 #ifdef LISP_COMMAND_LOOP
580         UNGCPRO;
581         return Qnil;
582 #else
583         return Qnil;
584 #endif
585 }
586 \f
587 /**********************************************************************/
588 /*                         Initialization                             */
589 /**********************************************************************/
590
591 void syms_of_cmdloop(void)
592 {
593         defsymbol(&Qcommand_error, "command-error");
594         defsymbol(&Qreally_early_error_handler, "really-early-error-handler");
595         defsymbol(&Qtop_level, "top-level");
596         defsymbol(&Qerrors_deactivate_region, "errors-deactivate-region");
597
598 #ifndef LISP_COMMAND_LOOP
599         DEFSUBR(Frecursive_edit);
600 #endif
601         DEFSUBR(Freally_early_error_handler);
602         DEFSUBR(Fcommand_loop_1);
603 }
604
605 void vars_of_cmdloop(void)
606 {
607         DEFVAR_INT("command-loop-level", &command_loop_level    /*
608 Number of recursive edits in progress.
609                                                                  */ );
610         command_loop_level = 0;
611
612         DEFVAR_LISP("disabled-command-hook", &Vdisabled_command_hook    /*
613 Value is called instead of any command that is disabled,
614 i.e. has a non-nil `disabled' property.
615                                                                          */ );
616         Vdisabled_command_hook = intern("disabled-command-hook");
617
618         DEFVAR_LISP("leave-window-hook", &Vleave_window_hook    /*
619 Not yet implemented.
620                                                                  */ );
621         Vleave_window_hook = Qnil;
622
623         DEFVAR_LISP("enter-window-hook", &Venter_window_hook    /*
624 Not yet implemented.
625                                                                  */ );
626         Venter_window_hook = Qnil;
627
628 #ifndef LISP_COMMAND_LOOP
629         DEFVAR_LISP("top-level", &Vtop_level    /*
630 Form to evaluate when Emacs starts up.
631 Useful to set before you dump a modified Emacs.
632                                                  */ );
633         Vtop_level = Qnil;
634 #else
635         DEFVAR_LISP("command-loop", &Vcommand_loop      /*
636 Function or one argument to call to read and process keyboard commands.
637 The passed argument specifies whether or not to handle errors.
638                                                          */ );
639         Vcommand_loop = Qnil;
640 #endif                          /* LISP_COMMAND_LOOP */
641 }