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