/* Call a Lisp function interactively.
- Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
This file is part of GNU Emacs.
extern char *index ();
+int current_prefix_partial;
Lisp_Object Vprefix_arg, Vcurrent_prefix_arg, Qminus, Qplus;
Lisp_Object Qcall_interactively;
Lisp_Object Vcommand_history;
even if mark_active is 0. */
Lisp_Object Vmark_even_if_inactive;
+Lisp_Object Vmouse_leave_buffer_hook, Qmouse_leave_buffer_hook;
+
Lisp_Object Qlist;
-Lisp_Object preserved_fns;
+static Lisp_Object preserved_fns;
+
+/* Marker used within call-interactively to refer to point. */
+static Lisp_Object point_marker;
+
+
+void
+clear_prefix_arg ()
+{
+ Vprefix_arg = Qnil;
+ if (!current_prefix_partial)
+ {
+ current_kboard->prefix_factor = Qnil;
+ current_kboard->prefix_value = Qnil;
+ current_kboard->prefix_sign = 1;
+ current_kboard->prefix_partial = 0;
+ }
+}
+
+void
+finalize_prefix_arg ()
+{
+ if (!NILP (current_kboard->prefix_factor))
+ Vprefix_arg = Fcons (current_kboard->prefix_factor, Qnil);
+ else if (NILP (current_kboard->prefix_value))
+ Vprefix_arg = (current_kboard->prefix_sign > 0 ? Qnil : Qminus);
+ else if (current_kboard->prefix_sign > 0)
+ Vprefix_arg = current_kboard->prefix_value;
+ else
+ XSETINT (Vprefix_arg, -XINT (current_kboard->prefix_value));
+ current_kboard->prefix_partial = 0;
+}
+
+static void
+describe_prefix_arg ()
+{
+ if (INTEGERP (Vprefix_arg))
+ message ("Arg: %d", Vprefix_arg);
+ else if (CONSP (Vprefix_arg))
+ message ("Arg: [%d]", XCONS (Vprefix_arg)->car);
+ else if (EQ (Vprefix_arg, Qminus))
+ message ("Arg: -");
+}
+
/* This comment supplies the doc string for interactive,
for make-docfile to see. We cannot put this in the real DEFUN
This skips events that are integers or symbols.\n\
f -- Existing file name.\n\
F -- Possibly nonexistent file name.\n\
-k -- Key sequence (string).\n\
+k -- Key sequence (downcase the last event if needed to get a definition).\n\
+K -- Key sequence to be redefined (do not downcase the last event).\n\
m -- Value of mark as number. Does not do I/O.\n\
n -- Number read using minibuffer.\n\
-N -- Prefix arg converted to number, or if none, do like code `n'.\n\
+N -- Raw prefix arg, or if none, do like code `n'.\n\
p -- Prefix arg converted to number. Does not do I/O.\n\
P -- Prefix arg in raw form. Does not do I/O.\n\
r -- Region: point and mark as 2 numeric args, smallest first. Does no I/O.\n\
}
else if (COMPILEDP (fun))
{
- if (XVECTOR (fun)->size <= COMPILED_INTERACTIVE)
+ if ((XVECTOR (fun)->size & PSEUDOVECTOR_SIZE_MASK) <= COMPILED_INTERACTIVE)
goto lose;
specs = XVECTOR (fun)->contents[COMPILED_INTERACTIVE];
}
specs = Fcar (Fcdr (specs));
}
else if (EQ (funcar, Qmocklisp))
- return ml_apply (fun, Qinteractive);
+ {
+ single_kboard_state ();
+ return ml_apply (fun, Qinteractive);
+ }
else
goto lose;
Vcommand_history
= Fcons (Fcons (function, values), Vcommand_history);
}
+ single_kboard_state ();
return apply1 (function, specs);
}
break;
/* Handle special starting chars `*' and `@'. Also `-'. */
+ /* Note that `+' is reserved for user extensions. */
while (1)
{
- if (*string == '*')
+ if (*string == '+')
+ error ("`+' is not used in `interactive' for ordinary commands");
+ else if (*string == '*')
{
string++;
if (!NILP (current_buffer->read_only))
if (MINI_WINDOW_P (XWINDOW (event))
&& ! (minibuf_level > 0 && EQ (event, minibuf_window)))
error ("Attempt to select inactive minibuffer window");
+
+ /* If the current buffer wants to clean up, let it. */
+ if (!NILP (Vmouse_leave_buffer_hook))
+ call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
+
Fselect_window (event);
}
string++;
break;
case 'd': /* Value of point. Does not do I/O. */
- XFASTINT (args[i]) = point;
+ Fset_marker (point_marker, make_number (PT), Qnil);
+ args[i] = point_marker;
/* visargs[i] = Qnil; */
varies[i] = 1;
break;
Qnil, Qnil, Qnil, Qnil);
break;
- case 'k': /* Key sequence (string) */
- args[i] = Fread_key_sequence (build_string (prompt), Qnil);
+ case 'k': /* Key sequence. */
+ args[i] = Fread_key_sequence (build_string (prompt), Qnil, Qnil, Qnil);
+ teml = args[i];
+ visargs[i] = Fkey_description (teml);
+ break;
+
+ case 'K': /* Key sequence to be defined. */
+ args[i] = Fread_key_sequence (build_string (prompt), Qnil, Qt, Qnil);
teml = args[i];
visargs[i] = Fkey_description (teml);
break;
case 'm': /* Value of mark. Does not do I/O. */
check_mark ();
/* visargs[i] = Qnil; */
- XFASTINT (args[i]) = marker_position (current_buffer->mark);
+ args[i] = current_buffer->mark;
varies[i] = 2;
break;
case 'r': /* Region, point and mark as 2 args. */
check_mark ();
+ Fset_marker (point_marker, make_number (PT), Qnil);
/* visargs[i+1] = Qnil; */
foo = marker_position (current_buffer->mark);
/* visargs[i] = Qnil; */
- XFASTINT (args[i]) = point < foo ? point : foo;
+ args[i] = point < foo ? point_marker : current_buffer->mark;
varies[i] = 3;
- XFASTINT (args[++i]) = point > foo ? point : foo;
+ args[++i] = point > foo ? point_marker : current_buffer->mark;
varies[i] = 4;
break;
case 's': /* String read via minibuffer. */
- args[i] = Fread_string (build_string (prompt), Qnil);
+ args[i] = Fread_string (build_string (prompt), Qnil, Qnil);
break;
case 'S': /* Any symbol. */
- visargs[i] = Fread_string (build_string (prompt), Qnil);
+ visargs[i] = Fread_string (build_string (prompt), Qnil, Qnil);
/* Passing args[i] directly stimulates compiler bug */
teml = visargs[i];
args[i] = Fintern (teml, Qnil);
visargs[i] = last_minibuf_string;
break;
+ /* We have a case for `+' so we get an error
+ if anyone tries to define one here. */
+ case '+':
default:
- error ("Invalid control letter \"%c\" (%03o) in interactive calling string",
+ error ("Invalid control letter `%c' (%03o) in interactive calling string",
*tem, *tem);
}
{
visargs[0] = function;
for (i = 1; i < count + 1; i++)
- if (varies[i] > 0)
- visargs[i] = Fcons (intern (callint_argfuns[varies[i]]), Qnil);
- else
- visargs[i] = quotify_arg (args[i]);
+ {
+ if (varies[i] > 0)
+ visargs[i] = Fcons (intern (callint_argfuns[varies[i]]), Qnil);
+ else
+ visargs[i] = quotify_arg (args[i]);
+ }
Vcommand_history = Fcons (Flist (count + 1, visargs),
Vcommand_history);
}
+ /* If we used a marker to hold point, mark, or an end of the region,
+ temporarily, convert it to an integer now. */
+ for (i = 1; i <= count; i++)
+ if (varies[i] >= 1 && varies[i] <= 4)
+ XSETINT (args[i], marker_position (args[i]));
+
+ single_kboard_state ();
+
{
Lisp_Object val;
specbind (Qcommand_debug_status, Qnil);
Lisp_Object val;
if (NILP (raw))
- XFASTINT (val) = 1;
+ XSETFASTINT (val, 1);
else if (EQ (raw, Qminus))
XSETINT (val, -1);
else if (CONSP (raw))
else if (INTEGERP (raw))
val = raw;
else
- XFASTINT (val) = 1;
+ XSETFASTINT (val, 1);
return val;
}
+DEFUN ("universal-argument", Funiversal_argument, Suniversal_argument, 0, 0, "",
+ "Begin a numeric argument for the following command.\n\
+Digits or minus sign following \\[universal-argument] make up the numeric argument.\n\
+\\[universal-argument] following the digits or minus sign ends the argument.\n\
+\\[universal-argument] without digits or minus sign provides 4 as argument.\n\
+Repeating \\[universal-argument] without digits or minus sign\n\
+ multiplies the argument by 4 each time.")
+ ()
+{
+ if (!current_prefix_partial)
+ {
+ /* First C-u */
+ XSETFASTINT (current_kboard->prefix_factor, 4);
+ current_kboard->prefix_value = Qnil;
+ current_kboard->prefix_sign = 1;
+ current_kboard->prefix_partial = 1;
+ }
+ else if (!NILP (current_kboard->prefix_factor))
+ {
+ /* Subsequent C-u */
+ XSETINT (current_kboard->prefix_factor,
+ XINT (current_kboard->prefix_factor) * 4);
+ current_kboard->prefix_partial = 1;
+ }
+ else
+ {
+ /* Terminating C-u */
+ finalize_prefix_arg ();
+ describe_prefix_arg ();
+ }
+}
+
+DEFUN ("negative-argument", Fnegative_argument, Snegative_argument, 0, 0, "",
+ "Begin a negative numeric argument for the next command.\n\
+\\[universal-argument] following digits or minus sign ends the argument.")
+ ()
+{
+ current_kboard->prefix_factor = Qnil;
+ current_kboard->prefix_sign *= -1;
+ current_kboard->prefix_partial = 1;
+}
+
+DEFUN ("digit-argument", Fdigit_argument, Sdigit_argument, 0, 0, "",
+ "Part of the numeric argument for the next command.\n\
+\\[universal-argument] following digits or minus sign ends the argument.")
+ ()
+{
+ int c;
+ if (!(INTEGERP (last_command_char)
+ && (c = (XINT (last_command_char) & 0177)) >= '0' && c <= '9'))
+ error("digit-argument must be bound to a digit key");
+ current_kboard->prefix_factor = Qnil;
+ if (NILP (current_kboard->prefix_value))
+ XSETFASTINT (current_kboard->prefix_value, 0);
+ XSETINT (current_kboard->prefix_value,
+ XINT (current_kboard->prefix_value) * 10 + (c - '0'));
+ current_kboard->prefix_partial = 1;
+}
+
syms_of_callint ()
{
+ point_marker = Fmake_marker ();
+ staticpro (&point_marker);
+
preserved_fns = Fcons (intern ("region-beginning"),
Fcons (intern ("region-end"),
Fcons (intern ("point"),
Qenable_recursive_minibuffers = intern ("enable-recursive-minibuffers");
staticpro (&Qenable_recursive_minibuffers);
+ Qmouse_leave_buffer_hook = intern ("mouse-leave-buffer-hook");
+ staticpro (&Qmouse_leave_buffer_hook);
+
DEFVAR_LISP ("prefix-arg", &Vprefix_arg,
"The value of the prefix argument for the next editing command.\n\
It may be a number, or the symbol `-' for just a minus sign as arg,\n\
behave as if the mark were still active.");
Vmark_even_if_inactive = Qnil;
+ DEFVAR_LISP ("mouse-leave-buffer-hook", &Vmouse_leave_buffer_hook,
+ "Hook to run when about to switch windows with a mouse command.\n\
+Its purpose is to give temporary modes such as Isearch mode\n\
+a way to turn themselves off when a mouse command switches windows.");
+ Vmouse_leave_buffer_hook = Qnil;
+
defsubr (&Sinteractive);
defsubr (&Scall_interactively);
defsubr (&Sprefix_numeric_value);
+ defsubr (&Suniversal_argument);
+ defsubr (&Snegative_argument);
+ defsubr (&Sdigit_argument);
}