(x_bitmap_icon): Fix test for unallocated icon bitmap.
[bpt/emacs.git] / src / callint.c
CommitLineData
ec28a64d 1/* Call a Lisp function interactively.
4e87700b 2 Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
ec28a64d
MB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
dbc4e1c1 8the Free Software Foundation; either version 2, or (at your option)
ec28a64d
MB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
18160b98 21#include <config.h>
ec28a64d
MB
22#include "lisp.h"
23#include "buffer.h"
24#include "commands.h"
760cbdd3 25#include "keyboard.h"
ec28a64d
MB
26#include "window.h"
27#include "mocklisp.h"
28
29extern char *index ();
30
b498c415 31Lisp_Object Qminus, Qplus;
ec28a64d
MB
32Lisp_Object Qcall_interactively;
33Lisp_Object Vcommand_history;
34
35Lisp_Object Vcommand_debug_status, Qcommand_debug_status;
52614803 36Lisp_Object Qenable_recursive_minibuffers;
ec28a64d 37
9f315aeb
RS
38/* Non-nil means treat the mark as active
39 even if mark_active is 0. */
40Lisp_Object Vmark_even_if_inactive;
41
ef2515c0
RS
42Lisp_Object Vmouse_leave_buffer_hook, Qmouse_leave_buffer_hook;
43
03e130d5
RS
44Lisp_Object Qlist;
45Lisp_Object preserved_fns;
46
ec28a64d
MB
47/* This comment supplies the doc string for interactive,
48 for make-docfile to see. We cannot put this in the real DEFUN
49 due to limits in the Unix cpp.
50
51DEFUN ("interactive", Ffoo, Sfoo, 0, 0, 0,
52 "Specify a way of parsing arguments for interactive use of a function.\n\
53For example, write\n\
54 (defun foo (arg) \"Doc string\" (interactive \"p\") ...use arg...)\n\
55to make ARG be the prefix argument when `foo' is called as a command.\n\
56The \"call\" to `interactive' is actually a declaration rather than a function;\n\
57 it tells `call-interactively' how to read arguments\n\
58 to pass to the function.\n\
59When actually called, `interactive' just returns nil.\n\
60\n\
61The argument of `interactive' is usually a string containing a code letter\n\
62 followed by a prompt. (Some code letters do not use I/O to get\n\
63 the argument and do not need prompts.) To prompt for multiple arguments,\n\
64 give a code letter, its prompt, a newline, and another code letter, etc.\n\
65 Prompts are passed to format, and may use % escapes to print the\n\
66 arguments that have already been read.\n\
67If the argument is not a string, it is evaluated to get a list of\n\
68 arguments to pass to the function.\n\
69Just `(interactive)' means pass no args when calling interactively.\n\
70\nCode letters available are:\n\
71a -- Function name: symbol with a function definition.\n\
72b -- Name of existing buffer.\n\
73B -- Name of buffer, possibly nonexistent.\n\
74c -- Character.\n\
75C -- Command name: symbol with interactive function definition.\n\
76d -- Value of point as number. Does not do I/O.\n\
77D -- Directory name.\n\
4d1f43c0
RS
78e -- Parametrized event (i.e., one that's a list) that invoked this command.\n\
79 If used more than once, the Nth `e' returns the Nth parameterized event.\n\
80 This skips events that are integers or symbols.\n\
ec28a64d
MB
81f -- Existing file name.\n\
82F -- Possibly nonexistent file name.\n\
83k -- Key sequence (string).\n\
84m -- Value of mark as number. Does not do I/O.\n\
85n -- Number read using minibuffer.\n\
701ca6c0 86N -- Raw prefix arg, or if none, do like code `n'.\n\
ec28a64d
MB
87p -- Prefix arg converted to number. Does not do I/O.\n\
88P -- Prefix arg in raw form. Does not do I/O.\n\
89r -- Region: point and mark as 2 numeric args, smallest first. Does no I/O.\n\
90s -- Any string.\n\
91S -- Any symbol.\n\
92v -- Variable name: symbol that is user-variable-p.\n\
93x -- Lisp expression read but not evaluated.\n\
94X -- Lisp expression read and evaluated.\n\
95In addition, if the string begins with `*'\n\
96 then an error is signaled if the buffer is read-only.\n\
97 This happens before reading any arguments.\n\
dbc4e1c1
JB
98If the string begins with `@', then Emacs searches the key sequence\n\
99 which invoked the command for its first mouse click (or any other\n\
100 event which specifies a window), and selects that window before\n\
101 reading any arguments. You may use both `@' and `*'; they are\n\
102 processed in the order that they appear." */
ec28a64d
MB
103
104/* ARGSUSED */
105DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0,
106 0 /* See immediately above */)
107 (args)
108 Lisp_Object args;
109{
110 return Qnil;
111}
112
113/* Quotify EXP: if EXP is constant, return it.
114 If EXP is not constant, return (quote EXP). */
115Lisp_Object
116quotify_arg (exp)
117 register Lisp_Object exp;
118{
6e54b3de 119 if (!INTEGERP (exp) && !STRINGP (exp)
265a9e55 120 && !NILP (exp) && !EQ (exp, Qt))
ec28a64d
MB
121 return Fcons (Qquote, Fcons (exp, Qnil));
122
123 return exp;
124}
125
126/* Modify EXP by quotifying each element (except the first). */
127Lisp_Object
128quotify_args (exp)
129 Lisp_Object exp;
130{
131 register Lisp_Object tail;
132 register struct Lisp_Cons *ptr;
133 for (tail = exp; CONSP (tail); tail = ptr->cdr)
134 {
135 ptr = XCONS (tail);
136 ptr->car = quotify_arg (ptr->car);
137 }
138 return exp;
139}
140
141char *callint_argfuns[]
142 = {"", "point", "mark", "region-beginning", "region-end"};
143
144static void
145check_mark ()
146{
86c1cf23
KH
147 Lisp_Object tem;
148 tem = Fmarker_buffer (current_buffer->mark);
265a9e55 149 if (NILP (tem) || (XBUFFER (tem) != current_buffer))
ec28a64d 150 error ("The mark is not set now");
6497d2d8
RM
151 if (!NILP (Vtransient_mark_mode) && NILP (Vmark_even_if_inactive)
152 && NILP (current_buffer->mark_active))
153 Fsignal (Qmark_inactive, Qnil);
ec28a64d
MB
154}
155
156
157DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 2, 0,
158 "Call FUNCTION, reading args according to its interactive calling specs.\n\
159The function contains a specification of how to do the argument reading.\n\
160In the case of user-defined functions, this is specified by placing a call\n\
161to the function `interactive' at the top level of the function body.\n\
162See `interactive'.\n\
163\n\
164Optional second arg RECORD-FLAG non-nil\n\
165means unconditionally put this command in the command-history.\n\
166Otherwise, this is done only if an arg is read using the minibuffer.")
167 (function, record)
168 Lisp_Object function, record;
169{
170 Lisp_Object *args, *visargs;
171 unsigned char **argstrings;
172 Lisp_Object fun;
173 Lisp_Object funcar;
174 Lisp_Object specs;
175 Lisp_Object teml;
52614803
RS
176 Lisp_Object enable;
177 int speccount = specpdl_ptr - specpdl;
ec28a64d 178
bc78232c
JB
179 /* The index of the next element of this_command_keys to examine for
180 the 'e' interactive code. */
dbc4e1c1 181 int next_event;
bc78232c 182
ec28a64d
MB
183 Lisp_Object prefix_arg;
184 unsigned char *string;
185 unsigned char *tem;
63007de2
JB
186
187 /* If varies[i] > 0, the i'th argument shouldn't just have its value
188 in this call quoted in the command history. It should be
189 recorded as a call to the function named callint_argfuns[varies[i]]. */
ec28a64d 190 int *varies;
63007de2 191
ec28a64d
MB
192 register int i, j;
193 int count, foo;
194 char prompt[100];
195 char prompt1[100];
196 char *tem1;
197 int arg_from_tty = 0;
198 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
199
e5d77022 200 /* Save this now, since use of minibuffer will clobber it. */
b498c415 201 prefix_arg = current_perdisplay->Vcurrent_prefix_arg;
ec28a64d 202
46947372 203 retry:
ec28a64d 204
6e54b3de 205 if (SYMBOLP (function))
afa4c0f3 206 enable = Fget (function, Qenable_recursive_minibuffers);
52614803 207
ffd56f97 208 fun = indirect_function (function);
ec28a64d
MB
209
210 specs = Qnil;
211 string = 0;
212
213 /* Decode the kind of function. Either handle it and return,
214 or go to `lose' if not interactive, or go to `retry'
215 to specify a different function, or set either STRING or SPECS. */
216
6e54b3de 217 if (SUBRP (fun))
ec28a64d
MB
218 {
219 string = (unsigned char *) XSUBR (fun)->prompt;
220 if (!string)
221 {
222 lose:
b37902c8 223 function = wrong_type_argument (Qcommandp, function);
ec28a64d
MB
224 goto retry;
225 }
132b9337 226 if ((EMACS_INT) string == 1)
ec28a64d
MB
227 /* Let SPECS (which is nil) be used as the args. */
228 string = 0;
229 }
6e54b3de 230 else if (COMPILEDP (fun))
ec28a64d 231 {
f9b4aacf 232 if ((XVECTOR (fun)->size & PSEUDOVECTOR_SIZE_MASK) <= COMPILED_INTERACTIVE)
ec28a64d
MB
233 goto lose;
234 specs = XVECTOR (fun)->contents[COMPILED_INTERACTIVE];
235 }
236 else if (!CONSP (fun))
237 goto lose;
238 else if (funcar = Fcar (fun), EQ (funcar, Qautoload))
239 {
240 GCPRO2 (function, prefix_arg);
241 do_autoload (fun, function);
242 UNGCPRO;
243 goto retry;
244 }
245 else if (EQ (funcar, Qlambda))
246 {
247 specs = Fassq (Qinteractive, Fcdr (Fcdr (fun)));
265a9e55 248 if (NILP (specs))
ec28a64d
MB
249 goto lose;
250 specs = Fcar (Fcdr (specs));
251 }
252 else if (EQ (funcar, Qmocklisp))
253 return ml_apply (fun, Qinteractive);
254 else
255 goto lose;
256
46947372 257 /* If either specs or string is set to a string, use it. */
6e54b3de 258 if (STRINGP (specs))
46947372
JB
259 {
260 /* Make a copy of string so that if a GC relocates specs,
261 `string' will still be valid. */
e5d77022 262 string = (unsigned char *) alloca (XSTRING (specs)->size + 1);
46947372
JB
263 bcopy (XSTRING (specs)->data, string, XSTRING (specs)->size + 1);
264 }
ec28a64d
MB
265 else if (string == 0)
266 {
03e130d5 267 Lisp_Object input;
ec28a64d 268 i = num_input_chars;
03e130d5
RS
269 input = specs;
270 /* Compute the arg values using the user's expression. */
ec28a64d 271 specs = Feval (specs);
265a9e55 272 if (i != num_input_chars || !NILP (record))
03e130d5
RS
273 {
274 /* We should record this command on the command history. */
275 Lisp_Object values, car;
276 /* Make a copy of the list of values, for the command history,
277 and turn them into things we can eval. */
278 values = quotify_args (Fcopy_sequence (specs));
279 /* If the list of args was produced with an explicit call to `list',
280 look for elements that were computed with (region-beginning)
281 or (region-end), and put those expressions into VALUES
282 instead of the present values. */
283 car = Fcar (input);
284 if (EQ (car, Qlist))
285 {
286 Lisp_Object intail, valtail;
287 for (intail = Fcdr (input), valtail = values;
288 CONSP (valtail);
289 intail = Fcdr (intail), valtail = Fcdr (valtail))
290 {
291 Lisp_Object elt;
292 elt = Fcar (intail);
293 if (CONSP (elt))
294 {
295 Lisp_Object presflag;
296 presflag = Fmemq (Fcar (elt), preserved_fns);
297 if (!NILP (presflag))
298 Fsetcar (valtail, Fcar (intail));
299 }
300 }
301 }
302 Vcommand_history
303 = Fcons (Fcons (function, values), Vcommand_history);
304 }
ec28a64d
MB
305 return apply1 (function, specs);
306 }
307
308 /* Here if function specifies a string to control parsing the defaults */
309
dbc4e1c1
JB
310 /* Set next_event to point to the first event with parameters. */
311 for (next_event = 0; next_event < this_command_key_count; next_event++)
312 if (EVENT_HAS_PARAMETERS
313 (XVECTOR (this_command_keys)->contents[next_event]))
314 break;
315
42bb2790 316 /* Handle special starting chars `*' and `@'. Also `-'. */
ec28a64d
MB
317 while (1)
318 {
319 if (*string == '*')
320 {
321 string++;
265a9e55 322 if (!NILP (current_buffer->read_only))
ec28a64d
MB
323 Fbarf_if_buffer_read_only ();
324 }
42bb2790
RS
325 /* Ignore this for semi-compatibility with Lucid. */
326 else if (*string == '-')
327 string++;
ec28a64d
MB
328 else if (*string == '@')
329 {
86c1cf23 330 Lisp_Object event;
dbc4e1c1 331
86c1cf23 332 event = XVECTOR (this_command_keys)->contents[next_event];
dbc4e1c1 333 if (EVENT_HAS_PARAMETERS (event)
6e54b3de
KH
334 && (event = XCONS (event)->car, CONSP (event))
335 && (event = XCONS (event)->car, CONSP (event))
336 && (event = XCONS (event)->car), WINDOWP (event))
d1fa2e8a 337 {
d68807fc 338 if (MINI_WINDOW_P (XWINDOW (event))
42bb2790 339 && ! (minibuf_level > 0 && EQ (event, minibuf_window)))
d1fa2e8a 340 error ("Attempt to select inactive minibuffer window");
ef2515c0
RS
341
342 /* If the current buffer wants to clean up, let it. */
343 if (!NILP (Vmouse_leave_buffer_hook))
344 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
345
d1fa2e8a
KH
346 Fselect_window (event);
347 }
ec28a64d 348 string++;
ec28a64d
MB
349 }
350 else break;
351 }
352
353 /* Count the number of arguments the interactive spec would have
354 us give to the function. */
355 tem = string;
356 for (j = 0; *tem; j++)
357 {
358 /* 'r' specifications ("point and mark as 2 numeric args")
359 produce *two* arguments. */
360 if (*tem == 'r') j++;
361 tem = (unsigned char *) index (tem, '\n');
362 if (tem)
363 tem++;
364 else
365 tem = (unsigned char *) "";
366 }
367 count = j;
368
369 args = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object));
370 visargs = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object));
371 argstrings = (unsigned char **) alloca ((count + 1) * sizeof (char *));
372 varies = (int *) alloca ((count + 1) * sizeof (int));
373
374 for (i = 0; i < (count + 1); i++)
375 {
376 args[i] = Qnil;
377 visargs[i] = Qnil;
378 varies[i] = 0;
379 }
380
381 GCPRO4 (prefix_arg, function, *args, *visargs);
382 gcpro3.nvars = (count + 1);
383 gcpro4.nvars = (count + 1);
384
52614803
RS
385 if (!NILP (enable))
386 specbind (Qenable_recursive_minibuffers, Qt);
387
ec28a64d 388 tem = string;
46947372 389 for (i = 1; *tem; i++)
ec28a64d
MB
390 {
391 strncpy (prompt1, tem + 1, sizeof prompt1 - 1);
392 prompt1[sizeof prompt1 - 1] = 0;
393 tem1 = index (prompt1, '\n');
394 if (tem1) *tem1 = 0;
395 /* Fill argstrings with a vector of C strings
396 corresponding to the Lisp strings in visargs. */
397 for (j = 1; j < i; j++)
398 argstrings[j]
399 = EQ (visargs[j], Qnil)
400 ? (unsigned char *) ""
46947372 401 : XSTRING (visargs[j])->data;
ec28a64d
MB
402
403 doprnt (prompt, sizeof prompt, prompt1, 0, j - 1, argstrings + 1);
404
405 switch (*tem)
406 {
407 case 'a': /* Symbol defined as a function */
408 visargs[i] = Fcompleting_read (build_string (prompt),
409 Vobarray, Qfboundp, Qt, Qnil, Qnil);
410 /* Passing args[i] directly stimulates compiler bug */
411 teml = visargs[i];
412 args[i] = Fintern (teml, Qnil);
413 break;
414
415 case 'b': /* Name of existing buffer */
416 args[i] = Fcurrent_buffer ();
417 if (EQ (selected_window, minibuf_window))
9262fcb6 418 args[i] = Fother_buffer (args[i], Qnil);
ec28a64d
MB
419 args[i] = Fread_buffer (build_string (prompt), args[i], Qt);
420 break;
421
422 case 'B': /* Name of buffer, possibly nonexistent */
423 args[i] = Fread_buffer (build_string (prompt),
9262fcb6
RS
424 Fother_buffer (Fcurrent_buffer (), Qnil),
425 Qnil);
ec28a64d
MB
426 break;
427
428 case 'c': /* Character */
429 message1 (prompt);
430 args[i] = Fread_char ();
431 /* Passing args[i] directly stimulates compiler bug */
432 teml = args[i];
433 visargs[i] = Fchar_to_string (teml);
434 break;
435
436 case 'C': /* Command: symbol with interactive function */
437 visargs[i] = Fcompleting_read (build_string (prompt),
438 Vobarray, Qcommandp, Qt, Qnil, Qnil);
439 /* Passing args[i] directly stimulates compiler bug */
440 teml = visargs[i];
441 args[i] = Fintern (teml, Qnil);
442 break;
443
444 case 'd': /* Value of point. Does not do I/O. */
acab6442 445 XSETFASTINT (args[i], point);
ec28a64d
MB
446 /* visargs[i] = Qnil; */
447 varies[i] = 1;
448 break;
449
ec28a64d
MB
450 case 'D': /* Directory name. */
451 args[i] = Fread_file_name (build_string (prompt), Qnil,
452 current_buffer->directory, Qlambda, Qnil);
453 break;
454
455 case 'f': /* Existing file name. */
456 args[i] = Fread_file_name (build_string (prompt),
457 Qnil, Qnil, Qlambda, Qnil);
458 break;
459
460 case 'F': /* Possibly nonexistent file name. */
461 args[i] = Fread_file_name (build_string (prompt),
462 Qnil, Qnil, Qnil, Qnil);
463 break;
464
1989e7bc
RS
465 case 'k': /* Key sequence. */
466 args[i] = Fread_key_sequence (build_string (prompt), Qnil, Qnil);
467 teml = args[i];
468 visargs[i] = Fkey_description (teml);
469 break;
470
471 case 'K': /* Key sequence to be defined. */
472 args[i] = Fread_key_sequence (build_string (prompt), Qnil, Qt);
ec28a64d
MB
473 teml = args[i];
474 visargs[i] = Fkey_description (teml);
475 break;
476
bc78232c 477 case 'e': /* The invoking event. */
bc78232c
JB
478 if (next_event >= this_command_key_count)
479 error ("%s must be bound to an event with parameters",
6e54b3de 480 (SYMBOLP (function)
63007de2 481 ? (char *) XSYMBOL (function)->name->data
bc78232c 482 : "command"));
7e6491d3 483 args[i] = XVECTOR (this_command_keys)->contents[next_event++];
e5d77022 484 varies[i] = -1;
dbc4e1c1
JB
485
486 /* Find the next parameterized event. */
487 while (next_event < this_command_key_count
488 && ! (EVENT_HAS_PARAMETERS
489 (XVECTOR (this_command_keys)->contents[next_event])))
490 next_event++;
491
63007de2
JB
492 break;
493
ec28a64d
MB
494 case 'm': /* Value of mark. Does not do I/O. */
495 check_mark ();
496 /* visargs[i] = Qnil; */
acab6442 497 XSETFASTINT (args[i], marker_position (current_buffer->mark));
ec28a64d
MB
498 varies[i] = 2;
499 break;
500
501 case 'N': /* Prefix arg, else number from minibuffer */
265a9e55 502 if (!NILP (prefix_arg))
ec28a64d
MB
503 goto have_prefix_arg;
504 case 'n': /* Read number from minibuffer. */
505 do
506 args[i] = Fread_minibuffer (build_string (prompt), Qnil);
4746118a 507 while (! NUMBERP (args[i]));
ec28a64d
MB
508 visargs[i] = last_minibuf_string;
509 break;
510
511 case 'P': /* Prefix arg in raw form. Does no I/O. */
512 have_prefix_arg:
513 args[i] = prefix_arg;
514 /* visargs[i] = Qnil; */
515 varies[i] = -1;
516 break;
517
518 case 'p': /* Prefix arg converted to number. No I/O. */
519 args[i] = Fprefix_numeric_value (prefix_arg);
520 /* visargs[i] = Qnil; */
521 varies[i] = -1;
522 break;
523
524 case 'r': /* Region, point and mark as 2 args. */
525 check_mark ();
526 /* visargs[i+1] = Qnil; */
527 foo = marker_position (current_buffer->mark);
528 /* visargs[i] = Qnil; */
acab6442 529 XSETFASTINT (args[i], point < foo ? point : foo);
ec28a64d 530 varies[i] = 3;
acab6442 531 XSETFASTINT (args[++i], point > foo ? point : foo);
ec28a64d
MB
532 varies[i] = 4;
533 break;
534
535 case 's': /* String read via minibuffer. */
80896ab4 536 args[i] = Fread_string (build_string (prompt), Qnil, Qnil);
ec28a64d
MB
537 break;
538
539 case 'S': /* Any symbol. */
80896ab4 540 visargs[i] = Fread_string (build_string (prompt), Qnil, Qnil);
ec28a64d
MB
541 /* Passing args[i] directly stimulates compiler bug */
542 teml = visargs[i];
543 args[i] = Fintern (teml, Qnil);
544 break;
545
546 case 'v': /* Variable name: symbol that is
547 user-variable-p. */
548 args[i] = Fread_variable (build_string (prompt));
549 visargs[i] = last_minibuf_string;
550 break;
551
552 case 'x': /* Lisp expression read but not evaluated */
553 args[i] = Fread_minibuffer (build_string (prompt), Qnil);
554 visargs[i] = last_minibuf_string;
555 break;
556
557 case 'X': /* Lisp expression read and evaluated */
558 args[i] = Feval_minibuffer (build_string (prompt), Qnil);
559 visargs[i] = last_minibuf_string;
560 break;
561
562 default:
563 error ("Invalid control letter \"%c\" (%03o) in interactive calling string",
564 *tem, *tem);
565 }
566
567 if (varies[i] == 0)
568 arg_from_tty = 1;
569
6e54b3de 570 if (NILP (visargs[i]) && STRINGP (args[i]))
ec28a64d
MB
571 visargs[i] = args[i];
572
573 tem = (unsigned char *) index (tem, '\n');
574 if (tem) tem++;
575 else tem = (unsigned char *) "";
576 }
52614803 577 unbind_to (speccount, Qnil);
ec28a64d
MB
578
579 QUIT;
580
581 args[0] = function;
582
265a9e55 583 if (arg_from_tty || !NILP (record))
ec28a64d
MB
584 {
585 visargs[0] = function;
63007de2
JB
586 for (i = 1; i < count + 1; i++)
587 if (varies[i] > 0)
ec28a64d
MB
588 visargs[i] = Fcons (intern (callint_argfuns[varies[i]]), Qnil);
589 else
590 visargs[i] = quotify_arg (args[i]);
591 Vcommand_history = Fcons (Flist (count + 1, visargs),
592 Vcommand_history);
593 }
594
595 {
596 Lisp_Object val;
ec28a64d
MB
597 specbind (Qcommand_debug_status, Qnil);
598
599 val = Ffuncall (count + 1, args);
600 UNGCPRO;
601 return unbind_to (speccount, val);
602 }
603}
604
605DEFUN ("prefix-numeric-value", Fprefix_numeric_value, Sprefix_numeric_value,
606 1, 1, 0,
607 "Return numeric meaning of raw prefix argument ARG.\n\
608A raw prefix argument is what you get from `(interactive \"P\")'.\n\
609Its numeric meaning is what you would get from `(interactive \"p\")'.")
610 (raw)
611 Lisp_Object raw;
612{
613 Lisp_Object val;
614
265a9e55 615 if (NILP (raw))
acab6442 616 XSETFASTINT (val, 1);
fd5285f3 617 else if (EQ (raw, Qminus))
ec28a64d
MB
618 XSETINT (val, -1);
619 else if (CONSP (raw))
620 XSETINT (val, XINT (XCONS (raw)->car));
6e54b3de 621 else if (INTEGERP (raw))
ec28a64d
MB
622 val = raw;
623 else
acab6442 624 XSETFASTINT (val, 1);
ec28a64d
MB
625
626 return val;
627}
628
629syms_of_callint ()
630{
03e130d5
RS
631 preserved_fns = Fcons (intern ("region-beginning"),
632 Fcons (intern ("region-end"),
633 Fcons (intern ("point"),
634 Fcons (intern ("mark"), Qnil))));
635 staticpro (&preserved_fns);
636
637 Qlist = intern ("list");
638 staticpro (&Qlist);
639
ec28a64d
MB
640 Qminus = intern ("-");
641 staticpro (&Qminus);
642
fdb4a38c
RS
643 Qplus = intern ("+");
644 staticpro (&Qplus);
645
ec28a64d
MB
646 Qcall_interactively = intern ("call-interactively");
647 staticpro (&Qcall_interactively);
648
649 Qcommand_debug_status = intern ("command-debug-status");
650 staticpro (&Qcommand_debug_status);
651
52614803
RS
652 Qenable_recursive_minibuffers = intern ("enable-recursive-minibuffers");
653 staticpro (&Qenable_recursive_minibuffers);
654
ef2515c0
RS
655 Qmouse_leave_buffer_hook = intern ("mouse-leave-buffer-hook");
656 staticpro (&Qmouse_leave_buffer_hook);
657
ec28a64d
MB
658 DEFVAR_LISP ("command-history", &Vcommand_history,
659 "List of recent commands that read arguments from terminal.\n\
660Each command is represented as a form to evaluate.");
661 Vcommand_history = Qnil;
662
663 DEFVAR_LISP ("command-debug-status", &Vcommand_debug_status,
664 "Debugging status of current interactive command.\n\
665Bound each time `call-interactively' is called;\n\
666may be set by the debugger as a reminder for itself.");
667 Vcommand_debug_status = Qnil;
668
2ad6c959 669 DEFVAR_LISP ("mark-even-if-inactive", &Vmark_even_if_inactive,
9f315aeb
RS
670 "*Non-nil means you can use the mark even when inactive.\n\
671This option makes a difference in Transient Mark mode.\n\
672When the option is non-nil, deactivation of the mark\n\
673turns off region highlighting, but commands that use the mark\n\
674behave as if the mark were still active.");
675 Vmark_even_if_inactive = Qnil;
676
ef2515c0
RS
677 DEFVAR_LISP ("mouse-leave-buffer-hook", &Vmouse_leave_buffer_hook,
678 "Hook to run when about to switch windows with a mouse command.\n\
679Its purpose is to give temporary modes such as Isearch mode\n\
680a way to turn themselves off when a mouse command switches windows.");
681 Vmouse_leave_buffer_hook = Qnil;
682
ec28a64d
MB
683 defsubr (&Sinteractive);
684 defsubr (&Scall_interactively);
685 defsubr (&Sprefix_numeric_value);
686}