bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Viewing the *Messages* buffer is too inconvenient


From: Albino Petrofsky
Subject: Re: Viewing the *Messages* buffer is too inconvenient
Date: 08 Jan 2002 16:24:55 -0800
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.1

address@hidden (Kenichi Handa) writes:

> Algol Petrofsky <address@hidden> writes:
> > Viewing recent echo area messages is at least as frequently useful as
> > viewing recent input (C-h l), and similarly deserves a convenient key
> > binding.  I suggest C-h M.
> 
> I agree that it will be convenient to have a command key for
> viewing *Messages* buffer.  But, I was also going to suggest
> C-h M for M-x man which I have been used for long years.

The more I ponder it the more I believe that these features are
closely related and should be part of the same command, and thus can
share the C-h l keybinding, with C-u specifying that you want to see
the recent output as well as the recent input.  They are both useful
for diagnosing lossage.  

The xemacs view-lossage has included both input and output for a
while, but it separates the two, which loses the useful information
inherent in their ordering.  With the code below, C-u C-h l generates
an interleaved keystrokes/messages buffer.  One can still get just
keystrokes or just messages with C-h l or C-x b *Messages* RET.
It generates output like the following, but with different faces for
keystrokes and messages to make them more easily distinguished:

    C-_
  Undo!
    C-e C-b C-b C-b SPC SPC ESC C-x
  view-lossage
    C-u C-h l C-x 0 C-v ESC v ESC v
  call-interactively: Beginning of buffer
    ESC >
  Mark set
    ESC ! d f SPC / u s r RET
  Filesystem           1k-blocks      Used Available Use% Mounted on
  /dev/hda3              1733768    868748    776948  53% /usr
    C-u C-h l

This implementation isn't great, but it's sufficient to try the idea
out.  If you (the emacs maintainers) are interested in including
this feature, I would be willing to put more work into it.

-al


(defun view-lossage (show-messages)
  "Display last 100 input keystrokes.

With prefix arg, or if SHOW-MESSAGES is non-nil, show the last 200
input keystrokes and echo-area messages interleaved.

To record all your input on a file, use `open-dribble-file'."
  (interactive "P")
  (with-output-to-temp-buffer "*Help*"
    (save-excursion
      (set-buffer standard-output)
      (let* ((fill-keys
              (if show-messages
                  (lambda ()
                    (beginning-of-line)
                    (insert "  ")
                    (let ((start (point)))
                      (while (progn (move-to-column 50) (not (eobp)))
                        (search-forward " " nil t)
                        (insert "\n")
                        (unless (eobp) (insert "  ")))
                      (put-text-property start (point) 'face 'bold))
                    (or (bolp) (insert "\n")))
                (lambda ()
                  (beginning-of-line)
                  (let ((start (point)))
                    (while (progn (move-to-column 50) (not (eobp)))
                      (search-forward " " nil t)
                      (insert "\n")))
                  (or (bolp) (insert "\n")))))
             (objs (if show-messages (recent-keys-and-messages) (recent-keys)))
             (len (length objs))
             (i 0)
             (prev nil))
        (while (< i len)
          (let ((obj (aref objs i)))
            (if (stringp obj)
                (if (stringp prev)
                    (progn
                      ;; Check for "foo..." followed by "foo...bar".
                      (when (and (>= (length obj) 4)
                                 (>= (length prev) 4)
                                 (eq t (compare-strings
                                        "...\n" 0 nil
                                        prev (- (length prev) 4) nil))
                                 (eq t (compare-strings
                                        prev 0 (1- (length prev))
                                        obj 0 (1- (length prev)))))
                        (delete-region (line-beginning-position 0) (point)))
                      (insert obj))
                  (funcall fill-keys)
                  (unless (string= obj "\n")
                    (insert obj)))
              (if (and (stringp prev) (not (bolp)))
                  (insert "\n"))
              (if (or (integerp obj)
                      (symbolp obj)
                      (listp obj))
                  (insert (single-key-description obj) " ")
                (prin1 obj nil)
                (insert " ")))
            (setq prev obj i (1+ i))))
        (funcall fill-keys))
      (setq help-xref-stack nil
            help-xref-stack-item nil))
    (print-help-return-message)))



--- xdisp.c     2002/01/08 23:16:52     1.1
+++ xdisp.c     2002/01/08 23:17:04
@@ -5599,6 +5599,28 @@
      int nbytes, nlflag, multibyte;
 {
   if (!NILP (Vmessage_log_max))
+    /* Create a string and pass it to add_recent_key_or_message.  */
+    {
+      Lisp_Object str;
+      int nlbytes = nlflag ? 1 : 0;
+      if (multibyte)
+       {
+         int nchars, nbytes_1;
+         parse_str_as_multibyte (m, nbytes, &nchars, &nbytes_1);
+         str = make_uninit_multibyte_string (nchars + nlbytes,
+                                             nbytes + nlbytes);
+       }
+      else
+       {
+         str = make_uninit_string (nbytes + nlbytes);
+       }
+      bcopy (m, XSTRING (str)->data, nbytes);
+      if (nlflag)
+       XSTRING (str)->data[nbytes] = '\n';
+      add_recent_key_or_message (str);
+    }
+
+  if (!NILP (Vmessage_log_max))
     {
       struct buffer *oldbuf;
       Lisp_Object oldpoint, oldbegv, oldzv;


--- keyboard.h  2002/01/08 23:15:00     1.1
+++ keyboard.h  2002/01/08 23:15:03
@@ -342,3 +342,4 @@
 extern void kbd_buffer_store_help_event P_ ((Lisp_Object, Lisp_Object));
 extern Lisp_Object menu_item_eval_property P_ ((Lisp_Object));
 extern int  kbd_buffer_events_waiting P_ ((int));
+extern void add_recent_key_or_message P_ ((Lisp_Object));


--- keyboard.c  2002/01/06 22:39:10     1.1
+++ keyboard.c  2002/01/08 07:05:40
@@ -139,6 +139,11 @@
 int total_keys;                /* Total number of elements stored into 
recent_keys */
 Lisp_Object recent_keys; /* A vector, holding the last 100 keystrokes */
 
+#define NUM_RECENT_KEYS_AND_MESSAGES (200)
+int recent_keys_and_messages_index;
+int total_keys_and_messages;
+Lisp_Object recent_keys_and_messages;
+
 /* Vector holding the key sequence that invoked the current command.
    It is reused for each command, and it may be longer than the current
    sequence; this_command_key_count indicates how many elements
@@ -2961,6 +2966,31 @@
   return 0;
 }
 
+/* Add a key or message to recent_keys_and_messages.  */
+
+void
+add_recent_key_or_message (o)
+     Lisp_Object o;
+{
+  total_keys_and_messages++;
+  ASET (recent_keys_and_messages, recent_keys_and_messages_index, o);
+  if (++recent_keys_and_messages_index >= NUM_RECENT_KEYS_AND_MESSAGES)
+    recent_keys_and_messages_index = 0;
+}
+
+/* Add a key to recent_keys and to recent_keys_and_messages.  */
+
+static void
+add_recent_key (c)
+     Lisp_Object c;
+{
+  total_keys++;
+  ASET (recent_keys, recent_keys_index, c);
+  if (++recent_keys_index >= NUM_RECENT_KEYS)
+    recent_keys_index = 0;
+  add_recent_key_or_message (c);
+}
+
 /* Record the input event C in various ways.  */
 
 static void
@@ -2989,20 +3019,12 @@
              || !EQ (XCAR (last_c), Qhelp_echo)
              || (last_help = Fnth (make_number (2), last_c),
                  !EQ (last_help, help)))
-           {
-             total_keys++;
-             ASET (recent_keys, recent_keys_index, c);
-             if (++recent_keys_index >= NUM_RECENT_KEYS)
-               recent_keys_index = 0;
-           }
+           add_recent_key (c);
        }
     }
   else
     {
-      total_keys++;
-      ASET (recent_keys, recent_keys_index, c);
-      if (++recent_keys_index >= NUM_RECENT_KEYS)
-       recent_keys_index = 0;
+      add_recent_key (c);
     }
       
   /* Write c to the dribble file.  If c is a lispy event, write
@@ -9515,6 +9537,31 @@
     }
 }
 
+DEFUN ("recent-keys-and-messages", Frecent_keys_and_messages,
+       Srecent_keys_and_messages, 0, 0, 0,
+  "Return vector of last 200 events and messages.")
+  ()
+{
+  Lisp_Object *keys_and_messages = XVECTOR 
(recent_keys_and_messages)->contents;
+  Lisp_Object val;
+
+  if (total_keys_and_messages < NUM_RECENT_KEYS_AND_MESSAGES)
+    return Fvector (total_keys_and_messages, keys_and_messages);
+  else
+    {
+      val = Fvector (NUM_RECENT_KEYS_AND_MESSAGES, keys_and_messages);
+      bcopy (keys_and_messages + recent_keys_and_messages_index,
+            XVECTOR (val)->contents,
+            ((NUM_RECENT_KEYS_AND_MESSAGES - recent_keys_and_messages_index)
+             * sizeof (Lisp_Object)));
+      bcopy (keys_and_messages,
+            (XVECTOR (val)->contents
+             + NUM_RECENT_KEYS_AND_MESSAGES - recent_keys_and_messages_index),
+            recent_keys_and_messages_index * sizeof (Lisp_Object));
+      return val;
+    }
+}
+
 DEFUN ("this-command-keys", Fthis_command_keys, Sthis_command_keys, 0, 0, 0,
   "Return the key sequence that invoked this command.\n\
 The value is a string or a vector.")
@@ -9582,7 +9629,7 @@
 DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
   Sclear_this_command_keys, 0, 0, 0,
   "Clear out the vector that `this-command-keys' returns.\n\
-Clear vector containing last 100 events.")
+Clear the vectors used by `recent-keys' and `recent-keys-and-messages'.")
   ()
 {
   int i;
@@ -9593,6 +9640,12 @@
     XVECTOR (recent_keys)->contents[i] = Qnil;
   total_keys = 0;
   recent_keys_index = 0;
+
+  for (i = 0; i < XVECTOR (recent_keys_and_messages)->size; ++i)
+    XVECTOR (recent_keys_and_messages)->contents[i] = Qnil;
+  total_keys_and_messages = 0;
+  recent_keys_and_messages_index = 0;
+
   return Qnil;
 }
 
@@ -10139,6 +10192,8 @@
   EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
   total_keys = 0;
   recent_keys_index = 0;
+  total_keys_and_messages = 0;
+  recent_keys_and_messages_index = 0;
   kbd_fetch_ptr = kbd_buffer;
   kbd_store_ptr = kbd_buffer;
   kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil);
@@ -10411,6 +10466,10 @@
   recent_keys = Fmake_vector (make_number (NUM_RECENT_KEYS), Qnil);
   staticpro (&recent_keys);
 
+  recent_keys_and_messages
+    = Fmake_vector (make_number (NUM_RECENT_KEYS_AND_MESSAGES), Qnil);
+  staticpro (&recent_keys_and_messages);
+
   this_command_keys = Fmake_vector (make_number (40), Qnil);
   staticpro (&this_command_keys);
 
@@ -10460,6 +10519,7 @@
   defsubr (&Sinput_pending_p);
   defsubr (&Scommand_execute);
   defsubr (&Srecent_keys);
+  defsubr (&Srecent_keys_and_messages);
   defsubr (&Sthis_command_keys);
   defsubr (&Sthis_command_keys_vector);
   defsubr (&Sthis_single_command_keys);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]