[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 |
handa@etl.go.jp (Kenichi Handa) writes:
> Algol Petrofsky <algol@petrofsky.org> 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);