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