]> code.delx.au - gnu-emacs/blobdiff - src/callint.c
(pos_visible_p): Adjust X value if window is hscrolled.
[gnu-emacs] / src / callint.c
index 21a6bd0b1ad014b613ae8fb73197eea1e7aff784..5979e495ac361aab38ddd60bf939bc30132d7cdb 100644 (file)
@@ -1,6 +1,6 @@
 /* Call a Lisp function interactively.
 /* Call a Lisp function interactively.
-   Copyright (C) 1985, 86, 93, 94, 95, 1997, 2000, 02, 2003
-   Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 2000, 2002, 2003,
+                 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 
 #include <config.h>
 
 
 #include <config.h>
@@ -98,6 +98,7 @@ e -- Parametrized event (i.e., one that's a list) that invoked this command.
      This skips events that are integers or symbols.
 f -- Existing file name.
 F -- Possibly nonexistent file name.
      This skips events that are integers or symbols.
 f -- Existing file name.
 F -- Possibly nonexistent file name.
+G -- Possibly nonexistent file name, defaulting to just directory name.
 i -- Ignored, i.e. always nil.  Does not do I/O.
 k -- Key sequence (downcase the last event if needed to get a definition).
 K -- Key sequence to be redefined (do not downcase the last event).
 i -- Ignored, i.e. always nil.  Does not do I/O.
 k -- Key sequence (downcase the last event if needed to get a definition).
 K -- Key sequence to be redefined (do not downcase the last event).
@@ -110,6 +111,7 @@ P -- Prefix arg in raw form.  Does not do I/O.
 r -- Region: point and mark as 2 numeric args, smallest first.  Does no I/O.
 s -- Any string.  Does not inherit the current input method.
 S -- Any symbol.
 r -- Region: point and mark as 2 numeric args, smallest first.  Does no I/O.
 s -- Any string.  Does not inherit the current input method.
 S -- Any symbol.
+U -- Mouse up event discarded by a previous k or K argument.
 v -- Variable name: symbol that is user-variable-p.
 x -- Lisp expression read but not evaluated.
 X -- Lisp expression read and evaluated.
 v -- Variable name: symbol that is user-variable-p.
 x -- Lisp expression read but not evaluated.
 X -- Lisp expression read and evaluated.
@@ -209,7 +211,7 @@ fix_command (input, values)
          Lisp_Object intail, valtail;
          for (intail = Fcdr (input), valtail = values;
               CONSP (valtail);
          Lisp_Object intail, valtail;
          for (intail = Fcdr (input), valtail = values;
               CONSP (valtail);
-              intail = Fcdr (intail), valtail = Fcdr (valtail))
+              intail = Fcdr (intail), valtail = XCDR (valtail))
            {
              Lisp_Object elt;
              elt = Fcar (intail);
            {
              Lisp_Object elt;
              elt = Fcar (intail);
@@ -256,17 +258,18 @@ Optional second arg RECORD-FLAG non-nil
 means unconditionally put this command in the command-history.
 Otherwise, this is done only if an arg is read using the minibuffer.
 Optional third arg KEYS, if given, specifies the sequence of events to
 means unconditionally put this command in the command-history.
 Otherwise, this is done only if an arg is read using the minibuffer.
 Optional third arg KEYS, if given, specifies the sequence of events to
-supply if the command inquires which events were used to invoke it.  */)
+supply if the command inquires which events were used to invoke it.
+If KEYS is omitted or nil, the return value of `this-command-keys' is used.  */)
      (function, record_flag, keys)
      Lisp_Object function, record_flag, keys;
 {
   Lisp_Object *args, *visargs;
   unsigned char **argstrings;
   Lisp_Object fun;
      (function, record_flag, keys)
      Lisp_Object function, record_flag, keys;
 {
   Lisp_Object *args, *visargs;
   unsigned char **argstrings;
   Lisp_Object fun;
-  Lisp_Object funcar;
   Lisp_Object specs;
   Lisp_Object filter_specs;
   Lisp_Object teml;
   Lisp_Object specs;
   Lisp_Object filter_specs;
   Lisp_Object teml;
+  Lisp_Object up_event;
   Lisp_Object enable;
   int speccount = SPECPDL_INDEX ();
 
   Lisp_Object enable;
   int speccount = SPECPDL_INDEX ();
 
@@ -288,7 +291,7 @@ supply if the command inquires which events were used to invoke it.  */)
   char prompt1[100];
   char *tem1;
   int arg_from_tty = 0;
   char prompt1[100];
   char *tem1;
   int arg_from_tty = 0;
-  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   int key_count;
   int record_then_fail = 0;
 
   int key_count;
   int record_then_fail = 0;
 
@@ -327,6 +330,9 @@ supply if the command inquires which events were used to invoke it.  */)
      The feature is not fully implemented.  */
   filter_specs = Qnil;
 
      The feature is not fully implemented.  */
   filter_specs = Qnil;
 
+  /* If k or K discard an up-event, save it here so it can be retrieved with U */
+  up_event = Qnil;
+
   /* Decode the kind of function.  Either handle it and return,
      or go to `lose' if not interactive, or go to `retry'
      to specify a different function, or set either STRING or SPECS.  */
   /* Decode the kind of function.  Either handle it and return,
      or go to `lose' if not interactive, or go to `retry'
      to specify a different function, or set either STRING or SPECS.  */
@@ -347,25 +353,17 @@ supply if the command inquires which events were used to invoke it.  */)
        goto lose;
       specs = XVECTOR (fun)->contents[COMPILED_INTERACTIVE];
     }
        goto lose;
       specs = XVECTOR (fun)->contents[COMPILED_INTERACTIVE];
     }
-  else if (!CONSP (fun))
-    goto lose;
-  else if (funcar = XCAR (fun), EQ (funcar, Qautoload))
+  else
     {
     {
+      Lisp_Object form;
       GCPRO2 (function, prefix_arg);
       GCPRO2 (function, prefix_arg);
-      do_autoload (fun, function);
+      form = Finteractive_form (function);
       UNGCPRO;
       UNGCPRO;
-      goto retry;
-    }
-  else if (EQ (funcar, Qlambda))
-    {
-      specs = Fassq (Qinteractive, Fcdr (XCDR (fun)));
-      if (NILP (specs))
+      if (CONSP (form))
+       specs = filter_specs = Fcar (XCDR (form));
+      else
        goto lose;
        goto lose;
-      filter_specs = Fnth (make_number (1), specs);
-      specs = Fcar (Fcdr (specs));
     }
     }
-  else
-    goto lose;
 
   /* If either SPECS or STRING is set to a string, use it.  */
   if (STRINGP (specs))
 
   /* If either SPECS or STRING is set to a string, use it.  */
   if (STRINGP (specs))
@@ -453,25 +451,25 @@ supply if the command inquires which events were used to invoke it.  */)
        string++;
       else if (*string == '@')
        {
        string++;
       else if (*string == '@')
        {
-         Lisp_Object event;
+         Lisp_Object event, tem;
 
          event = (next_event < key_count
                   ? XVECTOR (keys)->contents[next_event]
                   : Qnil);
          if (EVENT_HAS_PARAMETERS (event)
 
          event = (next_event < key_count
                   ? XVECTOR (keys)->contents[next_event]
                   : Qnil);
          if (EVENT_HAS_PARAMETERS (event)
-             && (event = XCDR (event), CONSP (event))
-             && (event = XCAR (event), CONSP (event))
-             && (event = XCAR (event), WINDOWP (event)))
+             && (tem = XCDR (event), CONSP (tem))
+             && (tem = XCAR (tem), CONSP (tem))
+             && (tem = XCAR (tem), WINDOWP (tem)))
            {
            {
-             if (MINI_WINDOW_P (XWINDOW (event))
-                 && ! (minibuf_level > 0 && EQ (event, minibuf_window)))
+             if (MINI_WINDOW_P (XWINDOW (tem))
+                 && ! (minibuf_level > 0 && EQ (tem, 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);
 
                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, Qnil);
+             Fselect_window (tem, Qnil);
            }
          string++;
        }
            }
          string++;
        }
@@ -506,7 +504,7 @@ supply if the command inquires which events were used to invoke it.  */)
       varies[i] = 0;
     }
 
       varies[i] = 0;
     }
 
-  GCPRO4 (prefix_arg, function, *args, *visargs);
+  GCPRO5 (prefix_arg, function, *args, *visargs, up_event);
   gcpro3.nvars = (count + 1);
   gcpro4.nvars = (count + 1);
 
   gcpro3.nvars = (count + 1);
   gcpro4.nvars = (count + 1);
 
@@ -608,6 +606,12 @@ supply if the command inquires which events were used to invoke it.  */)
                                     Qnil, Qnil, Qnil, Qnil, Qnil);
          break;
 
                                     Qnil, Qnil, Qnil, Qnil, Qnil);
          break;
 
+       case 'G':               /* Possibly nonexistent file name,
+                                  default to directory alone. */
+         args[i] = Fread_file_name (build_string (callint_message),
+                                    Qnil, Qnil, Qnil, build_string (""), Qnil);
+         break;
+
        case 'i':               /* Ignore an argument -- Does not do I/O */
          varies[i] = -1;
          break;
        case 'i':               /* Ignore an argument -- Does not do I/O */
          varies[i] = -1;
          break;
@@ -620,7 +624,7 @@ supply if the command inquires which events were used to invoke it.  */)
                                          Qnil, Qnil, Qnil, Qnil);
            unbind_to (speccount1, Qnil);
            teml = args[i];
                                          Qnil, Qnil, Qnil, Qnil);
            unbind_to (speccount1, Qnil);
            teml = args[i];
-           visargs[i] = Fkey_description (teml);
+           visargs[i] = Fkey_description (teml, Qnil);
 
            /* If the key sequence ends with a down-event,
               discard the following up-event.  */
 
            /* If the key sequence ends with a down-event,
               discard the following up-event.  */
@@ -635,7 +639,7 @@ supply if the command inquires which events were used to invoke it.  */)
                /* Ignore first element, which is the base key.  */
                tem2 = Fmemq (intern ("down"), Fcdr (teml));
                if (! NILP (tem2))
                /* Ignore first element, which is the base key.  */
                tem2 = Fmemq (intern ("down"), Fcdr (teml));
                if (! NILP (tem2))
-                 Fread_event (Qnil, Qnil);
+                 up_event = Fread_event (Qnil, Qnil);
              }
          }
          break;
              }
          }
          break;
@@ -647,7 +651,7 @@ supply if the command inquires which events were used to invoke it.  */)
            args[i] = Fread_key_sequence (build_string (callint_message),
                                          Qnil, Qt, Qnil, Qnil);
            teml = args[i];
            args[i] = Fread_key_sequence (build_string (callint_message),
                                          Qnil, Qt, Qnil, Qnil);
            teml = args[i];
-           visargs[i] = Fkey_description (teml);
+           visargs[i] = Fkey_description (teml, Qnil);
            unbind_to (speccount1, Qnil);
 
            /* If the key sequence ends with a down-event,
            unbind_to (speccount1, Qnil);
 
            /* If the key sequence ends with a down-event,
@@ -663,11 +667,21 @@ supply if the command inquires which events were used to invoke it.  */)
                /* Ignore first element, which is the base key.  */
                tem2 = Fmemq (intern ("down"), Fcdr (teml));
                if (! NILP (tem2))
                /* Ignore first element, which is the base key.  */
                tem2 = Fmemq (intern ("down"), Fcdr (teml));
                if (! NILP (tem2))
-                 Fread_event (Qnil, Qnil);
+                 up_event = Fread_event (Qnil, Qnil);
              }
          }
          break;
 
              }
          }
          break;
 
+       case 'U':               /* Up event from last k or K */
+         if (!NILP (up_event))
+           {
+             args[i] = Fmake_vector (make_number (1), up_event);
+             up_event = Qnil;
+             teml = args[i];
+             visargs[i] = Fkey_description (teml, Qnil);
+           }
+         break;
+
        case 'e':               /* The invoking event.  */
          if (next_event >= key_count)
            error ("%s must be bound to an event with parameters",
        case 'e':               /* The invoking event.  */
          if (next_event >= key_count)
            error ("%s must be bound to an event with parameters",
@@ -716,7 +730,7 @@ supply if the command inquires which events were used to invoke it.  */)
 
                tem = Fread_from_minibuffer (build_string (callint_message),
                                             Qnil, Qnil, Qnil, Qnil, Qnil,
 
                tem = Fread_from_minibuffer (build_string (callint_message),
                                             Qnil, Qnil, Qnil, Qnil, Qnil,
-                                            Qnil);
+                                            Qnil, Qnil);
                if (! STRINGP (tem) || SCHARS (tem) == 0)
                  args[i] = Qnil;
                else
                if (! STRINGP (tem) || SCHARS (tem) == 0)
                  args[i] = Qnil;
                else