I think a simpler and better change is to relax this restriction in `fix_command' to allow `if' with else-forms, and keep region-beginning in the history only if it is presented in then-form.
This is not correct. Specifically, it gives wrong results in the case of (if FOO (region-beginning) (my-function)) It will "preserve" this argument even if (my-function) should not be treated that way. It would be ok to change fix_command to check _both_ arms of the if. I wrote a patch for that; see below. Could you try it? After the release, I think it calls for a different approach. For instance, we could write (interactive (list (recompute-arg EXPRESSION) (recompute-arg EXPRESSION) ...)) When evaluated, recompute-arg would return its arg, but when fix_command sees it, it would save EXPRESSION as the value. *** callint.c 07 Aug 2005 13:30:36 -0400 1.140 --- callint.c 11 Dec 2005 17:40:40 -0500 *************** *** 64,69 **** --- 64,71 ---- /* Allocated length of that buffer. */ static int callint_message_size; + static int recomputable_arg_p P_ ((Lisp_Object)); + /* ARGSUSED */ DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0, doc: /* Specify a way of parsing arguments for interactive use of a function. *************** *** 189,210 **** fix_command (input, values) Lisp_Object input, values; { ! if (CONSP (input)) { Lisp_Object car; car = XCAR (input); /* Skip through certain special forms. */ ! while (EQ (car, Qlet) || EQ (car, Qletx) ! || EQ (car, Qsave_excursion) ! || EQ (car, Qprogn)) { ! while (CONSP (XCDR (input))) ! input = XCDR (input); ! input = XCAR (input); ! if (!CONSP (input)) break; - car = XCAR (input); } if (EQ (car, Qlist)) { --- 191,226 ---- fix_command (input, values) Lisp_Object input, values; { ! if (CONSP (input) && CONSP (values)) { Lisp_Object car; car = XCAR (input); /* Skip through certain special forms. */ ! while (1) { ! if (EQ (car, Qlet) || EQ (car, Qletx) ! || EQ (car, Qsave_excursion) ! || EQ (car, Qprogn) ! || EQ (car, Qwhen)) ! { ! while (CONSP (XCDR (input))) ! input = XCDR (input); ! input = XCAR (input); ! if (!CONSP (input)) ! break; ! car = XCAR (input); ! } ! else if (EQ (car, Qif) ! && EQ (Fnthcdr (make_number (3), input), Qnil)) ! { ! input = Fnth (make_number (2), input); ! if (!CONSP (input)) ! break; ! car = XCAR (input); ! } ! else break; } if (EQ (car, Qlist)) { *************** *** 215,249 **** { Lisp_Object elt; elt = Fcar (intail); ! if (CONSP (elt)) ! { ! Lisp_Object presflag, carelt; ! carelt = Fcar (elt); ! /* If it is (if X Y), look at Y. */ ! if (EQ (carelt, Qif) ! && EQ (Fnthcdr (make_number (3), elt), Qnil)) ! elt = Fnth (make_number (2), elt); ! /* If it is (when ... Y), look at Y. */ ! else if (EQ (carelt, Qwhen)) ! { ! while (CONSP (XCDR (elt))) ! elt = XCDR (elt); ! elt = Fcar (elt); ! } ! ! /* If the function call we're looking at ! is a special preserved one, copy the ! whole expression for this argument. */ ! if (CONSP (elt)) ! { ! presflag = Fmemq (Fcar (elt), preserved_fns); ! if (!NILP (presflag)) ! Fsetcar (valtail, Fcar (intail)); ! } ! } } } } } DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0, --- 231,286 ---- { Lisp_Object elt; elt = Fcar (intail); ! ! if (recomputable_arg_p (elt)) ! Fsetcar (valtail, elt); } } } + } + + /* Return 1 if EXP, when used in (interactive (list ...)) + to compute one of the arguments, should be recorded and + recomputed if we repeat the command. */ + + static int + recomputable_arg_p (exp) + Lisp_Object exp; + { + Lisp_Object presflag, carelt; + + if (!CONSP (exp)) + return 0; + + carelt = Fcar (exp); + /* If it is (if X Y), look at Y. + If it is (if X Y Z), look at Y and Z. */ + if (EQ (carelt, Qif)) + { + /* Test the then-clause. */ + if (! recomputable_arg_p (Fnth (make_number (2), exp))) + return 0; + /* More than one else-clause means we fail. */ + if (! NILP (Fnthcdr (make_number (4), exp))) + return 0; + /* Test the else-clause. */ + return recomputable_arg_p (Fnth (make_number (3), exp)); + } + + /* If it is (when X Y), look at Y. */ + if (EQ (carelt, Qwhen)) + { + /* More than one then-clause means we fail. */ + if (! NILP (Fnthcdr (make_number (4), exp))) + return 0; + /* Test Y. */ + return recomputable_arg_p (Fnth (make_number (2), exp)); + } + + /* If the function call we're looking at + is a special preserved one, it is ok. */ + presflag = Fmemq (carelt, preserved_fns); + return !NILP (presflag); } DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0, _______________________________________________ emacs-pretest-bug mailing list emacs-pretest-bug@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-pretest-bug