unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* kill ring menu
@ 2002-04-28 19:41 Colin Walters
  2002-04-28 20:06 ` Colin Walters
                   ` (4 more replies)
  0 siblings, 5 replies; 82+ messages in thread
From: Colin Walters @ 2002-04-28 19:41 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 2068 bytes --]

Hello,

I received a mail from Michael Slass, which I will quote here with
permission:

On Tue, 2002-04-23 at 17:35, Michael Slass wrote:
> Colin:
> 
> I just found browse-kill-ring, and I really like it; thanks for
> writing it.  I wasn't sure where to bind it on my keyboard, but then
> I thought of that annoying message you get - "The last command was not
> a yank" - when you accidentally hit M-y, and thought that would be a
> great place to put it.

I think this idea is so good that it should be the default behavior for
Emacs.  

Attached is a patch for review.  This patch doesn't remove any behavior,
but it is conceptually a fairly large change, so I think we should
consider it carefully.

There are several pros and cons, as I see it.  The main thing we gain is
that the old behavior of M-y was useless if the previous command wasn't
a yank, and the suggested new behavior is, I personally believe, quite
useful.

The main disadvantage I see is that users may type just M-y accidentally
and be confused.  For this reason, I've made C-g quit the kill ring menu
as well (as Michael Slass suggested in a later message).  Further
suggestions here would be appreciated.

As for the patch itself: basically, I renamed `browse-kill-ring' to
`kill-ring-menu', removed the more esoteric functionality (like editing
kill ring entries), and rewrote it to use font lock, among other things.

Some minor points:

I have moved all the killing stuff out from simple.el into kill-ring.el;
I feel that anything which defines a mode should, as a general
principle, be in a separate file.  However, if there is disagreement
about this, we can put everything back in simple.el.  It is not
important to the main change.

There are some minor additions to font-lock.el; ignore those for the
moment, please.  I'm just sharing some code between replace.el and
kill-ring.el (and probably ibuffer.el soon).

Finally, I'm not totally satisfied with the manual additions; there are
some bootstrapping issues, since we haven't discussed windows at that
point in the manual yet, etc.

[-- Attachment #2: kill-ring.patch --]
[-- Type: text/plain, Size: 61834 bytes --]

--- NEWS.~1.660.~	Sat Apr 27 17:20:39 2002
+++ NEWS	Sun Apr 28 14:43:43 2002
@@ -49,6 +48,13 @@
 
 \f
 * Changes in Emacs 21.4
+
++++
+** The key `M-y' has been extended to display a menu of kill ring
+entries, if the previous command was not a 'C-y'.  Previously, `M-y'
+ran the command `yank-pop'.  Now it runs `yank-previous', which will
+either display a menu (`kill-ring-menu') or call `yank-pop'.  See the
+node "Yanking Earlier Kills" in the Emacs manual for more information.
 
 ---
 ** The new options `buffers-menu-show-directories' and
--- killing.texi.~1.26.~	Wed Sep 12 17:01:34 2001
+++ killing.texi	Sun Apr 28 13:08:24 2002
@@ -270,8 +270,7 @@
 @item C-y
 Yank last killed text (@code{yank}).
 @item M-y
-Replace text just yanked with an earlier batch of killed text
-(@code{yank-pop}).
+Choose previously yanked text to insert (@code{yank-pop}).
 @item M-w
 Save region as last killed text without actually killing it
 (@code{kill-ring-save}).
@@ -374,49 +373,92 @@
 
 @cindex yanking previous kills
 @kindex M-y
-@findex yank-pop
-  To recover killed text that is no longer the most recent kill, use the
-@kbd{M-y} command (@code{yank-pop}).  It takes the text previously
-yanked and replaces it with the text from an earlier kill.  So, to
-recover the text of the next-to-the-last kill, first use @kbd{C-y} to
-yank the last kill, and then use @kbd{M-y} to replace it with the
-previous kill.  @kbd{M-y} is allowed only after a @kbd{C-y} or another
-@kbd{M-y}.
-
-  You can understand @kbd{M-y} in terms of a ``last yank'' pointer which
-points at an entry in the kill ring.  Each time you kill, the ``last
-yank'' pointer moves to the newly made entry at the front of the ring.
-@kbd{C-y} yanks the entry which the ``last yank'' pointer points to.
-@kbd{M-y} moves the ``last yank'' pointer to a different entry, and the
-text in the buffer changes to match.  Enough @kbd{M-y} commands can move
-the pointer to any entry in the ring, so you can get any entry into the
+@findex yank-previous
+  To recover killed text that is no longer the most recent kill, use
+the @kbd{M-y} command (@code{yank-previous}).  This command can act in
+two different ways.  If the previous command was not a yank, then
+@kbd{M-y} will display a menu of kill ring entries, which you can
+choose from (@code{kill-ring-menu}).  If the previous command was a
+yank, then @kbd{M-y} will replace the previously yanked text with the
+text from an earlier kill (@code{yank-pop}).
+
+@subsubsection The Kill Ring Menu 
+If you are not sure how long ago you killed the piece of text you're
+loooking for, it can often be easiest to use the kill ring menu.
+Simply type @kbd{M-y} (which was not preceeded by a @kbd{C-y}), and a
+window should pop up, which will display the text previously killed,
+one entry on each line.  In this special mode, keys do not insert
+themselves; instead, they choose actions to perform.
+
+@table @kbd
+@item RET
+Choose the text at point to yank (@code{kill-ring-menu-insert}).
+@item n
+Move point forward by one kill ring entry
+(@code{kill-ring-menu-forward}).
+@item p
+Move point backwards by one kill ring entry
+(@code{kill-ring-menu-backward}).
+@item q
+Quit the kill ring menu without yanking any text
+(@code{kill-ring-menu-quit}).
+@item d
+Remove the text at point from the kill ring
+(@code{kill-ring-menu-delete}).
+@end table
+
+The kill ring menu can display multi-line text; In the default display
+style, all text is shown on one line, and newlines are shown as a
+@samp{\n}.
+
+@subsubsection Cycling Through Yanked Text
+
+If you know precisely where the text you previously yanked is in the
+@code{kill-ring}, or it was very recently yanked, you may find using
+the @code{yank-pop} functionality of @kbd{M-y} to be faster than the
+kill ring menu.  For example, to recover the text of the
+next-to-the-last kill, you could first use @kbd{C-y} to yank the last
+kill, and then type @kbd{M-y} to replace it with the previous kill.
+
+  You can understand @code{yank-pop} in terms of a ``last yank''
+pointer which points at an entry in the kill ring.  Each time you
+kill, the ``last yank'' pointer moves to the newly made entry at the
+front of the ring.  @kbd{C-y} yanks the entry which the ``last yank''
+pointer points to.  After that, typing @kbd{M-y} moves the ``last
+yank'' pointer to a different entry, and the text in the buffer
+changes to match.  Enough @code{yank-pop} commands can move the
+pointer to any entry in the ring, so you can get any entry into the
 buffer.  Eventually the pointer reaches the end of the ring; the next
 @kbd{M-y} loops back around to the first entry again.
 
-  @kbd{M-y} moves the ``last yank'' pointer around the ring, but it does
-not change the order of the entries in the ring, which always runs from
-the most recent kill at the front to the oldest one still remembered.
-
-  @kbd{M-y} can take a numeric argument, which tells it how many entries
-to advance the ``last yank'' pointer by.  A negative argument moves the
-pointer toward the front of the ring; from the front of the ring, it
-moves ``around'' to the last entry and continues forward from there.
-
-  Once the text you are looking for is brought into the buffer, you can
-stop doing @kbd{M-y} commands and it will stay there.  It's just a copy
-of the kill ring entry, so editing it in the buffer does not change
-what's in the ring.  As long as no new killing is done, the ``last
-yank'' pointer remains at the same place in the kill ring, so repeating
-@kbd{C-y} will yank another copy of the same previous kill.
-
-  If you know how many @kbd{M-y} commands it would take to find the
-text you want, you can yank that text in one step using @kbd{C-y} with
-a numeric argument.  @kbd{C-y} with an argument restores the text from
-the specified kill ring entry, counting back from the most recent as
-1.  Thus, @kbd{C-u 2 C-y} gets the next-to-the-last block of killed
+  @code{yank-pop} moves the ``last yank'' pointer around the ring, but
+it does not change the order of the entries in the ring, which always
+runs from the most recent kill at the front to the oldest one still
+remembered.
+
+  @code{yank-pop} can take a numeric argument, which tells it how many
+entries to advance the ``last yank'' pointer by.  A negative argument
+moves the pointer toward the front of the ring; from the front of the
+ring, it moves ``around'' to the last entry and continues forward from
+there.
+
+  Once the text you are looking for is brought into the buffer, you
+can stop doing @code{yank-pop} commands and it will stay there.  It's
+just a copy of the kill ring entry, so editing it in the buffer does
+not change what's in the ring.  As long as no new killing is done, the
+``last yank'' pointer remains at the same place in the kill ring, so
+repeating @kbd{C-y} will yank another copy of the same previous kill.
+
+  If you know how many @code{yank-pop} commands it would take to find
+the text you want, you can yank that text in one step using @kbd{C-y}
+with a numeric argument.  @kbd{C-y} with an argument restores the text
+from the specified kill ring entry, counting back from the most recent
+as 1.  Thus, @kbd{C-u 2 C-y} gets the next-to-the-last block of killed
 text---it is equivalent to @kbd{C-y M-y}.  @kbd{C-y} with a numeric
 argument starts counting from the ``last yank'' pointer, and sets the
 ``last yank'' pointer to the entry that it yanks.
+
+@subsubsection The Kill Ring Data
 
 @vindex kill-ring-max
   The length of the kill ring is controlled by the variable
+there.
+
+  Once the text you are looking for is brought into the buffer, you
+can stop doing @code{yank-pop} commands and it will stay there.  It's
+just a copy of the kill ring entry, so editing it in the buffer does
+not change what's in the ring.  As long as no new killing is done, the
+``last yank'' pointer remains at the same place in the kill ring, so
+repeating @kbd{C-y} will yank another copy of the same previous kill.
+
+  If you know how many @code{yank-pop} commands it would take to find
+the text you want, you can yank that text in one step using @kbd{C-y}
+with a numeric argument.  @kbd{C-y} with an argument restores the text
+from the specified kill ring entry, counting back from the most recent
+as 1.  Thus, @kbd{C-u 2 C-y} gets the next-to-the-last block of killed
 text---it is equivalent to @kbd{C-y M-y}.  @kbd{C-y} with a numeric
 argument starts counting from the ``last yank'' pointer, and sets the
 ``last yank'' pointer to the entry that it yanks.
+
+@subsubsection The Kill Ring Data
 
 @vindex kill-ring-max
   The length of the kill ring is controlled by the variable
--- simple.el	27 Apr 2002 23:16:18 -0000	1.539
+++ simple.el	28 Apr 2002 19:28:53 -0000
@@ -32,11 +32,6 @@
   (autoload 'shell-mode "shell")
   (require 'cl))
 
-
-(defgroup killing nil
-  "Killing and yanking commands"
-  :group 'editing)
-
 (defgroup paren-matching nil
   "Highlight (un)matching of parens and expressions."
   :group 'matching)
@@ -1656,334 +1651,6 @@
 		  unread-command-events)))
   (reset-this-command-lengths)
   (setq overriding-terminal-local-map nil))
-\f
-;;;; Window system cut and paste hooks.
-
-(defvar interprogram-cut-function nil
-  "Function to call to make a killed region available to other programs.
-
-Most window systems provide some sort of facility for cutting and
-pasting text between the windows of different programs.
-This variable holds a function that Emacs calls whenever text
-is put in the kill ring, to make the new kill available to other
-programs.
-
-The function takes one or two arguments.
-The first argument, TEXT, is a string containing
-the text which should be made available.
-The second, PUSH, if non-nil means this is a \"new\" kill;
-nil means appending to an \"old\" kill.")
-
-(defvar interprogram-paste-function nil
-  "Function to call to get text cut from other programs.
-
-Most window systems provide some sort of facility for cutting and
-pasting text between the windows of different programs.
-This variable holds a function that Emacs calls to obtain
-text that other programs have provided for pasting.
-
-The function should be called with no arguments.  If the function
-returns nil, then no other program has provided such text, and the top
-of the Emacs kill ring should be used.  If the function returns a
-string, that string should be put in the kill ring as the latest kill.
-
-Note that the function should return a string only if a program other
-than Emacs has provided a string for pasting; if Emacs provided the
-most recent string, the function should return nil.  If it is
-difficult to tell whether Emacs or some other program provided the
-current string, it is probably good enough to return nil if the string
-is equal (according to `string=') to the last text Emacs provided.")
-\f
-
-
-;;;; The kill ring data structure.
-
-(defvar kill-ring nil
-  "List of killed text sequences.
-Since the kill ring is supposed to interact nicely with cut-and-paste
-facilities offered by window systems, use of this variable should
-interact nicely with `interprogram-cut-function' and
-`interprogram-paste-function'.  The functions `kill-new',
-`kill-append', and `current-kill' are supposed to implement this
-interaction; you may want to use them instead of manipulating the kill
-ring directly.")
-
-(defcustom kill-ring-max 60
-  "*Maximum length of kill ring before oldest elements are thrown away."
-  :type 'integer
-  :group 'killing)
-
-(defvar kill-ring-yank-pointer nil
-  "The tail of the kill ring whose car is the last thing yanked.")
-
-(defun kill-new (string &optional replace)
-  "Make STRING the latest kill in the kill ring.
-Set `kill-ring-yank-pointer' to point to it.
-If `interprogram-cut-function' is non-nil, apply it to STRING.
-Optional second argument REPLACE non-nil means that STRING will replace
-the front of the kill ring, rather than being added to the list."
-  (and (fboundp 'menu-bar-update-yank-menu)
-       (menu-bar-update-yank-menu string (and replace (car kill-ring))))
-  (if (and replace kill-ring)
-      (setcar kill-ring string)
-    (setq kill-ring (cons string kill-ring))
-    (if (> (length kill-ring) kill-ring-max)
-	(setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
-  (setq kill-ring-yank-pointer kill-ring)
-  (if interprogram-cut-function
-      (funcall interprogram-cut-function string (not replace))))
-
-(defun kill-append (string before-p)
-  "Append STRING to the end of the latest kill in the kill ring.
-If BEFORE-P is non-nil, prepend STRING to the kill.
-If `interprogram-cut-function' is set, pass the resulting kill to
-it."
-  (kill-new (if before-p
-		(concat string (car kill-ring))
-	      (concat (car kill-ring) string))
-	    t))
-
-(defun current-kill (n &optional do-not-move)
-  "Rotate the yanking point by N places, and then return that kill.
-If N is zero, `interprogram-paste-function' is set, and calling it
-returns a string, then that string is added to the front of the
-kill ring and returned as the latest kill.
-If optional arg DO-NOT-MOVE is non-nil, then don't actually move the
-yanking point; just return the Nth kill forward."
-  (let ((interprogram-paste (and (= n 0)
-				 interprogram-paste-function
-				 (funcall interprogram-paste-function))))
-    (if interprogram-paste
-	(progn
-	  ;; Disable the interprogram cut function when we add the new
-	  ;; text to the kill ring, so Emacs doesn't try to own the
-	  ;; selection, with identical text.
-	  (let ((interprogram-cut-function nil))
-	    (kill-new interprogram-paste))
-	  interprogram-paste)
-      (or kill-ring (error "Kill ring is empty"))
-      (let ((ARGth-kill-element
-	     (nthcdr (mod (- n (length kill-ring-yank-pointer))
-			  (length kill-ring))
-		     kill-ring)))
-	(or do-not-move
-	    (setq kill-ring-yank-pointer ARGth-kill-element))
-	(car ARGth-kill-element)))))
-
-
-
-;;;; Commands for manipulating the kill ring.
-
-(defcustom kill-read-only-ok nil
-  "*Non-nil means don't signal an error for killing read-only text."
-  :type 'boolean
-  :group 'killing)
-
-(put 'text-read-only 'error-conditions
-     '(text-read-only buffer-read-only error))
-(put 'text-read-only 'error-message "Text is read-only")
-
-(defun kill-region (beg end)
-  "Kill between point and mark.
-The text is deleted but saved in the kill ring.
-The command \\[yank] can retrieve it from there.
-\(If you want to kill and then yank immediately, use \\[kill-ring-save].)
-
-If you want to append the killed region to the last killed text,
-use \\[append-next-kill] before \\[kill-region].
-
-If the buffer is read-only, Emacs will beep and refrain from deleting
-the text, but put the text in the kill ring anyway.  This means that
-you can use the killing commands to copy text from a read-only buffer.
-
-This is the primitive for programs to kill text (as opposed to deleting it).
-Supply two arguments, character numbers indicating the stretch of text
- to be killed.
-Any command that calls this function is a \"kill command\".
-If the previous command was also a kill command,
-the text killed this time appends to the text killed last time
-to make one entry in the kill ring."
-  (interactive "r")
-  (condition-case nil
-      (let ((string (delete-and-extract-region beg end)))
-	(when string			;STRING is nil if BEG = END
-	  ;; Add that string to the kill ring, one way or another.
-	  (if (eq last-command 'kill-region)
-	      (kill-append string (< end beg))
-	    (kill-new string)))
-	(setq this-command 'kill-region))
-    ((buffer-read-only text-read-only)
-     ;; The code above failed because the buffer, or some of the characters
-     ;; in the region, are read-only.
-     ;; We should beep, in case the user just isn't aware of this.
-     ;; However, there's no harm in putting
-     ;; the region's text in the kill ring, anyway.
-     (copy-region-as-kill beg end)
-     ;; Set this-command now, so it will be set even if we get an error.
-     (setq this-command 'kill-region)
-     ;; This should barf, if appropriate, and give us the correct error.
-     (if kill-read-only-ok
-	 (message "Read only text copied to kill ring")
-       ;; Signal an error if the buffer is read-only.
-       (barf-if-buffer-read-only)
-       ;; If the buffer isn't read-only, the text is.
-       (signal 'text-read-only (list (current-buffer)))))))
-
-;; copy-region-as-kill no longer sets this-command, because it's confusing
-;; to get two copies of the text when the user accidentally types M-w and
-;; then corrects it with the intended C-w.
-(defun copy-region-as-kill (beg end)
-  "Save the region as if killed, but don't kill it.
-In Transient Mark mode, deactivate the mark.
-If `interprogram-cut-function' is non-nil, also save the text for a window
-system cut and paste."
-  (interactive "r")
-  (if (eq last-command 'kill-region)
-      (kill-append (buffer-substring beg end) (< end beg))
-    (kill-new (buffer-substring beg end)))
-  (if transient-mark-mode
-      (setq deactivate-mark t))
-  nil)
-
-(defun kill-ring-save (beg end)
-  "Save the region as if killed, but don't kill it.
-In Transient Mark mode, deactivate the mark.
-If `interprogram-cut-function' is non-nil, also save the text for a window
-system cut and paste.
-
-If you want to append the killed line to the last killed text,
-use \\[append-next-kill] before \\[kill-ring-save].
-
-This command is similar to `copy-region-as-kill', except that it gives
-visual feedback indicating the extent of the region being copied."
-  (interactive "r")
-  (copy-region-as-kill beg end)
-  (if (interactive-p)
-      (let ((other-end (if (= (point) beg) end beg))
-	    (opoint (point))
-	    ;; Inhibit quitting so we can make a quit here
-	    ;; look like a C-g typed as a command.
-	    (inhibit-quit t))
-	(if (pos-visible-in-window-p other-end (selected-window))
-	    (unless transient-mark-mode
-	      ;; Swap point and mark.
-	      (set-marker (mark-marker) (point) (current-buffer))
-	      (goto-char other-end)
-	      (sit-for 1)
-	      ;; Swap back.
-	      (set-marker (mark-marker) other-end (current-buffer))
-	      (goto-char opoint)
-	      ;; If user quit, deactivate the mark
-	      ;; as C-g would as a command.
-	      (and quit-flag mark-active
-		   (deactivate-mark)))
-	  (let* ((killed-text (current-kill 0))
-		 (message-len (min (length killed-text) 40)))
-	    (if (= (point) beg)
-		;; Don't say "killed"; that is misleading.
-		(message "Saved text until \"%s\""
-			(substring killed-text (- message-len)))
-	      (message "Saved text from \"%s\""
-		      (substring killed-text 0 message-len))))))))
-
-(defun append-next-kill (&optional interactive)
-  "Cause following command, if it kills, to append to previous kill.
-The argument is used for internal purposes; do not supply one."
-  (interactive "p")
-  ;; We don't use (interactive-p), since that breaks kbd macros.
-  (if interactive
-      (progn
-	(setq this-command 'kill-region)
-	(message "If the next command is a kill, it will append"))
-    (setq last-command 'kill-region)))
-\f
-;; Yanking.
-
-;; This is actually used in subr.el but defcustom does not work there.
-(defcustom yank-excluded-properties
-  '(read-only invisible intangible field mouse-face local-map keymap)
-  "*Text properties to discard when yanking."
-  :type '(choice (const :tag "All" t) (repeat symbol))
-  :group 'editing
-  :version 21.4)
-
-(defun yank-pop (arg)
-  "Replace just-yanked stretch of killed text with a different stretch.
-This command is allowed only immediately after a `yank' or a `yank-pop'.
-At such a time, the region contains a stretch of reinserted
-previously-killed text.  `yank-pop' deletes that text and inserts in its
-place a different stretch of killed text.
-
-With no argument, the previous kill is inserted.
-With argument N, insert the Nth previous kill.
-If N is negative, this is a more recent kill.
-
-The sequence of kills wraps around, so that after the oldest one
-comes the newest one."
-  (interactive "*p")
-  (if (not (eq last-command 'yank))
-      (error "Previous command was not a yank"))
-  (setq this-command 'yank)
-  (let ((inhibit-read-only t)
-	(before (< (point) (mark t))))
-    (delete-region (point) (mark t))
-    (set-marker (mark-marker) (point) (current-buffer))
-    (insert-for-yank (current-kill arg))
-    (if before
-	;; This is like exchange-point-and-mark, but doesn't activate the mark.
-	;; It is cleaner to avoid activation, even though the command
-	;; loop would deactivate the mark because we inserted text.
-	(goto-char (prog1 (mark t)
-		     (set-marker (mark-marker) (point) (current-buffer))))))
-  nil)
-
-(defun yank (&optional arg)
-  "Reinsert the last stretch of killed text.
-More precisely, reinsert the stretch of killed text most recently
-killed OR yanked.  Put point at end, and set mark at beginning.
-With just C-u as argument, same but put point at beginning (and mark at end).
-With argument N, reinsert the Nth most recently killed stretch of killed
-text.
-See also the command \\[yank-pop]."
-  (interactive "*P")
-  ;; If we don't get all the way thru, make last-command indicate that
-  ;; for the following command.
-  (setq this-command t)
-  (push-mark (point))
-  (insert-for-yank (current-kill (cond
-				  ((listp arg) 0)
-				  ((eq arg '-) -1)
-				  (t (1- arg)))))
-  (if (consp arg)
-      ;; This is like exchange-point-and-mark, but doesn't activate the mark.
-      ;; It is cleaner to avoid activation, even though the command
-      ;; loop would deactivate the mark because we inserted text.
-      (goto-char (prog1 (mark t)
-		   (set-marker (mark-marker) (point) (current-buffer)))))
-  ;; If we do get all the way thru, make this-command indicate that.
-  (setq this-command 'yank)
-  nil)
-
-(defun rotate-yank-pointer (arg)
-  "Rotate the yanking point in the kill ring.
-With argument, rotate that many kills forward (or backward, if negative)."
-  (interactive "p")
-  (current-kill arg))
-\f
-;; Some kill commands.
-
-;; Internal subroutine of delete-char
-(defun kill-forward-chars (arg)
-  (if (listp arg) (setq arg (car arg)))
-  (if (eq arg '-) (setq arg -1))
-  (kill-region (point) (forward-point arg)))
-
-;; Internal subroutine of backward-delete-char
-(defun kill-backward-chars (arg)
-  (if (listp arg) (setq arg (car arg)))
-  (if (eq arg '-) (setq arg -1))
-  (kill-region (point) (forward-point (- arg))))
-
 (defcustom backward-delete-char-untabify-method 'untabify
   "*The method for untabifying when deleting backward.
 Can be `untabify' -- turn a tab to many spaces, then delete one space;
@@ -2033,53 +1700,6 @@
 			 (search-forward (char-to-string char) nil nil arg)
 ;			 (goto-char (if (> arg 0) (1- (point)) (1+ (point))))
 			 (point))))
-
-;; kill-line and its subroutines.
-
-(defcustom kill-whole-line nil
-  "*If non-nil, `kill-line' with no arg at beg of line kills the whole line."
-  :type 'boolean
-  :group 'killing)
-
-(defun kill-line (&optional arg)
-  "Kill the rest of the current line; if no nonblanks there, kill thru newline.
-With prefix argument, kill that many lines from point.
-Negative arguments kill lines backward.
-With zero argument, kills the text before point on the current line.
-
-When calling from a program, nil means \"no arg\",
-a number counts as a prefix arg.
-
-To kill a whole line, when point is not at the beginning, type \
-\\[beginning-of-line] \\[kill-line] \\[kill-line].
-
-If `kill-whole-line' is non-nil, then this command kills the whole line
-including its terminating newline, when used at the beginning of a line
-with no argument.  As a consequence, you can always kill a whole line
-by typing \\[beginning-of-line] \\[kill-line].
-
-If you want to append the killed line to the last killed text,
-use \\[append-next-kill] before \\[kill-line].
-
-If the buffer is read-only, Emacs will beep and refrain from deleting
-the line, but put the line in the kill ring anyway.  This means that
-you can use this command to copy text from a read-only buffer."
-  (interactive "P")
-  (kill-region (point)
-	       ;; It is better to move point to the other end of the kill
-	       ;; before killing.  That way, in a read-only buffer, point
-	       ;; moves across the text that is copied to the kill ring.
-	       ;; The choice has no effect on undo now that undo records
-	       ;; the value of point from before the command was run.
-	       (progn
-		 (if arg
-		     (forward-visible-line (prefix-numeric-value arg))
-		   (if (eobp)
-		       (signal 'end-of-buffer nil))
-		   (if (or (looking-at "[ \t]*$") (and kill-whole-line (bolp)))
-		       (forward-visible-line 1)
-		     (end-of-visible-line)))
-		 (point))))
 
 (defun forward-visible-line (arg)
   "Move forward by ARG lines, ignoring currently invisible newlines only.
--- /dev/null	Wed Dec 31 19:00:00 1969
+++ kill-ring.el	Sun Apr 28 14:27:12 2002
@@ -0,0 +1,723 @@
+;;; kill-ring.el --- killing, yanking, and kill ring browsing
+
+;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 99, 2000, 2001, 2002
+;;        Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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 the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(eval-when-compile
+  (require 'cl)
+  (require 'derived))
+
+(defgroup killing nil
+  "Killing and yanking commands"
+  :group 'editing)
+
+\f
+;;;; Window system cut and paste hooks.
+
+(defvar interprogram-cut-function nil
+  "Function to call to make a killed region available to other programs.
+
+Most window systems provide some sort of facility for cutting and
+pasting text between the windows of different programs.
+This variable holds a function that Emacs calls whenever text
+is put in the kill ring, to make the new kill available to other
+programs.
+
+The function takes one or two arguments.
+The first argument, TEXT, is a string containing
+the text which should be made available.
+The second, PUSH, if non-nil means this is a \"new\" kill;
+nil means appending to an \"old\" kill.")
+
+(defvar interprogram-paste-function nil
+  "Function to call to get text cut from other programs.
+
+Most window systems provide some sort of facility for cutting and
+pasting text between the windows of different programs.
+This variable holds a function that Emacs calls to obtain
+text that other programs have provided for pasting.
+
+The function should be called with no arguments.  If the function
+returns nil, then no other program has provided such text, and the top
+of the Emacs kill ring should be used.  If the function returns a
+string, that string should be put in the kill ring as the latest kill.
+
+Note that the function should return a string only if a program other
+than Emacs has provided a string for pasting; if Emacs provided the
+most recent string, the function should return nil.  If it is
+difficult to tell whether Emacs or some other program provided the
+current string, it is probably good enough to return nil if the string
+is equal (according to `string=') to the last text Emacs provided.")
+\f
+
+;;;; The kill ring data structure.
+
+(defvar kill-ring nil
+  "List of killed text sequences.
+Since the kill ring is supposed to interact nicely with cut-and-paste
+facilities offered by window systems, use of this variable should
+interact nicely with `interprogram-cut-function' and
+`interprogram-paste-function'.  The functions `kill-new',
+`kill-append', and `current-kill' are supposed to implement this
+interaction; you may want to use them instead of manipulating the kill
+ring directly.")
+
+(defcustom kill-ring-max 60
+  "*Maximum length of kill ring before oldest elements are thrown away."
+  :type 'integer
+  :group 'killing)
+
+(defcustom kill-ring-menu-display-style 'one-line
+  "How to display the kill ring menu items.
+
+If `one-line', then replace newlines with \"\\n\" for display.
+
+If `separated', then display `kill-ring-menu-separator' between
+entries."
+  :type '(choice (const :tag "One line" one-line)
+		 (const :tag "Separated" separated))
+  :group 'killing)
+
+(defcustom kill-ring-menu-quit-action 'bury-and-delete-window
+  "What action to take when `kill-ring-menu-quit' is called.
+
+If `bury-buffer', then simply bury the *Kill Ring* buffer, but keep
+the window.
+
+If `bury-and-delete-window', then bury the buffer, and (if there is
+more than one window) delete the window.  This is the default.
+
+If `kill-and-delete-window', then kill the *Kill Ring* buffer, and
+delete the window on close.
+
+Otherwise, it should be a function to call."
+  :type '(choice (const :tag "Bury buffer" :value bury-buffer)
+		 (const :tag "Delete window" :value delete-window)
+		 (const :tag "Bury buffer and delete window" :value bury-and-delete-window)
+		 (const :tag "Kill buffer and delete window" :value kill-and-delete-window))
+  :group 'killing)
+
+(defcustom kill-ring-menu-maximum-display-length nil
+  "Whether or not to limit the length of displayed items.
+
+If this variable is an integer, the display of `kill-ring' will be
+limited to that many characters.
+Setting this variable to nil means no limit."
+  :type '(choice (const :tag "None" nil)
+		 integer)
+  :group 'browse-kill-ring)
+
+(defcustom kill-ring-menu-separator "-------"
+  "The string separating entries in the `separated' style.
+See `kill-ring-menu-display-style'."
+  :type 'string
+  :group 'killing)
+
+(defcustom kill-ring-menu-highlight-current-entry nil
+  "If non-nil, highlight the currently selected `kill-ring' entry."
+  :type 'boolean
+  :group 'killing)
+
+(defcustom kill-ring-menu-separator-face 'bold
+  "The face in which to highlight the `kill-ring-menu-separator'."
+  :type 'face
+  :group 'killing)
+
+(defvar kill-ring-yank-pointer nil
+  "The tail of the kill ring whose car is the last thing yanked.")
+
+(defvar kill-ring-menu-original-window nil
+  "The window in which chosen kill ring data will be inserted.
+It is probably not a good idea to set this variable directly; simply
+call `kill-ring-menu' again.")
+
+(defun kill-new (string &optional replace)
+  "Make STRING the latest kill in the kill ring.
+Set `kill-ring-yank-pointer' to point to it.
+If `interprogram-cut-function' is non-nil, apply it to STRING.
+Optional second argument REPLACE non-nil means that STRING will replace
+the front of the kill ring, rather than being added to the list."
+  (and (fboundp 'menu-bar-update-yank-menu)
+       (menu-bar-update-yank-menu string (and replace (car kill-ring))))
+  (if (and replace kill-ring)
+      (setcar kill-ring string)
+    (setq kill-ring (cons string kill-ring))
+    (if (> (length kill-ring) kill-ring-max)
+	(setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
+  (setq kill-ring-yank-pointer kill-ring)
+  (if interprogram-cut-function
+      (funcall interprogram-cut-function string (not replace))))
+
+(defun kill-append (string before-p)
+  "Append STRING to the end of the latest kill in the kill ring.
+If BEFORE-P is non-nil, prepend STRING to the kill.
+If `interprogram-cut-function' is set, pass the resulting kill to
+it."
+  (kill-new (if before-p
+		(concat string (car kill-ring))
+	      (concat (car kill-ring) string))
+	    t))
+
+(defun current-kill (n &optional do-not-move)
+  "Rotate the yanking point by N places, and then return that kill.
+If N is zero, `interprogram-paste-function' is set, and calling it
+returns a string, then that string is added to the front of the
+kill ring and returned as the latest kill.
+If optional arg DO-NOT-MOVE is non-nil, then don't actually move the
+yanking point; just return the Nth kill forward."
+  (let ((interprogram-paste (and (= n 0)
+				 interprogram-paste-function
+				 (funcall interprogram-paste-function))))
+    (if interprogram-paste
+	(progn
+	  ;; Disable the interprogram cut function when we add the new
+	  ;; text to the kill ring, so Emacs doesn't try to own the
+	  ;; selection, with identical text.
+	  (let ((interprogram-cut-function nil))
+	    (kill-new interprogram-paste))
+	  interprogram-paste)
+      (or kill-ring (error "Kill ring is empty"))
+      (let ((ARGth-kill-element
+	     (nthcdr (mod (- n (length kill-ring-yank-pointer))
+			  (length kill-ring))
+		     kill-ring)))
+	(or do-not-move
+	    (setq kill-ring-yank-pointer ARGth-kill-element))
+	(car ARGth-kill-element)))))
+
+;;;; Commands for manipulating the kill ring.
+
+(defcustom kill-read-only-ok nil
+  "*Non-nil means don't signal an error for killing read-only text."
+  :type 'boolean
+  :group 'killing)
+
+(put 'text-read-only 'error-conditions
+     '(text-read-only buffer-read-only error))
+(put 'text-read-only 'error-message "Text is read-only")
+
+(defun kill-region (beg end)
+  "Kill between point and mark.
+The text is deleted but saved in the kill ring.
+The command \\[yank] can retrieve it from there.
+\(If you want to kill and then yank immediately, use \\[kill-ring-save].)
+
+If you want to append the killed region to the last killed text,
+use \\[append-next-kill] before \\[kill-region].
+
+If the buffer is read-only, Emacs will beep and refrain from deleting
+the text, but put the text in the kill ring anyway.  This means that
+you can use the killing commands to copy text from a read-only buffer.
+
+This is the primitive for programs to kill text (as opposed to deleting it).
+Supply two arguments, character numbers indicating the stretch of text
+ to be killed.
+Any command that calls this function is a \"kill command\".
+If the previous command was also a kill command,
+the text killed this time appends to the text killed last time
+to make one entry in the kill ring."
+  (interactive "r")
+  (condition-case nil
+      (let ((string (delete-and-extract-region beg end)))
+	(when string			;STRING is nil if BEG = END
+	  ;; Add that string to the kill ring, one way or another.
+	  (if (eq last-command 'kill-region)
+	      (kill-append string (< end beg))
+	    (kill-new string)))
+	(setq this-command 'kill-region))
+    ((buffer-read-only text-read-only)
+     ;; The code above failed because the buffer, or some of the characters
+     ;; in the region, are read-only.
+     ;; We should beep, in case the user just isn't aware of this.
+     ;; However, there's no harm in putting
+     ;; the region's text in the kill ring, anyway.
+     (copy-region-as-kill beg end)
+     ;; Set this-command now, so it will be set even if we get an error.
+     (setq this-command 'kill-region)
+     ;; This should barf, if appropriate, and give us the correct error.
+     (if kill-read-only-ok
+	 (message "Read only text copied to kill ring")
+       ;; Signal an error if the buffer is read-only.
+       (barf-if-buffer-read-only)
+       ;; If the buffer isn't read-only, the text is.
+       (signal 'text-read-only (list (current-buffer)))))))
+
+;; copy-region-as-kill no longer sets this-command, because it's confusing
+;; to get two copies of the text when the user accidentally types M-w and
+;; then corrects it with the intended C-w.
+(defun copy-region-as-kill (beg end)
+  "Save the region as if killed, but don't kill it.
+In Transient Mark mode, deactivate the mark.
+If `interprogram-cut-function' is non-nil, also save the text for a window
+system cut and paste."
+  (interactive "r")
+  (if (eq last-command 'kill-region)
+      (kill-append (buffer-substring beg end) (< end beg))
+    (kill-new (buffer-substring beg end)))
+  (if transient-mark-mode
+      (setq deactivate-mark t))
+  nil)
+
+(defun kill-ring-save (beg end)
+  "Save the region as if killed, but don't kill it.
+In Transient Mark mode, deactivate the mark.
+If `interprogram-cut-function' is non-nil, also save the text for a window
+system cut and paste.
+
+If you want to append the killed line to the last killed text,
+use \\[append-next-kill] before \\[kill-ring-save].
+
+This command is similar to `copy-region-as-kill', except that it gives
+visual feedback indicating the extent of the region being copied."
+  (interactive "r")
+  (copy-region-as-kill beg end)
+  (if (interactive-p)
+      (let ((other-end (if (= (point) beg) end beg))
+	    (opoint (point))
+	    ;; Inhibit quitting so we can make a quit here
+	    ;; look like a C-g typed as a command.
+	    (inhibit-quit t))
+	(if (pos-visible-in-window-p other-end (selected-window))
+	    (unless transient-mark-mode
+	      ;; Swap point and mark.
+	      (set-marker (mark-marker) (point) (current-buffer))
+	      (goto-char other-end)
+	      (sit-for 1)
+	      ;; Swap back.
+	      (set-marker (mark-marker) other-end (current-buffer))
+	      (goto-char opoint)
+	      ;; If user quit, deactivate the mark
+	      ;; as C-g would as a command.
+	      (and quit-flag mark-active
+		   (deactivate-mark)))
+	  (let* ((killed-text (current-kill 0))
+		 (message-len (min (length killed-text) 40)))
+	    (if (= (point) beg)
+		;; Don't say "killed"; that is misleading.
+		(message "Saved text until \"%s\""
+			(substring killed-text (- message-len)))
+	      (message "Saved text from \"%s\""
+		      (substring killed-text 0 message-len))))))))
+
+(defun append-next-kill (&optional interactive)
+  "Cause following command, if it kills, to append to previous kill.
+The argument is used for internal purposes; do not supply one."
+  (interactive "p")
+  ;; We don't use (interactive-p), since that breaks kbd macros.
+  (if interactive
+      (progn
+	(setq this-command 'kill-region)
+	(message "If the next command is a kill, it will append"))
+    (setq last-command 'kill-region)))
+\f
+;; Yanking.
+
+;; This is actually used in subr.el but defcustom does not work there.
+(defcustom yank-excluded-properties
+  '(read-only invisible intangible field mouse-face local-map keymap)
+  "*Text properties to discard when yanking."
+  :type '(choice (const :tag "All" t) (repeat symbol))
+  :group 'editing
+  :version 21.4)
+
+(defun yank-pop (arg)
+  "Replace just-yanked stretch of killed text with a different stretch.
+This command is allowed only immediately after a `yank' or a `yank-pop'.
+At such a time, the region contains a stretch of reinserted
+previously-killed text.  `yank-pop' deletes that text and inserts in its
+place a different stretch of killed text.
+
+With no argument, the previous kill is inserted.
+With argument N, insert the Nth previous kill.
+If N is negative, this is a more recent kill.
+
+The sequence of kills wraps around, so that after the oldest one
+comes the newest one."
+  (interactive "*p")
+  (setq this-command 'yank)
+  (let ((inhibit-read-only t)
+	(before (< (point) (mark t))))
+    (delete-region (point) (mark t))
+    (set-marker (mark-marker) (point) (current-buffer))
+    (insert-for-yank (current-kill arg))
+    (if before
+	;; This is like exchange-point-and-mark, but doesn't activate the mark.
+	;; It is cleaner to avoid activation, even though the command
+	;; loop would deactivate the mark because we inserted text.
+	(goto-char (prog1 (mark t)
+		     (set-marker (mark-marker) (point) (current-buffer))))))
+  nil)
+
+(defun yank-previous (arg)
+  "Replace previously yanked text, or display a kill ring menu.
+If the last command was a `yank', `yank-previous', or `yank-pop', then
+this command will replace a just-yanked section of text with a prevous
+entry in the kill ring, using ARG.  See `yank-pop'.
+Otherwise, this command will display a menu of kill ring entries; see
+`kill-ring-menu'."
+  (interactive "*p")
+  (if (not (memq last-command '(yank yank-previous)))
+      (kill-ring-menu)
+    (yank-pop arg)))
+
+(defun yank (&optional arg)
+  "Reinsert the last stretch of killed text.
+More precisely, reinsert the stretch of killed text most recently
+killed OR yanked.  Put point at end, and set mark at beginning.
+With just C-u as argument, same but put point at beginning (and mark at end).
+With argument N, reinsert the Nth most recently killed stretch of killed
+text.
+See also the command \\[yank-pop]."
+  (interactive "*P")
+  ;; If we don't get all the way thru, make last-command indicate that
+  ;; for the following command.
+  (setq this-command t)
+  (push-mark (point))
+  (insert-for-yank (current-kill (cond
+				  ((listp arg) 0)
+				  ((eq arg '-) -1)
+				  (t (1- arg)))))
+  (if (consp arg)
+      ;; This is like exchange-point-and-mark, but doesn't activate the mark.
+      ;; It is cleaner to avoid activation, even though the command
+      ;; loop would deactivate the mark because we inserted text.
+      (goto-char (prog1 (mark t)
+		   (set-marker (mark-marker) (point) (current-buffer)))))
+  ;; If we do get all the way thru, make this-command indicate that.
+  (setq this-command 'yank)
+  nil)
+
+(defun rotate-yank-pointer (arg)
+  "Rotate the yanking point in the kill ring.
+With argument, rotate that many kills forward (or backward, if negative)."
+  (interactive "p")
+  (current-kill arg))
+\f
+;; Some kill commands.
+
+;; Internal subroutine of delete-char
+(defun kill-forward-chars (arg)
+  (if (listp arg) (setq arg (car arg)))
+  (if (eq arg '-) (setq arg -1))
+  (kill-region (point) (forward-point arg)))
+
+;; Internal subroutine of backward-delete-char
+(defun kill-backward-chars (arg)
+  (if (listp arg) (setq arg (car arg)))
+  (if (eq arg '-) (setq arg -1))
+  (kill-region (point) (forward-point (- arg))))
+
+;; kill-line and its subroutines.
+
+(defcustom kill-whole-line nil
+  "*If non-nil, `kill-line' with no arg at beg of line kills the whole line."
+  :type 'boolean
+  :group 'killing)
+
+(defun kill-line (&optional arg)
+  "Kill the rest of the current line; if no nonblanks there, kill thru newline.
+With prefix argument, kill that many lines from point.
+Negative arguments kill lines backward.
+With zero argument, kills the text before point on the current line.
+
+When calling from a program, nil means \"no arg\",
+a number counts as a prefix arg.
+
+To kill a whole line, when point is not at the beginning, type \
+\\[beginning-of-line] \\[kill-line] \\[kill-line].
+
+If `kill-whole-line' is non-nil, then this command kills the whole line
+including its terminating newline, when used at the beginning of a line
+with no argument.  As a consequence, you can always kill a whole line
+by typing \\[beginning-of-line] \\[kill-line].
+
+If you want to append the killed line to the last killed text,
+use \\[append-next-kill] before \\[kill-line].
+
+If the buffer is read-only, Emacs will beep and refrain from deleting
+the line, but put the line in the kill ring anyway.  This means that
+you can use this command to copy text from a read-only buffer."
+  (interactive "P")
+  (kill-region (point)
+	       ;; It is better to move point to the other end of the kill
+	       ;; before killing.  That way, in a read-only buffer, point
+	       ;; moves across the text that is copied to the kill ring.
+	       ;; The choice has no effect on undo now that undo records
+	       ;; the value of point from before the command was run.
+	       (progn
+		 (if arg
+		     (forward-visible-line (prefix-numeric-value arg))
+		   (if (eobp)
+		       (signal 'end-of-buffer nil))
+		   (if (or (looking-at "[ \t]*$") (and kill-whole-line (bolp)))
+		       (forward-visible-line 1)
+		     (end-of-visible-line)))
+		 (point))))
+
+(put 'kill-ring-menu-mode 'mode-class 'special)
+(define-derived-mode kill-ring-menu-mode fundamental-mode
+  "Kill Ring"
+  "A major mode for browsing the `kill-ring'.
+You most likely do not want to call `kill-ring-menu-mode' directly; use
+`kill-ring-menu' instead.
+
+\\{kill-ring-menu-mode-map}"
+  (set (make-local-variable 'kill-ring-menu-original-window) nil)
+  (set (make-local-variable 'font-lock-defaults)
+       '(nil t nil nil nil
+	     (font-lock-fontify-region-function . kill-ring-menu-fontify-region-function)
+	     (font-lock-unfontify-region-function . kill-ring-menu-unfontify-region-function)))
+  (define-key kill-ring-menu-mode-map (kbd "q") 'kill-ring-menu-quit)
+  (define-key kill-ring-menu-mode-map (kbd "C-g") 'kill-ring-menu-quit)
+  (define-key kill-ring-menu-mode-map (kbd "d") 'kill-ring-menu-delete)
+  (define-key kill-ring-menu-mode-map (kbd "g") 'kill-ring-menu-update)
+  (define-key kill-ring-menu-mode-map (kbd "n") 'kill-ring-menu-forward)
+  (define-key kill-ring-menu-mode-map (kbd "p") 'kill-ring-menu-backward)
+  (define-key kill-ring-menu-mode-map [(mouse-2)] 'kill-ring-menu-mouse-insert)
+  (define-key kill-ring-menu-mode-map (kbd "?") 'describe-mode)
+  (define-key kill-ring-menu-mode-map (kbd "h") 'describe-mode)
+  (define-key kill-ring-menu-mode-map (kbd "RET") 'kill-ring-menu-insert))
+
+(defun kill-ring-menu-fontify-region-function (beg end &optional verbose)
+  (when verbose (message "Fontifying..."))
+  (let ((inhibit-read-only t))
+    (font-lock-fontify-on-text-properties
+     beg end 'kill-ring-menu-special 'bold)
+    (when verbose (message "Fontifying...done"))))
+
+(defun kill-ring-menu-unfontify-region-function (beg end)
+  (let ((inhibit-read-only t))
+    (remove-text-properties beg end '(face nil))))
+
+(defun kill-ring-menu-elide (str)
+  (if (and kill-ring-menu-maximum-display-length
+	   (> (length str)
+	      kill-ring-menu-maximum-display-length))
+      (concat (substring str 0 (- kill-ring-menu-maximum-display-length 3))
+	      (propertize "..." 'kill-ring-menu-special t)))
+  str)
+
+(defmacro kill-ring-menu-add-overlays-for (item &rest body)
+  (let ((beg (gensym "kill-ring-menu-add-overlays-"))
+	(end (gensym "kill-ring-menu-add-overlays-")))
+    `(let ((,beg (point))
+	   (,end
+	    (progn
+	      ,@body
+	      (point))))
+       (let ((o (make-overlay ,beg ,end)))
+	 (overlay-put o 'kill-ring-menu-target ,item)
+	 (overlay-put o 'mouse-face 'highlight)))))
+;; (put 'kill-ring-menu-add-overlays-for 'lisp-indent-function 1)
+
+(defun kill-ring-menu-insert-as-one-line (items)
+  (dolist (item items)
+    (kill-ring-menu-add-overlays-for item
+      (let* ((item (kill-ring-menu-elide item))
+	     (len (length item))
+	     (start 0)
+	     (newl (propertize "\\n" 'kill-ring-menu-special t)))
+	(while (and (< start len)
+		    (string-match "\n" item start))
+	  (insert (substring item start (match-beginning 0))
+		  newl)
+	  (setq start (match-end 0)))
+	(insert (substring item start len))))
+    (insert "\n")))
+
+(defun kill-ring-menu-insert-as-separated (items)
+  (while (cdr items)
+    (kill-ring-menu-insert-as-separated-1 (car items) t)
+    (setq items (cdr items)))
+  (when items
+    (kill-ring-menu-insert-as-separated-1 (car items) nil)))
+
+(defun kill-ring-menu-insert-as-separated-1 (origitem separatep)
+  (let* ((item (kill-ring-menu-elide origitem))
+	 (len (length item)))
+    (kill-ring-menu-add-overlays-for origitem
+	(insert item))
+    (insert "\n")
+    (when separatep
+      (insert (propertize kill-ring-menu-separator
+			  'kill-ring-menu-special t))
+      (insert "\n"))))
+
+;; (unintern 'kill-ring-menu-add-overlays-for)
+
+(defun kill-ring-menu-quit ()
+  "Take the action specified by `kill-ring-menu-quit-action'."
+  (interactive)
+  (case kill-ring-menu-quit-action
+    (kill-and-delete-window
+     (kill-buffer (current-buffer))
+     (unless (= (count-windows) 1)
+       (delete-window)))
+    (bury-and-delete-window
+     (bury-buffer)
+     (unless (= (count-windows) 1)
+       (delete-window)))
+    (t
+     (funcall kill-ring-menu-quit-action))))
+
+(defun kill-ring-menu-forward (&optional arg)
+  "Move forward by ARG `kill-ring' entries."
+  (interactive "p")
+  (beginning-of-line)
+  (while (not (zerop arg))
+    (if (< arg 0)
+	(progn
+	  (incf arg)
+	  (if (overlays-at (point))
+	      (progn
+		(goto-char (overlay-start (car (overlays-at (point)))))
+		(goto-char (previous-overlay-change (point)))
+		(goto-char (previous-overlay-change (point))))
+	    (progn
+	      (goto-char (1- (previous-overlay-change (point))))
+	      (unless (bobp)
+		(goto-char (overlay-start (car (overlays-at (point)))))))))
+      (progn
+	(decf arg)
+	(if (overlays-at (point))
+	    (progn
+	      (goto-char (overlay-end (car (overlays-at (point)))))
+	      (goto-char (next-overlay-change (point))))
+	  (goto-char (next-overlay-change (point)))
+	  (unless (eobp)
+	    (goto-char (overlay-start (car (overlays-at (point))))))))))
+  ;; This could probably be implemented in a more intelligent manner.
+  ;; Perhaps keep track over the overlay we started from?  That would
+  ;; break when the user moved manually, though.
+  (when (and kill-ring-menu-highlight-current-entry
+	     (overlays-at (point)))
+    (let ((overs (overlay-lists))
+	  (current-overlay (car (overlays-at (point)))))
+      (mapcar #'(lambda (o)
+		  (overlay-put o 'face nil))
+	      (nconc (car overs) (cdr overs)))
+      (overlay-put current-overlay 'face 'highlight))))
+
+(defun kill-ring-menu-backward (&optional arg)
+  "Move backward by ARG `kill-ring' entries."
+  (interactive "p")
+  (kill-ring-menu-forward (- arg)))
+
+(defun kill-ring-menu-do-insert (buf pt)
+  (let ((str (with-current-buffer buf
+	       (let ((overs (overlays-at pt)))
+		 (or (and overs
+			  (overlay-get (car overs) 'kill-ring-menu-target))
+		     (error "No kill ring item here"))))))
+    (let ((orig (current-buffer)))
+      (unwind-protect
+	  (progn
+	    (unless (window-live-p kill-ring-menu-original-window)
+	      (kill-ring-menu-quit)
+	      (error (substitute-command-keys "Window %s has been deleted; Try calling '\\[yank-previous]' again")
+		     kill-ring-menu-original-window))
+	    (set-buffer (window-buffer kill-ring-menu-original-window))
+	    (save-excursion
+	      (insert str)))
+	(set-buffer orig)))))
+
+(defun kill-ring-menu-mouse-insert (e)
+  "Insert the chosen text in the last selected buffer."
+  (interactive "e")
+  (let* ((end (event-end e))
+	 (win (posn-window end))
+	 (buf (window-buffer win)))
+    (select-window win)
+    (kill-ring-menu-do-insert buf (posn-point end))
+    (kill-ring-menu-quit)))
+
+(defun kill-ring-menu-insert (&optional noquit)
+  "Insert the kill ring item at point, and close the kill ring menu.
+If optional argument NOQUIT is non-nil, don't close the menu."
+  (interactive "P")
+  (kill-ring-menu-do-insert (current-buffer) (point))
+  (unless noquit
+    (kill-ring-menu-quit)))
+
+(defun kill-ring-menu-update ()
+  "Update the buffer to reflect outside changes to `kill-ring'."
+  (interactive)
+  (assert (eq major-mode 'kill-ring-menu-mode))
+  (kill-ring-menu-setup (current-buffer)
+			  kill-ring-menu-original-window))
+
+(defun kill-ring-menu-setup (buf window &optional regexp)
+  (with-current-buffer buf
+    (unwind-protect
+	(progn
+	  (kill-ring-menu-mode)
+	  (setq buffer-read-only nil)
+	  (when (eq kill-ring-menu-display-style
+		    'one-line)
+	    (setq truncate-lines t))
+	  (erase-buffer)
+	  (setq kill-ring-menu-original-window window)
+	  (let ((kill-ring-menu-maximum-display-length
+		 (if (and kill-ring-menu-maximum-display-length
+			  (<= kill-ring-menu-maximum-display-length 3))
+		     4
+		   kill-ring-menu-maximum-display-length))
+		(items (mapcar #'copy-sequence kill-ring)))
+;; 	    (when (not kill-ring-menu-display-duplicates)
+;; 	      (setq items (delete-duplicates items :test #'equal)))
+	    (when (stringp regexp)
+	      (setq items (delq nil
+				(mapcar
+				 #'(lambda (item)
+				     (when (string-match regexp item)
+				       item))
+				 items))))
+	    (funcall (intern
+		      (concat "kill-ring-menu-insert-as-"
+			      (symbol-name kill-ring-menu-display-style)))
+		     items)
+	    (if (not regexp)
+		(message "%s entries in the kill ring" (length kill-ring))
+	      (message "%s (of %s) entries in the kill ring shown"
+		       (length items) (length kill-ring)))
+	    (set-buffer-modified-p nil)
+	    (goto-char (point-min))
+	    (kill-ring-menu-forward 0)
+	    (when regexp
+	      (setq mode-name (concat "Kill Ring [" regexp "]")))
+	    (run-hooks 'kill-ring-menu-hook)))
+      (progn
+	(setq buffer-read-only t)))))
+
+;;;###autoload
+(defun kill-ring-menu ()
+  "Display items in the `kill-ring' in another buffer."
+  (interactive)
+  (let ((orig-buf (current-buffer))
+	(buf (get-buffer-create "*Kill Ring*")))
+    (kill-ring-menu-setup buf (selected-window))
+    (pop-to-buffer buf)
+    nil))
+
+(provide 'kill-ring)
--- killing.texi.~1.26.~	Wed Sep 12 17:01:34 2001
+++ killing.texi	Sun Apr 28 13:08:24 2002
@@ -270,8 +270,7 @@
 @item C-y
 Yank last killed text (@code{yank}).
 @item M-y
-Replace text just yanked with an earlier batch of killed text
-(@code{yank-pop}).
+Choose previously yanked text to insert (@code{yank-pop}).
 @item M-w
 Save region as last killed text without actually killing it
 (@code{kill-ring-save}).
@@ -374,49 +373,92 @@
 
 @cindex yanking previous kills
 @kindex M-y
-@findex yank-pop
-  To recover killed text that is no longer the most recent kill, use the
-@kbd{M-y} command (@code{yank-pop}).  It takes the text previously
-yanked and replaces it with the text from an earlier kill.  So, to
-recover the text of the next-to-the-last kill, first use @kbd{C-y} to
-yank the last kill, and then use @kbd{M-y} to replace it with the
-previous kill.  @kbd{M-y} is allowed only after a @kbd{C-y} or another
-@kbd{M-y}.
-
-  You can understand @kbd{M-y} in terms of a ``last yank'' pointer which
-points at an entry in the kill ring.  Each time you kill, the ``last
-yank'' pointer moves to the newly made entry at the front of the ring.
-@kbd{C-y} yanks the entry which the ``last yank'' pointer points to.
-@kbd{M-y} moves the ``last yank'' pointer to a different entry, and the
-text in the buffer changes to match.  Enough @kbd{M-y} commands can move
-the pointer to any entry in the ring, so you can get any entry into the
+@findex yank-previous
+  To recover killed text that is no longer the most recent kill, use
+the @kbd{M-y} command (@code{yank-previous}).  This command can act in
+two different ways.  If the previous command was not a yank, then
+@kbd{M-y} will display a menu of kill ring entries, which you can
+choose from (@code{kill-ring-menu}).  If the previous command was a
+yank, then @kbd{M-y} will replace the previously yanked text with the
+text from an earlier kill (@code{yank-pop}).
+
+@subsubsection The Kill Ring Menu 
+If you are not sure how long ago you killed the piece of text you're
+loooking for, it can often be easiest to use the kill ring menu.
+Simply type @kbd{M-y} (which was not preceeded by a @kbd{C-y}), and a
+window should pop up, which will display the text previously killed,
+one entry on each line.  In this special mode, keys do not insert
+themselves; instead, they choose actions to perform.
+
+@table @kbd
+@item RET
+Choose the text at point to yank (@code{kill-ring-menu-insert}).
+@item n
+Move point forward by one kill ring entry
+(@code{kill-ring-menu-forward}).
+@item p
+Move point backwards by one kill ring entry
+(@code{kill-ring-menu-backward}).
+@item q
+Quit the kill ring menu without yanking any text
+(@code{kill-ring-menu-quit}).
+@item d
+Remove the text at point from the kill ring
+(@code{kill-ring-menu-delete}).
+@end table
+
+The kill ring menu can display multi-line text; In the default display
+style, all text is shown on one line, and newlines are shown as a
+@samp{\n}.
+
+@subsubsection Cycling Through Yanked Text
+
+If you know precisely where the text you previously yanked is in the
+@code{kill-ring}, or it was very recently yanked, you may find using
+the @code{yank-pop} functionality of @kbd{M-y} to be faster than the
+kill ring menu.  For example, to recover the text of the
+next-to-the-last kill, you could first use @kbd{C-y} to yank the last
+kill, and then type @kbd{M-y} to replace it with the previous kill.
+
+  You can understand @code{yank-pop} in terms of a ``last yank''
+pointer which points at an entry in the kill ring.  Each time you
+kill, the ``last yank'' pointer moves to the newly made entry at the
+front of the ring.  @kbd{C-y} yanks the entry which the ``last yank''
+pointer points to.  After that, typing @kbd{M-y} moves the ``last
+yank'' pointer to a different entry, and the text in the buffer
+changes to match.  Enough @code{yank-pop} commands can move the
+pointer to any entry in the ring, so you can get any entry into the
 buffer.  Eventually the pointer reaches the end of the ring; the next
 @kbd{M-y} loops back around to the first entry again.
 
-  @kbd{M-y} moves the ``last yank'' pointer around the ring, but it does
-not change the order of the entries in the ring, which always runs from
-the most recent kill at the front to the oldest one still remembered.
-
-  @kbd{M-y} can take a numeric argument, which tells it how many entries
-to advance the ``last yank'' pointer by.  A negative argument moves the
-pointer toward the front of the ring; from the front of the ring, it
-moves ``around'' to the last entry and continues forward from there.
-
-  Once the text you are looking for is brought into the buffer, you can
-stop doing @kbd{M-y} commands and it will stay there.  It's just a copy
-of the kill ring entry, so editing it in the buffer does not change
-what's in the ring.  As long as no new killing is done, the ``last
-yank'' pointer remains at the same place in the kill ring, so repeating
-@kbd{C-y} will yank another copy of the same previous kill.
-
-  If you know how many @kbd{M-y} commands it would take to find the
-text you want, you can yank that text in one step using @kbd{C-y} with
-a numeric argument.  @kbd{C-y} with an argument restores the text from
-the specified kill ring entry, counting back from the most recent as
-1.  Thus, @kbd{C-u 2 C-y} gets the next-to-the-last block of killed
+  @code{yank-pop} moves the ``last yank'' pointer around the ring, but
+it does not change the order of the entries in the ring, which always
+runs from the most recent kill at the front to the oldest one still
+remembered.
+
+  @code{yank-pop} can take a numeric argument, which tells it how many
+entries to advance the ``last yank'' pointer by.  A negative argument
+moves the pointer toward the front of the ring; from the front of the
+ring, it moves ``around'' to the last entry and continues forward from
--- font-lock.el.~1.195.~	Fri Apr  5 04:37:40 2002
+++ font-lock.el	Sun Apr 28 03:41:17 2002
@@ -1358,6 +1358,32 @@
       (put-text-property start next prop value object)
       (setq start (text-property-any next end prop nil object)))))
 
+(defun font-lock-fontify-on-text-properties (beg end &rest plist)
+  "Match areas of text which have text properties with faces.
+Only areas of text between BEG and END are considered.  The remaining
+arguments should form a property list which looks like
+ (PROPERTY FACE PROPERTY FACE ...)."
+  (save-excursion
+    (let ((change-end nil))
+      (while plist
+	(goto-char beg)
+	(while (and plist
+		    (setq change-end (font-lock-fontify-on-text-property
+				      (car plist) (cadr plist) (point) end)))
+	  (goto-char change-end))
+	(setq plist (cddr plist))))))
+
+(defun font-lock-fontify-on-text-property (prop face beg end)
+  "Add face FACE to areas of text which have text property PROP.
+Only areas of text between BEG and END are considered."
+  (let ((prop-beg (or (and (get-text-property (point) prop) (point))
+		      (next-single-property-change (point) prop nil end))))
+    (when (and prop-beg (not (= prop-beg end)))
+      (let ((prop-end (next-single-property-change beg prop nil end)))
+	(when (and prop-end (not (= prop-end end)))
+	  (put-text-property prop-beg prop-end 'face face)
+	  prop-end)))))
+
 ;; For completeness: this is to `remove-text-properties' as `put-text-property'
 ;; is to `add-text-properties', etc.
 ;(defun remove-text-property (start end property &optional object)

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-28 19:41 kill ring menu Colin Walters
@ 2002-04-28 20:06 ` Colin Walters
  2002-04-29  5:05   ` Richard Stallman
  2002-04-28 22:53 ` Miles Bader
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-04-28 20:06 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 89 bytes --]

Forgot to attach these minor changes to bindings.el and loadup.el, which
we also need.



[-- Attachment #2: kill-ring2.patch --]
[-- Type: text/plain, Size: 648 bytes --]

--- bindings.el.~1.100.~	Wed Apr 17 17:38:22 2002
+++ bindings.el	Sun Apr 28 02:09:00 2002
@@ -643,7 +643,7 @@
 (define-key esc-map "w" 'kill-ring-save)
 (define-key esc-map "\C-w" 'append-next-kill)
 (define-key global-map "\C-y" 'yank)
-(define-key esc-map "y" 'yank-pop)
+(define-key esc-map "y" 'yank-previous)
 
 ;; (define-key ctl-x-map "a" 'append-to-buffer)
 
--- loadup.el.~1.122.~	Sat Apr 27 17:20:53 2002
+++ loadup.el	Sun Apr 28 02:09:41 2002
@@ -65,6 +65,7 @@
 (load "bindings")
 (setq load-source-file-function 'load-with-code-conversion)
 (load "simple")
+(load "kill-ring")
 (load "files")
 
 (load "cus-face")

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-28 19:41 kill ring menu Colin Walters
  2002-04-28 20:06 ` Colin Walters
@ 2002-04-28 22:53 ` Miles Bader
  2002-04-28 23:36 ` Stefan Monnier
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-04-28 22:53 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@debian.org> writes:
> As for the patch itself: basically, I renamed `browse-kill-ring' to
> `kill-ring-menu', removed the more esoteric functionality (like editing
> kill ring entries), and rewrote it to use font lock, among other things.

Why?  `browse-kill-ring' seems quite clear, whereas `kill-ring-menu'
sounds vaguely like it's going to pop down from the menu-bar.

Also, something seems screwy with your patch -- it's basically just one
big delete followed by one big add, even though much has changed.  This
makes it very hard to read.

-Miles
-- 
Suburbia: where they tear out the trees and then name streets after them.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-28 19:41 kill ring menu Colin Walters
  2002-04-28 20:06 ` Colin Walters
  2002-04-28 22:53 ` Miles Bader
@ 2002-04-28 23:36 ` Stefan Monnier
  2002-04-28 23:42   ` Miles Bader
  2002-04-29  4:34   ` Colin Walters
  2002-04-29  3:35 ` Miles Bader
       [not found] ` <200204290505.g3T55t006146@aztec.santafe.edu>
  4 siblings, 2 replies; 82+ messages in thread
From: Stefan Monnier @ 2002-04-28 23:36 UTC (permalink / raw)
  Cc: emacs-devel

> I have moved all the killing stuff out from simple.el into kill-ring.el;

I think that's a good idea, but as Miles pointed out, it makes the patch
"unreadable", so please make the change in two steps.

> Finally, I'm not totally satisfied with the manual additions; there are
> some bootstrapping issues, since we haven't discussed windows at that
> point in the manual yet, etc.

You'll need to add kill-ring.elc to the list of files to pass
to make-docfile (in src/Makefile.in) if it's preloaded.

> +(defun font-lock-fontify-on-text-properties (beg end &rest plist)
> +  "Match areas of text which have text properties with faces.

By "have text-property" it seems you mean "have non-nil text-property".
Check `default-text-properties' to discover that the two notions
are actually different.


	Stefan

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-28 23:36 ` Stefan Monnier
@ 2002-04-28 23:42   ` Miles Bader
  2002-04-29  4:34   ` Colin Walters
  1 sibling, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-04-28 23:42 UTC (permalink / raw)
  Cc: Colin Walters, emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@RUM.cs.yale.edu> writes:
> > I have moved all the killing stuff out from simple.el into kill-ring.el;
> 
> I think that's a good idea, but as Miles pointed out, it makes the patch
> "unreadable", so please make the change in two steps.

Oh, _that's_ why that happened...  (duh)

-Miles
-- 
A zen-buddhist walked into a pizza shop and
said, "Make me one with everything."

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-28 19:41 kill ring menu Colin Walters
                   ` (2 preceding siblings ...)
  2002-04-28 23:36 ` Stefan Monnier
@ 2002-04-29  3:35 ` Miles Bader
  2002-04-29  4:37   ` Colin Walters
  2002-04-29 18:40   ` Richard Stallman
       [not found] ` <200204290505.g3T55t006146@aztec.santafe.edu>
  4 siblings, 2 replies; 82+ messages in thread
From: Miles Bader @ 2002-04-29  3:35 UTC (permalink / raw)
  Cc: emacs-devel

Also another comment:

+(defcustom kill-ring-menu-separator-face 'bold
+  "The face in which to highlight the `kill-ring-menu-separator'."

It's the general custom now-days to not define variables holding faces,
but instead simply make a specialized face if you need it, and use the
:inherit attribute if you want to use a builtin face by default.  This
is more convenient and less confusing for users.

E.g. instead of above, use:

(defface kill-ring-menu-separator '((t :inherit bold))
  "The face in which to highlight the `kill-ring-menu-separator'."
   :group 'killing)

[or just use `:weight bold' instead of :inherit]

-Miles
-- 
I have seen the enemy, and he is us.  -- Pogo

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-28 23:36 ` Stefan Monnier
  2002-04-28 23:42   ` Miles Bader
@ 2002-04-29  4:34   ` Colin Walters
  2002-04-30  4:49     ` Eli Zaretskii
  1 sibling, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-04-29  4:34 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 891 bytes --]

[ No need to CC me, I do read emacs-devel ]

On Sun, 2002-04-28 at 19:36, Stefan Monnier wrote:
> > I have moved all the killing stuff out from simple.el into kill-ring.el;
> 
> I think that's a good idea, but as Miles pointed out, it makes the patch
> "unreadable", so please make the change in two steps.

Ok.  Please find a version of the patch attached which keeps things in
simple.el.

It's not arranged as nicely as I would like, but it does show pretty
clearly that there are almost no changes to previously existing
functions.

> You'll need to add kill-ring.elc to the list of files to pass
> to make-docfile (in src/Makefile.in) if it's preloaded.

Thanks, I'll remember to do that.

> By "have text-property" it seems you mean "have non-nil text-property".
> Check `default-text-properties' to discover that the two notions
> are actually different.

Docstrings fixed, thanks.




[-- Attachment #2: kill-ring.patch --]
[-- Type: text/x-patch, Size: 23882 bytes --]

Index: NEWS
===================================================================
RCS file: /cvsroot/emacs/emacs/etc/NEWS,v
retrieving revision 1.661
diff -u -u -r1.661 NEWS
--- NEWS	28 Apr 2002 21:16:32 -0000	1.661
+++ NEWS	29 Apr 2002 04:30:49 -0000
@@ -49,6 +48,13 @@
 
 \f
 * Changes in Emacs 21.4
+
++++
+** The key `M-y' has been extended to display a menu of kill ring
+entries, if the previous command was not a 'C-y'.  Previously, `M-y'
+ran the command `yank-pop'.  Now it runs `yank-previous', which will
+either display a menu (`kill-ring-menu') or call `yank-pop'.  See the
+node "Yanking Earlier Kills" in the Emacs manual for more information.
 
 ---
 ** The new options `buffers-menu-show-directories' and
--- killing.texi.~1.26.~	Wed Sep 12 17:01:34 2001
+++ killing.texi	Sun Apr 28 16:25:50 2002
@@ -270,8 +270,7 @@
 @item C-y
 Yank last killed text (@code{yank}).
 @item M-y
-Replace text just yanked with an earlier batch of killed text
-(@code{yank-pop}).
+Choose previously yanked text to insert (@code{yank-previous}).
 @item M-w
 Save region as last killed text without actually killing it
 (@code{kill-ring-save}).
@@ -374,49 +373,94 @@
 
 @cindex yanking previous kills
 @kindex M-y
+@findex yank-previous
 @findex yank-pop
-  To recover killed text that is no longer the most recent kill, use the
-@kbd{M-y} command (@code{yank-pop}).  It takes the text previously
-yanked and replaces it with the text from an earlier kill.  So, to
-recover the text of the next-to-the-last kill, first use @kbd{C-y} to
-yank the last kill, and then use @kbd{M-y} to replace it with the
-previous kill.  @kbd{M-y} is allowed only after a @kbd{C-y} or another
-@kbd{M-y}.
-
-  You can understand @kbd{M-y} in terms of a ``last yank'' pointer which
-points at an entry in the kill ring.  Each time you kill, the ``last
-yank'' pointer moves to the newly made entry at the front of the ring.
-@kbd{C-y} yanks the entry which the ``last yank'' pointer points to.
-@kbd{M-y} moves the ``last yank'' pointer to a different entry, and the
-text in the buffer changes to match.  Enough @kbd{M-y} commands can move
-the pointer to any entry in the ring, so you can get any entry into the
+@findex kill-ring-menu
+  To recover killed text that is no longer the most recent kill, use
+the @kbd{M-y} command (@code{yank-previous}).  This command can act in
+two different ways.  If the previous command was not a yank, then
+@kbd{M-y} will display a menu of kill ring entries, which you can
+choose from (@code{kill-ring-menu}).  If the previous command was a
+yank, then @kbd{M-y} will replace the previously yanked text with the
+text from an earlier kill (@code{yank-pop}).
+
+@subsubsection The Kill Ring Menu 
+If you are not sure how long ago you killed the piece of text you're
+loooking for, it can often be easiest to use the kill ring menu.
+Simply type @kbd{M-y} (which was not preceeded by a @kbd{C-y}), and a
+window should pop up, which will display the text previously killed,
+one entry on each line.  In this special mode, keys do not insert
+themselves; instead, they choose actions to perform.
+
+@table @kbd
+@item RET
+Choose the text at point to yank (@code{kill-ring-menu-insert}).
+@item n
+Move point forward by one kill ring entry
+(@code{kill-ring-menu-forward}).
+@item p
+Move point backwards by one kill ring entry
+(@code{kill-ring-menu-backward}).
+@item q
+Quit the kill ring menu without yanking any text
+(@code{kill-ring-menu-quit}).
+@item d
+Remove the text at point from the kill ring
+(@code{kill-ring-menu-delete}).
+@end table
+
+The kill ring menu can display multi-line text; In the default display
+style, all text is shown on one line, and newlines are shown as a
+@samp{\n}.
+
+@subsubsection Cycling Through Yanked Text
+
+If you know precisely where the text you previously yanked is in the
+@code{kill-ring}, or it was very recently yanked, you may find using
+the @code{yank-pop} functionality of @kbd{M-y} to be faster than the
+kill ring menu.  For example, to recover the text of the
+next-to-the-last kill, you could first use @kbd{C-y} to yank the last
+kill, and then type @kbd{M-y} to replace it with the previous kill.
+
+  You can understand @code{yank-pop} in terms of a ``last yank''
+pointer which points at an entry in the kill ring.  Each time you
+kill, the ``last yank'' pointer moves to the newly made entry at the
+front of the ring.  @kbd{C-y} yanks the entry which the ``last yank''
+pointer points to.  After that, typing @kbd{M-y} moves the ``last
+yank'' pointer to a different entry, and the text in the buffer
+changes to match.  Enough @code{yank-pop} commands can move the
+pointer to any entry in the ring, so you can get any entry into the
 buffer.  Eventually the pointer reaches the end of the ring; the next
 @kbd{M-y} loops back around to the first entry again.
 
-  @kbd{M-y} moves the ``last yank'' pointer around the ring, but it does
-not change the order of the entries in the ring, which always runs from
-the most recent kill at the front to the oldest one still remembered.
-
-  @kbd{M-y} can take a numeric argument, which tells it how many entries
-to advance the ``last yank'' pointer by.  A negative argument moves the
-pointer toward the front of the ring; from the front of the ring, it
-moves ``around'' to the last entry and continues forward from there.
-
-  Once the text you are looking for is brought into the buffer, you can
-stop doing @kbd{M-y} commands and it will stay there.  It's just a copy
-of the kill ring entry, so editing it in the buffer does not change
-what's in the ring.  As long as no new killing is done, the ``last
-yank'' pointer remains at the same place in the kill ring, so repeating
-@kbd{C-y} will yank another copy of the same previous kill.
-
-  If you know how many @kbd{M-y} commands it would take to find the
-text you want, you can yank that text in one step using @kbd{C-y} with
-a numeric argument.  @kbd{C-y} with an argument restores the text from
-the specified kill ring entry, counting back from the most recent as
-1.  Thus, @kbd{C-u 2 C-y} gets the next-to-the-last block of killed
+  @code{yank-pop} moves the ``last yank'' pointer around the ring, but
+it does not change the order of the entries in the ring, which always
+runs from the most recent kill at the front to the oldest one still
+remembered.
+
+  @code{yank-pop} can take a numeric argument, which tells it how many
+entries to advance the ``last yank'' pointer by.  A negative argument
+moves the pointer toward the front of the ring; from the front of the
+ring, it moves ``around'' to the last entry and continues forward from
+there.
+
+  Once the text you are looking for is brought into the buffer, you
+can stop doing @code{yank-pop} commands and it will stay there.  It's
+just a copy of the kill ring entry, so editing it in the buffer does
+not change what's in the ring.  As long as no new killing is done, the
+``last yank'' pointer remains at the same place in the kill ring, so
+repeating @kbd{C-y} will yank another copy of the same previous kill.
+
+  If you know how many @code{yank-pop} commands it would take to find
+the text you want, you can yank that text in one step using @kbd{C-y}
+with a numeric argument.  @kbd{C-y} with an argument restores the text
+from the specified kill ring entry, counting back from the most recent
+as 1.  Thus, @kbd{C-u 2 C-y} gets the next-to-the-last block of killed
 text---it is equivalent to @kbd{C-y M-y}.  @kbd{C-y} with a numeric
 argument starts counting from the ``last yank'' pointer, and sets the
 ``last yank'' pointer to the entry that it yanks.
+
+@subsubsection The Kill Ring Data
 
 @vindex kill-ring-max
   The length of the kill ring is controlled by the variable
Index: simple.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/simple.el,v
retrieving revision 1.539
diff -u -u -r1.539 simple.el
--- simple.el	27 Apr 2002 23:16:18 -0000	1.539
+++ simple.el	29 Apr 2002 04:29:23 -0000
@@ -1713,9 +1713,69 @@
   :type 'integer
   :group 'killing)
 
+(defcustom browse-kill-ring-display-style 'one-line
+  "How to display the kill ring menu items.
+
+If `one-line', then replace newlines with \"\\n\" for display.
+
+If `separated', then display `browse-kill-ring-separator' between
+entries."
+  :type '(choice (const :tag "One line" one-line)
+		 (const :tag "Separated" separated))
+  :group 'killing)
+
+(defcustom browse-kill-ring-quit-action 'bury-and-delete-window
+  "What action to take when `browse-kill-ring-quit' is called.
+
+If `bury-buffer', then simply bury the *Kill Ring* buffer, but keep
+the window.
+
+If `bury-and-delete-window', then bury the buffer, and (if there is
+more than one window) delete the window.  This is the default.
+
+If `kill-and-delete-window', then kill the *Kill Ring* buffer, and
+delete the window on close.
+
+Otherwise, it should be a function to call."
+  :type '(choice (const :tag "Bury buffer" :value bury-buffer)
+		 (const :tag "Delete window" :value delete-window)
+		 (const :tag "Bury buffer and delete window" :value bury-and-delete-window)
+		 (const :tag "Kill buffer and delete window" :value kill-and-delete-window))
+  :group 'killing)
+
+(defcustom browse-kill-ring-maximum-display-length nil
+  "Whether or not to limit the length of displayed items.
+
+If this variable is an integer, the display of `kill-ring' will be
+limited to that many characters.
+Setting this variable to nil means no limit."
+  :type '(choice (const :tag "None" nil)
+		 integer)
+  :group 'browse-kill-ring)
+
+(defcustom browse-kill-ring-separator "-------"
+  "The string separating entries in the `separated' style.
+See `browse-kill-ring-display-style'."
+  :type 'string
+  :group 'killing)
+
+(defcustom browse-kill-ring-highlight-current-entry nil
+  "If non-nil, highlight the currently selected `kill-ring' entry."
+  :type 'boolean
+  :group 'killing)
+
+(defface browse-kill-ring-separator-face '((t :inherit bold))
+  "The face in which to highlight the `browse-kill-ring-separator'."
+  :group 'killing)
+
 (defvar kill-ring-yank-pointer nil
   "The tail of the kill ring whose car is the last thing yanked.")
 
+(defvar browse-kill-ring-original-window nil
+  "The window in which chosen kill ring data will be inserted.
+It is probably not a good idea to set this variable directly; simply
+call `browse-kill-ring' again.")
+
 (defun kill-new (string &optional replace)
   "Make STRING the latest kill in the kill ring.
 Set `kill-ring-yank-pointer' to point to it.
@@ -1770,8 +1830,6 @@
 	    (setq kill-ring-yank-pointer ARGth-kill-element))
 	(car ARGth-kill-element)))))
 
-
-
 ;;;; Commands for manipulating the kill ring.
 
 (defcustom kill-read-only-ok nil
@@ -1921,8 +1979,8 @@
 The sequence of kills wraps around, so that after the oldest one
 comes the newest one."
   (interactive "*p")
-  (if (not (eq last-command 'yank))
-      (error "Previous command was not a yank"))
+  (unless (eq last-command 'yank)
+    (error "Previous command was not a yank"))
   (setq this-command 'yank)
   (let ((inhibit-read-only t)
 	(before (< (point) (mark t))))
@@ -1937,6 +1995,18 @@
 		     (set-marker (mark-marker) (point) (current-buffer))))))
   nil)
 
+(defun yank-previous (arg)
+  "Replace previously yanked text, or display a kill ring menu.
+If the last command was a `yank', `yank-previous', or `yank-pop', then
+this command will replace a just-yanked section of text with a prevous
+entry in the kill ring, using ARG.  See `yank-pop'.
+Otherwise, this command will display a menu of kill ring entries; see
+`browse-kill-ring'."
+  (interactive "*p")
+  (if (not (memq last-command '(yank yank-previous)))
+      (browse-kill-ring)
+    (yank-pop arg)))
+
 (defun yank (&optional arg)
   "Reinsert the last stretch of killed text.
 More precisely, reinsert the stretch of killed text most recently
@@ -1983,6 +2053,251 @@
   (if (listp arg) (setq arg (car arg)))
   (if (eq arg '-) (setq arg -1))
   (kill-region (point) (forward-point (- arg))))
+
+(put 'browse-kill-ring-mode 'mode-class 'special)
+(define-derived-mode browse-kill-ring-mode fundamental-mode
+  "Kill Ring"
+  "A major mode for browsing the `kill-ring'.
+You most likely do not want to call `browse-kill-ring-mode' directly; use
+`browse-kill-ring' instead.
+
+\\{browse-kill-ring-mode-map}"
+  (set (make-local-variable 'browse-kill-ring-original-window) nil)
+  (set (make-local-variable 'font-lock-defaults)
+       '(nil t nil nil nil
+	     (font-lock-fontify-region-function . browse-kill-ring-fontify-region-function)
+	     (font-lock-unfontify-region-function . browse-kill-ring-unfontify-region-function)))
+  (define-key browse-kill-ring-mode-map (kbd "q") 'browse-kill-ring-quit)
+  (define-key browse-kill-ring-mode-map (kbd "C-g") 'browse-kill-ring-quit)
+  (define-key browse-kill-ring-mode-map (kbd "d") 'browse-kill-ring-delete)
+  (define-key browse-kill-ring-mode-map (kbd "g") 'browse-kill-ring-update)
+  (define-key browse-kill-ring-mode-map (kbd "n") 'browse-kill-ring-forward)
+  (define-key browse-kill-ring-mode-map (kbd "p") 'browse-kill-ring-backward)
+  (define-key browse-kill-ring-mode-map [(mouse-2)] 'browse-kill-ring-mouse-insert)
+  (define-key browse-kill-ring-mode-map (kbd "?") 'describe-mode)
+  (define-key browse-kill-ring-mode-map (kbd "h") 'describe-mode)
+  (define-key browse-kill-ring-mode-map (kbd "RET") 'browse-kill-ring-insert))
+
+(defun browse-kill-ring-fontify-region-function (beg end &optional verbose)
+  (when verbose (message "Fontifying..."))
+  (let ((inhibit-read-only t))
+    (font-lock-fontify-on-text-properties
+     beg end 'browse-kill-ring-special 'bold)
+    (when verbose (message "Fontifying...done"))))
+
+(defun browse-kill-ring-unfontify-region-function (beg end)
+  (let ((inhibit-read-only t))
+    (remove-text-properties beg end '(face nil))))
+
+(defun browse-kill-ring-elide (str)
+  (if (and browse-kill-ring-maximum-display-length
+	   (> (length str)
+	      browse-kill-ring-maximum-display-length))
+      (concat (substring str 0 (- browse-kill-ring-maximum-display-length 3))
+	      (propertize "..." 'browse-kill-ring-special t)))
+  str)
+
+(defmacro browse-kill-ring-add-overlays-for (item &rest body)
+  (let ((beg (gensym "browse-kill-ring-add-overlays-"))
+	(end (gensym "browse-kill-ring-add-overlays-")))
+    `(let ((,beg (point))
+	   (,end
+	    (progn
+	      ,@body
+	      (point))))
+       (let ((o (make-overlay ,beg ,end)))
+	 (overlay-put o 'browse-kill-ring-target ,item)
+	 (overlay-put o 'mouse-face 'highlight)))))
+;; (put 'browse-kill-ring-add-overlays-for 'lisp-indent-function 1)
+
+(defun browse-kill-ring-insert-as-one-line (items)
+  (dolist (item items)
+    (browse-kill-ring-add-overlays-for item
+      (let* ((item (browse-kill-ring-elide item))
+	     (len (length item))
+	     (start 0)
+	     (newl (propertize "\\n" 'browse-kill-ring-special t)))
+	(while (and (< start len)
+		    (string-match "\n" item start))
+	  (insert (substring item start (match-beginning 0))
+		  newl)
+	  (setq start (match-end 0)))
+	(insert (substring item start len))))
+    (insert "\n")))
+
+(defun browse-kill-ring-insert-as-separated (items)
+  (while (cdr items)
+    (browse-kill-ring-insert-as-separated-1 (car items) t)
+    (setq items (cdr items)))
+  (when items
+    (browse-kill-ring-insert-as-separated-1 (car items) nil)))
+
+(defun browse-kill-ring-insert-as-separated-1 (origitem separatep)
+  (let* ((item (browse-kill-ring-elide origitem))
+	 (len (length item)))
+    (browse-kill-ring-add-overlays-for origitem
+	(insert item))
+    (insert "\n")
+    (when separatep
+      (insert (propertize browse-kill-ring-separator
+			  'browse-kill-ring-special t))
+      (insert "\n"))))
+
+;; (unintern 'browse-kill-ring-add-overlays-for)
+
+(defun browse-kill-ring-quit ()
+  "Take the action specified by `browse-kill-ring-quit-action'."
+  (interactive)
+  (case browse-kill-ring-quit-action
+    (kill-and-delete-window
+     (kill-buffer (current-buffer))
+     (unless (= (count-windows) 1)
+       (delete-window)))
+    (bury-and-delete-window
+     (bury-buffer)
+     (unless (= (count-windows) 1)
+       (delete-window)))
+    (t
+     (funcall browse-kill-ring-quit-action))))
+
+(defun browse-kill-ring-forward (&optional arg)
+  "Move forward by ARG `kill-ring' entries."
+  (interactive "p")
+  (beginning-of-line)
+  (while (not (zerop arg))
+    (if (< arg 0)
+	(progn
+	  (incf arg)
+	  (if (overlays-at (point))
+	      (progn
+		(goto-char (overlay-start (car (overlays-at (point)))))
+		(goto-char (previous-overlay-change (point)))
+		(goto-char (previous-overlay-change (point))))
+	    (progn
+	      (goto-char (1- (previous-overlay-change (point))))
+	      (unless (bobp)
+		(goto-char (overlay-start (car (overlays-at (point)))))))))
+      (progn
+	(decf arg)
+	(if (overlays-at (point))
+	    (progn
+	      (goto-char (overlay-end (car (overlays-at (point)))))
+	      (goto-char (next-overlay-change (point))))
+	  (goto-char (next-overlay-change (point)))
+	  (unless (eobp)
+	    (goto-char (overlay-start (car (overlays-at (point))))))))))
+  ;; This could probably be implemented in a more intelligent manner.
+  ;; Perhaps keep track over the overlay we started from?  That would
+  ;; break when the user moved manually, though.
+  (when (and browse-kill-ring-highlight-current-entry
+	     (overlays-at (point)))
+    (let ((overs (overlay-lists))
+	  (current-overlay (car (overlays-at (point)))))
+      (mapcar #'(lambda (o)
+		  (overlay-put o 'face nil))
+	      (nconc (car overs) (cdr overs)))
+      (overlay-put current-overlay 'face 'highlight))))
+
+(defun browse-kill-ring-backward (&optional arg)
+  "Move backward by ARG `kill-ring' entries."
+  (interactive "p")
+  (browse-kill-ring-forward (- arg)))
+
+(defun browse-kill-ring-do-insert (buf pt)
+  (let ((str (with-current-buffer buf
+	       (let ((overs (overlays-at pt)))
+		 (or (and overs
+			  (overlay-get (car overs) 'browse-kill-ring-target))
+		     (error "No kill ring item here"))))))
+    (let ((orig (current-buffer)))
+      (unwind-protect
+	  (progn
+	    (unless (window-live-p browse-kill-ring-original-window)
+	      (browse-kill-ring-quit)
+	      (error (substitute-command-keys "Window %s has been deleted; Try calling '\\[yank-previous]' again")
+		     browse-kill-ring-original-window))
+	    (set-buffer (window-buffer browse-kill-ring-original-window))
+	    (save-excursion
+	      (insert str)))
+	(set-buffer orig)))))
+
+(defun browse-kill-ring-mouse-insert (e)
+  "Insert the chosen text in the last selected buffer."
+  (interactive "e")
+  (let* ((end (event-end e))
+	 (win (posn-window end))
+	 (buf (window-buffer win)))
+    (select-window win)
+    (browse-kill-ring-do-insert buf (posn-point end))
+    (browse-kill-ring-quit)))
+
+(defun browse-kill-ring-insert (&optional noquit)
+  "Insert the kill ring item at point, and close the kill ring menu.
+If optional argument NOQUIT is non-nil, don't close the menu."
+  (interactive "P")
+  (browse-kill-ring-do-insert (current-buffer) (point))
+  (unless noquit
+    (browse-kill-ring-quit)))
+
+(defun browse-kill-ring-update ()
+  "Update the buffer to reflect outside changes to `kill-ring'."
+  (interactive)
+  (assert (eq major-mode 'browse-kill-ring-mode))
+  (browse-kill-ring-setup (current-buffer)
+			  browse-kill-ring-original-window))
+
+(defun browse-kill-ring-setup (buf window &optional regexp)
+  (with-current-buffer buf
+    (unwind-protect
+	(progn
+	  (browse-kill-ring-mode)
+	  (setq buffer-read-only nil)
+	  (when (eq browse-kill-ring-display-style
+		    'one-line)
+	    (setq truncate-lines t))
+	  (erase-buffer)
+	  (setq browse-kill-ring-original-window window)
+	  (let ((browse-kill-ring-maximum-display-length
+		 (if (and browse-kill-ring-maximum-display-length
+			  (<= browse-kill-ring-maximum-display-length 3))
+		     4
+		   browse-kill-ring-maximum-display-length))
+		(items (mapcar #'copy-sequence kill-ring)))
+;; 	    (when (not browse-kill-ring-display-duplicates)
+;; 	      (setq items (delete-duplicates items :test #'equal)))
+	    (when (stringp regexp)
+	      (setq items (delq nil
+				(mapcar
+				 #'(lambda (item)
+				     (when (string-match regexp item)
+				       item))
+				 items))))
+	    (funcall (intern
+		      (concat "browse-kill-ring-insert-as-"
+			      (symbol-name browse-kill-ring-display-style)))
+		     items)
+	    (if (not regexp)
+		(message "%s entries in the kill ring" (length kill-ring))
+	      (message "%s (of %s) entries in the kill ring shown"
+		       (length items) (length kill-ring)))
+	    (set-buffer-modified-p nil)
+	    (goto-char (point-min))
+	    (browse-kill-ring-forward 0)
+	    (when regexp
+	      (setq mode-name (concat "Kill Ring [" regexp "]")))
+	    (run-hooks 'browse-kill-ring-hook)))
+      (progn
+	(setq buffer-read-only t)))))
+
+;;;###autoload
+(defun browse-kill-ring ()
+  "Display items in the `kill-ring' in another buffer."
+  (interactive)
+  (let ((orig-buf (current-buffer))
+	(buf (get-buffer-create "*Kill Ring*")))
+    (browse-kill-ring-setup buf (selected-window))
+    (pop-to-buffer buf)
+    nil))
 
 (defcustom backward-delete-char-untabify-method 'untabify
   "*The method for untabifying when deleting backward.
--- font-lock.el.~1.195.~	Fri Apr  5 04:37:40 2002
+++ font-lock.el	Sun Apr 28 22:31:57 2002
@@ -1358,6 +1358,32 @@
       (put-text-property start next prop value object)
       (setq start (text-property-any next end prop nil object)))))
 
+(defun font-lock-fontify-on-text-properties (beg end &rest plist)
+  "Match areas of text which have non-nil text properties with faces.
+Only areas of text between BEG and END are considered.  The remaining
+arguments should form a property list which looks like
+ (PROPERTY FACE PROPERTY FACE ...)."
+  (save-excursion
+    (let ((change-end nil))
+      (while plist
+	(goto-char beg)
+	(while (and plist
+		    (setq change-end (font-lock-fontify-on-text-property
+				      (car plist) (cadr plist) (point) end)))
+	  (goto-char change-end))
+	(setq plist (cddr plist))))))
+
+(defun font-lock-fontify-on-text-property (prop face beg end)
+  "Add face FACE to areas of text which have non-nil text property PROP.
+Only areas of text between BEG and END are considered."
+  (let ((prop-beg (or (and (get-text-property (point) prop) (point))
+		      (next-single-property-change (point) prop nil end))))
+    (when (and prop-beg (not (= prop-beg end)))
+      (let ((prop-end (next-single-property-change beg prop nil end)))
+	(when (and prop-end (not (= prop-end end)))
+	  (put-text-property prop-beg prop-end 'face face)
+	  prop-end)))))
+
 ;; For completeness: this is to `remove-text-properties' as `put-text-property'
 ;; is to `add-text-properties', etc.
 ;(defun remove-text-property (start end property &optional object)
--- bindings.el.~1.100.~	Wed Apr 17 17:38:22 2002
+++ bindings.el	Sun Apr 28 02:09:00 2002
@@ -643,7 +643,7 @@
 (define-key esc-map "w" 'kill-ring-save)
 (define-key esc-map "\C-w" 'append-next-kill)
 (define-key global-map "\C-y" 'yank)
-(define-key esc-map "y" 'yank-pop)
+(define-key esc-map "y" 'yank-previous)
 
 ;; (define-key ctl-x-map "a" 'append-to-buffer)
 

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  3:35 ` Miles Bader
@ 2002-04-29  4:37   ` Colin Walters
  2002-04-29  4:56     ` Miles Bader
  2002-04-29 18:40   ` Richard Stallman
  1 sibling, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-04-29  4:37 UTC (permalink / raw)


On Sun, 2002-04-28 at 23:35, Miles Bader wrote:
> Also another comment:
> 
> +(defcustom kill-ring-menu-separator-face 'bold
> +  "The face in which to highlight the `kill-ring-menu-separator'."
> 
> It's the general custom [...]

:)

Thanks for your comments.  I have incorporated the changes (including
renaming it back to `browse-kill-ring') in the latest patch.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  4:37   ` Colin Walters
@ 2002-04-29  4:56     ` Miles Bader
  2002-04-29  5:37       ` Colin Walters
  0 siblings, 1 reply; 82+ messages in thread
From: Miles Bader @ 2002-04-29  4:56 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@debian.org> writes:
> Thanks for your comments.  I have incorporated the changes (including
> renaming it back to `browse-kill-ring') in the latest patch.

Please don't append `-face' to the name of the face, though -- faces
have a separate namespace, so it's quite redundant (it's like appending
`-variable' to the name of all your variables); note that none of emacs'
`primitive' faces (those in faces.el) use the `-face' suffix.

BTW, re: [ No need to CC me, I do read emacs-devel ] -- if it bothers
you to be CC'd, you should probably add one of those magic headers that
prevents it; I forget the names offhand, but they're probably in the
Gnus docs or something.  Since in general one can't be sure which
people are on a mailing list or not, it's best to reply to all addresses
by default (it never bothers me to receive such mail because Gnus
can automatically suppress duplicates).

-Miles
-- 
Come now, if we were really planning to harm you, would we be waiting here, 
 beside the path, in the very darkest part of the forest?

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-28 20:06 ` Colin Walters
@ 2002-04-29  5:05   ` Richard Stallman
  2002-04-29 18:40     ` Richard Stallman
  0 siblings, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-04-29  5:05 UTC (permalink / raw)
  Cc: emacs-devel

     (load "simple")
    +(load "kill-ring")
     (load "files")

I see no reason to preload this file, so let's not.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  4:56     ` Miles Bader
@ 2002-04-29  5:37       ` Colin Walters
  2002-04-29  7:09         ` Miles Bader
                           ` (3 more replies)
  0 siblings, 4 replies; 82+ messages in thread
From: Colin Walters @ 2002-04-29  5:37 UTC (permalink / raw)


On Mon, 2002-04-29 at 00:56, Miles Bader wrote:
> Colin Walters <walters@debian.org> writes:
> > Thanks for your comments.  I have incorporated the changes (including
> > renaming it back to `browse-kill-ring') in the latest patch.
> 
> Please don't append `-face' to the name of the face, though -- faces
> have a separate namespace, so it's quite redundant (it's like appending
> `-variable' to the name of all your variables); note that none of emacs'
> `primitive' faces (those in faces.el) use the `-face' suffix.

Fixed, thanks.  I take it with these comments that you are satisfied
with the rest of the patch?

> [...] Since in general one can't be sure which
> people are on a mailing list or not, it's best to reply to all addresses
> by default [...]

I don't really wish to debate this in depth, since I sense this has the
potential to develop into a long thread, where I will certainly be CC'd
:) ...so this will be the last thing I'll say about it on this list.

In Debian culture (where I mainly come from), the general opinion on the
issue is against it.  The CC is another separate identical copy of the
message, which goes straight to my inbox.  When CC'ing, you are making
an assumption that I filter my mail into separate mailboxes, and that I
don't read those lists constantly.

If that isn't true, then I have to spend time deleting lots of duplicate
messages.  Or I have to set up a complex email filtering system, which
also takes my time and is difficult to manage.

A more reasonable assumption to make is that someone who posts to a list
is subscribed to it.  Almost all of us who participate in regular
discussion are subscribed, I'm sure.  If someone posts who *isn't*
subscribed, then the onus is on *them* to say "Please CC me".  That way
everyone else doesn't suffer just because a few lazy people occasionally
post to the list without being subscribed outside.

From what I see GNU culture generally is in support of CC'ing.  If I
can't change this, then I just hope that a polite request at the top of
my messages will at least prevent me personally from being CC'd.  And
again, it's just a request; nobody has to listen to it.  But doing so
will make my life easier.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  5:37       ` Colin Walters
@ 2002-04-29  7:09         ` Miles Bader
  2002-04-30  5:18           ` Richard Stallman
  2002-04-29  9:22         ` CC (was: Re: kill ring menu) Per Abrahamsen
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 82+ messages in thread
From: Miles Bader @ 2002-04-29  7:09 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@debian.org> writes:
> Fixed, thanks.  I take it with these comments that you are satisfied
> with the rest of the patch?

Er, rather I'm picking off low-hanging fruit.  I'll look at the rest of
the diff now that it's in easy-to-read format (I trust you intend to
move the code back into kill-ring.el, BTW, since it seems like a good
idea, aside from making the patch hard to read).

> If that isn't true, then I have to spend time deleting lots of duplicate
> messages.  Or I have to set up a complex email filtering system, which
> also takes my time and is difficult to manage.

...or your MUA can discard duplicates.  This is not hard, and is clearly
the right `technical solution.'

> If I can't change this, then I just hope that a polite request at the
> top of my messages will at least prevent me personally from being
> CC'd.  And again, it's just a request; nobody has to listen to it.
> But doing so will make my life easier.

If you put the following header in your messages, then some MUAs (at
least Gnus, and probably others) will do this automatically:

Mail-Copies-To: never

I suppose a cute hack would be to have the mailing list software
automatically insert such a header into message from people it knows to
be on the list (but maybe that would cause other problems, I don't
know).

-Miles
-- 
Love is a snowmobile racing across the tundra.  Suddenly it flips over,
pinning you underneath.  At night the ice weasels come.  --Nietzsche

^ permalink raw reply	[flat|nested] 82+ messages in thread

* CC (was: Re: kill ring menu)
  2002-04-29  5:37       ` Colin Walters
  2002-04-29  7:09         ` Miles Bader
@ 2002-04-29  9:22         ` Per Abrahamsen
  2002-04-29 15:11           ` Benjamin Rutt
  2002-04-30 10:14           ` Per Abrahamsen
  2002-04-29 10:10         ` Addressing email (was: " Eli Zaretskii
  2002-04-29 13:13         ` kill ring menu Stefan Monnier
  3 siblings, 2 replies; 82+ messages in thread
From: Per Abrahamsen @ 2002-04-29  9:22 UTC (permalink / raw)


Colin Walters <walters@debian.org> writes:

> When CC'ing, you are making an assumption that I filter my mail into
> separate mailboxes, and that I don't read those lists constantly.

Nope, we make the assumption that it is an open list where
non-subscribers can send messages, and do not make the extra manual
effort to remove the CC for people we believe are subscribing.

> A more reasonable assumption to make is that someone who posts to a
> list is subscribed to it.  Almost all of us who participate in
> regular discussion are subscribed, I'm sure.  If someone posts who
> *isn't* subscribed, then the onus is on *them* to say "Please CC
> me".  That way everyone else doesn't suffer just because a few lazy
> people occasionally post to the list without being subscribed
> outside.

Nobody has to suffer, as it is trivial (depending on the agent) to 

1) avoid getting the duplicates in the first place, and
2) filter out the duplicates if you get them

and both can be fully automated.

We can't really expect non-subscribers to know special rules for the
mailing lists, or subscribers to remember who is and isn't subscribed,
and manually add or remove those from the list.  And none of that can
be automated.  

> If I can't change this, then I just hope that a polite request at
> the top of my messages will at least prevent me personally from
> being CC'd.

Please consider using 

       Mail-Followups-To: list-name 

or

       Mail-Copies-To: never

or both, which will make at least some mail clients avoid the CC
automatically.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: Addressing email (was: kill ring menu)
  2002-04-29  5:37       ` Colin Walters
  2002-04-29  7:09         ` Miles Bader
  2002-04-29  9:22         ` CC (was: Re: kill ring menu) Per Abrahamsen
@ 2002-04-29 10:10         ` Eli Zaretskii
  2002-04-29 13:13         ` kill ring menu Stefan Monnier
  3 siblings, 0 replies; 82+ messages in thread
From: Eli Zaretskii @ 2002-04-29 10:10 UTC (permalink / raw)



On 29 Apr 2002, Colin Walters wrote:

> If that isn't true, then I have to spend time deleting lots of duplicate
> messages.

A second or two per message is not so bad.  It's a minor inconvenience, 
hardly worth any action, let alone action that could have adverse effects.

> If someone posts who *isn't*
> subscribed, then the onus is on *them* to say "Please CC me".

That's not a good idea, I think: people will forget and get thrown out of 
the discussion they started.  I don't think we should treat subscribers' 
convenience any different than that of others.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  5:37       ` Colin Walters
                           ` (2 preceding siblings ...)
  2002-04-29 10:10         ` Addressing email (was: " Eli Zaretskii
@ 2002-04-29 13:13         ` Stefan Monnier
  3 siblings, 0 replies; 82+ messages in thread
From: Stefan Monnier @ 2002-04-29 13:13 UTC (permalink / raw)
  Cc: emacs-devel

> messages.  Or I have to set up a complex email filtering system, which
> also takes my time and is difficult to manage.

There is no reason why the deletion of duplicates can't be made the default.
I wish more people used it because it is The Right Thing and because it
would put more pressure onto people sending CFPs to reuse the same
Message-ID rather than to say "we apologize if you receive this a hundred
times".


	Stefan

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: CC (was: Re: kill ring menu)
  2002-04-29  9:22         ` CC (was: Re: kill ring menu) Per Abrahamsen
@ 2002-04-29 15:11           ` Benjamin Rutt
  2002-04-29 15:31             ` Miles Bader
  2002-04-30  5:19             ` Richard Stallman
  2002-04-30 10:14           ` Per Abrahamsen
  1 sibling, 2 replies; 82+ messages in thread
From: Benjamin Rutt @ 2002-04-29 15:11 UTC (permalink / raw)
  Cc: emacs-devel

Per Abrahamsen <abraham@dina.kvl.dk> writes:

[...]

> Please consider using 
>
>        Mail-Followups-To: list-name
                      ^

Is there a difference between Mail-Followups-To and Mail-Followup-To?
I've only ever used the latter to try to let some MUAs know that I
want followups to the list only.

>        Mail-Copies-To: never

I thought this was for usenet only, to prevent receiving "courtesy
copies".  How is it useful for mail?
-- 
Benjamin

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: CC (was: Re: kill ring menu)
  2002-04-29 15:11           ` Benjamin Rutt
@ 2002-04-29 15:31             ` Miles Bader
  2002-04-30  5:19             ` Richard Stallman
  1 sibling, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-04-29 15:31 UTC (permalink / raw)
  Cc: Per Abrahamsen, emacs-devel

Benjamin Rutt <rutt+news@cis.ohio-state.edu> writes:
> Is there a difference between Mail-Followups-To and Mail-Followup-To?
> I've only ever used the latter to try to let some MUAs know that I
> want followups to the list only.

The Gnus manual only mentions `Followups-To:' -- however it only uses
that headers for news, not mail.

> >        Mail-Copies-To: never
> 
> I thought this was for usenet only, to prevent receiving "courtesy
> copies".  How is it useful for mail?

Gnus always respects such a header; if it finds one, it won't include
the author of the message you're replying to in your reply.  If you're
sending news, this only matters when you also send `courtesy copies',
but if you're sending mail, it's actually more important, since
followups include the sender by default.

-Miles
-- 
"Most attacks seem to take place at night, during a rainstorm, uphill,
 where four map sheets join."   -- Anon. British Officer in WW I

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  3:35 ` Miles Bader
  2002-04-29  4:37   ` Colin Walters
@ 2002-04-29 18:40   ` Richard Stallman
  1 sibling, 0 replies; 82+ messages in thread
From: Richard Stallman @ 2002-04-29 18:40 UTC (permalink / raw)
  Cc: walters, emacs-devel

Let's not create faces profligately.

If there is some general-purpose face which is usable here,
I think it would be better to use that rather than define
another face.

If there is no general-purpose face for purposes like this,
let's make one, instead of making a face just for this feature.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  5:05   ` Richard Stallman
@ 2002-04-29 18:40     ` Richard Stallman
  0 siblings, 0 replies; 82+ messages in thread
From: Richard Stallman @ 2002-04-29 18:40 UTC (permalink / raw)
  Cc: walters, emacs-devel

	 (load "simple")
	+(load "kill-ring")
	 (load "files")

    I see no reason to preload this file, so let's not.

When I wrote that, I didn't realize that kill-ring was material moved
from simple.el.  I saw that the patch was in -u format and therefore
hard to read, so I asked for it in -c format and didn't try to read
it.

I should not have made a guess about what kill-ring.el contained.
Sorry.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  4:34   ` Colin Walters
@ 2002-04-30  4:49     ` Eli Zaretskii
  0 siblings, 0 replies; 82+ messages in thread
From: Eli Zaretskii @ 2002-04-30  4:49 UTC (permalink / raw)



On 29 Apr 2002, Colin Walters wrote:

> Ok.  Please find a version of the patch attached which keeps things in
> simple.el.

I suggest to add help text to the mouse-2 binding saying something like 
"mouse-2: yank this killed text".  Experience shows that many users don't 
know about mouse-2 bindings, so popping a tooltip will help.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-29  7:09         ` Miles Bader
@ 2002-04-30  5:18           ` Richard Stallman
  2002-04-30 10:18             ` Per Abrahamsen
  0 siblings, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-04-30  5:18 UTC (permalink / raw)
  Cc: walters, emacs-devel

    If you put the following header in your messages, then some MUAs (at
    least Gnus, and probably others) will do this automatically:

    Mail-Copies-To: never

I asked PMR, who is working on Rmail now, to implement this
in the Reply command.  Thanks.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: CC (was: Re: kill ring menu)
  2002-04-29 15:11           ` Benjamin Rutt
  2002-04-29 15:31             ` Miles Bader
@ 2002-04-30  5:19             ` Richard Stallman
  1 sibling, 0 replies; 82+ messages in thread
From: Richard Stallman @ 2002-04-30  5:19 UTC (permalink / raw)
  Cc: abraham, emacs-devel

    > Please consider using 
    >
    >        Mail-Followups-To: list-name
			  ^

    Is there a difference between Mail-Followups-To and Mail-Followup-To?

Can someone tell me the specs of this field?
I would like to make Rmail's reply command DTRT
but first I need to know what TRT is.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: CC (was: Re: kill ring menu)
  2002-04-29  9:22         ` CC (was: Re: kill ring menu) Per Abrahamsen
  2002-04-29 15:11           ` Benjamin Rutt
@ 2002-04-30 10:14           ` Per Abrahamsen
  2002-04-30 11:08             ` Simon Josefsson
  1 sibling, 1 reply; 82+ messages in thread
From: Per Abrahamsen @ 2002-04-30 10:14 UTC (permalink / raw)


Answers to multiple people:

- It is Mail-Followup-To, without an "s".

- It was invented by Dan Bernstein, and documented in
  < http://cr.yp.to/proto/replyto.html >

- It is supported in Gnus from the Oort line 
  (i.e. what will become the next version).

- Mail-Copies-To was invented by Lars Magne Ingebrigtsen for Gnus for
  both mail and news, and has been adopted by a large number of other
  news clients, but no other mail clients as far as I know.  

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-04-30  5:18           ` Richard Stallman
@ 2002-04-30 10:18             ` Per Abrahamsen
  0 siblings, 0 replies; 82+ messages in thread
From: Per Abrahamsen @ 2002-04-30 10:18 UTC (permalink / raw)
  Cc: miles, walters, emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     If you put the following header in your messages, then some MUAs (at
>     least Gnus, and probably others) will do this automatically:
>
>     Mail-Copies-To: never
>
> I asked PMR, who is working on Rmail now, to implement this
> in the Reply command.  Thanks.

It is being standardized for news in the form

   Mail-Copies-To: nobody

but older versions of Gnus does not understand that.

Here is the specification from USEFOR (the RFC 1036 replacement):

   < http://www.mibsoftware.com/userkt/usefor/05/0060.htm >

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: CC (was: Re: kill ring menu)
  2002-04-30 10:14           ` Per Abrahamsen
@ 2002-04-30 11:08             ` Simon Josefsson
  0 siblings, 0 replies; 82+ messages in thread
From: Simon Josefsson @ 2002-04-30 11:08 UTC (permalink / raw)
  Cc: emacs-devel

On Tue, 30 Apr 2002, Per Abrahamsen wrote:

> Answers to multiple people:
> 
> - It is Mail-Followup-To, without an "s".
> 
> - It was invented by Dan Bernstein, and documented in
>   < http://cr.yp.to/proto/replyto.html >
> 
> - It is supported in Gnus from the Oort line 
>   (i.e. what will become the next version).
> 
> - Mail-Copies-To was invented by Lars Magne Ingebrigtsen for Gnus for
>   both mail and news, and has been adopted by a large number of other
>   news clients, but no other mail clients as far as I know.  

If possible, wouldn't it be nice if RMAIL used the Gnus / message.el
functionality for this instead of duplicating code, variables and
documentation?

Wasn't message.el supposed to replace sendmail.el?

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
       [not found]           ` <1020284783.27106.3417.camel@space-ghost>
@ 2002-05-03 18:25             ` Richard Stallman
  2002-05-03 18:46               ` Miles Bader
  2002-05-03 19:05               ` Miles Bader
  0 siblings, 2 replies; 82+ messages in thread
From: Richard Stallman @ 2002-05-03 18:25 UTC (permalink / raw)
  Cc: emacs-devel

    Well, I can make it smaller.  I really do think that a *lot* of users
    will use it if we make it a core feature.  I think it's much easier to
    use than typing "C-y M-y M-y...". That is why I put it on M-y, which has
    no use if not preceeded by C-y.

Using M-y would be convenient, I agree.  However, it might be a
nuisance for people who type it by accident.  I do that from time to
time.  Right now I just get an error message when I do that; the
nuisance would be to get this menu instead.

    Perhaps we could ask the other people on emacs-devel what they think?

Ok.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-03 18:25             ` Richard Stallman
@ 2002-05-03 18:46               ` Miles Bader
  2002-05-03 19:05               ` Miles Bader
  1 sibling, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-03 18:46 UTC (permalink / raw)
  Cc: walters, emacs-devel

Richard Stallman <rms@gnu.org> writes:
>   That is why I put it on M-y, which has no use if not preceeded by C-y.
> 
> Using M-y would be convenient, I agree.  However, it might be a
> nuisance for people who type it by accident.  I do that from time to
> time.  Right now I just get an error message when I do that; the
> nuisance would be to get this menu instead.

I think it would be very easy to accidentally get the menu.  You usually
use the M-y command in a series (to move through the kill-ring), and
it's not uncommon to mistype it if you're really using `ESC y' and
accidentally hit another key in between two M-ys.  Getting the error
message in such a circumstance is a little annoying, but being popped
into a new buffer would drive me nuts.  That seems like too high a
penalty for a common typo.

It also just seems a little odd to have the radically different behavior
depending on whether it followed C-y or not, and it seems like it would
make M-y kind of hard to explain -- I still think of it as a separate
command, even if it's only really useful following C-y.

So, I'm against putting this mode on M-y.

BTW, why not make M-y do something reasonable if invoked without a
preceeding C-y?  I've always thought it would be handy if it would do
the equivalent of `C-w C-y M-y' in that situation -- i.e., replace the
current region with the first thing in the kill ring (and then you
could type further `M-y's to continue down the ring).

Note that doing that would make recovering from a `M-y typo' much more
pleasant; what I usually do in that situation to restart the M-y
sequence is `C-w C-y M-y'...

-Miles
-- 
P.S.  All information contained in the above letter is false,
      for reasons of military security.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-03 18:25             ` Richard Stallman
  2002-05-03 18:46               ` Miles Bader
@ 2002-05-03 19:05               ` Miles Bader
  2002-05-03 20:20                 ` Colin Walters
                                   ` (2 more replies)
  1 sibling, 3 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-03 19:05 UTC (permalink / raw)
  Cc: walters, emacs-devel

Richard Stallman <rms@gnu.org> writes:
>   That is why I put it on M-y, which has no use if not preceeded by C-y.
> 
> Using M-y would be convenient, I agree.  However, it might be a
> nuisance for people who type it by accident.  I do that from time to
> time.  Right now I just get an error message when I do that; the
> nuisance would be to get this menu instead.

I think it would be very easy to accidentally get the menu.  You usually
use the M-y command in a series (to move through the kill-ring), and
it's not uncommon to mistype it if you're really using `ESC y' and
accidentally hit another key in between two M-ys.  Getting the error
message in such a circumstance is a little annoying, but being popped
into a new buffer would drive me nuts.  That seems like too high a
penalty for a common typo.

It also just seems a little odd to have the radically different behavior
depending on whether it followed C-y or not, and it seems like it would
make M-y kind of hard to explain -- I still think of it as a separate
command, even if it's only really useful following C-y.

So, I'm against putting this mode on M-y.

BTW, why not make M-y do something reasonable if invoked without a
preceeding C-y?  I've always thought it would be handy if it would do
the equivalent of `C-w C-y M-y' in that situation -- i.e., replace the
current region with the first thing in the kill ring (and then you
could type further `M-y's to continue down the ring).

Note that doing that would make recovering from a `M-y typo' much more
pleasant; what I usually do in that situation to restart the M-y
sequence is `C-w C-y M-y'...

-Miles
-- 
P.S.  All information contained in the above letter is false,
      for reasons of military security.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-03 19:05               ` Miles Bader
@ 2002-05-03 20:20                 ` Colin Walters
  2002-05-04  1:34                   ` Miles Bader
  2002-05-04  3:36                 ` Richard Stallman
  2002-05-04  6:04                 ` Eli Zaretskii
  2 siblings, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-03 20:20 UTC (permalink / raw)


On Fri, 2002-05-03 at 15:05, Miles Bader wrote:

> I think it would be very easy to accidentally get the menu.  You usually
> use the M-y command in a series (to move through the kill-ring), and
> it's not uncommon to mistype it if you're really using `ESC y' and
> accidentally hit another key in between two M-ys.  Getting the error
> message in such a circumstance is a little annoying, but being popped
> into a new buffer would drive me nuts.

Well, you can just type 'q' in that case.  I mean, it might take some
getting used to, but for people new to Emacs I think it would be a big
win.

>  That seems like too high a penalty for a common typo.

Well, to me, what we should ask is whether or not the added
functionality is worth the cost of that typo.  

Personally, I've more or less altogether stopped using M-y repeatedly to
yank text.  It requires holding down Meta, whereas just doing 
'M-y n n n RET' is much nicer on my fingers.

> It also just seems a little odd to have the radically different behavior
> depending on whether it followed C-y or not, and it seems like it would
> make M-y kind of hard to explain -- I still think of it as a separate
> command, even if it's only really useful following C-y.

True, but we're rather stuck with the keybindings at this point.

> So, I'm against putting this mode on M-y.

That's too bad.  Does anyone else like the idea?

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-03 20:20                 ` Colin Walters
@ 2002-05-04  1:34                   ` Miles Bader
  0 siblings, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-04  1:34 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@debian.org> writes:
> >  That seems like too high a penalty for a common typo.
> 
> Well, to me, what we should ask is whether or not the added
> functionality is worth the cost of that typo.  

It's not as if you can't bind it to some _other_ key sequence...

I like the functionality, just not the binding.

-Miles
-- 
Saa, shall we dance?  (from a dance-class advertisement)

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-03 19:05               ` Miles Bader
  2002-05-03 20:20                 ` Colin Walters
@ 2002-05-04  3:36                 ` Richard Stallman
  2002-05-04  3:49                   ` Miles Bader
  2002-05-04  6:04                 ` Eli Zaretskii
  2 siblings, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-05-04  3:36 UTC (permalink / raw)
  Cc: walters, emacs-devel

    BTW, why not make M-y do something reasonable if invoked without a
    preceeding C-y?  I've always thought it would be handy if it would do
    the equivalent of `C-w C-y M-y' in that situation -- i.e., replace the
    current region with the first thing in the kill ring (and then you
    could type further `M-y's to continue down the ring).

This would be extremely annoying if you were not recently doing yanking.
There is always a region, after all.  Some unpredictable amount of text,
perhaps large, would be replaced.  If you did not notice, the results
would be really bad.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-04  3:36                 ` Richard Stallman
@ 2002-05-04  3:49                   ` Miles Bader
  2002-05-05  5:34                     ` Richard Stallman
  0 siblings, 1 reply; 82+ messages in thread
From: Miles Bader @ 2002-05-04  3:49 UTC (permalink / raw)
  Cc: walters, emacs-devel

Richard Stallman <rms@gnu.org> writes:
> I've always thought it would be handy if it would do
> the equivalent of `C-w C-y M-y' in that situation.
> 
> This would be extremely annoying if you were not recently doing yanking.
> There is always a region, after all.  Some unpredictable amount of text,
> perhaps large, would be replaced.  If you did not notice, the results
> would be really bad.

Ah -- I use transient-mark-mode, which makes the dynamics of such things
different.  I think with TMM active, it would be useful behavior, but I
can see that it would probably suck if TMM wasn't active...  Would this
make sense as `transient-mark-mode only' behavior?

BTW, I'm pretty sure I've used an emacs-like editor that did this, and
found it quite handy (the command bound to M-y was something like
`replace region' and behaved similarly to Emacs' M-y when repeated),
though I can't confidently remember which one; maybe it was the ATK `ez'
editor, which basically always used behavior similar to
transient-mark-mode.

-Miles
-- 
`The suburb is an obsolete and contradictory form of human settlement'

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-03 19:05               ` Miles Bader
  2002-05-03 20:20                 ` Colin Walters
  2002-05-04  3:36                 ` Richard Stallman
@ 2002-05-04  6:04                 ` Eli Zaretskii
  2 siblings, 0 replies; 82+ messages in thread
From: Eli Zaretskii @ 2002-05-04  6:04 UTC (permalink / raw)
  Cc: emacs-devel

> From: Miles Bader <miles@gnu.org>
> Date: 04 May 2002 04:05:49 +0900
> 
> I think it would be very easy to accidentally get the menu.  You usually
> use the M-y command in a series (to move through the kill-ring), and
> it's not uncommon to mistype it if you're really using `ESC y' and
> accidentally hit another key in between two M-ys.  Getting the error
> message in such a circumstance is a little annoying, but being popped
> into a new buffer would drive me nuts.  That seems like too high a
> penalty for a common typo.

We could have an option to disable this, for those users who don't
want such incidents.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-04  3:49                   ` Miles Bader
@ 2002-05-05  5:34                     ` Richard Stallman
  0 siblings, 0 replies; 82+ messages in thread
From: Richard Stallman @ 2002-05-05  5:34 UTC (permalink / raw)
  Cc: walters, emacs-devel

    Ah -- I use transient-mark-mode, which makes the dynamics of such things
    different.  I think with TMM active, it would be useful behavior, but I
    can see that it would probably suck if TMM wasn't active...  Would this
    make sense as `transient-mark-mode only' behavior?

I don't think it makes sense for M-y to be THAT different in Transient
Mark mode.  It would be much better to use a different interface, one
that would be ok to use in both modes.

Perhaps C-u M-y should do one of these features.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
       [not found]           ` <1020502030.5286.25.camel@space-ghost>
@ 2002-05-05 17:46             ` Richard Stallman
  2002-05-06  5:15               ` Colin Walters
  0 siblings, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-05-05 17:46 UTC (permalink / raw)
  Cc: emacs-devel

    It means that if the user decides they don't want any fontification
    (perhaps they find it distracting when viewing an *Occur* or *Kill Ring*
    buffer), then they can just use the normal font-lock mechanism for
    disabling fontification in those buffers.  Or, conversely, if they do
    decide they want it, it's easy to enable; they can just type 'M-x
    font-lock-mode' to toggle things.  It is a good, clean interface.  I
    think every mode should be changed to respect font-lock-mode.

That might be a valid point.  It raises the question: whether it is
better, in these modes that construct special text and can highlight
it, to enable its highlighting by default, or to make it controllable
with M-x font-lock-mode.

In the past we've acted on the view that it is better to highlight
these buffers by default, and the expectation that a considerable
fraction of users won't use Font-Lock mode but will benefit from
highlighting these special buffers.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-05 17:46             ` Richard Stallman
@ 2002-05-06  5:15               ` Colin Walters
  2002-05-06  6:39                 ` Miles Bader
                                   ` (2 more replies)
  0 siblings, 3 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-06  5:15 UTC (permalink / raw)


Since we're apparently moving this discussion to emacs-devel, I'll give
some context:

One of the things Richard commented on was how my proposed
browse-kill-ring patch used font-lock for fontification.  He suggested
to apply the faces when the buffer was constructed, and that using
font-lock was wasteful.

However, I think there is a more general and useful paradigm for
fontification in special modes.  What I do in that patch (and also in
ibuffer and the new occur-mode) is to apply a special text property (say
'occur-match) to areas of text, and then set up a
`font-lock-fontify-region-function' which then searches for those text
properties and applies faces.

If the user never turns on font-lock-mode, then no fontification will
occur, and font-lock.el will never be loaded.  If they do, then things
will automagically be fontified.

For example, in the new Occur implementation, you can switch to the
*Occur* buffer and type 'M-x font-lock-mode' to toggle fontification on
and off, and it will Just Work.  The same is true for ibuffer.

On Sun, 2002-05-05 at 13:46, Richard Stallman wrote:

> That might be a valid point.  It raises the question: whether it is
> better, in these modes that construct special text and can highlight
> it, to enable its highlighting by default, or to make it controllable
> with M-x font-lock-mode.

Well, these are two separate issues.  If we make things controllable via
M-x font-lock-mode, then the user can choose whether or not to enable
highlighting by default through the usual font-lock mechanisms, such as
the functions `global-font-lock-mode', and `font-lock-mode', as well as
the variable `font-lock-global-modes', etc.

> In the past we've acted on the view that it is better to highlight
> these buffers by default, and the expectation that a considerable
> fraction of users won't use Font-Lock mode but will benefit from
> highlighting these special buffers.

I assert (without any statistics) that the vast majority of users put
(global-font-lock-mode 1) in their ~/.emacs file (thereby loading
font-lock.el), and expect fontification in every mode, while the
remaining portion don't want any fontification at all.  So in almost all
cases, there is no waste, because font-lock.el will already be loaded,
or will be used by other modes.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06  5:15               ` Colin Walters
@ 2002-05-06  6:39                 ` Miles Bader
  2002-05-06 22:55                   ` Colin Walters
  2002-05-06  6:46                 ` Stephen J. Turnbull
  2002-05-06 19:32                 ` Richard Stallman
  2 siblings, 1 reply; 82+ messages in thread
From: Miles Bader @ 2002-05-06  6:39 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@verbum.org> writes:
> I assert (without any statistics) that the vast majority of users put
> (global-font-lock-mode 1) in their ~/.emacs file (thereby loading
> font-lock.el), and expect fontification in every mode, while the
> remaining portion don't want any fontification at all.

I think there needs to be a bit more evidence to justify changing the
status quo.

For my part, I've never seen any complaints on any of the emacs
lists/newsgroups from people that dislike fontification in non-font-lock
modes (this is the important case, because most package currently seem
to either use font-lock, or if not, to default to always having
fontification).

I think it is true that using font-lock is wasteful if all it does is
examine text-properties which could have just as easily been face
properties.

-Miles
-- 
P.S.  All information contained in the above letter is false,
      for reasons of military security.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06  5:15               ` Colin Walters
  2002-05-06  6:39                 ` Miles Bader
@ 2002-05-06  6:46                 ` Stephen J. Turnbull
  2002-05-06 22:46                   ` Colin Walters
  2002-05-06 19:32                 ` Richard Stallman
  2 siblings, 1 reply; 82+ messages in thread
From: Stephen J. Turnbull @ 2002-05-06  6:46 UTC (permalink / raw)
  Cc: emacs-devel

>>>>> "Colin" == Colin Walters <walters@verbum.org> writes:

    Colin> I assert (without any statistics) that the vast majority of
    Colin> users put (global-font-lock-mode 1) in their ~/.emacs file
    Colin> (thereby loading font-lock.el), and expect fontification in
    Colin> every mode,

I have no statistics (nobody does) on .emacs content, but I can say
that "how do I turn on font-lock permanently everywhere" is a Top 10
FAQ (since XEmacs doesn't have `global-font-lock-mode'), and "who do I
tell to add font-lock to some-unusual-mode" probably doesn't hit the
Top 10, but it's a regular.

    Colin> while the remaining portion don't want any fontification at
    Colin> all.

I'm a counter-example, possibly because at root I'm a Henry Ford
acolyte: "You can have your [text] in any color you want, as long as
it's black."  I don't like font-lock in text/plain, but I do like it
in program source and I do like color ls.

To be honest, my impression is that everybody likes font lock (except
maybe Jerry Pournelle), it's just that some people want it sometimes,
and some people want it always.

-- 
Institute of Policy and Planning Sciences     http://turnbull.sk.tsukuba.ac.jp
University of Tsukuba                    Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
 My nostalgia for Icon makes me forget about any of the bad things.  I don't
have much nostalgia for Perl, so its faults I remember.  Scott Gilbert c.l.py

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06  5:15               ` Colin Walters
  2002-05-06  6:39                 ` Miles Bader
  2002-05-06  6:46                 ` Stephen J. Turnbull
@ 2002-05-06 19:32                 ` Richard Stallman
  2002-05-07  4:03                   ` Colin Walters
  2 siblings, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-05-06 19:32 UTC (permalink / raw)
  Cc: emacs-devel

    I assert (without any statistics) that the vast majority of users put
    (global-font-lock-mode 1) in their ~/.emacs file (thereby loading
    font-lock.el), and expect fontification in every mode, while the
    remaining portion don't want any fontification at all.

I don't think so.  I expect there are many users like me who find
Font-Lock mode strange and/or slow in programs, and thus do not turn
it on, but appreciate the fontification of some special buffers.  I
don't want to turn that off.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06  6:46                 ` Stephen J. Turnbull
@ 2002-05-06 22:46                   ` Colin Walters
  2002-05-08 10:06                     ` Francesco Potorti`
  0 siblings, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-06 22:46 UTC (permalink / raw)


On Mon, 2002-05-06 at 02:46, Stephen J. Turnbull wrote:

> I have no statistics (nobody does) on .emacs content, but I can say
> that "how do I turn on font-lock permanently everywhere" is a Top 10
> FAQ (since XEmacs doesn't have `global-font-lock-mode'), and "who do I
> tell to add font-lock to some-unusual-mode" probably doesn't hit the
> Top 10, but it's a regular.

Right; all the Emacs and XEmacs users I personally know have enabled
font-lock globally.

> I'm a counter-example, possibly because at root I'm a Henry Ford
> acolyte: "You can have your [text] in any color you want, as long as
> it's black."  I don't like font-lock in text/plain, but I do like it
> in program source and I do like color ls.

Hm, I don't personally see, say, an *Occur* buffer as text/plain.  But
regardless, in the new implementation it's easy to disable
fontification; just

(add-hook 'occur-mode-hook 'font-lock-mode)

Or

(add-hook 'occur-mode-hook (lambda () (font-lock-mode 0))

> To be honest, my impression is that everybody likes font lock (except
> maybe Jerry Pournelle), it's just that some people want it sometimes,
> and some people want it always.

Using font-lock for all modes where possible makes things easier for
both groups of people.  Previously, you would have to hunt down a
`foo-mode-face' variable, or a `foo-mode-enable-fontification', etc.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06  6:39                 ` Miles Bader
@ 2002-05-06 22:55                   ` Colin Walters
  2002-05-07  1:35                     ` Miles Bader
  2002-05-07 19:22                     ` Alex Schroeder
  0 siblings, 2 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-06 22:55 UTC (permalink / raw)


On Mon, 2002-05-06 at 02:39, Miles Bader wrote:

> For my part, I've never seen any complaints on any of the emacs
> lists/newsgroups from people that dislike fontification in non-font-lock
> modes (this is the important case, because most package currently seem
> to either use font-lock, or if not, to default to always having
> fontification).

It is true that this does change the default; it removes fontification
in an *Occur* buffer where there was fontification before.  But in the
end, the user gets more control, in a more consistent fashion, and I
think this win outweighs the change of default.

Using font-lock from the start is a win for other reasons, too.  Suppose
that Occur mode was changed so you could actually edit the buffer, and
changes would be reflected in the original buffer.  If the user typed
additional matches for the search string into the *Occur* buffer, we
would expect them to be made bold, too.  This is possible in a clean way
if we use a dynamic font-lock mechanism.

> I think it is true that using font-lock is wasteful if all it does is
> examine text-properties which could have just as easily been face
> properties.

It's only "wasteful" for those users who liked fontification in special
modes like *Occur*, but not elsewhere.  I really do think that those
users are a relatively rare breed.

And finally, this is a situation where we have a user-interface win
(consistency of interface to enabling/disabling fontification) over
resource consumption (loading of font-lock.el).  I think that as a
general principle, the former should win over the latter. 

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06 22:55                   ` Colin Walters
@ 2002-05-07  1:35                     ` Miles Bader
  2002-05-07  3:55                       ` Colin Walters
  2002-05-07 19:22                     ` Alex Schroeder
  1 sibling, 1 reply; 82+ messages in thread
From: Miles Bader @ 2002-05-07  1:35 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@debian.org> writes:
> And finally, this is a situation where we have a user-interface win
> (consistency of interface to enabling/disabling fontification) over
> resource consumption (loading of font-lock.el).  I think that as a
> general principle, the former should win over the latter. 

You're assuming such `consistency' is a win.  Usually consistency is,
but several people have said on this thread that they _like_ the current
`inconsistency.'  The rules people follow are not always as simple as
you might wish.  Perhaps in this case people see a distinction between
fontifying existing `text files' (like program source) and buffers that
are created by emacs to display some information.

In any case, if it's _really_ desirable to have the single concept of
font-locking control all fontification in buffers (and obviously this is
not clear), then it still seems a bit silly to have font-lock following
non-face properties in the buffer; you could just as easily arrange for
the font-lock `user interface' (e.g., toggling font-lock mode) to be
separate from the font-lock `mechanism' (the part that adds face
properties), and have whatever ad-hoc fontification code you wish follow
the dictates of the former without using the latter.

> Using font-lock from the start is a win for other reasons, too.  Suppose
> that Occur mode was changed so you could actually edit the buffer, and
> changes would be reflected in the original buffer.  If the user typed
> additional matches for the search string into the *Occur* buffer, we
> would expect them to be made bold, too.  This is possible in a clean way
> if we use a dynamic font-lock mechanism.

This is only true if you use `real' font-locking -- e.g., regexps that
match the buffer text -- instead of making font-lock follow text
properties to do its locking.  You could have _both_ of course, but that
seems silly; if you really want to dynamically update user added text,
you may as well just use traditional font-locking from the start.

-Miles
-- 
Fast, small, soon; pick any 2.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07  1:35                     ` Miles Bader
@ 2002-05-07  3:55                       ` Colin Walters
  2002-05-07  4:18                         ` Miles Bader
  2002-05-07 20:07                         ` Richard Stallman
  0 siblings, 2 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-07  3:55 UTC (permalink / raw)


On Mon, 2002-05-06 at 21:35, Miles Bader wrote:

> You're assuming such `consistency' is a win.  Usually consistency is,
> but several people have said on this thread that they _like_ the current
> `inconsistency.'  The rules people follow are not always as simple as
> you might wish.  Perhaps in this case people see a distinction between
> fontifying existing `text files' (like program source) and buffers that
> are created by emacs to display some information.

I think that distinction is arbitrary; I don't see it at all. 
Especially when one considers that these "special" buffers could quite
legitimately later be extended to be real modes; in that case, are we
going to tell our users, "Oh, you have to set `foo-mode-fontification'
to be non-nil to get special highlighting"?  I don't think so; it's
better to make the *interface* via font-lock from the start.

> In any case, if it's _really_ desirable to have the single concept of
> font-locking control all fontification in buffers (and obviously this is
> not clear), then it still seems a bit silly to have font-lock following
> non-face properties in the buffer; you could just as easily arrange for
> the font-lock `user interface' (e.g., toggling font-lock mode) to be
> separate from the font-lock `mechanism' (the part that adds face
> properties), and have whatever ad-hoc fontification code you wish follow
> the dictates of the former without using the latter.

This is *exactly* the way things already work.  font-lock in this case
just calls the `font-lock-fontify-region' function to do the
fontification.  Thus, font-lock becomes the "user interface", as you
say, and the mode author implements the mechanism.

> This is only true if you use `real' font-locking -- e.g., regexps that
> match the buffer text -- instead of making font-lock follow text
> properties to do its locking.  

And why is the former "real" font-locking?  Fontification based on
regular expressions is unreliable when we are dealing with a non-regular
language.  This is why (or at least I think a major reason why) the
maintainers of font-lock added the ability for the major mode author to
perform fontification themselves.

> You could have _both_ of course, but that
> seems silly; if you really want to dynamically update user added text,
> you may as well just use traditional font-locking from the start.

By "traditional" you mean "based on regexps"?  Again, regexp-based
font-lock is not reliable.  I personally will always try to avoid
regexp-based fontification in modes I write.  And implementing your own
`font-lock-fontify-region' function doesn't mean it has to search for
existing text properties; you can perform arbitrary computation.

But this is a digression.  Again, my point is very simple: I think we
should move towards making M-x font-lock-mode, as much as possible, the
standard *interface* for enabling and disabling fontification.  Whether
or not is based on regexps is irrelevant.

One other important point; if resource consumption is an issue, we could
quite easily split font-lock.el into font-lock-core.el and font-lock.el,
or whatever.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06 19:32                 ` Richard Stallman
@ 2002-05-07  4:03                   ` Colin Walters
  2002-05-07  5:27                     ` Eli Zaretskii
  0 siblings, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-07  4:03 UTC (permalink / raw)


On Mon, 2002-05-06 at 15:32, Richard Stallman wrote:

> I don't think so.  I expect there are many users like me who find
> Font-Lock mode strange and/or slow in programs, and thus do not turn
> it on, but appreciate the fontification of some special buffers.  

I don't know how to respond to font-lock being "strange", but if it is
slow (and I haven't had that perception), then I think we should regard
that as an optimization problem, not a reason to change the user
interface.

> I don't want to turn that off.

You could quite easily turn it back on:

(add-hook 'occur-mode-hook 'font-lock-mode)

That could even be the default.  And if resource consumption is a
problem, then we should be able to trim down font-lock.el such that if a
mode implements its own `font-lock-fontify-region' function, all the
regexp and other machinery wouldn't be loaded.

Honestly I really don't understand the objections to this.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07  3:55                       ` Colin Walters
@ 2002-05-07  4:18                         ` Miles Bader
  2002-05-07 20:07                         ` Richard Stallman
  1 sibling, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-07  4:18 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@gnu.org> writes:
> > Perhaps in this case people see a distinction between
> > fontifying existing `text files' (like program source) and buffers that
> > are created by emacs to display some information.
> 
> I think that distinction is arbitrary; I don't see it at all. 

Perhaps so, but others do.

There (apparently) are people who (1) don't want font-locking in the
`traditional' sense, but (2) do want special buffers fontified.  I think
if you want your proposal to fly, you have to at least try to cater to
this group, in some way more convenient than making them stick calls to
`font-lock-mode' in all of their mode hooks.

> This is *exactly* the way things already work.  font-lock in this case
> just calls the `font-lock-fontify-region' function to do the
> fontification.  Thus, font-lock becomes the "user interface", as you
> say, and the mode author implements the mechanism.

Ok, then I was mistaken about how things worked -- I read Richard's
comment to mean that you were adding non-face properties to the text,
and then using the normal font-lock engine to convert these into face
properties (this the inefficiency I alluded to, not the cost of loading
font-lock.el).

> But this is a digression.  Again, my point is very simple: I think we
> should move towards making M-x font-lock-mode, as much as possible, the
> standard *interface* for enabling and disabling fontification.

Agreed, this is the major issue.

-Miles
-- 
o The existentialist, not having a pillow, goes everywhere with the book by
  Sullivan, _I am going to spit on your graves_.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07  4:03                   ` Colin Walters
@ 2002-05-07  5:27                     ` Eli Zaretskii
  0 siblings, 0 replies; 82+ messages in thread
From: Eli Zaretskii @ 2002-05-07  5:27 UTC (permalink / raw)


> From: Colin Walters <walters@gnu.org>
> Date: 07 May 2002 00:03:59 -0400
> 
> if resource consumption is a
> problem, then we should be able to trim down font-lock.el such that if a
> mode implements its own `font-lock-fontify-region' function, all the
> regexp and other machinery wouldn't be loaded.

Just to give you more insight about the efficiency and resource
consumption: these issues popped up several time in the past, and IIRC
the problems uncovered by people who tinkered with and profiled the
relevant code were such that trimming font-lock.el would not solve
them.  For example, in some cases the syntactic fontification causes
Emacs to perform long searches (to find the beginning of a syntactic
entity), and thus slows down redisplay in large buffers, since
font-lock is run by hooks provided by the display engine.

I suggest to search the archives of emacs-devel for related keywords,
if you are interested in the details.

(I'm not saying that I'm for or against the proposal you put forward.
I just commented on something that seems to be related to this
discussion.)

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06 22:55                   ` Colin Walters
  2002-05-07  1:35                     ` Miles Bader
@ 2002-05-07 19:22                     ` Alex Schroeder
  2002-05-09 20:09                       ` Colin Walters
  2002-05-11  6:30                       ` Richard Stallman
  1 sibling, 2 replies; 82+ messages in thread
From: Alex Schroeder @ 2002-05-07 19:22 UTC (permalink / raw)


Colin Walters <walters@debian.org> writes:

> And finally, this is a situation where we have a user-interface win
> (consistency of interface to enabling/disabling fontification) over
> resource consumption (loading of font-lock.el).  I think that as a
> general principle, the former should win over the latter. 

I agree with Colin.  The user interface should improve, and
"improvement" translates to "easy to explain" and "easy to use" and
"flexible if needed" -- IMHO, of course.  Colin's idea of enabling or
disabling all of font-lock in one go, and even enabling font-lock by
default is the right way to go: Easier to explain to newbies, easy to
use for newbies, flexible for oldbies.  The explanation is: M-x
font-lock toggles fontification as a whole.  Font-lock is just one
part of it.

Perhaps we should rephrase the proposal as follows: M-x
toggle-global-fontification will toggle all fontifications, including
font-lock.

In fact the only people suffering will be oldbies that have font-lock
switched off and still like fontification in some buffers (people such
as Richard, apparently).  My personal experience in supporting newbies
is that all want to switch font-lock on.  Those that did not do this,
usually worked on the console, so they did not benefit from fontified
some buffers.

I think the group of people suffering due to Colin's change is small,
and it knows elisp, so they will be able to customize Emacs to do
their bidding.  Thus the damage is small, and the benefit is big.  I
think the user interface to fontification should be simplified.

Alex.
-- 
http://www.electronicintifada.net/diaries/index.html
http://www.us-israel.org/jsource/US-Israel/hr2506c.html

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07  3:55                       ` Colin Walters
  2002-05-07  4:18                         ` Miles Bader
@ 2002-05-07 20:07                         ` Richard Stallman
  2002-05-07 20:38                           ` Colin Walters
  1 sibling, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-05-07 20:07 UTC (permalink / raw)
  Cc: emacs-devel

    Especially when one considers that these "special" buffers could quite
    legitimately later be extended to be real modes;

They ARE real modes.  What is special about them is that the text is
generated by Emacs.  If we extend these modes, which may happen,
that basic fact won't change.


Here is a proposal:

* M-x font-lock-mode will enable and disable fontification in any
  buffer.

* font-lock-mode, when enabled, will not always use the mechanism in
  font-lock.el.  In special buffers, it will just set a flag that
  directs the mechanism to insert faces when constructing the text.

* global-font-lock-mode, when enabled, will cause use of
  fontification in all buffers that can do it.  In each buffer,
  it will work as if M-x font-lock had been enabled; which means,
  therefore, that special buffers will do it directly, while others
  will use font-lock.el.

* When global-font-lock-mode is not enabled, there will be two
  possible alternatives for which buffers to fontify: special buffers
  only, or no buffers.

The defaults will be that global-font-lock-mode is not enabled
and fontification is for special buffers only.

This should satisfy all of us who have said anything about the
issue.  Does it?

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07 20:07                         ` Richard Stallman
@ 2002-05-07 20:38                           ` Colin Walters
  2002-05-08  0:20                             ` Miles Bader
  2002-05-09  2:45                             ` Richard Stallman
  0 siblings, 2 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-07 20:38 UTC (permalink / raw)


On Tue, 2002-05-07 at 16:07, Richard Stallman wrote:

> * M-x font-lock-mode will enable and disable fontification in any
>   buffer.

This is the main goal, and I would be happy if we could achieve this.

> * font-lock-mode, when enabled, will not always use the mechanism in
>   font-lock.el.  In special buffers, it will just set a flag that
>   directs the mechanism to insert faces when constructing the text.

The disadvantage with this approach is that the user couldn't toggle
fontification on and off by typing 'M-x font-lock-mode' in a special
buffer; they would have to regenerate the buffer text (e.g. by typing
'g' in an *Occur* buffer).

This is an inconsistency that we are apparently introducing for
performance reasons.  While I don't like that, I accept your decision,
because we could quite easily later change the implementation mechanism
to support toggling fontification independently of the construction of
buffer text.  The important part is to standardize on the interface.

> This should satisfy all of us who have said anything about the
> issue.  Does it?

Besides the above issue (which is not entirely crucial), I think your
proposal is good.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07 20:38                           ` Colin Walters
@ 2002-05-08  0:20                             ` Miles Bader
  2002-05-08  6:05                               ` Colin Walters
  2002-05-09  2:45                             ` Richard Stallman
  1 sibling, 1 reply; 82+ messages in thread
From: Miles Bader @ 2002-05-08  0:20 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@verbum.org> writes:
> The disadvantage with this approach is that the user couldn't toggle
> fontification on and off by typing 'M-x font-lock-mode' in a special
> buffer; they would have to regenerate the buffer text (e.g. by typing
> 'g' in an *Occur* buffer).

There could be a `font-lock-refontify-function' variable that such modes
set, which `font-lock-mode' would call if necessary to refontify the
buffer.

Then the interface will seem to work consistently for users, but special
modes can avoid the overhead of the font-lock engine if they desire.

-Miles
-- 
Ich bin ein Virus. Mach' mit und kopiere mich in Deine .signature.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-08  0:20                             ` Miles Bader
@ 2002-05-08  6:05                               ` Colin Walters
  2002-05-08  6:50                                 ` Miles Bader
  0 siblings, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-08  6:05 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 4533 bytes --]

On Tue, 2002-05-07 at 20:20, Miles Bader wrote:

> There could be a `font-lock-refontify-function' variable that such modes
> set, which `font-lock-mode' would call if necessary to refontify the
> buffer.

Ok, That might be one way to optimize things, if it turns out to be
necessary.

> Then the interface will seem to work consistently for users, but special
> modes can avoid the overhead of the font-lock engine if they desire.

OK.  I have thought about this issue a lot more carefully.  

Richard: I have changed my mind with regards to your proposal.  I first
actually wrote a patch which implemented things the way you suggested. 
But from a user perspective, things still wouldn't be consistent,
because typing 'M-x font-lock-mode' wouldn't always do the Right Thing
in special buffers. So we might as well have kept the status quo.  

I believe your original objection to my approach was that loading
font-lock.el was a lot of overhead.  I have addressed this in the
attached patch, by creating a "font-core.el".

Miles: You objected to putting special text properties on the buffer
text, and then fontifying on them later, correct?  Unfortunately this is
the only way I can think of to implement fontification for special
buffers, such that typing M-x font-lock-mode will always do the Right
Thing.  I believe I can optimize this such that the mode's
`font-lock-fontify-region' function is only called *once*.  This should
minimize the overhead.  I don't think this will actually be very slow at
all, anyways.  Text properties are quite fast.  Or we could solve this
issue the way you suggest above.  So this should not be a problem.

One other issue that came up was that special modes wouldn't be
fontified by default.  I have solved this in a simple way; we add
`font-lock-mode' to the default value of the mode's hooks.  This allows
a user to customize fontification in a clean way.  If a user *doesn't*
want those modes fontified, they can

(remove-hook 'foo-mode-hook 'font-lock-mode)

Let me restate things in terms of advantages and disadvantages:

Advantages:
* From a user perspective, the attached patch doesn't change anything at
all, except that typing M-x font-lock-mode will now suddenly work in
special modes like Occur; if we decide to put this patch in, then I will
change Info and all the other modes to support it.
* The memory impact should be quite small, since we only load
font-core.el for special modes.

Disadvantages:
* Fontification of special buffers may take a bit longer.  I personally
don't believe the difference will be noticeable.  If it is (and I
haven't noticed any slowdown), I will work on making it faster.


In this patch, most of the changes are moved functions.  See the entries
for font-core.el to see what (little) code was actually changed.

2002-05-08  Colin Walters  <walters@gnu.org>

	* font-lock.el (font-lock)
	(font-lock-highlighting-faces, font-lock-extra-types)
	(fast-lock, lazy-lock, jit-lock, font-lock-maximum-size)
	(font-lock-maximum-decoration, font-lock-verbose)
	(font-lock-defaults, font-lock-fontify-buffer-function)
	(font-lock-unfontify-buffer-function)
	(font-lock-fontify-region-function)
	(font-lock-unfontify-region-function)
	(font-lock-inhibit-thing-lock, font-lock-multiline)
	(font-lock-fontified, save-buffer-state)
	(font-lock-face-attributes, font-lock-mode)
	(turn-on-font-lock, global-font-lock-mode)
	(font-lock-global-modes, font-lock-support-mode)
	(fast-lock-mode, lazy-lock-mode, jit-lock-mode)
	(font-lock-turn-on-thing-lock, font-lock-turn-off-thing-lock)
	(font-lock-after-fontify-buffer, font-lock-after-unfontify-buffer)
	(font-lock-fontify-buffer, font-lock-unfontify-buffer)
	(font-lock-fontify-region, font-lock-unfontify-region)
	(font-lock-default-fontify-buffer)
	(font-lock-default-unfontify-buffer)
	(font-lock-default-unfontify-region)
	(font-lock-after-change-function):
	Moved to font-core.el.
	(font-lock-set-defaults): Renamed to `font-lock-set-defaults-1';
	partially moved to font-core.el.

	* font-core.el: New file, with functions broken out from
	font-lock.el.
	(font-lock-core-only): New variable.
	(font-lock-mode): If `font-lock-core-only' is non-nil, fontify the
	whole buffer immediately; don't enable a font-lock support mode.
	(font-lock-set-defaults): Partially moved here from font-lock.el.
	We try to only load all of font-lock.el if the mode doesn't set
	`font-lock-core-only'.

	* replace.el (occur-mode-hooks): New variable.
	(occur-mode): Set `font-lock-core-only'.  Run `occur-mode-hooks'
	too.




[-- Attachment #2: font-lock.patch --]
[-- Type: text/plain, Size: 61475 bytes --]

--- loadup.el.~1.122.~	Sun Apr 28 22:29:16 2002
+++ loadup.el	Wed May  8 00:38:36 2002
@@ -149,6 +149,7 @@
 (load "emacs-lisp/lisp-mode")
 (load "textmodes/text-mode")
 (load "textmodes/fill")
+(load "font-core")
 (message "%s" (garbage-collect))
 
 (load "replace")
--- replace.el.~1.140.~	Tue May  7 23:49:58 2002
+++ replace.el	Wed May  8 01:28:26 2002
@@ -453,6 +453,11 @@
   "Arguments to pass to `occur-1' to revert an Occur mode buffer.
 See `occur-revert-function'.")
 
+(defcustom occur-mode-hooks '(font-lock-mode)
+  "Hooks run upon entry into `occur-mode'."
+  :type 'hook
+  :group 'matching)
+
 (put 'occur-mode 'mode-class 'special)
 (defun occur-mode ()
   "Major mode for output from \\[occur].
@@ -468,11 +473,13 @@
   (make-local-variable 'revert-buffer-function)
   (set (make-local-variable 'font-lock-defaults)
        '(nil t nil nil nil
+	     (font-lock-core-only . t)
 	     (font-lock-fontify-region-function . occur-fontify-region-function)))
   (setq revert-buffer-function 'occur-revert-function)
   (set (make-local-variable 'revert-buffer-function) 'occur-revert-function)
   (make-local-variable 'occur-revert-arguments)
-  (run-hooks 'occur-mode-hook))
+  (run-hooks 'occur-mode-hook)
+  (run-hooks 'occur-mode-hooks))
 
 (defun occur-revert-function (ignore1 ignore2)
   "Handle `revert-buffer' for Occur mode buffers."
--- font-lock.el.~1.195.~	Tue May  7 18:20:10 2002
+++ font-lock.el	Wed May  8 01:21:52 2002
@@ -208,99 +208,8 @@
 ;;; Code:
 
 (require 'syntax)
+(require 'font-core)
 
-;; Define core `font-lock' group.
-(defgroup font-lock nil
-  "Font Lock mode text highlighting package."
-  :link '(custom-manual "(emacs)Font Lock")
-  :link '(custom-manual "(elisp)Font Lock Mode")
-  :group 'faces)
-
-(defgroup font-lock-highlighting-faces nil
-  "Faces for highlighting text."
-  :prefix "font-lock-"
-  :group 'font-lock)
-
-(defgroup font-lock-extra-types nil
-  "Extra mode-specific type names for highlighting declarations."
-  :group 'font-lock)
-
-;; Define support mode groups here to impose `font-lock' group order.
-(defgroup fast-lock nil
-  "Font Lock support mode to cache fontification."
-  :link '(custom-manual "(emacs)Support Modes")
-  :load 'fast-lock
-  :group 'font-lock)
-
-(defgroup lazy-lock nil
-  "Font Lock support mode to fontify lazily."
-  :link '(custom-manual "(emacs)Support Modes")
-  :load 'lazy-lock
-  :group 'font-lock)
-
-(defgroup jit-lock nil
-  "Font Lock support mode to fontify just-in-time."
-  :link '(custom-manual "(emacs)Support Modes")
-  :version "21.1"
-  :load 'jit-lock
-  :group 'font-lock)
-\f
-;; User variables.
-
-(defcustom font-lock-maximum-size 256000
-  "*Maximum size of a buffer for buffer fontification.
-Only buffers less than this can be fontified when Font Lock mode is turned on.
-If nil, means size is irrelevant.
-If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
-where MAJOR-MODE is a symbol or t (meaning the default).  For example:
- ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576))
-means that the maximum size is 250K for buffers in C or C++ modes, one megabyte
-for buffers in Rmail mode, and size is irrelevant otherwise."
-  :type '(choice (const :tag "none" nil)
-		 (integer :tag "size")
-		 (repeat :menu-tag "mode specific" :tag "mode specific"
-			 :value ((t . nil))
-			 (cons :tag "Instance"
-			       (radio :tag "Mode"
-				      (const :tag "all" t)
-				      (symbol :tag "name"))
-			       (radio :tag "Size"
-				      (const :tag "none" nil)
-				      (integer :tag "size")))))
-  :group 'font-lock)
-
-(defcustom font-lock-maximum-decoration t
-  "*Maximum decoration level for fontification.
-If nil, use the default decoration (typically the minimum available).
-If t, use the maximum decoration available.
-If a number, use that level of decoration (or if not available the maximum).
-If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
-where MAJOR-MODE is a symbol or t (meaning the default).  For example:
- ((c-mode . t) (c++-mode . 2) (t . 1))
-means use the maximum decoration available for buffers in C mode, level 2
-decoration for buffers in C++ mode, and level 1 decoration otherwise."
-  :type '(choice (const :tag "default" nil)
-		 (const :tag "maximum" t)
-		 (integer :tag "level" 1)
-		 (repeat :menu-tag "mode specific" :tag "mode specific"
-			 :value ((t . t))
-			 (cons :tag "Instance"
-			       (radio :tag "Mode"
-				      (const :tag "all" t)
-				      (symbol :tag "name"))
-			       (radio :tag "Decoration"
-				      (const :tag "default" nil)
-				      (const :tag "maximum" t)
-				      (integer :tag "level" 1)))))
-  :group 'font-lock)
-
-(defcustom font-lock-verbose 0
-  "*If non-nil, means show status messages for buffer fontification.
-If a number, only buffers greater than this size have fontification messages."
-  :type '(choice (const :tag "never" nil)
-		 (other :tag "always" t)
-		 (integer :tag "size"))
-  :group 'font-lock)
 \f
 
 ;; Originally these variable values were face names such as `bold' etc.
@@ -446,55 +355,6 @@
 Be careful when composing regexps for this list; a poorly written pattern can
 dramatically slow things down!")
 
-;; This variable is used by mode packages that support Font Lock mode by
-;; defining their own keywords to use for `font-lock-keywords'.  (The mode
-;; command should make it buffer-local and set it to provide the set up.)
-(defvar font-lock-defaults nil
-  "Defaults for Font Lock mode specified by the major mode.
-Defaults should be of the form:
-
- (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
-
-KEYWORDS may be a symbol (a variable or function whose value is the keywords to
-use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
-syntactic fontification (strings and comments) is not performed.
-If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
-If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
-\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
-keyword and syntactic fontification (see `modify-syntax-entry').
-
-If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
-backwards outside any enclosing syntactic block, for syntactic fontification.
-Typical values are `beginning-of-line' (i.e., the start of the line is known to
-be outside a syntactic block), or `beginning-of-defun' for programming modes or
-`backward-paragraph' for textual modes (i.e., the mode-dependent function is
-known to move outside a syntactic block).  If nil, the beginning of the buffer
-is used as a position outside of a syntactic block, in the worst case.
-
-These item elements are used by Font Lock mode to set the variables
-`font-lock-keywords', `font-lock-keywords-only',
-`font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
-`font-lock-beginning-of-syntax-function', respectively.
-
-Further item elements are alists of the form (VARIABLE . VALUE) and are in no
-particular order.  Each VARIABLE is made buffer-local before set to VALUE.
-
-Currently, appropriate variables include `font-lock-mark-block-function'.
-If this is non-nil, it should be a function with no args used to mark any
-enclosing block of text, for fontification via \\[font-lock-fontify-block].
-Typical values are `mark-defun' for programming modes or `mark-paragraph' for
-textual modes (i.e., the mode-dependent function is known to put point and mark
-around a text block relevant to that mode).
-
-Other variables include that for syntactic keyword fontification,
-`font-lock-syntactic-keywords'
-and those for buffer-specialised fontification functions,
-`font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function',
-`font-lock-fontify-region-function', `font-lock-unfontify-region-function',
-`font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.")
-;;;###autoload
-(make-variable-buffer-local 'font-lock-defaults)
-
 ;; This variable is used where font-lock.el itself supplies the keywords.
 (defvar font-lock-defaults-alist
   (let (;; We use `beginning-of-defun', rather than nil, for SYNTAX-BEGIN.
@@ -632,153 +492,6 @@
 enclosing textual block and mark at the end.
 This is normally set via `font-lock-defaults'.")
 
-(defvar font-lock-fontify-buffer-function 'font-lock-default-fontify-buffer
-  "Function to use for fontifying the buffer.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-unfontify-buffer-function 'font-lock-default-unfontify-buffer
-  "Function to use for unfontifying the buffer.
-This is used when turning off Font Lock mode.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
-  "Function to use for fontifying a region.
-It should take two args, the beginning and end of the region, and an optional
-third arg VERBOSE.  If non-nil, the function should print status messages.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
-  "Function to use for unfontifying a region.
-It should take two args, the beginning and end of the region.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-inhibit-thing-lock nil
-  "List of Font Lock mode related modes that should not be turned on.
-Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
-`lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-multiline nil
-  "Whether font-lock should cater to multiline keywords.
-If nil, don't try to handle multiline patterns.
-If t, always handle multiline patterns.
-If `undecided', don't try to handle multiline patterns until you see one.
-Major/minor modes can set this variable if they know which option applies.")
-
-(defvar font-lock-fontified nil)	; Whether we have fontified the buffer.
-\f
-;; Font Lock mode.
-
-(eval-when-compile
-  ;;
-  ;; We don't do this at the top-level as we only use non-autoloaded macros.
-  (require 'cl)
-  ;;
-  ;; Borrowed from lazy-lock.el.
-  ;; We use this to preserve or protect things when modifying text properties.
-  (defmacro save-buffer-state (varlist &rest body)
-    "Bind variables according to VARLIST and eval BODY restoring buffer state."
-    (let ((modified (make-symbol "modified")))
-      `(let* ,(append varlist
-		      `((,modified (buffer-modified-p))
-			(buffer-undo-list t)
-			(inhibit-read-only t)
-			(inhibit-point-motion-hooks t)
-			(inhibit-modification-hooks t)
-			deactivate-mark
-			buffer-file-name
-			buffer-file-truename))
-	 (progn
-	   ,@body)
-	 (unless ,modified
-	   (restore-buffer-modified-p nil)))))
-  (put 'save-buffer-state 'lisp-indent-function 1)
-  (def-edebug-spec save-buffer-state let)
-  ;;
-  ;; Shut up the byte compiler.
-  (defvar font-lock-face-attributes))	; Obsolete but respected if set.
-
-;;;###autoload
-(define-minor-mode font-lock-mode
-  "Toggle Font Lock mode.
-With arg, turn Font Lock mode off if and only if arg is a non-positive
-number; if arg is nil, toggle Font Lock mode; anything else turns Font
-Lock on.
-\(Font Lock is also known as \"syntax highlighting\".)
-
-When Font Lock mode is enabled, text is fontified as you type it:
-
- - Comments are displayed in `font-lock-comment-face';
- - Strings are displayed in `font-lock-string-face';
- - Certain other expressions are displayed in other faces according to the
-   value of the variable `font-lock-keywords'.
-
-To customize the faces (colors, fonts, etc.) used by Font Lock for
-fontifying different parts of buffer text, use \\[customize-face].
-
-You can enable Font Lock mode in any major mode automatically by turning on in
-the major mode's hook.  For example, put in your ~/.emacs:
-
- (add-hook 'c-mode-hook 'turn-on-font-lock)
-
-Alternatively, you can use Global Font Lock mode to automagically turn on Font
-Lock mode in buffers whose major mode supports it and whose major mode is one
-of `font-lock-global-modes'.  For example, put in your ~/.emacs:
-
- (global-font-lock-mode t)
-
-There are a number of support modes that may be used to speed up Font Lock mode
-in various ways, specified via the variable `font-lock-support-mode'.  Where
-major modes support different levels of fontification, you can use the variable
-`font-lock-maximum-decoration' to specify which level you generally prefer.
-When you turn Font Lock mode on/off the buffer is fontified/defontified, though
-fontification occurs only if the buffer is less than `font-lock-maximum-size'.
-
-For example, to specify that Font Lock mode use use Lazy Lock mode as a support
-mode and use maximum levels of fontification, put in your ~/.emacs:
-
- (setq font-lock-support-mode 'lazy-lock-mode)
- (setq font-lock-maximum-decoration t)
-
-To add your own highlighting for some major mode, and modify the highlighting
-selected automatically via the variable `font-lock-maximum-decoration', you can
-use `font-lock-add-keywords'.
-
-To fontify a buffer, without turning on Font Lock mode and regardless of buffer
-size, you can use \\[font-lock-fontify-buffer].
-
-To fontify a block (the function or paragraph containing point, or a number of
-lines around point), perhaps because modification on the current line caused
-syntactic change on other lines, you can use \\[font-lock-fontify-block].
-
-See the variable `font-lock-defaults-alist' for the Font Lock mode default
-settings.  You can set your own default settings for some mode, by setting a
-buffer local value for `font-lock-defaults', via its mode hook."
-  nil nil nil
-  ;; Don't turn on Font Lock mode if we don't have a display (we're running a
-  ;; batch job) or if the buffer is invisible (the name starts with a space).
-  (when (or noninteractive (eq (aref (buffer-name) 0) ?\ ))
-    (setq font-lock-mode nil))
-
-  ;; Turn on Font Lock mode.
-  (when font-lock-mode
-    (add-hook 'after-change-functions 'font-lock-after-change-function t t)
-    (font-lock-set-defaults)
-    (font-lock-turn-on-thing-lock)
-    ;; Fontify the buffer if we have to.
-    (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
-      (cond (font-lock-fontified
-	     nil)
-	    ((or (null max-size) (> max-size (buffer-size)))
-	     (font-lock-fontify-buffer))
-	    (font-lock-verbose
-	     (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
-		      (buffer-name))))))
-  ;; Turn off Font Lock mode.
-  (unless font-lock-mode
-    (remove-hook 'after-change-functions 'font-lock-after-change-function t)
-    (font-lock-unfontify-buffer)
-    (font-lock-turn-off-thing-lock)))
-
 ;;;###autoload
 (defun turn-on-font-lock ()
   "Turn on Font Lock mode (only if the terminal can display it)."
@@ -937,279 +650,10 @@
 			 (delete (font-lock-compile-keyword keyword)
 				 font-lock-keywords)))))))
 \f
-;;; Global Font Lock mode.
-
-;; A few people have hassled in the past for a way to make it easier to turn on
-;; Font Lock mode, without the user needing to know for which modes s/he has to
-;; turn it on, perhaps the same way hilit19.el/hl319.el does.  I've always
-;; balked at that way, as I see it as just re-moulding the same problem in
-;; another form.  That is; some person would still have to keep track of which
-;; modes (which may not even be distributed with Emacs) support Font Lock mode.
-;; The list would always be out of date.  And that person might have to be me.
-
-;; Implementation.
-;;
-;; In a previous discussion the following hack came to mind.  It is a gross
-;; hack, but it generally works.  We use the convention that major modes start
-;; by calling the function `kill-all-local-variables', which in turn runs
-;; functions on the hook variable `change-major-mode-hook'.  We attach our
-;; function `font-lock-change-major-mode' to that hook.  Of course, when this
-;; hook is run, the major mode is in the process of being changed and we do not
-;; know what the final major mode will be.  So, `font-lock-change-major-mode'
-;; only (a) notes the name of the current buffer, and (b) adds our function
-;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
-;; `post-command-hook' (for buffers that are not visiting files).  By the time
-;; the functions on the first of these hooks to be run are run, the new major
-;; mode is assumed to be in place.  This way we get a Font Lock function run
-;; when a major mode is turned on, without knowing major modes or their hooks.
-;;
-;; Naturally this requires that (a) major modes run `kill-all-local-variables',
-;; as they are supposed to do, and (b) the major mode is in place after the
-;; file is visited or the command that ran `kill-all-local-variables' has
-;; finished, whichever the sooner.  Arguably, any major mode that does not
-;; follow the convension (a) is broken, and I can't think of any reason why (b)
-;; would not be met (except `gnudoit' on non-files).  However, it is not clean.
-;;
-;; Probably the cleanest solution is to have each major mode function run some
-;; hook, e.g., `major-mode-hook', but maybe implementing that change is
-;; impractical.  I am personally against making `setq' a macro or be advised,
-;; or have a special function such as `set-major-mode', but maybe someone can
-;; come up with another solution?
-
-;; User interface.
-;;
-;; Although Global Font Lock mode is a pseudo-mode, I think that the user
-;; interface should conform to the usual Emacs convention for modes, i.e., a
-;; command to toggle the feature (`global-font-lock-mode') with a variable for
-;; finer control of the mode's behaviour (`font-lock-global-modes').
-;;
-;; The feature should not be enabled by loading font-lock.el, since other
-;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
-;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
-;; turned on everywhere.  That would not be intuitive or informative because
-;; loading a file tells you nothing about the feature or how to control it.  It
-;; would also be contrary to the Principle of Least Surprise.  sm.
-
-(defcustom font-lock-global-modes t
-  "*Modes for which Font Lock mode is automagically turned on.
-Global Font Lock mode is controlled by the command `global-font-lock-mode'.
-If nil, means no modes have Font Lock mode automatically turned on.
-If t, all modes that support Font Lock mode have it automatically turned on.
-If a list, it should be a list of `major-mode' symbol names for which Font Lock
-mode should be automatically turned on.  The sense of the list is negated if it
-begins with `not'.  For example:
- (c-mode c++-mode)
-means that Font Lock mode is turned on for buffers in C and C++ modes only."
-  :type '(choice (const :tag "none" nil)
-		 (const :tag "all" t)
-		 (set :menu-tag "mode specific" :tag "modes"
-		      :value (not)
-		      (const :tag "Except" not)
-		      (repeat :inline t (symbol :tag "mode"))))
-  :group 'font-lock)
-
-(defun turn-on-font-lock-if-enabled ()
-  (when (and (or font-lock-defaults
-		 (assq major-mode font-lock-defaults-alist))
-	     (or (eq font-lock-global-modes t)
-		 (if (eq (car-safe font-lock-global-modes) 'not)
-		     (not (memq major-mode (cdr font-lock-global-modes)))
-		   (memq major-mode font-lock-global-modes))))
-    (let (inhibit-quit)
-      (turn-on-font-lock))))
 
-;;;###autoload
-(easy-mmode-define-global-mode
- global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
- :extra-args (dummy))
-
-;;; End of Global Font Lock mode.
-\f
-;;; Font Lock Support mode.
-
-;; This is the code used to interface font-lock.el with any of its add-on
-;; packages, and provide the user interface.  Packages that have their own
-;; local buffer fontification functions (see below) may have to call
-;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
-;; themselves.
-
-(defcustom font-lock-support-mode 'jit-lock-mode
-  "*Support mode for Font Lock mode.
-Support modes speed up Font Lock mode by being choosy about when fontification
-occurs.  Known support modes are Fast Lock mode (symbol `fast-lock-mode'),
-Lazy Lock mode (symbol `lazy-lock-mode'), and Just-in-time Lock mode (symbol
-`jit-lock-mode'.  See those modes for more info.
-If nil, means support for Font Lock mode is never performed.
-If a symbol, use that support mode.
-If a list, each element should be of the form (MAJOR-MODE . SUPPORT-MODE),
-where MAJOR-MODE is a symbol or t (meaning the default).  For example:
- ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
-means that Fast Lock mode is used to support Font Lock mode for buffers in C or
-C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
-
-The value of this variable is used when Font Lock mode is turned on."
-  :type '(choice (const :tag "none" nil)
-		 (const :tag "fast lock" fast-lock-mode)
-		 (const :tag "lazy lock" lazy-lock-mode)
-		 (const :tag "jit lock" jit-lock-mode)
-		 (repeat :menu-tag "mode specific" :tag "mode specific"
-			 :value ((t . jit-lock-mode))
-			 (cons :tag "Instance"
-			       (radio :tag "Mode"
-				      (const :tag "all" t)
-				      (symbol :tag "name"))
-			       (radio :tag "Support"
-				      (const :tag "none" nil)
-				      (const :tag "fast lock" fast-lock-mode)
-				      (const :tag "lazy lock" lazy-lock-mode)
-				      (const :tag "JIT lock" jit-lock-mode)))
-			 ))
-  :version "21.1"
-  :group 'font-lock)
-
-(defvar fast-lock-mode nil)
-(defvar lazy-lock-mode nil)
-(defvar jit-lock-mode nil)
-
-(defun font-lock-turn-on-thing-lock ()
-  (let ((thing-mode (font-lock-value-in-major-mode font-lock-support-mode)))
-    (cond ((eq thing-mode 'fast-lock-mode)
-	   (fast-lock-mode t))
-	  ((eq thing-mode 'lazy-lock-mode)
-	   (lazy-lock-mode t))
-	  ((eq thing-mode 'jit-lock-mode)
-	   ;; Prepare for jit-lock
-	   (remove-hook 'after-change-functions
-			'font-lock-after-change-function t)
-	   (set (make-local-variable 'font-lock-fontify-buffer-function)
-		'jit-lock-refontify)
-	   ;; Don't fontify eagerly (and don't abort is the buffer is large).
-	   (set (make-local-variable 'font-lock-fontified) t)
-	   ;; Use jit-lock.
-	   (jit-lock-register 'font-lock-fontify-region
-			      (not font-lock-keywords-only))))))
-
-(defun font-lock-turn-off-thing-lock ()
-  (cond (fast-lock-mode
-	 (fast-lock-mode -1))
-	(jit-lock-mode
-	 (jit-lock-unregister 'font-lock-fontify-region)
-	 ;; Reset local vars to the non-jit-lock case.
-	 (kill-local-variable 'font-lock-fontify-buffer-function))
-	(lazy-lock-mode
-	 (lazy-lock-mode -1))))
-
-(defun font-lock-after-fontify-buffer ()
-  (cond (fast-lock-mode
-	 (fast-lock-after-fontify-buffer))
-	;; Useless now that jit-lock intercepts font-lock-fontify-buffer.  -sm
-	;; (jit-lock-mode
-	;;  (jit-lock-after-fontify-buffer))
-	(lazy-lock-mode
-	 (lazy-lock-after-fontify-buffer))))
-
-(defun font-lock-after-unfontify-buffer ()
-  (cond (fast-lock-mode
-	 (fast-lock-after-unfontify-buffer))
-	;; Useless as well.  It's only called when:
-	;; - turning off font-lock: it does not matter if we leave spurious
-	;;   `fontified' text props around since jit-lock-mode is also off.
-	;; - font-lock-default-fontify-buffer fails: this is not run
-	;;   any more anyway.   -sm
-	;;
-	;; (jit-lock-mode
-	;;  (jit-lock-after-unfontify-buffer))
-	(lazy-lock-mode
-	 (lazy-lock-after-unfontify-buffer))))
-
-;;; End of Font Lock Support mode.
 \f
-;;; Fontification functions.
 
-;; Rather than the function, e.g., `font-lock-fontify-region' containing the
-;; code to fontify a region, the function runs the function whose name is the
-;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,
-;; the value of this variable is, e.g., `font-lock-default-fontify-region'
-;; which does contain the code to fontify a region.  However, the value of the
-;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
-;; do anything.  The indirection of the fontification functions gives major
-;; modes the capability of modifying the way font-lock.el fontifies.  Major
-;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
-;; via the variable `font-lock-defaults'.
-;;
-;; For example, Rmail mode sets the variable `font-lock-defaults' so that
-;; font-lock.el uses its own function for buffer fontification.  This function
-;; makes fontification be on a message-by-message basis and so visiting an
-;; RMAIL file is much faster.  A clever implementation of the function might
-;; fontify the headers differently than the message body.  (It should, and
-;; correspondingly for Mail mode, but I can't be bothered to do the work.  Can
-;; you?)  This hints at a more interesting use...
-;;
-;; Languages that contain text normally contained in different major modes
-;; could define their own fontification functions that treat text differently
-;; depending on its context.  For example, Perl mode could arrange that here
-;; docs are fontified differently than Perl code.  Or Yacc mode could fontify
-;; rules one way and C code another.  Neat!
-;;
-;; A further reason to use the fontification indirection feature is when the
-;; default syntactual fontification, or the default fontification in general,
-;; is not flexible enough for a particular major mode.  For example, perhaps
-;; comments are just too hairy for `font-lock-fontify-syntactically-region' to
-;; cope with.  You need to write your own version of that function, e.g.,
-;; `hairy-fontify-syntactically-region', and make your own version of
-;; `hairy-fontify-region' call that function before calling
-;; `font-lock-fontify-keywords-region' for the normal regexp fontification
-;; pass.  And Hairy mode would set `font-lock-defaults' so that font-lock.el
-;; would call your region fontification function instead of its own.  For
-;; example, TeX modes could fontify {\foo ...} and \bar{...}  etc. multi-line
-;; directives correctly and cleanly.  (It is the same problem as fontifying
-;; multi-line strings and comments; regexps are not appropriate for the job.)
-
-;;;###autoload
-(defun font-lock-fontify-buffer ()
-  "Fontify the current buffer the way the function `font-lock-mode' would."
-  (interactive)
-  (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
-    (funcall font-lock-fontify-buffer-function)))
-
-(defun font-lock-unfontify-buffer ()
-  (funcall font-lock-unfontify-buffer-function))
-
-(defun font-lock-fontify-region (beg end &optional loudly)
-  (funcall font-lock-fontify-region-function beg end loudly))
-
-(defun font-lock-unfontify-region (beg end)
-  (funcall font-lock-unfontify-region-function beg end))
-
-(defun font-lock-default-fontify-buffer ()
-  (let ((verbose (if (numberp font-lock-verbose)
-		     (> (buffer-size) font-lock-verbose)
-		   font-lock-verbose)))
-    (with-temp-message
-	(when verbose
-	  (format "Fontifying %s..." (buffer-name)))
-      ;; Make sure we have the right `font-lock-keywords' etc.
-      (unless font-lock-mode
-	(font-lock-set-defaults))
-      ;; Make sure we fontify etc. in the whole buffer.
-      (save-restriction
-	(widen)
-	(condition-case nil
-	    (save-excursion
-	      (save-match-data
-		(font-lock-fontify-region (point-min) (point-max) verbose)
-		(font-lock-after-fontify-buffer)
-		(setq font-lock-fontified t)))
-	  ;; We don't restore the old fontification, so it's best to unfontify.
-	  (quit (font-lock-unfontify-buffer)))))))
-
-(defun font-lock-default-unfontify-buffer ()
-  ;; Make sure we unfontify etc. in the whole buffer.
-  (save-restriction
-    (widen)
-    (font-lock-unfontify-region (point-min) (point-max))
-    (font-lock-after-unfontify-buffer)
-    (setq font-lock-fontified nil)))
+;;; Non-core fontification functions.
 
 (defun font-lock-default-fontify-region (beg end loudly)
   (save-buffer-state
@@ -1248,41 +692,6 @@
       ;; Clean up.
       (set-syntax-table old-syntax-table))))
 
-;; The following must be rethought, since keywords can override fontification.
-;      ;; Now scan for keywords, but not if we are inside a comment now.
-;      (or (and (not font-lock-keywords-only)
-;	       (let ((state (parse-partial-sexp beg end nil nil
-;						font-lock-cache-state)))
-;		 (or (nth 4 state) (nth 7 state))))
-;	  (font-lock-fontify-keywords-region beg end))
-
-(defvar font-lock-extra-managed-props nil
-  "Additional text properties managed by font-lock.
-This is used by `font-lock-default-unfontify-region' to decide
-what properties to clear before refontifying a region.
-Since it is more or less directly passed to `remove-text-properties',
-it should have the shape of a property list (i.e. every other element
-is ignored).")
-
-(defun font-lock-default-unfontify-region (beg end)
-  (save-buffer-state nil
-    (remove-text-properties
-     beg end (append
-	      font-lock-extra-managed-props
-	      (if font-lock-syntactic-keywords
-		  '(face nil syntax-table nil font-lock-multiline nil)
-		'(face nil font-lock-multiline nil))))))
-
-;; Called when any modification is made to buffer text.
-(defun font-lock-after-change-function (beg end old-len)
-  (let ((inhibit-point-motion-hooks t))
-    (save-excursion
-      (save-match-data
-	;; Rescan between start of lines enclosing the region.
-	(font-lock-fontify-region
-	 (progn (goto-char beg) (beginning-of-line) (point))
-	 (progn (goto-char end) (forward-line 1) (point)))))))
-
 (defun font-lock-fontify-block (&optional arg)
   "Fontify some lines the way `font-lock-fontify-buffer' would.
 The lines could be a function or paragraph, or a specified number of lines.
@@ -1309,7 +718,13 @@
 
 (define-key facemenu-keymap "\M-g" 'font-lock-fontify-block)
 
-;;; End of Fontification functions.
+;; The following must be rethought, since keywords can override fontification.
+;      ;; Now scan for keywords, but not if we are inside a comment now.
+;      (or (and (not font-lock-keywords-only)
+;	       (let ((state (parse-partial-sexp beg end nil nil
+;						font-lock-cache-state)))
+;		 (or (nth 4 state) (nth 7 state))))
+;	  (font-lock-fontify-keywords-region beg end))
 \f
 ;;; Additional text property functions.
 
@@ -1718,17 +1133,8 @@
 	(t
 	 (car keywords))))
 
-(defvar font-lock-set-defaults nil)	; Whether we have set up defaults.
-
-(defun font-lock-set-defaults ()
-  "Set fontification defaults appropriately for this mode.
-Sets various variables using `font-lock-defaults' (or, if nil, using
-`font-lock-defaults-alist') and `font-lock-maximum-decoration'."
+(defun font-lock-set-defaults-1 ()
   ;; Set fontification defaults iff not previously set.
-  (unless font-lock-set-defaults
-    (set (make-local-variable 'font-lock-set-defaults)		t)
-    (make-local-variable 'font-lock-fontified)
-    (make-local-variable 'font-lock-multiline)
     (let* ((defaults (or font-lock-defaults
 			 (cdr (assq major-mode font-lock-defaults-alist))))
 	   (keywords
@@ -1771,7 +1177,7 @@
 	(font-lock-add-keywords nil (car (car local)) (cdr (car local)))
 	(setq local (cdr local)))
       (when removed-keywords
-	(font-lock-remove-keywords nil removed-keywords)))))
+	(font-lock-remove-keywords nil removed-keywords))))
 \f
 ;;; Colour etc. support.
--- /dev/null	Wed Dec 31 19:00:00 1969
+++ font-core.el	Wed May  8 01:21:03 2002
@@ -0,0 +1,647 @@
+;;; font-core.el --- Core interface to font-lock
+
+;; Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999, 2000, 2001, 2002
+;;  Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+;; Keywords: languages, faces
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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 the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+;; Define core `font-lock' group.
+(defgroup font-lock nil
+  "Font Lock mode text highlighting package."
+  :link '(custom-manual "(emacs)Font Lock")
+  :link '(custom-manual "(elisp)Font Lock Mode")
+  :group 'faces)
+
+(defgroup font-lock-highlighting-faces nil
+  "Faces for highlighting text."
+  :prefix "font-lock-"
+  :group 'font-lock)
+
+(defgroup font-lock-extra-types nil
+  "Extra mode-specific type names for highlighting declarations."
+  :group 'font-lock)
+
+;; Define support mode groups here to impose `font-lock' group order.
+(defgroup fast-lock nil
+  "Font Lock support mode to cache fontification."
+  :link '(custom-manual "(emacs)Support Modes")
+  :load 'fast-lock
+  :group 'font-lock)
+
+(defgroup lazy-lock nil
+  "Font Lock support mode to fontify lazily."
+  :link '(custom-manual "(emacs)Support Modes")
+  :load 'lazy-lock
+  :group 'font-lock)
+
+(defgroup jit-lock nil
+  "Font Lock support mode to fontify just-in-time."
+  :link '(custom-manual "(emacs)Support Modes")
+  :version "21.1"
+  :load 'jit-lock
+  :group 'font-lock)
+\f
+;; User variables.
+
+(defcustom font-lock-maximum-size 256000
+  "*Maximum size of a buffer for buffer fontification.
+Only buffers less than this can be fontified when Font Lock mode is turned on.
+If nil, means size is irrelevant.
+If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
+where MAJOR-MODE is a symbol or t (meaning the default).  For example:
+ ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576))
+means that the maximum size is 250K for buffers in C or C++ modes, one megabyte
+for buffers in Rmail mode, and size is irrelevant otherwise."
+  :type '(choice (const :tag "none" nil)
+		 (integer :tag "size")
+		 (repeat :menu-tag "mode specific" :tag "mode specific"
+			 :value ((t . nil))
+			 (cons :tag "Instance"
+			       (radio :tag "Mode"
+				      (const :tag "all" t)
+				      (symbol :tag "name"))
+			       (radio :tag "Size"
+				      (const :tag "none" nil)
+				      (integer :tag "size")))))
+  :group 'font-lock)
+
+(defcustom font-lock-maximum-decoration t
+  "*Maximum decoration level for fontification.
+If nil, use the default decoration (typically the minimum available).
+If t, use the maximum decoration available.
+If a number, use that level of decoration (or if not available the maximum).
+If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
+where MAJOR-MODE is a symbol or t (meaning the default).  For example:
+ ((c-mode . t) (c++-mode . 2) (t . 1))
+means use the maximum decoration available for buffers in C mode, level 2
+decoration for buffers in C++ mode, and level 1 decoration otherwise."
+  :type '(choice (const :tag "default" nil)
+		 (const :tag "maximum" t)
+		 (integer :tag "level" 1)
+		 (repeat :menu-tag "mode specific" :tag "mode specific"
+			 :value ((t . t))
+			 (cons :tag "Instance"
+			       (radio :tag "Mode"
+				      (const :tag "all" t)
+				      (symbol :tag "name"))
+			       (radio :tag "Decoration"
+				      (const :tag "default" nil)
+				      (const :tag "maximum" t)
+				      (integer :tag "level" 1)))))
+  :group 'font-lock)
+
+(defcustom font-lock-verbose 0
+  "*If non-nil, means show status messages for buffer fontification.
+If a number, only buffers greater than this size have fontification messages."
+  :type '(choice (const :tag "never" nil)
+		 (other :tag "always" t)
+		 (integer :tag "size"))
+  :group 'font-lock)
+
+;; This variable is used by mode packages that support Font Lock mode by
+;; defining their own keywords to use for `font-lock-keywords'.  (The mode
+;; command should make it buffer-local and set it to provide the set up.)
+(defvar font-lock-defaults nil
+  "Defaults for Font Lock mode specified by the major mode.
+Defaults should be of the form:
+
+ (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
+
+KEYWORDS may be a symbol (a variable or function whose value is the keywords to
+use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
+syntactic fontification (strings and comments) is not performed.
+If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
+If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
+\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
+keyword and syntactic fontification (see `modify-syntax-entry').
+
+If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
+backwards outside any enclosing syntactic block, for syntactic fontification.
+Typical values are `beginning-of-line' (i.e., the start of the line is known to
+be outside a syntactic block), or `beginning-of-defun' for programming modes or
+`backward-paragraph' for textual modes (i.e., the mode-dependent function is
+known to move outside a syntactic block).  If nil, the beginning of the buffer
+is used as a position outside of a syntactic block, in the worst case.
+
+These item elements are used by Font Lock mode to set the variables
+`font-lock-keywords', `font-lock-keywords-only',
+`font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
+`font-lock-beginning-of-syntax-function', respectively.
+
+Further item elements are alists of the form (VARIABLE . VALUE) and are in no
+particular order.  Each VARIABLE is made buffer-local before set to VALUE.
+
+Currently, appropriate variables include `font-lock-mark-block-function'.
+If this is non-nil, it should be a function with no args used to mark any
+enclosing block of text, for fontification via \\[font-lock-fontify-block].
+Typical values are `mark-defun' for programming modes or `mark-paragraph' for
+textual modes (i.e., the mode-dependent function is known to put point and mark
+around a text block relevant to that mode).
+
+Other variables include that for syntactic keyword fontification,
+`font-lock-syntactic-keywords'
+and those for buffer-specialised fontification functions,
+`font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function',
+`font-lock-fontify-region-function', `font-lock-unfontify-region-function',
+`font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.")
+;;;###autoload
+(make-variable-buffer-local 'font-lock-defaults)
+
+(defvar font-lock-fontify-buffer-function 'font-lock-default-fontify-buffer
+  "Function to use for fontifying the buffer.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-unfontify-buffer-function 'font-lock-default-unfontify-buffer
+  "Function to use for unfontifying the buffer.
+This is used when turning off Font Lock mode.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
+  "Function to use for fontifying a region.
+It should take two args, the beginning and end of the region, and an optional
+third arg VERBOSE.  If non-nil, the function should print status messages.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
+  "Function to use for unfontifying a region.
+It should take two args, the beginning and end of the region.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-inhibit-thing-lock nil
+  "List of Font Lock mode related modes that should not be turned on.
+Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
+`lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-multiline nil
+  "Whether font-lock should cater to multiline keywords.
+If nil, don't try to handle multiline patterns.
+If t, always handle multiline patterns.
+If `undecided', don't try to handle multiline patterns until you see one.
+Major/minor modes can set this variable if they know which option applies.")
+
+(defvar font-lock-fontified nil)	; Whether we have fontified the buffer.
+(defvar font-lock-core-only nil)
+
+;; Font Lock mode.
+
+(define-minor-mode font-lock-mode
+  "Toggle Font Lock mode.
+With arg, turn Font Lock mode off if and only if arg is a non-positive
+number; if arg is nil, toggle Font Lock mode; anything else turns Font
+Lock on.
+\(Font Lock is also known as \"syntax highlighting\".)
+
+When Font Lock mode is enabled, text is fontified as you type it:
+
+ - Comments are displayed in `font-lock-comment-face';
+ - Strings are displayed in `font-lock-string-face';
+ - Certain other expressions are displayed in other faces according to the
+   value of the variable `font-lock-keywords'.
+
+To customize the faces (colors, fonts, etc.) used by Font Lock for
+fontifying different parts of buffer text, use \\[customize-face].
+
+You can enable Font Lock mode in any major mode automatically by turning on in
+the major mode's hook.  For example, put in your ~/.emacs:
+
+ (add-hook 'c-mode-hook 'turn-on-font-lock)
+
+Alternatively, you can use Global Font Lock mode to automagically turn on Font
+Lock mode in buffers whose major mode supports it and whose major mode is one
+of `font-lock-global-modes'.  For example, put in your ~/.emacs:
+
+ (global-font-lock-mode t)
+
+There are a number of support modes that may be used to speed up Font Lock mode
+in various ways, specified via the variable `font-lock-support-mode'.  Where
+major modes support different levels of fontification, you can use the variable
+`font-lock-maximum-decoration' to specify which level you generally prefer.
+When you turn Font Lock mode on/off the buffer is fontified/defontified, though
+fontification occurs only if the buffer is less than `font-lock-maximum-size'.
+
+For example, to specify that Font Lock mode use use Lazy Lock mode as a support
+mode and use maximum levels of fontification, put in your ~/.emacs:
+
+ (setq font-lock-support-mode 'lazy-lock-mode)
+ (setq font-lock-maximum-decoration t)
+
+To add your own highlighting for some major mode, and modify the highlighting
+selected automatically via the variable `font-lock-maximum-decoration', you can
+use `font-lock-add-keywords'.
+
+To fontify a buffer, without turning on Font Lock mode and regardless of buffer
+size, you can use \\[font-lock-fontify-buffer].
+
+To fontify a block (the function or paragraph containing point, or a number of
+lines around point), perhaps because modification on the current line caused
+syntactic change on other lines, you can use \\[font-lock-fontify-block].
+
+See the variable `font-lock-defaults-alist' for the Font Lock mode default
+settings.  You can set your own default settings for some mode, by setting a
+buffer local value for `font-lock-defaults', via its mode hook."
+  nil nil nil
+  ;; Don't turn on Font Lock mode if we don't have a display (we're running a
+  ;; batch job) or if the buffer is invisible (the name starts with a space).
+  (when (or noninteractive (eq (aref (buffer-name) 0) ?\ ))
+    (setq font-lock-mode nil))
+
+  ;; Turn on Font Lock mode.
+  (when font-lock-mode
+    (add-hook 'after-change-functions 'font-lock-after-change-function t t)
+    (font-lock-set-defaults)
+    (if font-lock-core-only
+	(font-lock-fontify-buffer)
+      (progn
+	(font-lock-turn-on-thing-lock)
+	;; Fontify the buffer if we have to.
+	(let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
+	  (cond (font-lock-fontified
+		 nil)
+		((or (null max-size) (> max-size (buffer-size)))
+		 (font-lock-fontify-buffer))
+		(font-lock-verbose
+		 (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
+			  (buffer-name))))))))
+  ;; Turn off Font Lock mode.
+  (unless font-lock-mode
+    (remove-hook 'after-change-functions 'font-lock-after-change-function t)
+    (font-lock-unfontify-buffer)
+    (unless font-lock-core-only
+      (font-lock-turn-off-thing-lock))))
+
+;;; Global Font Lock mode.
+
+;; A few people have hassled in the past for a way to make it easier to turn on
+;; Font Lock mode, without the user needing to know for which modes s/he has to
+;; turn it on, perhaps the same way hilit19.el/hl319.el does.  I've always
+;; balked at that way, as I see it as just re-moulding the same problem in
+;; another form.  That is; some person would still have to keep track of which
+;; modes (which may not even be distributed with Emacs) support Font Lock mode.
+;; The list would always be out of date.  And that person might have to be me.
+
+;; Implementation.
+;;
+;; In a previous discussion the following hack came to mind.  It is a gross
+;; hack, but it generally works.  We use the convention that major modes start
+;; by calling the function `kill-all-local-variables', which in turn runs
+;; functions on the hook variable `change-major-mode-hook'.  We attach our
+;; function `font-lock-change-major-mode' to that hook.  Of course, when this
+;; hook is run, the major mode is in the process of being changed and we do not
+;; know what the final major mode will be.  So, `font-lock-change-major-mode'
+;; only (a) notes the name of the current buffer, and (b) adds our function
+;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
+;; `post-command-hook' (for buffers that are not visiting files).  By the time
+;; the functions on the first of these hooks to be run are run, the new major
+;; mode is assumed to be in place.  This way we get a Font Lock function run
+;; when a major mode is turned on, without knowing major modes or their hooks.
+;;
+;; Naturally this requires that (a) major modes run `kill-all-local-variables',
+;; as they are supposed to do, and (b) the major mode is in place after the
+;; file is visited or the command that ran `kill-all-local-variables' has
+;; finished, whichever the sooner.  Arguably, any major mode that does not
+;; follow the convension (a) is broken, and I can't think of any reason why (b)
+;; would not be met (except `gnudoit' on non-files).  However, it is not clean.
+;;
+;; Probably the cleanest solution is to have each major mode function run some
+;; hook, e.g., `major-mode-hook', but maybe implementing that change is
+;; impractical.  I am personally against making `setq' a macro or be advised,
+;; or have a special function such as `set-major-mode', but maybe someone can
+;; come up with another solution?
+
+;; User interface.
+;;
+;; Although Global Font Lock mode is a pseudo-mode, I think that the user
+;; interface should conform to the usual Emacs convention for modes, i.e., a
+;; command to toggle the feature (`global-font-lock-mode') with a variable for
+;; finer control of the mode's behaviour (`font-lock-global-modes').
+;;
+;; The feature should not be enabled by loading font-lock.el, since other
+;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
+;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
+;; turned on everywhere.  That would not be intuitive or informative because
+;; loading a file tells you nothing about the feature or how to control it.  It
+;; would also be contrary to the Principle of Least Surprise.  sm.
+
+(defcustom font-lock-global-modes t
+  "*Modes for which Font Lock mode is automagically turned on.
+Global Font Lock mode is controlled by the command `global-font-lock-mode'.
+If nil, means no modes have Font Lock mode automatically turned on.
+If t, all modes that support Font Lock mode have it automatically turned on.
+If a list, it should be a list of `major-mode' symbol names for which Font Lock
+mode should be automatically turned on.  The sense of the list is negated if it
+begins with `not'.  For example:
+ (c-mode c++-mode)
+means that Font Lock mode is turned on for buffers in C and C++ modes only."
+  :type '(choice (const :tag "none" nil)
+		 (const :tag "all" t)
+		 (set :menu-tag "mode specific" :tag "modes"
+		      :value (not)
+		      (const :tag "Except" not)
+		      (repeat :inline t (symbol :tag "mode"))))
+  :group 'font-lock)
+
+(easy-mmode-define-global-mode
+ global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
+ :extra-args (dummy))
+
+(defun turn-on-font-lock-if-enabled ()
+  (when (and (or font-lock-defaults
+		 (assq major-mode font-lock-defaults-alist))
+	     (or (eq font-lock-global-modes t)
+		 (if (eq (car-safe font-lock-global-modes) 'not)
+		     (not (memq major-mode (cdr font-lock-global-modes)))
+		   (memq major-mode font-lock-global-modes))))
+    (let (inhibit-quit)
+      (turn-on-font-lock))))
+
+;;; End of Global Font Lock mode.
+
+
+;;; Font Lock Support mode.
+
+;; This is the code used to interface font-lock.el with any of its add-on
+;; packages, and provide the user interface.  Packages that have their own
+;; local buffer fontification functions (see below) may have to call
+;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
+;; themselves.
+
+(defcustom font-lock-support-mode 'jit-lock-mode
+  "*Support mode for Font Lock mode.
+Support modes speed up Font Lock mode by being choosy about when fontification
+occurs.  Known support modes are Fast Lock mode (symbol `fast-lock-mode'),
+Lazy Lock mode (symbol `lazy-lock-mode'), and Just-in-time Lock mode (symbol
+`jit-lock-mode'.  See those modes for more info.
+If nil, means support for Font Lock mode is never performed.
+If a symbol, use that support mode.
+If a list, each element should be of the form (MAJOR-MODE . SUPPORT-MODE),
+where MAJOR-MODE is a symbol or t (meaning the default).  For example:
+ ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
+means that Fast Lock mode is used to support Font Lock mode for buffers in C or
+C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
+
+The value of this variable is used when Font Lock mode is turned on."
+  :type '(choice (const :tag "none" nil)
+		 (const :tag "fast lock" fast-lock-mode)
+		 (const :tag "lazy lock" lazy-lock-mode)
+		 (const :tag "jit lock" jit-lock-mode)
+		 (repeat :menu-tag "mode specific" :tag "mode specific"
+			 :value ((t . jit-lock-mode))
+			 (cons :tag "Instance"
+			       (radio :tag "Mode"
+				      (const :tag "all" t)
+				      (symbol :tag "name"))
+			       (radio :tag "Support"
+				      (const :tag "none" nil)
+				      (const :tag "fast lock" fast-lock-mode)
+				      (const :tag "lazy lock" lazy-lock-mode)
+				      (const :tag "JIT lock" jit-lock-mode)))
+			 ))
+  :version "21.1"
+  :group 'font-lock)
+
+(defvar fast-lock-mode nil)
+(defvar lazy-lock-mode nil)
+(defvar jit-lock-mode nil)
+
+(defun font-lock-turn-on-thing-lock ()
+  (let ((thing-mode (font-lock-value-in-major-mode font-lock-support-mode)))
+    (cond ((eq thing-mode 'fast-lock-mode)
+	   (fast-lock-mode t))
+	  ((eq thing-mode 'lazy-lock-mode)
+	   (lazy-lock-mode t))
+	  ((eq thing-mode 'jit-lock-mode)
+	   ;; Prepare for jit-lock
+	   (remove-hook 'after-change-functions
+			'font-lock-after-change-function t)
+	   (set (make-local-variable 'font-lock-fontify-buffer-function)
+		'jit-lock-refontify)
+	   ;; Don't fontify eagerly (and don't abort is the buffer is large).
+	   (set (make-local-variable 'font-lock-fontified) t)
+	   ;; Use jit-lock.
+	   (jit-lock-register 'font-lock-fontify-region
+			      (not font-lock-keywords-only))))))
+
+(defun font-lock-turn-off-thing-lock ()
+  (cond (fast-lock-mode
+	 (fast-lock-mode -1))
+	(jit-lock-mode
+	 (jit-lock-unregister 'font-lock-fontify-region)
+	 ;; Reset local vars to the non-jit-lock case.
+	 (kill-local-variable 'font-lock-fontify-buffer-function))
+	(lazy-lock-mode
+	 (lazy-lock-mode -1))))
+
+(defun font-lock-after-fontify-buffer ()
+  (cond (fast-lock-mode
+	 (fast-lock-after-fontify-buffer))
+	;; Useless now that jit-lock intercepts font-lock-fontify-buffer.  -sm
+	;; (jit-lock-mode
+	;;  (jit-lock-after-fontify-buffer))
+	(lazy-lock-mode
+	 (lazy-lock-after-fontify-buffer))))
+
+(defun font-lock-after-unfontify-buffer ()
+  (cond (fast-lock-mode
+	 (fast-lock-after-unfontify-buffer))
+	;; Useless as well.  It's only called when:
+	;; - turning off font-lock: it does not matter if we leave spurious
+	;;   `fontified' text props around since jit-lock-mode is also off.
+	;; - font-lock-default-fontify-buffer fails: this is not run
+	;;   any more anyway.   -sm
+	;;
+	;; (jit-lock-mode
+	;;  (jit-lock-after-unfontify-buffer))
+	(lazy-lock-mode
+	 (lazy-lock-after-unfontify-buffer))))
+
+;;; End of Font Lock Support mode.
+
+;;; Core fontification functions.
+
+;; Rather than the function, e.g., `font-lock-fontify-region' containing the
+;; code to fontify a region, the function runs the function whose name is the
+;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,
+;; the value of this variable is, e.g., `font-lock-default-fontify-region'
+;; which does contain the code to fontify a region.  However, the value of the
+;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
+;; do anything.  The indirection of the fontification functions gives major
+;; modes the capability of modifying the way font-lock.el fontifies.  Major
+;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
+;; via the variable `font-lock-defaults'.
+;;
+;; For example, Rmail mode sets the variable `font-lock-defaults' so that
+;; font-lock.el uses its own function for buffer fontification.  This function
+;; makes fontification be on a message-by-message basis and so visiting an
+;; RMAIL file is much faster.  A clever implementation of the function might
+;; fontify the headers differently than the message body.  (It should, and
+;; correspondingly for Mail mode, but I can't be bothered to do the work.  Can
+;; you?)  This hints at a more interesting use...
+;;
+;; Languages that contain text normally contained in different major modes
+;; could define their own fontification functions that treat text differently
+;; depending on its context.  For example, Perl mode could arrange that here
+;; docs are fontified differently than Perl code.  Or Yacc mode could fontify
+;; rules one way and C code another.  Neat!
+;;
+;; A further reason to use the fontification indirection feature is when the
+;; default syntactual fontification, or the default fontification in general,
+;; is not flexible enough for a particular major mode.  For example, perhaps
+;; comments are just too hairy for `font-lock-fontify-syntactically-region' to
+;; cope with.  You need to write your own version of that function, e.g.,
+;; `hairy-fontify-syntactically-region', and make your own version of
+;; `hairy-fontify-region' call that function before calling
+;; `font-lock-fontify-keywords-region' for the normal regexp fontification
+;; pass.  And Hairy mode would set `font-lock-defaults' so that font-lock.el
+;; would call your region fontification function instead of its own.  For
+;; example, TeX modes could fontify {\foo ...} and \bar{...}  etc. multi-line
+;; directives correctly and cleanly.  (It is the same problem as fontifying
+;; multi-line strings and comments; regexps are not appropriate for the job.)
+
+(defun font-lock-fontify-buffer ()
+  "Fontify the current buffer the way the function `font-lock-mode' would."
+  (interactive)
+  (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
+    (funcall font-lock-fontify-buffer-function)))
+
+(defun font-lock-unfontify-buffer ()
+  (funcall font-lock-unfontify-buffer-function))
+
+(defun font-lock-fontify-region (beg end &optional loudly)
+  (funcall font-lock-fontify-region-function beg end loudly))
+
+(defun font-lock-unfontify-region (beg end)
+  (funcall font-lock-unfontify-region-function beg end))
+
+(defun font-lock-default-fontify-buffer ()
+  (let ((verbose (if (numberp font-lock-verbose)
+		     (> (buffer-size) font-lock-verbose)
+		   font-lock-verbose)))
+    (with-temp-message
+	(when verbose
+	  (format "Fontifying %s..." (buffer-name)))
+      ;; Make sure we have the right `font-lock-keywords' etc.
+      (unless font-lock-mode
+	(font-lock-set-defaults))
+      ;; Make sure we fontify etc. in the whole buffer.
+      (save-restriction
+	(widen)
+	(condition-case nil
+	    (save-excursion
+	      (save-match-data
+		(font-lock-fontify-region (point-min) (point-max) verbose)
+		(font-lock-after-fontify-buffer)
+		(setq font-lock-fontified t)))
+	  ;; We don't restore the old fontification, so it's best to unfontify.
+	  (quit (font-lock-unfontify-buffer)))))))
+
+(defun font-lock-default-unfontify-buffer ()
+  ;; Make sure we unfontify etc. in the whole buffer.
+  (save-restriction
+    (widen)
+    (font-lock-unfontify-region (point-min) (point-max))
+    (font-lock-after-unfontify-buffer)
+    (setq font-lock-fontified nil)))
+
+\f
+(eval-when-compile
+  ;;
+  ;; We don't do this at the top-level as we only use non-autoloaded macros.
+  (require 'cl)
+  ;;
+  ;; Borrowed from lazy-lock.el.
+  ;; We use this to preserve or protect things when modifying text properties.
+  (defmacro save-buffer-state (varlist &rest body)
+    "Bind variables according to VARLIST and eval BODY restoring buffer state."
+    (let ((modified (make-symbol "modified")))
+      `(let* ,(append varlist
+		      `((,modified (buffer-modified-p))
+			(buffer-undo-list t)
+			(inhibit-read-only t)
+			(inhibit-point-motion-hooks t)
+			(inhibit-modification-hooks t)
+			deactivate-mark
+			buffer-file-name
+			buffer-file-truename))
+	 (progn
+	   ,@body)
+	 (unless ,modified
+	   (restore-buffer-modified-p nil)))))
+  (put 'save-buffer-state 'lisp-indent-function 1)
+  (def-edebug-spec save-buffer-state let)
+  ;;
+  ;; Shut up the byte compiler.
+  (defvar font-lock-face-attributes))	; Obsolete but respected if set.
+
+(defvar font-lock-extra-managed-props nil
+  "Additional text properties managed by font-lock.
+This is used by `font-lock-default-unfontify-region' to decide
+what properties to clear before refontifying a region.
+Since it is more or less directly passed to `remove-text-properties',
+it should have the shape of a property list (i.e. every other element
+is ignored).")
+
+(defun font-lock-default-unfontify-region (beg end)
+  (save-buffer-state nil
+    (remove-text-properties
+     beg end (append
+	      font-lock-extra-managed-props
+	      (if font-lock-syntactic-keywords
+		  '(face nil syntax-table nil font-lock-multiline nil)
+		'(face nil font-lock-multiline nil))))))
+
+;; Called when any modification is made to buffer text.
+(defun font-lock-after-change-function (beg end old-len)
+  (let ((inhibit-point-motion-hooks t))
+    (save-excursion
+      (save-match-data
+	;; Rescan between start of lines enclosing the region.
+	(font-lock-fontify-region
+	 (progn (goto-char beg) (beginning-of-line) (point))
+	 (progn (goto-char end) (forward-line 1) (point)))))))
+
+;;; End of Fontification functions.
+
+(defvar font-lock-set-defaults nil)	; Whether we have set up defaults.
+
+(defun font-lock-set-defaults ()
+  "Set fontification defaults appropriately for this mode.
+Sets various variables using `font-lock-defaults' (or, if nil, using
+`font-lock-defaults-alist') and `font-lock-maximum-decoration'."
+  (unless font-lock-set-defaults
+    (set (make-local-variable 'font-lock-set-defaults) t)
+    (make-local-variable 'font-lock-fontified)
+    (make-local-variable 'font-lock-multiline)
+    (let ((options (nthcdr 5 font-lock-defaults)))
+      ;; Detect if this is a simple mode, which doesn't use any
+      ;; syntactic fontification functions.
+      (if (and (assq 'font-lock-fontify-region-function options)
+	       (assq 'font-lock-core-only options))
+	  (dolist (x (nthcdr 5 font-lock-defaults))
+	    (set (make-local-variable (car x)) (cdr x)))
+	(require 'font-lock)
+	(font-lock-set-defaults-1)))))
+
+(provide 'font-core)
+
+;;; font-core.el ends here
+

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-08  6:05                               ` Colin Walters
@ 2002-05-08  6:50                                 ` Miles Bader
  2002-05-08  7:36                                   ` Colin Walters
  0 siblings, 1 reply; 82+ messages in thread
From: Miles Bader @ 2002-05-08  6:50 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@gnu.org> writes:
> Miles: You objected to putting special text properties on the buffer
> text, and then fontifying on them later, correct?  Unfortunately this
> is the only way I can think of to implement fontification for special
> buffers, such that typing M-x font-lock-mode will always do the Right
> Thing.

First of all, I think you're being overly aggressive about all this --
the status quo is _not a problem_.  The mailing lists are not
overflowing with bug reports about this issue, and I have yet to hear a
single clamor.

If we decide to adopt a generalized font-lock user interface, and it
satisfies all the objections made, it really doesn't matter if some
special modes take a while to be adapted to it.  More consistency is
usually a good thing, especially when it's easy to do, but there's
really no need for immediate 100% coverage in this case.

For special modes that add currently add face properties to directly the
buffer, and which might have a hard time implementing an on-demand
`font-lock-refontify-function' (perhaps they don't maintain enough
context), why not just add a variable that tells the redisplay engine to
ignore face properties for the buffer (it should probably keep paying
attention to overlays)?  That'd make the whole thing trivial in many
cases.

-Miles
-- 
Would you like fries with that?

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-08  6:50                                 ` Miles Bader
@ 2002-05-08  7:36                                   ` Colin Walters
  2002-05-08  7:48                                     ` Miles Bader
  2002-05-08  8:57                                     ` Colin Walters
  0 siblings, 2 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-08  7:36 UTC (permalink / raw)


On Wed, 2002-05-08 at 02:50, Miles Bader wrote:

> why not just add a variable that tells the redisplay engine to
> ignore face properties for the buffer (it should probably keep paying
> attention to overlays)?  That'd make the whole thing trivial in many
> cases.

And then M-x font-lock-mode would toggle that variable?  I can't think
of a flaw in that solution.  Yes; I definitely like this idea more than
my patch.

The only problem really is that portable code wouldn't be able to use
it.  That's probably not a big deal.

I will try to implement this.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-08  7:36                                   ` Colin Walters
@ 2002-05-08  7:48                                     ` Miles Bader
  2002-05-08  8:57                                     ` Colin Walters
  1 sibling, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-08  7:48 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@debian.org> writes:
> > why not just add a variable that tells the redisplay engine to
> > ignore face properties for the buffer (it should probably keep paying
> > attention to overlays)?
> 
> And then M-x font-lock-mode would toggle that variable?  I can't think
> of a flaw in that solution.  Yes; I definitely like this idea more than
> my patch.

The biggest flaw that I can think of is that many modes use overlays to
add faces, and I'm not sure if it's a good idea to turn them off.

-Miles
-- 
"1971 pickup truck; will trade for guns"

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-08  7:36                                   ` Colin Walters
  2002-05-08  7:48                                     ` Miles Bader
@ 2002-05-08  8:57                                     ` Colin Walters
  2002-05-08 13:14                                       ` Stefan Monnier
  1 sibling, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-08  8:57 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 2244 bytes --]

On Wed, 2002-05-08 at 03:36, Colin Walters wrote:

> I will try to implement this.

How about the following?

lisp/ChangeLog:
2002-05-08  Colin Walters  <walters@gnu.org>

	* font-lock.el (font-lock, font-lock-defaults-alist)
	(font-lock-highlighting-faces, font-lock-extra-types)
	(fast-lock, lazy-lock, jit-lock, font-lock-maximum-size)
	(font-lock-maximum-decoration, font-lock-verbose)
	(font-lock-defaults, font-lock-fontify-buffer-function)
	(font-lock-unfontify-buffer-function)
	(font-lock-fontify-region-function)
	(font-lock-unfontify-region-function)
	(font-lock-inhibit-thing-lock, font-lock-multiline)
	(font-lock-fontified, save-buffer-state)
	(font-lock-face-attributes, font-lock-mode)
	(turn-on-font-lock, global-font-lock-mode)
	(font-lock-global-modes, font-lock-support-mode)
	(fast-lock-mode, lazy-lock-mode, jit-lock-mode)
	(font-lock-turn-on-thing-lock, font-lock-turn-off-thing-lock)
	(font-lock-after-fontify-buffer, font-lock-after-unfontify-buffer)
	(font-lock-fontify-buffer, font-lock-unfontify-buffer)
	(font-lock-fontify-region, font-lock-unfontify-region)
	(font-lock-default-fontify-buffer)
	(font-lock-default-unfontify-buffer)
	(font-lock-default-unfontify-region)
	(font-lock-after-change-function):
	Moved to font-core.el.
	(font-lock-set-defaults): Renamed to `font-lock-set-defaults-1';
	partially moved to font-core.el.

	* replace.el (occur-mode-hooks): New variable.
	(occur-mode): Set `font-lock-core-only'.  Don't set
	`font-lock-fontify-region-function'.  Run `occur-mode-hooks' too.
	(occur-1): Pass faces to `occur-engine'.
	(occur-fontify-on-property): Deleted.
	(occur-fontify-region-function): Deleted.

	* font-core.el: New file, with functions broken out from
	font-lock.el.
	(font-lock-core-only): New variable.
	(font-lock-mode): If `font-lock-core-only' is non-nil, don't
	enable a font-lock support mode.
	(font-lock-set-defaults): Partially moved here from font-lock.el.
	We try to only load all of font-lock.el if the mode doesn't set
	`font-lock-core-only'.

src/ChangeLog:
2002-05-08  Colin Walters  <walters@gnu.org>

	* xfaces.c (Vinhibit_text_property_faces): New variable.
	(face_at_buffer_position): Respect it.
	(syms_of_xfaces) <Vinhibit_text_property_faces>: DEFVAR_LISP.





[-- Attachment #2: font-lock.patch --]
[-- Type: text/plain, Size: 67726 bytes --]

--- font-lock.el.~1.195.~	Tue May  7 18:20:10 2002
+++ font-lock.el	Wed May  8 04:48:16 2002
@@ -208,99 +208,8 @@
 ;;; Code:
 
 (require 'syntax)
+(require 'font-core)
 
-;; Define core `font-lock' group.
-(defgroup font-lock nil
-  "Font Lock mode text highlighting package."
-  :link '(custom-manual "(emacs)Font Lock")
-  :link '(custom-manual "(elisp)Font Lock Mode")
-  :group 'faces)
-
-(defgroup font-lock-highlighting-faces nil
-  "Faces for highlighting text."
-  :prefix "font-lock-"
-  :group 'font-lock)
-
-(defgroup font-lock-extra-types nil
-  "Extra mode-specific type names for highlighting declarations."
-  :group 'font-lock)
-
-;; Define support mode groups here to impose `font-lock' group order.
-(defgroup fast-lock nil
-  "Font Lock support mode to cache fontification."
-  :link '(custom-manual "(emacs)Support Modes")
-  :load 'fast-lock
-  :group 'font-lock)
-
-(defgroup lazy-lock nil
-  "Font Lock support mode to fontify lazily."
-  :link '(custom-manual "(emacs)Support Modes")
-  :load 'lazy-lock
-  :group 'font-lock)
-
-(defgroup jit-lock nil
-  "Font Lock support mode to fontify just-in-time."
-  :link '(custom-manual "(emacs)Support Modes")
-  :version "21.1"
-  :load 'jit-lock
-  :group 'font-lock)
-\f
-;; User variables.
-
-(defcustom font-lock-maximum-size 256000
-  "*Maximum size of a buffer for buffer fontification.
-Only buffers less than this can be fontified when Font Lock mode is turned on.
-If nil, means size is irrelevant.
-If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
-where MAJOR-MODE is a symbol or t (meaning the default).  For example:
- ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576))
-means that the maximum size is 250K for buffers in C or C++ modes, one megabyte
-for buffers in Rmail mode, and size is irrelevant otherwise."
-  :type '(choice (const :tag "none" nil)
-		 (integer :tag "size")
-		 (repeat :menu-tag "mode specific" :tag "mode specific"
-			 :value ((t . nil))
-			 (cons :tag "Instance"
-			       (radio :tag "Mode"
-				      (const :tag "all" t)
-				      (symbol :tag "name"))
-			       (radio :tag "Size"
-				      (const :tag "none" nil)
-				      (integer :tag "size")))))
-  :group 'font-lock)
-
-(defcustom font-lock-maximum-decoration t
-  "*Maximum decoration level for fontification.
-If nil, use the default decoration (typically the minimum available).
-If t, use the maximum decoration available.
-If a number, use that level of decoration (or if not available the maximum).
-If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
-where MAJOR-MODE is a symbol or t (meaning the default).  For example:
- ((c-mode . t) (c++-mode . 2) (t . 1))
-means use the maximum decoration available for buffers in C mode, level 2
-decoration for buffers in C++ mode, and level 1 decoration otherwise."
-  :type '(choice (const :tag "default" nil)
-		 (const :tag "maximum" t)
-		 (integer :tag "level" 1)
-		 (repeat :menu-tag "mode specific" :tag "mode specific"
-			 :value ((t . t))
-			 (cons :tag "Instance"
-			       (radio :tag "Mode"
-				      (const :tag "all" t)
-				      (symbol :tag "name"))
-			       (radio :tag "Decoration"
-				      (const :tag "default" nil)
-				      (const :tag "maximum" t)
-				      (integer :tag "level" 1)))))
-  :group 'font-lock)
-
-(defcustom font-lock-verbose 0
-  "*If non-nil, means show status messages for buffer fontification.
-If a number, only buffers greater than this size have fontification messages."
-  :type '(choice (const :tag "never" nil)
-		 (other :tag "always" t)
-		 (integer :tag "size"))
-  :group 'font-lock)
 \f
 
 ;; Originally these variable values were face names such as `bold' etc.
@@ -446,106 +355,6 @@
 Be careful when composing regexps for this list; a poorly written pattern can
 dramatically slow things down!")
 
-;; This variable is used by mode packages that support Font Lock mode by
-;; defining their own keywords to use for `font-lock-keywords'.  (The mode
-;; command should make it buffer-local and set it to provide the set up.)
-(defvar font-lock-defaults nil
-  "Defaults for Font Lock mode specified by the major mode.
-Defaults should be of the form:
-
- (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
-
-KEYWORDS may be a symbol (a variable or function whose value is the keywords to
-use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
-syntactic fontification (strings and comments) is not performed.
-If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
-If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
-\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
-keyword and syntactic fontification (see `modify-syntax-entry').
-
-If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
-backwards outside any enclosing syntactic block, for syntactic fontification.
-Typical values are `beginning-of-line' (i.e., the start of the line is known to
-be outside a syntactic block), or `beginning-of-defun' for programming modes or
-`backward-paragraph' for textual modes (i.e., the mode-dependent function is
-known to move outside a syntactic block).  If nil, the beginning of the buffer
-is used as a position outside of a syntactic block, in the worst case.
-
-These item elements are used by Font Lock mode to set the variables
-`font-lock-keywords', `font-lock-keywords-only',
-`font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
-`font-lock-beginning-of-syntax-function', respectively.
-
-Further item elements are alists of the form (VARIABLE . VALUE) and are in no
-particular order.  Each VARIABLE is made buffer-local before set to VALUE.
-
-Currently, appropriate variables include `font-lock-mark-block-function'.
-If this is non-nil, it should be a function with no args used to mark any
-enclosing block of text, for fontification via \\[font-lock-fontify-block].
-Typical values are `mark-defun' for programming modes or `mark-paragraph' for
-textual modes (i.e., the mode-dependent function is known to put point and mark
-around a text block relevant to that mode).
-
-Other variables include that for syntactic keyword fontification,
-`font-lock-syntactic-keywords'
-and those for buffer-specialised fontification functions,
-`font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function',
-`font-lock-fontify-region-function', `font-lock-unfontify-region-function',
-`font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.")
-;;;###autoload
-(make-variable-buffer-local 'font-lock-defaults)
-
-;; This variable is used where font-lock.el itself supplies the keywords.
-(defvar font-lock-defaults-alist
-  (let (;; We use `beginning-of-defun', rather than nil, for SYNTAX-BEGIN.
-	;; Thus the calculation of the cache is usually faster but not
-	;; infallible, so we risk mis-fontification.  sm.
-	(c-mode-defaults
-	 '((c-font-lock-keywords c-font-lock-keywords-1
-	    c-font-lock-keywords-2 c-font-lock-keywords-3)
-	   nil nil ((?_ . "w")) beginning-of-defun
-	   (font-lock-syntactic-face-function
-	    . c-font-lock-syntactic-face-function)
-	   (font-lock-mark-block-function . mark-defun)))
-	(c++-mode-defaults
-	 '((c++-font-lock-keywords c++-font-lock-keywords-1
-	    c++-font-lock-keywords-2 c++-font-lock-keywords-3)
-	   nil nil ((?_ . "w")) beginning-of-defun
-	   (font-lock-syntactic-face-function
-	    . c-font-lock-syntactic-face-function)
-	   (font-lock-mark-block-function . mark-defun)))
-	(objc-mode-defaults
-	 '((objc-font-lock-keywords objc-font-lock-keywords-1
-	    objc-font-lock-keywords-2 objc-font-lock-keywords-3)
-	   nil nil ((?_ . "w") (?$ . "w")) nil
-	   (font-lock-syntactic-face-function
-	    . c-font-lock-syntactic-face-function)
-	   (font-lock-mark-block-function . mark-defun)))
-	(java-mode-defaults
-	 '((java-font-lock-keywords java-font-lock-keywords-1
-	    java-font-lock-keywords-2 java-font-lock-keywords-3)
-	   nil nil ((?_ . "w") (?$ . "w")) nil
-	   (font-lock-syntactic-face-function
-	    . java-font-lock-syntactic-face-function)
-	   (font-lock-mark-block-function . mark-defun))))
-    (list
-     (cons 'c-mode			c-mode-defaults)
-     (cons 'c++-mode			c++-mode-defaults)
-     (cons 'objc-mode			objc-mode-defaults)
-     (cons 'java-mode			java-mode-defaults)))
-  "Alist of fall-back Font Lock defaults for major modes.
-
-This variable should not be used any more.
-Set the buffer-local `font-lock-keywords' in the major mode instead.
-
-Each item should be a list of the form:
-
- (MAJOR-MODE . FONT-LOCK-DEFAULTS)
-
-where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default
-settings.  See the variable `font-lock-defaults', which takes precedence.")
-(make-obsolete-variable 'font-lock-defaults-alist 'font-lock-defaults)
-
 (defvar font-lock-keywords-alist nil
   "*Alist of `font-lock-keywords' local to a `major-mode'.
 This is normally set via `font-lock-add-keywords' and
@@ -632,153 +441,6 @@
 enclosing textual block and mark at the end.
 This is normally set via `font-lock-defaults'.")
 
-(defvar font-lock-fontify-buffer-function 'font-lock-default-fontify-buffer
-  "Function to use for fontifying the buffer.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-unfontify-buffer-function 'font-lock-default-unfontify-buffer
-  "Function to use for unfontifying the buffer.
-This is used when turning off Font Lock mode.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
-  "Function to use for fontifying a region.
-It should take two args, the beginning and end of the region, and an optional
-third arg VERBOSE.  If non-nil, the function should print status messages.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
-  "Function to use for unfontifying a region.
-It should take two args, the beginning and end of the region.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-inhibit-thing-lock nil
-  "List of Font Lock mode related modes that should not be turned on.
-Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
-`lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-multiline nil
-  "Whether font-lock should cater to multiline keywords.
-If nil, don't try to handle multiline patterns.
-If t, always handle multiline patterns.
-If `undecided', don't try to handle multiline patterns until you see one.
-Major/minor modes can set this variable if they know which option applies.")
-
-(defvar font-lock-fontified nil)	; Whether we have fontified the buffer.
-\f
-;; Font Lock mode.
-
-(eval-when-compile
-  ;;
-  ;; We don't do this at the top-level as we only use non-autoloaded macros.
-  (require 'cl)
-  ;;
-  ;; Borrowed from lazy-lock.el.
-  ;; We use this to preserve or protect things when modifying text properties.
-  (defmacro save-buffer-state (varlist &rest body)
-    "Bind variables according to VARLIST and eval BODY restoring buffer state."
-    (let ((modified (make-symbol "modified")))
-      `(let* ,(append varlist
-		      `((,modified (buffer-modified-p))
-			(buffer-undo-list t)
-			(inhibit-read-only t)
-			(inhibit-point-motion-hooks t)
-			(inhibit-modification-hooks t)
-			deactivate-mark
-			buffer-file-name
-			buffer-file-truename))
-	 (progn
-	   ,@body)
-	 (unless ,modified
-	   (restore-buffer-modified-p nil)))))
-  (put 'save-buffer-state 'lisp-indent-function 1)
-  (def-edebug-spec save-buffer-state let)
-  ;;
-  ;; Shut up the byte compiler.
-  (defvar font-lock-face-attributes))	; Obsolete but respected if set.
-
-;;;###autoload
-(define-minor-mode font-lock-mode
-  "Toggle Font Lock mode.
-With arg, turn Font Lock mode off if and only if arg is a non-positive
-number; if arg is nil, toggle Font Lock mode; anything else turns Font
-Lock on.
-\(Font Lock is also known as \"syntax highlighting\".)
-
-When Font Lock mode is enabled, text is fontified as you type it:
-
- - Comments are displayed in `font-lock-comment-face';
- - Strings are displayed in `font-lock-string-face';
- - Certain other expressions are displayed in other faces according to the
-   value of the variable `font-lock-keywords'.
-
-To customize the faces (colors, fonts, etc.) used by Font Lock for
-fontifying different parts of buffer text, use \\[customize-face].
-
-You can enable Font Lock mode in any major mode automatically by turning on in
-the major mode's hook.  For example, put in your ~/.emacs:
-
- (add-hook 'c-mode-hook 'turn-on-font-lock)
-
-Alternatively, you can use Global Font Lock mode to automagically turn on Font
-Lock mode in buffers whose major mode supports it and whose major mode is one
-of `font-lock-global-modes'.  For example, put in your ~/.emacs:
-
- (global-font-lock-mode t)
-
-There are a number of support modes that may be used to speed up Font Lock mode
-in various ways, specified via the variable `font-lock-support-mode'.  Where
-major modes support different levels of fontification, you can use the variable
-`font-lock-maximum-decoration' to specify which level you generally prefer.
-When you turn Font Lock mode on/off the buffer is fontified/defontified, though
-fontification occurs only if the buffer is less than `font-lock-maximum-size'.
-
-For example, to specify that Font Lock mode use use Lazy Lock mode as a support
-mode and use maximum levels of fontification, put in your ~/.emacs:
-
- (setq font-lock-support-mode 'lazy-lock-mode)
- (setq font-lock-maximum-decoration t)
-
-To add your own highlighting for some major mode, and modify the highlighting
-selected automatically via the variable `font-lock-maximum-decoration', you can
-use `font-lock-add-keywords'.
-
-To fontify a buffer, without turning on Font Lock mode and regardless of buffer
-size, you can use \\[font-lock-fontify-buffer].
-
-To fontify a block (the function or paragraph containing point, or a number of
-lines around point), perhaps because modification on the current line caused
-syntactic change on other lines, you can use \\[font-lock-fontify-block].
-
-See the variable `font-lock-defaults-alist' for the Font Lock mode default
-settings.  You can set your own default settings for some mode, by setting a
-buffer local value for `font-lock-defaults', via its mode hook."
-  nil nil nil
-  ;; Don't turn on Font Lock mode if we don't have a display (we're running a
-  ;; batch job) or if the buffer is invisible (the name starts with a space).
-  (when (or noninteractive (eq (aref (buffer-name) 0) ?\ ))
-    (setq font-lock-mode nil))
-
-  ;; Turn on Font Lock mode.
-  (when font-lock-mode
-    (add-hook 'after-change-functions 'font-lock-after-change-function t t)
-    (font-lock-set-defaults)
-    (font-lock-turn-on-thing-lock)
-    ;; Fontify the buffer if we have to.
-    (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
-      (cond (font-lock-fontified
-	     nil)
-	    ((or (null max-size) (> max-size (buffer-size)))
-	     (font-lock-fontify-buffer))
-	    (font-lock-verbose
-	     (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
-		      (buffer-name))))))
-  ;; Turn off Font Lock mode.
-  (unless font-lock-mode
-    (remove-hook 'after-change-functions 'font-lock-after-change-function t)
-    (font-lock-unfontify-buffer)
-    (font-lock-turn-off-thing-lock)))
-
 ;;;###autoload
 (defun turn-on-font-lock ()
   "Turn on Font Lock mode (only if the terminal can display it)."
@@ -937,279 +599,10 @@
 			 (delete (font-lock-compile-keyword keyword)
 				 font-lock-keywords)))))))
 \f
-;;; Global Font Lock mode.
-
-;; A few people have hassled in the past for a way to make it easier to turn on
-;; Font Lock mode, without the user needing to know for which modes s/he has to
-;; turn it on, perhaps the same way hilit19.el/hl319.el does.  I've always
-;; balked at that way, as I see it as just re-moulding the same problem in
-;; another form.  That is; some person would still have to keep track of which
-;; modes (which may not even be distributed with Emacs) support Font Lock mode.
-;; The list would always be out of date.  And that person might have to be me.
-
-;; Implementation.
-;;
-;; In a previous discussion the following hack came to mind.  It is a gross
-;; hack, but it generally works.  We use the convention that major modes start
-;; by calling the function `kill-all-local-variables', which in turn runs
-;; functions on the hook variable `change-major-mode-hook'.  We attach our
-;; function `font-lock-change-major-mode' to that hook.  Of course, when this
-;; hook is run, the major mode is in the process of being changed and we do not
-;; know what the final major mode will be.  So, `font-lock-change-major-mode'
-;; only (a) notes the name of the current buffer, and (b) adds our function
-;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
-;; `post-command-hook' (for buffers that are not visiting files).  By the time
-;; the functions on the first of these hooks to be run are run, the new major
-;; mode is assumed to be in place.  This way we get a Font Lock function run
-;; when a major mode is turned on, without knowing major modes or their hooks.
-;;
-;; Naturally this requires that (a) major modes run `kill-all-local-variables',
-;; as they are supposed to do, and (b) the major mode is in place after the
-;; file is visited or the command that ran `kill-all-local-variables' has
-;; finished, whichever the sooner.  Arguably, any major mode that does not
-;; follow the convension (a) is broken, and I can't think of any reason why (b)
-;; would not be met (except `gnudoit' on non-files).  However, it is not clean.
-;;
-;; Probably the cleanest solution is to have each major mode function run some
-;; hook, e.g., `major-mode-hook', but maybe implementing that change is
-;; impractical.  I am personally against making `setq' a macro or be advised,
-;; or have a special function such as `set-major-mode', but maybe someone can
-;; come up with another solution?
-
-;; User interface.
-;;
-;; Although Global Font Lock mode is a pseudo-mode, I think that the user
-;; interface should conform to the usual Emacs convention for modes, i.e., a
-;; command to toggle the feature (`global-font-lock-mode') with a variable for
-;; finer control of the mode's behaviour (`font-lock-global-modes').
-;;
-;; The feature should not be enabled by loading font-lock.el, since other
-;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
-;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
-;; turned on everywhere.  That would not be intuitive or informative because
-;; loading a file tells you nothing about the feature or how to control it.  It
-;; would also be contrary to the Principle of Least Surprise.  sm.
-
-(defcustom font-lock-global-modes t
-  "*Modes for which Font Lock mode is automagically turned on.
-Global Font Lock mode is controlled by the command `global-font-lock-mode'.
-If nil, means no modes have Font Lock mode automatically turned on.
-If t, all modes that support Font Lock mode have it automatically turned on.
-If a list, it should be a list of `major-mode' symbol names for which Font Lock
-mode should be automatically turned on.  The sense of the list is negated if it
-begins with `not'.  For example:
- (c-mode c++-mode)
-means that Font Lock mode is turned on for buffers in C and C++ modes only."
-  :type '(choice (const :tag "none" nil)
-		 (const :tag "all" t)
-		 (set :menu-tag "mode specific" :tag "modes"
-		      :value (not)
-		      (const :tag "Except" not)
-		      (repeat :inline t (symbol :tag "mode"))))
-  :group 'font-lock)
-
-(defun turn-on-font-lock-if-enabled ()
-  (when (and (or font-lock-defaults
-		 (assq major-mode font-lock-defaults-alist))
-	     (or (eq font-lock-global-modes t)
-		 (if (eq (car-safe font-lock-global-modes) 'not)
-		     (not (memq major-mode (cdr font-lock-global-modes)))
-		   (memq major-mode font-lock-global-modes))))
-    (let (inhibit-quit)
-      (turn-on-font-lock))))
-
-;;;###autoload
-(easy-mmode-define-global-mode
- global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
- :extra-args (dummy))
-
-;;; End of Global Font Lock mode.
-\f
-;;; Font Lock Support mode.
-
-;; This is the code used to interface font-lock.el with any of its add-on
-;; packages, and provide the user interface.  Packages that have their own
-;; local buffer fontification functions (see below) may have to call
-;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
-;; themselves.
-
-(defcustom font-lock-support-mode 'jit-lock-mode
-  "*Support mode for Font Lock mode.
-Support modes speed up Font Lock mode by being choosy about when fontification
-occurs.  Known support modes are Fast Lock mode (symbol `fast-lock-mode'),
-Lazy Lock mode (symbol `lazy-lock-mode'), and Just-in-time Lock mode (symbol
-`jit-lock-mode'.  See those modes for more info.
-If nil, means support for Font Lock mode is never performed.
-If a symbol, use that support mode.
-If a list, each element should be of the form (MAJOR-MODE . SUPPORT-MODE),
-where MAJOR-MODE is a symbol or t (meaning the default).  For example:
- ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
-means that Fast Lock mode is used to support Font Lock mode for buffers in C or
-C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
-
-The value of this variable is used when Font Lock mode is turned on."
-  :type '(choice (const :tag "none" nil)
-		 (const :tag "fast lock" fast-lock-mode)
-		 (const :tag "lazy lock" lazy-lock-mode)
-		 (const :tag "jit lock" jit-lock-mode)
-		 (repeat :menu-tag "mode specific" :tag "mode specific"
-			 :value ((t . jit-lock-mode))
-			 (cons :tag "Instance"
-			       (radio :tag "Mode"
-				      (const :tag "all" t)
-				      (symbol :tag "name"))
-			       (radio :tag "Support"
-				      (const :tag "none" nil)
-				      (const :tag "fast lock" fast-lock-mode)
-				      (const :tag "lazy lock" lazy-lock-mode)
-				      (const :tag "JIT lock" jit-lock-mode)))
-			 ))
-  :version "21.1"
-  :group 'font-lock)
-
-(defvar fast-lock-mode nil)
-(defvar lazy-lock-mode nil)
-(defvar jit-lock-mode nil)
-
-(defun font-lock-turn-on-thing-lock ()
-  (let ((thing-mode (font-lock-value-in-major-mode font-lock-support-mode)))
-    (cond ((eq thing-mode 'fast-lock-mode)
-	   (fast-lock-mode t))
-	  ((eq thing-mode 'lazy-lock-mode)
-	   (lazy-lock-mode t))
-	  ((eq thing-mode 'jit-lock-mode)
-	   ;; Prepare for jit-lock
-	   (remove-hook 'after-change-functions
-			'font-lock-after-change-function t)
-	   (set (make-local-variable 'font-lock-fontify-buffer-function)
-		'jit-lock-refontify)
-	   ;; Don't fontify eagerly (and don't abort is the buffer is large).
-	   (set (make-local-variable 'font-lock-fontified) t)
-	   ;; Use jit-lock.
-	   (jit-lock-register 'font-lock-fontify-region
-			      (not font-lock-keywords-only))))))
-
-(defun font-lock-turn-off-thing-lock ()
-  (cond (fast-lock-mode
-	 (fast-lock-mode -1))
-	(jit-lock-mode
-	 (jit-lock-unregister 'font-lock-fontify-region)
-	 ;; Reset local vars to the non-jit-lock case.
-	 (kill-local-variable 'font-lock-fontify-buffer-function))
-	(lazy-lock-mode
-	 (lazy-lock-mode -1))))
-
-(defun font-lock-after-fontify-buffer ()
-  (cond (fast-lock-mode
-	 (fast-lock-after-fontify-buffer))
-	;; Useless now that jit-lock intercepts font-lock-fontify-buffer.  -sm
-	;; (jit-lock-mode
-	;;  (jit-lock-after-fontify-buffer))
-	(lazy-lock-mode
-	 (lazy-lock-after-fontify-buffer))))
-
-(defun font-lock-after-unfontify-buffer ()
-  (cond (fast-lock-mode
-	 (fast-lock-after-unfontify-buffer))
-	;; Useless as well.  It's only called when:
-	;; - turning off font-lock: it does not matter if we leave spurious
-	;;   `fontified' text props around since jit-lock-mode is also off.
-	;; - font-lock-default-fontify-buffer fails: this is not run
-	;;   any more anyway.   -sm
-	;;
-	;; (jit-lock-mode
-	;;  (jit-lock-after-unfontify-buffer))
-	(lazy-lock-mode
-	 (lazy-lock-after-unfontify-buffer))))
 
-;;; End of Font Lock Support mode.
 \f
-;;; Fontification functions.
 
-;; Rather than the function, e.g., `font-lock-fontify-region' containing the
-;; code to fontify a region, the function runs the function whose name is the
-;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,
-;; the value of this variable is, e.g., `font-lock-default-fontify-region'
-;; which does contain the code to fontify a region.  However, the value of the
-;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
-;; do anything.  The indirection of the fontification functions gives major
-;; modes the capability of modifying the way font-lock.el fontifies.  Major
-;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
-;; via the variable `font-lock-defaults'.
-;;
-;; For example, Rmail mode sets the variable `font-lock-defaults' so that
-;; font-lock.el uses its own function for buffer fontification.  This function
-;; makes fontification be on a message-by-message basis and so visiting an
-;; RMAIL file is much faster.  A clever implementation of the function might
-;; fontify the headers differently than the message body.  (It should, and
-;; correspondingly for Mail mode, but I can't be bothered to do the work.  Can
-;; you?)  This hints at a more interesting use...
-;;
-;; Languages that contain text normally contained in different major modes
-;; could define their own fontification functions that treat text differently
-;; depending on its context.  For example, Perl mode could arrange that here
-;; docs are fontified differently than Perl code.  Or Yacc mode could fontify
-;; rules one way and C code another.  Neat!
-;;
-;; A further reason to use the fontification indirection feature is when the
-;; default syntactual fontification, or the default fontification in general,
-;; is not flexible enough for a particular major mode.  For example, perhaps
-;; comments are just too hairy for `font-lock-fontify-syntactically-region' to
-;; cope with.  You need to write your own version of that function, e.g.,
-;; `hairy-fontify-syntactically-region', and make your own version of
-;; `hairy-fontify-region' call that function before calling
-;; `font-lock-fontify-keywords-region' for the normal regexp fontification
-;; pass.  And Hairy mode would set `font-lock-defaults' so that font-lock.el
-;; would call your region fontification function instead of its own.  For
-;; example, TeX modes could fontify {\foo ...} and \bar{...}  etc. multi-line
-;; directives correctly and cleanly.  (It is the same problem as fontifying
-;; multi-line strings and comments; regexps are not appropriate for the job.)
-
-;;;###autoload
-(defun font-lock-fontify-buffer ()
-  "Fontify the current buffer the way the function `font-lock-mode' would."
-  (interactive)
-  (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
-    (funcall font-lock-fontify-buffer-function)))
-
-(defun font-lock-unfontify-buffer ()
-  (funcall font-lock-unfontify-buffer-function))
-
-(defun font-lock-fontify-region (beg end &optional loudly)
-  (funcall font-lock-fontify-region-function beg end loudly))
-
-(defun font-lock-unfontify-region (beg end)
-  (funcall font-lock-unfontify-region-function beg end))
-
-(defun font-lock-default-fontify-buffer ()
-  (let ((verbose (if (numberp font-lock-verbose)
-		     (> (buffer-size) font-lock-verbose)
-		   font-lock-verbose)))
-    (with-temp-message
-	(when verbose
-	  (format "Fontifying %s..." (buffer-name)))
-      ;; Make sure we have the right `font-lock-keywords' etc.
-      (unless font-lock-mode
-	(font-lock-set-defaults))
-      ;; Make sure we fontify etc. in the whole buffer.
-      (save-restriction
-	(widen)
-	(condition-case nil
-	    (save-excursion
-	      (save-match-data
-		(font-lock-fontify-region (point-min) (point-max) verbose)
-		(font-lock-after-fontify-buffer)
-		(setq font-lock-fontified t)))
-	  ;; We don't restore the old fontification, so it's best to unfontify.
-	  (quit (font-lock-unfontify-buffer)))))))
-
-(defun font-lock-default-unfontify-buffer ()
-  ;; Make sure we unfontify etc. in the whole buffer.
-  (save-restriction
-    (widen)
-    (font-lock-unfontify-region (point-min) (point-max))
-    (font-lock-after-unfontify-buffer)
-    (setq font-lock-fontified nil)))
+;;; Non-core fontification functions.
 
 (defun font-lock-default-fontify-region (beg end loudly)
   (save-buffer-state
@@ -1248,41 +641,6 @@
       ;; Clean up.
       (set-syntax-table old-syntax-table))))
 
-;; The following must be rethought, since keywords can override fontification.
-;      ;; Now scan for keywords, but not if we are inside a comment now.
-;      (or (and (not font-lock-keywords-only)
-;	       (let ((state (parse-partial-sexp beg end nil nil
-;						font-lock-cache-state)))
-;		 (or (nth 4 state) (nth 7 state))))
-;	  (font-lock-fontify-keywords-region beg end))
-
-(defvar font-lock-extra-managed-props nil
-  "Additional text properties managed by font-lock.
-This is used by `font-lock-default-unfontify-region' to decide
-what properties to clear before refontifying a region.
-Since it is more or less directly passed to `remove-text-properties',
-it should have the shape of a property list (i.e. every other element
-is ignored).")
-
-(defun font-lock-default-unfontify-region (beg end)
-  (save-buffer-state nil
-    (remove-text-properties
-     beg end (append
-	      font-lock-extra-managed-props
-	      (if font-lock-syntactic-keywords
-		  '(face nil syntax-table nil font-lock-multiline nil)
-		'(face nil font-lock-multiline nil))))))
-
-;; Called when any modification is made to buffer text.
-(defun font-lock-after-change-function (beg end old-len)
-  (let ((inhibit-point-motion-hooks t))
-    (save-excursion
-      (save-match-data
-	;; Rescan between start of lines enclosing the region.
-	(font-lock-fontify-region
-	 (progn (goto-char beg) (beginning-of-line) (point))
-	 (progn (goto-char end) (forward-line 1) (point)))))))
-
 (defun font-lock-fontify-block (&optional arg)
   "Fontify some lines the way `font-lock-fontify-buffer' would.
 The lines could be a function or paragraph, or a specified number of lines.
@@ -1309,7 +667,13 @@
 
 (define-key facemenu-keymap "\M-g" 'font-lock-fontify-block)
 
-;;; End of Fontification functions.
+;; The following must be rethought, since keywords can override fontification.
+;      ;; Now scan for keywords, but not if we are inside a comment now.
+;      (or (and (not font-lock-keywords-only)
+;	       (let ((state (parse-partial-sexp beg end nil nil
+;						font-lock-cache-state)))
+;		 (or (nth 4 state) (nth 7 state))))
+;	  (font-lock-fontify-keywords-region beg end))
 \f
 ;;; Additional text property functions.
 
@@ -1718,17 +1082,8 @@
 	(t
 	 (car keywords))))
 
-(defvar font-lock-set-defaults nil)	; Whether we have set up defaults.
-
-(defun font-lock-set-defaults ()
-  "Set fontification defaults appropriately for this mode.
-Sets various variables using `font-lock-defaults' (or, if nil, using
-`font-lock-defaults-alist') and `font-lock-maximum-decoration'."
+(defun font-lock-set-defaults-1 ()
   ;; Set fontification defaults iff not previously set.
-  (unless font-lock-set-defaults
-    (set (make-local-variable 'font-lock-set-defaults)		t)
-    (make-local-variable 'font-lock-fontified)
-    (make-local-variable 'font-lock-multiline)
     (let* ((defaults (or font-lock-defaults
 			 (cdr (assq major-mode font-lock-defaults-alist))))
 	   (keywords
@@ -1771,7 +1126,7 @@
 	(font-lock-add-keywords nil (car (car local)) (cdr (car local)))
 	(setq local (cdr local)))
       (when removed-keywords
-	(font-lock-remove-keywords nil removed-keywords)))))
+	(font-lock-remove-keywords nil removed-keywords))))
 \f
 ;;; Colour etc. support.
 
--- replace.el.~1.140.~	Tue May  7 23:49:58 2002
+++ replace.el	Wed May  8 04:50:56 2002
@@ -453,6 +453,11 @@
   "Arguments to pass to `occur-1' to revert an Occur mode buffer.
 See `occur-revert-function'.")
 
+(defcustom occur-mode-hooks '(font-lock-mode)
+  "Hooks run upon entry into `occur-mode'."
+  :type 'hook
+  :group 'matching)
+
 (put 'occur-mode 'mode-class 'special)
 (defun occur-mode ()
   "Major mode for output from \\[occur].
@@ -468,11 +473,12 @@
   (make-local-variable 'revert-buffer-function)
   (set (make-local-variable 'font-lock-defaults)
        '(nil t nil nil nil
-	     (font-lock-fontify-region-function . occur-fontify-region-function)))
+	     (font-lock-core-only . t)))
   (setq revert-buffer-function 'occur-revert-function)
   (set (make-local-variable 'revert-buffer-function) 'occur-revert-function)
   (make-local-variable 'occur-revert-arguments)
-  (run-hooks 'occur-mode-hook))
+  (run-hooks 'occur-mode-hook)
+  (run-hooks 'occur-mode-hooks))
 
 (defun occur-revert-function (ignore1 ignore2)
   "Handle `revert-buffer' for Occur mode buffers."
@@ -699,7 +705,7 @@
 		    (or nlines list-matching-lines-default-context-lines)
 		    (and case-fold-search
 			 (isearch-no-upper-case-p regexp t))
-		    nil nil nil nil)))
+		    'underline nil 'bold nil)))
 	(let* ((diff (- (length bufs) (length active-bufs)))
 	       (msg (concat
 		     (format "Searched %d buffers" (- (length bufs) diff))
@@ -836,31 +842,6 @@
 		(goto-char (point-min)))))))
       ;; Return the number of matches
       globalcount)))
-
-(defun occur-fontify-on-property (prop face beg end)
-  (let ((prop-beg (or (and (get-text-property (point) prop) (point))
-		      (next-single-property-change (point) prop nil end))))
-    (when (and prop-beg (not (= prop-beg end)))
-      (let ((prop-end (next-single-property-change beg prop nil end)))
-	(when (and prop-end (not (= prop-end end)))
-	  (put-text-property prop-beg prop-end 'face face)
-	  prop-end)))))
-
-(defun occur-fontify-region-function (beg end &optional verbose)
-  (when verbose (message "Fontifying..."))
-  (let ((inhibit-read-only t))
-    (save-excursion
-      (dolist (e `((occur-title . ,list-matching-lines-buffer-name-face)
-		   (occur-match . ,list-matching-lines-face)))
-		   ; (occur-prefix . ,list-matching-lines-prefix-face)))
-	(goto-char beg)
-	(let ((change-end nil))
-	  (while (setq change-end (occur-fontify-on-property (car e)
-							     (cdr e)
-							     (point)
-							     end))
-	    (goto-char change-end))))))
-  (when verbose (message "Fontifying...done")))
 
 \f
 ;; It would be nice to use \\[...], but there is no reasonable way
--- loadup.el.~1.122.~	Sun Apr 28 22:29:16 2002
+++ loadup.el	Wed May  8 03:51:39 2002
@@ -149,6 +149,7 @@
 (load "emacs-lisp/lisp-mode")
 (load "textmodes/text-mode")
 (load "textmodes/fill")
+(load "font-core")
 (message "%s" (garbage-collect))
 
 (load "replace")
--- /dev/null	Wed Dec 31 19:00:00 1969
+++ font-core.el	Wed May  8 04:35:30 2002
@@ -0,0 +1,700 @@
+;;; font-core.el --- Core interface to font-lock
+
+;; Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999, 2000, 2001, 2002
+;;  Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+;; Keywords: languages, faces
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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 the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+;; Define core `font-lock' group.
+(defgroup font-lock nil
+  "Font Lock mode text highlighting package."
+  :link '(custom-manual "(emacs)Font Lock")
+  :link '(custom-manual "(elisp)Font Lock Mode")
+  :group 'faces)
+
+(defgroup font-lock-highlighting-faces nil
+  "Faces for highlighting text."
+  :prefix "font-lock-"
+  :group 'font-lock)
+
+(defgroup font-lock-extra-types nil
+  "Extra mode-specific type names for highlighting declarations."
+  :group 'font-lock)
+
+;; Define support mode groups here to impose `font-lock' group order.
+(defgroup fast-lock nil
+  "Font Lock support mode to cache fontification."
+  :link '(custom-manual "(emacs)Support Modes")
+  :load 'fast-lock
+  :group 'font-lock)
+
+(defgroup lazy-lock nil
+  "Font Lock support mode to fontify lazily."
+  :link '(custom-manual "(emacs)Support Modes")
+  :load 'lazy-lock
+  :group 'font-lock)
+
+(defgroup jit-lock nil
+  "Font Lock support mode to fontify just-in-time."
+  :link '(custom-manual "(emacs)Support Modes")
+  :version "21.1"
+  :load 'jit-lock
+  :group 'font-lock)
+\f
+;; User variables.
+
+(defcustom font-lock-maximum-size 256000
+  "*Maximum size of a buffer for buffer fontification.
+Only buffers less than this can be fontified when Font Lock mode is turned on.
+If nil, means size is irrelevant.
+If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
+where MAJOR-MODE is a symbol or t (meaning the default).  For example:
+ ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576))
+means that the maximum size is 250K for buffers in C or C++ modes, one megabyte
+for buffers in Rmail mode, and size is irrelevant otherwise."
+  :type '(choice (const :tag "none" nil)
+		 (integer :tag "size")
+		 (repeat :menu-tag "mode specific" :tag "mode specific"
+			 :value ((t . nil))
+			 (cons :tag "Instance"
+			       (radio :tag "Mode"
+				      (const :tag "all" t)
+				      (symbol :tag "name"))
+			       (radio :tag "Size"
+				      (const :tag "none" nil)
+				      (integer :tag "size")))))
+  :group 'font-lock)
+
+(defcustom font-lock-maximum-decoration t
+  "*Maximum decoration level for fontification.
+If nil, use the default decoration (typically the minimum available).
+If t, use the maximum decoration available.
+If a number, use that level of decoration (or if not available the maximum).
+If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
+where MAJOR-MODE is a symbol or t (meaning the default).  For example:
+ ((c-mode . t) (c++-mode . 2) (t . 1))
+means use the maximum decoration available for buffers in C mode, level 2
+decoration for buffers in C++ mode, and level 1 decoration otherwise."
+  :type '(choice (const :tag "default" nil)
+		 (const :tag "maximum" t)
+		 (integer :tag "level" 1)
+		 (repeat :menu-tag "mode specific" :tag "mode specific"
+			 :value ((t . t))
+			 (cons :tag "Instance"
+			       (radio :tag "Mode"
+				      (const :tag "all" t)
+				      (symbol :tag "name"))
+			       (radio :tag "Decoration"
+				      (const :tag "default" nil)
+				      (const :tag "maximum" t)
+				      (integer :tag "level" 1)))))
+  :group 'font-lock)
+
+(defcustom font-lock-verbose 0
+  "*If non-nil, means show status messages for buffer fontification.
+If a number, only buffers greater than this size have fontification messages."
+  :type '(choice (const :tag "never" nil)
+		 (other :tag "always" t)
+		 (integer :tag "size"))
+  :group 'font-lock)
+
+;; This variable is used by mode packages that support Font Lock mode by
+;; defining their own keywords to use for `font-lock-keywords'.  (The mode
+;; command should make it buffer-local and set it to provide the set up.)
+(defvar font-lock-defaults nil
+  "Defaults for Font Lock mode specified by the major mode.
+Defaults should be of the form:
+
+ (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
+
+KEYWORDS may be a symbol (a variable or function whose value is the keywords to
+use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
+syntactic fontification (strings and comments) is not performed.
+If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
+If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
+\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
+keyword and syntactic fontification (see `modify-syntax-entry').
+
+If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
+backwards outside any enclosing syntactic block, for syntactic fontification.
+Typical values are `beginning-of-line' (i.e., the start of the line is known to
+be outside a syntactic block), or `beginning-of-defun' for programming modes or
+`backward-paragraph' for textual modes (i.e., the mode-dependent function is
+known to move outside a syntactic block).  If nil, the beginning of the buffer
+is used as a position outside of a syntactic block, in the worst case.
+
+These item elements are used by Font Lock mode to set the variables
+`font-lock-keywords', `font-lock-keywords-only',
+`font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
+`font-lock-beginning-of-syntax-function', respectively.
+
+Further item elements are alists of the form (VARIABLE . VALUE) and are in no
+particular order.  Each VARIABLE is made buffer-local before set to VALUE.
+
+Currently, appropriate variables include `font-lock-mark-block-function'.
+If this is non-nil, it should be a function with no args used to mark any
+enclosing block of text, for fontification via \\[font-lock-fontify-block].
+Typical values are `mark-defun' for programming modes or `mark-paragraph' for
+textual modes (i.e., the mode-dependent function is known to put point and mark
+around a text block relevant to that mode).
+
+Other variables include that for syntactic keyword fontification,
+`font-lock-syntactic-keywords'
+and those for buffer-specialised fontification functions,
+`font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function',
+`font-lock-fontify-region-function', `font-lock-unfontify-region-function',
+`font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.")
+;;;###autoload
+(make-variable-buffer-local 'font-lock-defaults)
+
+(defvar font-lock-fontify-buffer-function 'font-lock-default-fontify-buffer
+  "Function to use for fontifying the buffer.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-unfontify-buffer-function 'font-lock-default-unfontify-buffer
+  "Function to use for unfontifying the buffer.
+This is used when turning off Font Lock mode.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
+  "Function to use for fontifying a region.
+It should take two args, the beginning and end of the region, and an optional
+third arg VERBOSE.  If non-nil, the function should print status messages.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
+  "Function to use for unfontifying a region.
+It should take two args, the beginning and end of the region.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-inhibit-thing-lock nil
+  "List of Font Lock mode related modes that should not be turned on.
+Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
+`lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-multiline nil
+  "Whether font-lock should cater to multiline keywords.
+If nil, don't try to handle multiline patterns.
+If t, always handle multiline patterns.
+If `undecided', don't try to handle multiline patterns until you see one.
+Major/minor modes can set this variable if they know which option applies.")
+
+(defvar font-lock-fontified nil)	; Whether we have fontified the buffer.
+(defvar font-lock-core-only nil)
+
+;; Font Lock mode.
+
+(define-minor-mode font-lock-mode
+  "Toggle Font Lock mode.
+With arg, turn Font Lock mode off if and only if arg is a non-positive
+number; if arg is nil, toggle Font Lock mode; anything else turns Font
+Lock on.
+\(Font Lock is also known as \"syntax highlighting\".)
+
+When Font Lock mode is enabled, text is fontified as you type it:
+
+ - Comments are displayed in `font-lock-comment-face';
+ - Strings are displayed in `font-lock-string-face';
+ - Certain other expressions are displayed in other faces according to the
+   value of the variable `font-lock-keywords'.
+
+To customize the faces (colors, fonts, etc.) used by Font Lock for
+fontifying different parts of buffer text, use \\[customize-face].
+
+You can enable Font Lock mode in any major mode automatically by turning on in
+the major mode's hook.  For example, put in your ~/.emacs:
+
+ (add-hook 'c-mode-hook 'turn-on-font-lock)
+
+Alternatively, you can use Global Font Lock mode to automagically turn on Font
+Lock mode in buffers whose major mode supports it and whose major mode is one
+of `font-lock-global-modes'.  For example, put in your ~/.emacs:
+
+ (global-font-lock-mode t)
+
+There are a number of support modes that may be used to speed up Font Lock mode
+in various ways, specified via the variable `font-lock-support-mode'.  Where
+major modes support different levels of fontification, you can use the variable
+`font-lock-maximum-decoration' to specify which level you generally prefer.
+When you turn Font Lock mode on/off the buffer is fontified/defontified, though
+fontification occurs only if the buffer is less than `font-lock-maximum-size'.
+
+For example, to specify that Font Lock mode use use Lazy Lock mode as a support
+mode and use maximum levels of fontification, put in your ~/.emacs:
+
+ (setq font-lock-support-mode 'lazy-lock-mode)
+ (setq font-lock-maximum-decoration t)
+
+To add your own highlighting for some major mode, and modify the highlighting
+selected automatically via the variable `font-lock-maximum-decoration', you can
+use `font-lock-add-keywords'.
+
+To fontify a buffer, without turning on Font Lock mode and regardless of buffer
+size, you can use \\[font-lock-fontify-buffer].
+
+To fontify a block (the function or paragraph containing point, or a number of
+lines around point), perhaps because modification on the current line caused
+syntactic change on other lines, you can use \\[font-lock-fontify-block].
+
+See the variable `font-lock-defaults-alist' for the Font Lock mode default
+settings.  You can set your own default settings for some mode, by setting a
+buffer local value for `font-lock-defaults', via its mode hook."
+  nil nil nil
+  ;; Don't turn on Font Lock mode if we don't have a display (we're running a
+  ;; batch job) or if the buffer is invisible (the name starts with a space).
+  (when (or noninteractive (eq (aref (buffer-name) 0) ?\ ))
+    (setq font-lock-mode nil))
+  
+  (setq inhibit-text-property-faces (not font-lock-mode))
+
+  ;; Turn on Font Lock mode.
+  (when font-lock-mode
+    (font-lock-set-defaults)
+    ;; If `font-lock-core-only', then don't use any of the font-lock
+    ;; machinery.
+    (unless font-lock-core-only
+      (add-hook 'after-change-functions 'font-lock-after-change-function t t)
+      (font-lock-fontify-buffer)
+      (font-lock-turn-on-thing-lock)
+      ;; Fontify the buffer if we have to.
+      (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
+	(cond (font-lock-fontified
+	       nil)
+	      ((or (null max-size) (> max-size (buffer-size)))
+	       (font-lock-fontify-buffer))
+	      (font-lock-verbose
+	       (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
+			(buffer-name)))))))
+  ;; Turn off Font Lock mode.
+  (unless font-lock-mode
+    (unless font-lock-core-only
+      (remove-hook 'after-change-functions 'font-lock-after-change-function t)
+      (font-lock-unfontify-buffer)
+      (font-lock-turn-off-thing-lock))))
+
+;; This variable is used where font-lock.el itself supplies the keywords.
+(defvar font-lock-defaults-alist
+  (let (;; We use `beginning-of-defun', rather than nil, for SYNTAX-BEGIN.
+	;; Thus the calculation of the cache is usually faster but not
+	;; infallible, so we risk mis-fontification.  sm.
+	(c-mode-defaults
+	 '((c-font-lock-keywords c-font-lock-keywords-1
+	    c-font-lock-keywords-2 c-font-lock-keywords-3)
+	   nil nil ((?_ . "w")) beginning-of-defun
+	   (font-lock-syntactic-face-function
+	    . c-font-lock-syntactic-face-function)
+	   (font-lock-mark-block-function . mark-defun)))
+	(c++-mode-defaults
+	 '((c++-font-lock-keywords c++-font-lock-keywords-1
+	    c++-font-lock-keywords-2 c++-font-lock-keywords-3)
+	   nil nil ((?_ . "w")) beginning-of-defun
+	   (font-lock-syntactic-face-function
+	    . c-font-lock-syntactic-face-function)
+	   (font-lock-mark-block-function . mark-defun)))
+	(objc-mode-defaults
+	 '((objc-font-lock-keywords objc-font-lock-keywords-1
+	    objc-font-lock-keywords-2 objc-font-lock-keywords-3)
+	   nil nil ((?_ . "w") (?$ . "w")) nil
+	   (font-lock-syntactic-face-function
+	    . c-font-lock-syntactic-face-function)
+	   (font-lock-mark-block-function . mark-defun)))
+	(java-mode-defaults
+	 '((java-font-lock-keywords java-font-lock-keywords-1
+	    java-font-lock-keywords-2 java-font-lock-keywords-3)
+	   nil nil ((?_ . "w") (?$ . "w")) nil
+	   (font-lock-syntactic-face-function
+	    . java-font-lock-syntactic-face-function)
+	   (font-lock-mark-block-function . mark-defun))))
+    (list
+     (cons 'c-mode			c-mode-defaults)
+     (cons 'c++-mode			c++-mode-defaults)
+     (cons 'objc-mode			objc-mode-defaults)
+     (cons 'java-mode			java-mode-defaults)))
+  "Alist of fall-back Font Lock defaults for major modes.
+
+This variable should not be used any more.
+Set the buffer-local `font-lock-keywords' in the major mode instead.
+
+Each item should be a list of the form:
+
+ (MAJOR-MODE . FONT-LOCK-DEFAULTS)
+
+where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default
+settings.  See the variable `font-lock-defaults', which takes precedence.")
+(make-obsolete-variable 'font-lock-defaults-alist 'font-lock-defaults)
+
+;;; Global Font Lock mode.
+
+;; A few people have hassled in the past for a way to make it easier to turn on
+;; Font Lock mode, without the user needing to know for which modes s/he has to
+;; turn it on, perhaps the same way hilit19.el/hl319.el does.  I've always
+;; balked at that way, as I see it as just re-moulding the same problem in
+;; another form.  That is; some person would still have to keep track of which
+;; modes (which may not even be distributed with Emacs) support Font Lock mode.
+;; The list would always be out of date.  And that person might have to be me.
+
+;; Implementation.
+;;
+;; In a previous discussion the following hack came to mind.  It is a gross
+;; hack, but it generally works.  We use the convention that major modes start
+;; by calling the function `kill-all-local-variables', which in turn runs
+;; functions on the hook variable `change-major-mode-hook'.  We attach our
+;; function `font-lock-change-major-mode' to that hook.  Of course, when this
+;; hook is run, the major mode is in the process of being changed and we do not
+;; know what the final major mode will be.  So, `font-lock-change-major-mode'
+;; only (a) notes the name of the current buffer, and (b) adds our function
+;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
+;; `post-command-hook' (for buffers that are not visiting files).  By the time
+;; the functions on the first of these hooks to be run are run, the new major
+;; mode is assumed to be in place.  This way we get a Font Lock function run
+;; when a major mode is turned on, without knowing major modes or their hooks.
+;;
+;; Naturally this requires that (a) major modes run `kill-all-local-variables',
+;; as they are supposed to do, and (b) the major mode is in place after the
+;; file is visited or the command that ran `kill-all-local-variables' has
+;; finished, whichever the sooner.  Arguably, any major mode that does not
+;; follow the convension (a) is broken, and I can't think of any reason why (b)
+;; would not be met (except `gnudoit' on non-files).  However, it is not clean.
+;;
+;; Probably the cleanest solution is to have each major mode function run some
+;; hook, e.g., `major-mode-hook', but maybe implementing that change is
+;; impractical.  I am personally against making `setq' a macro or be advised,
+;; or have a special function such as `set-major-mode', but maybe someone can
+;; come up with another solution?
+
+;; User interface.
+;;
+;; Although Global Font Lock mode is a pseudo-mode, I think that the user
+;; interface should conform to the usual Emacs convention for modes, i.e., a
+;; command to toggle the feature (`global-font-lock-mode') with a variable for
+;; finer control of the mode's behaviour (`font-lock-global-modes').
+;;
+;; The feature should not be enabled by loading font-lock.el, since other
+;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
+;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
+;; turned on everywhere.  That would not be intuitive or informative because
+;; loading a file tells you nothing about the feature or how to control it.  It
+;; would also be contrary to the Principle of Least Surprise.  sm.
+
+(defcustom font-lock-global-modes t
+  "*Modes for which Font Lock mode is automagically turned on.
+Global Font Lock mode is controlled by the command `global-font-lock-mode'.
+If nil, means no modes have Font Lock mode automatically turned on.
+If t, all modes that support Font Lock mode have it automatically turned on.
+If a list, it should be a list of `major-mode' symbol names for which Font Lock
+mode should be automatically turned on.  The sense of the list is negated if it
+begins with `not'.  For example:
+ (c-mode c++-mode)
+means that Font Lock mode is turned on for buffers in C and C++ modes only."
+  :type '(choice (const :tag "none" nil)
+		 (const :tag "all" t)
+		 (set :menu-tag "mode specific" :tag "modes"
+		      :value (not)
+		      (const :tag "Except" not)
+		      (repeat :inline t (symbol :tag "mode"))))
+  :group 'font-lock)
+
+(easy-mmode-define-global-mode
+ global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
+ :extra-args (dummy))
+
+(defun turn-on-font-lock-if-enabled ()
+  (when (and (or font-lock-defaults
+		 (assq major-mode font-lock-defaults-alist))
+	     (or (eq font-lock-global-modes t)
+		 (if (eq (car-safe font-lock-global-modes) 'not)
+		     (not (memq major-mode (cdr font-lock-global-modes)))
+		   (memq major-mode font-lock-global-modes))))
+    (let (inhibit-quit)
+      (turn-on-font-lock))))
+
+;;; End of Global Font Lock mode.
+
+
+;;; Font Lock Support mode.
+
+;; This is the code used to interface font-lock.el with any of its add-on
+;; packages, and provide the user interface.  Packages that have their own
+;; local buffer fontification functions (see below) may have to call
+;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
+;; themselves.
+
+(defcustom font-lock-support-mode 'jit-lock-mode
+  "*Support mode for Font Lock mode.
+Support modes speed up Font Lock mode by being choosy about when fontification
+occurs.  Known support modes are Fast Lock mode (symbol `fast-lock-mode'),
+Lazy Lock mode (symbol `lazy-lock-mode'), and Just-in-time Lock mode (symbol
+`jit-lock-mode'.  See those modes for more info.
+If nil, means support for Font Lock mode is never performed.
+If a symbol, use that support mode.
+If a list, each element should be of the form (MAJOR-MODE . SUPPORT-MODE),
+where MAJOR-MODE is a symbol or t (meaning the default).  For example:
+ ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
+means that Fast Lock mode is used to support Font Lock mode for buffers in C or
+C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
+
+The value of this variable is used when Font Lock mode is turned on."
+  :type '(choice (const :tag "none" nil)
+		 (const :tag "fast lock" fast-lock-mode)
+		 (const :tag "lazy lock" lazy-lock-mode)
+		 (const :tag "jit lock" jit-lock-mode)
+		 (repeat :menu-tag "mode specific" :tag "mode specific"
+			 :value ((t . jit-lock-mode))
+			 (cons :tag "Instance"
+			       (radio :tag "Mode"
+				      (const :tag "all" t)
+				      (symbol :tag "name"))
+			       (radio :tag "Support"
+				      (const :tag "none" nil)
+				      (const :tag "fast lock" fast-lock-mode)
+				      (const :tag "lazy lock" lazy-lock-mode)
+				      (const :tag "JIT lock" jit-lock-mode)))
+			 ))
+  :version "21.1"
+  :group 'font-lock)
+
+(defvar fast-lock-mode nil)
+(defvar lazy-lock-mode nil)
+(defvar jit-lock-mode nil)
+
+(defun font-lock-turn-on-thing-lock ()
+  (let ((thing-mode (font-lock-value-in-major-mode font-lock-support-mode)))
+    (cond ((eq thing-mode 'fast-lock-mode)
+	   (fast-lock-mode t))
+	  ((eq thing-mode 'lazy-lock-mode)
+	   (lazy-lock-mode t))
+	  ((eq thing-mode 'jit-lock-mode)
+	   ;; Prepare for jit-lock
+	   (remove-hook 'after-change-functions
+			'font-lock-after-change-function t)
+	   (set (make-local-variable 'font-lock-fontify-buffer-function)
+		'jit-lock-refontify)
+	   ;; Don't fontify eagerly (and don't abort is the buffer is large).
+	   (set (make-local-variable 'font-lock-fontified) t)
+	   ;; Use jit-lock.
+	   (jit-lock-register 'font-lock-fontify-region
+			      (not font-lock-keywords-only))))))
+
+(defun font-lock-turn-off-thing-lock ()
+  (cond (fast-lock-mode
+	 (fast-lock-mode -1))
+	(jit-lock-mode
+	 (jit-lock-unregister 'font-lock-fontify-region)
+	 ;; Reset local vars to the non-jit-lock case.
+	 (kill-local-variable 'font-lock-fontify-buffer-function))
+	(lazy-lock-mode
+	 (lazy-lock-mode -1))))
+
+(defun font-lock-after-fontify-buffer ()
+  (cond (fast-lock-mode
+	 (fast-lock-after-fontify-buffer))
+	;; Useless now that jit-lock intercepts font-lock-fontify-buffer.  -sm
+	;; (jit-lock-mode
+	;;  (jit-lock-after-fontify-buffer))
+	(lazy-lock-mode
+	 (lazy-lock-after-fontify-buffer))))
+
+(defun font-lock-after-unfontify-buffer ()
+  (cond (fast-lock-mode
+	 (fast-lock-after-unfontify-buffer))
+	;; Useless as well.  It's only called when:
+	;; - turning off font-lock: it does not matter if we leave spurious
+	;;   `fontified' text props around since jit-lock-mode is also off.
+	;; - font-lock-default-fontify-buffer fails: this is not run
+	;;   any more anyway.   -sm
+	;;
+	;; (jit-lock-mode
+	;;  (jit-lock-after-unfontify-buffer))
+	(lazy-lock-mode
+	 (lazy-lock-after-unfontify-buffer))))
+
+;;; End of Font Lock Support mode.
+
+;;; Core fontification functions.
+
+;; Rather than the function, e.g., `font-lock-fontify-region' containing the
+;; code to fontify a region, the function runs the function whose name is the
+;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,
+;; the value of this variable is, e.g., `font-lock-default-fontify-region'
+;; which does contain the code to fontify a region.  However, the value of the
+;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
+;; do anything.  The indirection of the fontification functions gives major
+;; modes the capability of modifying the way font-lock.el fontifies.  Major
+;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
+;; via the variable `font-lock-defaults'.
+;;
+;; For example, Rmail mode sets the variable `font-lock-defaults' so that
+;; font-lock.el uses its own function for buffer fontification.  This function
+;; makes fontification be on a message-by-message basis and so visiting an
+;; RMAIL file is much faster.  A clever implementation of the function might
+;; fontify the headers differently than the message body.  (It should, and
+;; correspondingly for Mail mode, but I can't be bothered to do the work.  Can
+;; you?)  This hints at a more interesting use...
+;;
+;; Languages that contain text normally contained in different major modes
+;; could define their own fontification functions that treat text differently
+;; depending on its context.  For example, Perl mode could arrange that here
+;; docs are fontified differently than Perl code.  Or Yacc mode could fontify
+;; rules one way and C code another.  Neat!
+;;
+;; A further reason to use the fontification indirection feature is when the
+;; default syntactual fontification, or the default fontification in general,
+;; is not flexible enough for a particular major mode.  For example, perhaps
+;; comments are just too hairy for `font-lock-fontify-syntactically-region' to
+;; cope with.  You need to write your own version of that function, e.g.,
+;; `hairy-fontify-syntactically-region', and make your own version of
+;; `hairy-fontify-region' call that function before calling
+;; `font-lock-fontify-keywords-region' for the normal regexp fontification
+;; pass.  And Hairy mode would set `font-lock-defaults' so that font-lock.el
+;; would call your region fontification function instead of its own.  For
+;; example, TeX modes could fontify {\foo ...} and \bar{...}  etc. multi-line
+;; directives correctly and cleanly.  (It is the same problem as fontifying
+;; multi-line strings and comments; regexps are not appropriate for the job.)
+
+(defun font-lock-fontify-buffer ()
+  "Fontify the current buffer the way the function `font-lock-mode' would."
+  (interactive)
+  (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
+    (funcall font-lock-fontify-buffer-function)))
+
+(defun font-lock-unfontify-buffer ()
+  (funcall font-lock-unfontify-buffer-function))
+
+(defun font-lock-fontify-region (beg end &optional loudly)
+  (funcall font-lock-fontify-region-function beg end loudly))
+
+(defun font-lock-unfontify-region (beg end)
+  (funcall font-lock-unfontify-region-function beg end))
+
+(defun font-lock-default-fontify-buffer ()
+  (let ((verbose (if (numberp font-lock-verbose)
+		     (> (buffer-size) font-lock-verbose)
+		   font-lock-verbose)))
+    (with-temp-message
+	(when verbose
+	  (format "Fontifying %s..." (buffer-name)))
+      ;; Make sure we have the right `font-lock-keywords' etc.
+      (unless font-lock-mode
+	(font-lock-set-defaults))
+      ;; Make sure we fontify etc. in the whole buffer.
+      (save-restriction
+	(widen)
+	(condition-case nil
+	    (save-excursion
+	      (save-match-data
+		(font-lock-fontify-region (point-min) (point-max) verbose)
+		(font-lock-after-fontify-buffer)
+		(setq font-lock-fontified t)))
+	  ;; We don't restore the old fontification, so it's best to unfontify.
+	  (quit (font-lock-unfontify-buffer)))))))
+
+(defun font-lock-default-unfontify-buffer ()
+  ;; Make sure we unfontify etc. in the whole buffer.
+  (save-restriction
+    (widen)
+    (font-lock-unfontify-region (point-min) (point-max))
+    (font-lock-after-unfontify-buffer)
+    (setq font-lock-fontified nil)))
+
+\f
+(eval-when-compile
+  ;;
+  ;; We don't do this at the top-level as we only use non-autoloaded macros.
+  (require 'cl)
+  ;;
+  ;; Borrowed from lazy-lock.el.
+  ;; We use this to preserve or protect things when modifying text properties.
+  (defmacro save-buffer-state (varlist &rest body)
+    "Bind variables according to VARLIST and eval BODY restoring buffer state."
+    (let ((modified (make-symbol "modified")))
+      `(let* ,(append varlist
+		      `((,modified (buffer-modified-p))
+			(buffer-undo-list t)
+			(inhibit-read-only t)
+			(inhibit-point-motion-hooks t)
+			(inhibit-modification-hooks t)
+			deactivate-mark
+			buffer-file-name
+			buffer-file-truename))
+	 (progn
+	   ,@body)
+	 (unless ,modified
+	   (restore-buffer-modified-p nil)))))
+  (put 'save-buffer-state 'lisp-indent-function 1)
+  (def-edebug-spec save-buffer-state let)
+  ;;
+  ;; Shut up the byte compiler.
+  (defvar font-lock-face-attributes))	; Obsolete but respected if set.
+
+(defvar font-lock-extra-managed-props nil
+  "Additional text properties managed by font-lock.
+This is used by `font-lock-default-unfontify-region' to decide
+what properties to clear before refontifying a region.
+Since it is more or less directly passed to `remove-text-properties',
+it should have the shape of a property list (i.e. every other element
+is ignored).")
+
+(defun font-lock-default-unfontify-region (beg end)
+  (save-buffer-state nil
+    (remove-text-properties
+     beg end (append
+	      font-lock-extra-managed-props
+	      (if font-lock-syntactic-keywords
+		  '(face nil syntax-table nil font-lock-multiline nil)
+		'(face nil font-lock-multiline nil))))))
+
+;; Called when any modification is made to buffer text.
+(defun font-lock-after-change-function (beg end old-len)
+  (let ((inhibit-point-motion-hooks t))
+    (save-excursion
+      (save-match-data
+	;; Rescan between start of lines enclosing the region.
+	(font-lock-fontify-region
+	 (progn (goto-char beg) (beginning-of-line) (point))
+	 (progn (goto-char end) (forward-line 1) (point)))))))
+
+;;; End of Fontification functions.
+
+(defvar font-lock-set-defaults nil)	; Whether we have set up defaults.
+
+(defun font-lock-set-defaults ()
+  "Set fontification defaults appropriately for this mode.
+Sets various variables using `font-lock-defaults' (or, if nil, using
+`font-lock-defaults-alist') and `font-lock-maximum-decoration'."
+  (unless font-lock-set-defaults
+    (set (make-local-variable 'font-lock-set-defaults) t)
+    (make-local-variable 'font-lock-fontified)
+    (make-local-variable 'font-lock-multiline)
+    (let ((options (nthcdr 5 font-lock-defaults)))
+      ;; Detect if this is a simple mode, which doesn't use any
+      ;; syntactic fontification functions.
+      (if (assq 'font-lock-core-only options)
+	  (dolist (x (nthcdr 5 font-lock-defaults))
+	    (set (make-local-variable (car x)) (cdr x)))
+	(require 'font-lock)
+	(font-lock-set-defaults-1)))))
+
+(provide 'font-core)
+
+;;; font-core.el ends here
+

[-- Attachment #3: xfaces.patch --]
[-- Type: text/plain, Size: 2077 bytes --]

--- xfaces.c.~1.252.~	Sat Apr 27 17:21:17 2002
+++ xfaces.c	Wed May  8 04:28:14 2002
@@ -388,6 +388,10 @@
 
 Lisp_Object Vface_ignored_fonts;
 
+/* If non-nil, ignore face text properties */
+ 
+Lisp_Object Vinhibit_text_property_faces;
+
 /* Maximum number of fonts to consider in font_list.  If not an
    integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead.  */
 
@@ -6809,7 +6813,7 @@
 {
   struct frame *f = XFRAME (w->frame);
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  Lisp_Object prop, position;
+  Lisp_Object prop = Qnil, position;
   int i, noverlays;
   Lisp_Object *overlay_vec;
   Lisp_Object frame;
@@ -6829,13 +6833,16 @@
   if (pos < region_beg && region_beg < endpos)
     endpos = region_beg;
 
-  /* Get the `face' or `mouse_face' text property at POS, and
-     determine the next position at which the property changes.  */
-  prop = Fget_text_property (position, propname, w->buffer);
-  XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
-  end = Fnext_single_property_change (position, propname, w->buffer, limit1);
-  if (INTEGERP (end))
-    endpos = XINT (end);
+  if (EQ(propname, Qface) && NILP(Vinhibit_text_property_faces))
+    {
+      /* Get the `face' or `mouse_face' text property at POS, and
+	 determine the next position at which the property changes.  */
+      prop = Fget_text_property (position, propname, w->buffer);
+      XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
+      end = Fnext_single_property_change (position, propname, w->buffer, limit1);
+      if (INTEGERP (end))
+	endpos = XINT (end);
+    }
 
   /* Look at properties from overlays.  */
   {
@@ -7321,6 +7328,10 @@
 Each element is a regular expression that matches names of fonts to
 ignore.  */);
   Vface_ignored_fonts = Qnil;
+
+  DEFVAR_LISP ("inhibit-text-property-faces", &Vinhibit_text_property_faces,
+	       doc: /* If non-nil, then a `face' text property will be ignored. */);
+  Vinhibit_text_property_faces = Qnil;
 
 #ifdef HAVE_WINDOW_SYSTEM
   defsubr (&Sbitmap_spec_p);

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-06 22:46                   ` Colin Walters
@ 2002-05-08 10:06                     ` Francesco Potorti`
  2002-05-08 10:20                       ` Eli Zaretskii
  0 siblings, 1 reply; 82+ messages in thread
From: Francesco Potorti` @ 2002-05-08 10:06 UTC (permalink / raw)
  Cc: emacs-devel

   Right; all the Emacs and XEmacs users I personally know have enabled
   font-lock globally.

I'd be very surprised to know a new Emacs user that does not want
colours. 

I expect only very experienced users having enough understanding of the
user interface to have preferences whether they want colours in certain
buffers or not.  The big majority would be content with colours.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-08 10:06                     ` Francesco Potorti`
@ 2002-05-08 10:20                       ` Eli Zaretskii
  0 siblings, 0 replies; 82+ messages in thread
From: Eli Zaretskii @ 2002-05-08 10:20 UTC (permalink / raw)
  Cc: emacs-devel


On 8 May 2002, Francesco Potorti` wrote:

>    Right; all the Emacs and XEmacs users I personally know have enabled
>    font-lock globally.
> 
> I'd be very surprised to know a new Emacs user that does not want
> colours. 

That matches my experience: I did look for such a user, but have yet to 
find him or her.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-08  8:57                                     ` Colin Walters
@ 2002-05-08 13:14                                       ` Stefan Monnier
  2002-05-09  4:29                                         ` Colin Walters
  0 siblings, 1 reply; 82+ messages in thread
From: Stefan Monnier @ 2002-05-08 13:14 UTC (permalink / raw)
  Cc: emacs-devel

> 	* font-lock.el (font-lock, font-lock-defaults-alist)
[...]
> 	Moved to font-core.el.

I don't like it because I don't like moving code around gratuitously
and because it looks like a might large "core".

I'd much rather create a new minor mode `syntax-highlight-mode' which
uses the variable `syntax-highlight-mode-function' (which defaults
to font-lock-mode) to turn the mode on/off.

Or something like that.  I'd probably prefer for this minor mode to be like
global-font-lock-mode rather than like font-lock-mode.

Or maybe global-font-lock-mode could be moved to simple.el and
extended to obey a variable like `syntax-highlight-mode-function'.


	Stefan

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07 20:38                           ` Colin Walters
  2002-05-08  0:20                             ` Miles Bader
@ 2002-05-09  2:45                             ` Richard Stallman
  2002-05-09  4:28                               ` Colin Walters
  1 sibling, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-05-09  2:45 UTC (permalink / raw)
  Cc: emacs-devel

    > * font-lock-mode, when enabled, will not always use the mechanism in
    >   font-lock.el.  In special buffers, it will just set a flag that
    >   directs the mechanism to insert faces when constructing the text.

    The disadvantage with this approach is that the user couldn't toggle
    fontification on and off by typing 'M-x font-lock-mode' in a special
    buffer; they would have to regenerate the buffer text (e.g. by typing
    'g' in an *Occur* buffer).

M-x font-lock-mode in these buffers could also revert,
so as to reconstruct the text with or without faces.

That is much simpler and much cleaner than the font-core alternative.
It fits the problem exactly.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-09  2:45                             ` Richard Stallman
@ 2002-05-09  4:28                               ` Colin Walters
  2002-05-10  0:30                                 ` Richard Stallman
  0 siblings, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-09  4:28 UTC (permalink / raw)


On Wed, 2002-05-08 at 22:45, Richard Stallman wrote:

> M-x font-lock-mode in these buffers could also revert,
> so as to reconstruct the text with or without faces.
> 
> That is much simpler and much cleaner than the font-core alternative.
> It fits the problem exactly.

An example of where this won't work is with an *Occur* buffer, if the
user just wants to temporarily turn on/off fontification, but has killed
the associated buffer(s).  The occur command will fail in this case.

A somewhat similar situation could happen with a *Kill Ring* buffer; if
the user has done more killing before typing M-x font-lock-mode, then
the entry they want to see unfontified could have been rotated off the
kill ring.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-08 13:14                                       ` Stefan Monnier
@ 2002-05-09  4:29                                         ` Colin Walters
  2002-05-09 10:08                                           ` Kim F. Storm
  0 siblings, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-09  4:29 UTC (permalink / raw)


On Wed, 2002-05-08 at 09:14, Stefan Monnier wrote:
> > 	* font-lock.el (font-lock, font-lock-defaults-alist)
> [...]
> > 	Moved to font-core.el.
> 
> I don't like it because I don't like moving code around gratuitously
> and because it looks like a might large "core".

I can make the core quite a bit smaller, actually.  The reason so many
functions were moved there is they were necessary in the approach taken
by my first patch.  In fact, I think all that's needed there is the
definition of the `font-lock-mode' function itself, plus one or two
variables.  Would that be small enough?

As for your other proposals, I will need to think about them.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-09  4:29                                         ` Colin Walters
@ 2002-05-09 10:08                                           ` Kim F. Storm
  0 siblings, 0 replies; 82+ messages in thread
From: Kim F. Storm @ 2002-05-09 10:08 UTC (permalink / raw)
  Cc: emacs-devel

> 
> I can make the core quite a bit smaller, actually.  The reason so many
> functions were moved there is they were necessary in the approach taken
> by my first patch.  In fact, I think all that's needed there is the
> definition of the `font-lock-mode' function itself, plus one or two
> variables.  Would that be small enough?

If that's the case, maybe just moving them to simple.el would be
preferable to adding a separate font-core.el file?


-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07 19:22                     ` Alex Schroeder
@ 2002-05-09 20:09                       ` Colin Walters
  2002-05-11  6:30                       ` Richard Stallman
  1 sibling, 0 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-09 20:09 UTC (permalink / raw)


On Tue, 2002-05-07 at 15:22, Alex Schroeder wrote:

> In fact the only people suffering will be oldbies that have font-lock
> switched off and still like fontification in some buffers (people such
> as Richard, apparently).  

Both of my previous patches do not change the defaults at all.

The only difference is that typing 'M-x font-lock-mode' in special
buffers (after we adapt them) starts to Just Work.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-09  4:28                               ` Colin Walters
@ 2002-05-10  0:30                                 ` Richard Stallman
  2002-05-16 18:47                                   ` Colin Walters
  0 siblings, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-05-10  0:30 UTC (permalink / raw)
  Cc: emacs-devel

    An example of where this won't work is with an *Occur* buffer, if the
    user just wants to temporarily turn on/off fontification, but has killed
    the associated buffer(s).  The occur command will fail in this case.

    A somewhat similar situation could happen with a *Kill Ring* buffer; if
    the user has done more killing before typing M-x font-lock-mode, then
    the entry they want to see unfontified could have been rotated off the
    kill ring.

That is a good point.  There needs to be a way for these modes to
specify how to add and remove fonts in the buffer.

But these should not have to use the whole font-lock-mode mechanism,
even if they use M-x font-lock-mode as a control interface to enable
and disable.  It should be possible to specify other functions
to do the job.

The easiest way to implement these functions will often be to use
a category property.  Then these functions can simply change the
properties of the category, and faces will appear or disappear all thru
the buffer.

In fact, it might make sense to have a buffer-local variable
font-lock-category-alist whose elements look like (CATEGORY-SYMBOL .
FACE-PROP).  If that is non-nil, turning on font-lock-mode just does

  (dolist (elt font-lock-category-alist)
    (put (car elt) 'face (cdr elt)))

and turning it off just does

  (dolist (elt font-lock-category-alist)
    (put (car elt) 'face nil))

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-07 19:22                     ` Alex Schroeder
  2002-05-09 20:09                       ` Colin Walters
@ 2002-05-11  6:30                       ` Richard Stallman
  2002-05-13 22:17                         ` Colin Walters
  1 sibling, 1 reply; 82+ messages in thread
From: Richard Stallman @ 2002-05-11  6:30 UTC (permalink / raw)
  Cc: emacs-devel

    I think the group of people suffering due to Colin's change is small,
    and it knows elisp, so they will be able to customize Emacs to do
    their bidding.

I want it to be implemented in advance.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-11  6:30                       ` Richard Stallman
@ 2002-05-13 22:17                         ` Colin Walters
  2002-05-14  8:36                           ` Miles Bader
                                             ` (2 more replies)
  0 siblings, 3 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-13 22:17 UTC (permalink / raw)


On Sat, 2002-05-11 at 02:30, Richard Stallman wrote:
>     I think the group of people suffering due to Colin's change is small,
>     and it knows elisp, so they will be able to customize Emacs to do
>     their bidding.
> 
> I want it to be implemented in advance.

Ok.  I have a suggestion.  Currently, the only modes I can think of
included with Emacs where typing M-x font-lock-mode twice doesn't work
are Info and shell-mode (can anyone think of any others?).  So, would
anyone object if I changed them to use a `font-lock-fontify-region'
function?  Then the goal of having every mode use 'M-x font-lock-mode'
as an interface to enabling and disabling fontification would be
complete.

All of the other suggestions so far were optimizations, either in time
or memory space.  This may simply not turn out to be necessary;
Searching for text properties is quite fast, and almost every mode now
uses font-lock.el for fontification anyways.  If they do turn out to be
necessary, then we can figure out what the best way to speed things up
and reduce memory usage is.

On a different but tangentially related topic, are there any guesses for
when 21.4 might be out?  If it's going to be (say) two weeks or less,
then maybe it would be better to defer these changes until 21.5 or
after.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-13 22:17                         ` Colin Walters
@ 2002-05-14  8:36                           ` Miles Bader
  2002-05-14 12:49                           ` Emacs 21.4 (was: kill ring menu) Eli Zaretskii
  2002-05-15  7:01                           ` kill ring menu Richard Stallman
  2 siblings, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-14  8:36 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@gnu.org> writes:
> Info and shell-mode
> So, would anyone object if I changed them to use a
> `font-lock-fontify-region' function?

As has been already stated quite a few times -- yes.

> Then the goal of having every mode use 'M-x font-lock-mode' as an
> interface to enabling and disabling fontification would be complete.

This is a nice abstract goal, but it doesn't seem important enough to
even pay the small unnecessary overhead of font-lock.

If you're so bothered by these exceptions to the `rule', why not just do
it right, and implement one of the simpler suggestions made recently
(e.g., have font-lock check for a buffer-local variable holding a
function to do the work of turning on or off fontification, which
defaults to the current font-lock)?

-Miles
-- 
Next to fried food, the South has suffered most from oratory.
  			-- Walter Hines Page

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: Emacs 21.4 (was: kill ring menu)
  2002-05-13 22:17                         ` Colin Walters
  2002-05-14  8:36                           ` Miles Bader
@ 2002-05-14 12:49                           ` Eli Zaretskii
  2002-05-15  7:01                           ` kill ring menu Richard Stallman
  2 siblings, 0 replies; 82+ messages in thread
From: Eli Zaretskii @ 2002-05-14 12:49 UTC (permalink / raw)
  Cc: emacs-devel

> On a different but tangentially related topic, are there any guesses for
> when 21.4 might be out?  If it's going to be (say) two weeks or less,
> then maybe it would be better to defer these changes until 21.5 or
> after.

There's no chance v21.4 will be released that soon, since it didn't
even enter the pretest phase yet.

The next release will be 21.3, which will be made from the RC branch
and will be a bugfix-only release.  I hope to make the first pretest
of 21.3 this weekend.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-13 22:17                         ` Colin Walters
  2002-05-14  8:36                           ` Miles Bader
  2002-05-14 12:49                           ` Emacs 21.4 (was: kill ring menu) Eli Zaretskii
@ 2002-05-15  7:01                           ` Richard Stallman
  2 siblings, 0 replies; 82+ messages in thread
From: Richard Stallman @ 2002-05-15  7:01 UTC (permalink / raw)
  Cc: emacs-devel

    Ok.  I have a suggestion.  Currently, the only modes I can think of
    included with Emacs where typing M-x font-lock-mode twice doesn't work
    are Info and shell-mode (can anyone think of any others?).  So, would
    anyone object if I changed them to use a `font-lock-fontify-region'
    function?

That depends on some details of what changes you have in mind.
Would you please explain more clearly what that change would imply?
What would the user-visible consequences be?  Would it mean that these
modes load font-lock.el in order to do fontification?

Could you do this by moving a minimal amount of the font-lock API into
a preloaded file, so that this will NOT require use of the font-lock
*mechanism* or loading font-lock?

    All of the other suggestions so far were optimizations, either in time
    or memory space.  This may simply not turn out to be necessary;
    Searching for text properties is quite fast, and almost every mode now
    uses font-lock.el for fontification anyways.  If they do turn out to be
    necessary, then we can figure out what the best way to speed things up
    and reduce memory usage is.

This approach says "fall down a long ways, and then think about
climbing up."  Sorry, I don't think this approach is acceptable.
I already made that decision; please don't keep proposing it.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-10  0:30                                 ` Richard Stallman
@ 2002-05-16 18:47                                   ` Colin Walters
  2002-05-16 19:12                                     ` Miles Bader
  2002-05-16 20:12                                     ` Miles Bader
  0 siblings, 2 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-16 18:47 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 1060 bytes --]

On Thu, 2002-05-09 at 20:30, Richard Stallman wrote:

> The easiest way to implement these functions will often be to use
> a category property.  Then these functions can simply change the
> properties of the category, and faces will appear or disappear all thru
> the buffer.
> 
> In fact, it might make sense to have a buffer-local variable
> font-lock-category-alist whose elements look like (CATEGORY-SYMBOL .
> FACE-PROP).  

This solution is genius!  I didn't understand it at all at first, so I
sort of deferred trying to implement it, but after discovering the
`category' text property in the elisp manual it made sense.

Please find attached a patch which implements it, and changes Info,
shell (via comint), occur, and ibuffer to use it.  

I believe this patch addresses everyone's issues.   In particular,
font-core.el is very small, and it is efficient (no runtime searching
for text properties).  

Really, I think info.el should be changed to use a
`font-lock-fontify-region' function; `Info-fontify-maximum-menu-size'
could then just go away.


[-- Attachment #2: font-lock.diff --]
[-- Type: text/plain, Size: 58488 bytes --]

--- /dev/null	Wed Dec 31 19:00:00 1969
+++ lisp/font-core.el	Thu May 16 14:38:10 2002
@@ -0,0 +1,346 @@
+;;; font-core.el --- Core interface to font-lock
+
+;; Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999, 2000, 2001, 2002
+;;  Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+;; Keywords: languages, faces
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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 the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+;; This variable is used by mode packages that support Font Lock mode by
+;; defining their own keywords to use for `font-lock-keywords'.  (The mode
+;; command should make it buffer-local and set it to provide the set up.)
+(defvar font-lock-defaults nil
+  "Defaults for Font Lock mode specified by the major mode.
+Defaults should be of the form:
+
+ (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
+
+KEYWORDS may be a symbol (a variable or function whose value is the keywords to
+use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
+syntactic fontification (strings and comments) is not performed.
+If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
+If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
+\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
+keyword and syntactic fontification (see `modify-syntax-entry').
+
+If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
+backwards outside any enclosing syntactic block, for syntactic fontification.
+Typical values are `beginning-of-line' (i.e., the start of the line is known to
+be outside a syntactic block), or `beginning-of-defun' for programming modes or
+`backward-paragraph' for textual modes (i.e., the mode-dependent function is
+known to move outside a syntactic block).  If nil, the beginning of the buffer
+is used as a position outside of a syntactic block, in the worst case.
+
+These item elements are used by Font Lock mode to set the variables
+`font-lock-keywords', `font-lock-keywords-only',
+`font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
+`font-lock-beginning-of-syntax-function', respectively.
+
+Further item elements are alists of the form (VARIABLE . VALUE) and are in no
+particular order.  Each VARIABLE is made buffer-local before set to VALUE.
+
+Currently, appropriate variables include `font-lock-mark-block-function'.
+If this is non-nil, it should be a function with no args used to mark any
+enclosing block of text, for fontification via \\[font-lock-fontify-block].
+Typical values are `mark-defun' for programming modes or `mark-paragraph' for
+textual modes (i.e., the mode-dependent function is known to put point and mark
+around a text block relevant to that mode).
+
+Other variables include that for syntactic keyword fontification,
+`font-lock-syntactic-keywords'
+and those for buffer-specialised fontification functions,
+`font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function',
+`font-lock-fontify-region-function', `font-lock-unfontify-region-function',
+`font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.")
+(make-variable-buffer-local 'font-lock-defaults)
+
+;; This variable is used where font-lock.el itself supplies the
+;; keywords.  Really, this shouldn't need to be in font-core.el, but
+;; we can't avoid it.  In the future, this stuff will hopefully be
+;; moved to cc-mode itself.
+(defvar font-lock-defaults-alist
+  (let (;; We use `beginning-of-defun', rather than nil, for SYNTAX-BEGIN.
+	;; Thus the calculation of the cache is usually faster but not
+	;; infallible, so we risk mis-fontification.  sm.
+	(c-mode-defaults
+	 '((c-font-lock-keywords c-font-lock-keywords-1
+	    c-font-lock-keywords-2 c-font-lock-keywords-3)
+	   nil nil ((?_ . "w")) beginning-of-defun
+	   (font-lock-syntactic-face-function
+	    . c-font-lock-syntactic-face-function)
+	   (font-lock-mark-block-function . mark-defun)))
+	(c++-mode-defaults
+	 '((c++-font-lock-keywords c++-font-lock-keywords-1
+	    c++-font-lock-keywords-2 c++-font-lock-keywords-3)
+	   nil nil ((?_ . "w")) beginning-of-defun
+	   (font-lock-syntactic-face-function
+	    . c-font-lock-syntactic-face-function)
+	   (font-lock-mark-block-function . mark-defun)))
+	(objc-mode-defaults
+	 '((objc-font-lock-keywords objc-font-lock-keywords-1
+	    objc-font-lock-keywords-2 objc-font-lock-keywords-3)
+	   nil nil ((?_ . "w") (?$ . "w")) nil
+	   (font-lock-syntactic-face-function
+	    . c-font-lock-syntactic-face-function)
+	   (font-lock-mark-block-function . mark-defun)))
+	(java-mode-defaults
+	 '((java-font-lock-keywords java-font-lock-keywords-1
+	    java-font-lock-keywords-2 java-font-lock-keywords-3)
+	   nil nil ((?_ . "w") (?$ . "w")) nil
+	   (font-lock-syntactic-face-function
+	    . java-font-lock-syntactic-face-function)
+	   (font-lock-mark-block-function . mark-defun))))
+    (list
+     (cons 'c-mode			c-mode-defaults)
+     (cons 'c++-mode			c++-mode-defaults)
+     (cons 'objc-mode			objc-mode-defaults)
+     (cons 'java-mode			java-mode-defaults)))
+  "Alist of fall-back Font Lock defaults for major modes.
+
+This variable should not be used any more.
+Set the buffer-local `font-lock-keywords' in the major mode instead.
+
+Each item should be a list of the form:
+
+ (MAJOR-MODE . FONT-LOCK-DEFAULTS)
+
+where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default
+settings.  See the variable `font-lock-defaults', which takes precedence.")
+(make-obsolete-variable 'font-lock-defaults-alist 'font-lock-defaults)
+
+(defvar font-lock-multiline nil
+  "Whether font-lock should cater to multiline keywords.
+If nil, don't try to handle multiline patterns.
+If t, always handle multiline patterns.
+If `undecided', don't try to handle multiline patterns until you see one.
+Major/minor modes can set this variable if they know which option applies.")
+
+(defvar font-lock-fontified nil)	; Whether we have fontified the buffer.
+
+(defvar font-lock-category-alist nil
+  "An alist of (CATEGORY-SYMBOL . FACE-PROP) controlled by Font Lock.
+This variable is intended to be used by special modes which construct
+buffer text for display to the user (i.e. buffer-menu, occur), but
+wish to have fontification turned on and off by Font Lock.  If this
+variable is non-nil, then calling `font-lock-mode' will simply toggle
+the symbol property `face' of CATEGORY-SYMBOL.")
+
+(define-minor-mode font-lock-mode
+  "Toggle Font Lock mode.
+With arg, turn Font Lock mode off if and only if arg is a non-positive
+number; if arg is nil, toggle Font Lock mode; anything else turns Font
+Lock on.
+\(Font Lock is also known as \"syntax highlighting\".)
+
+When Font Lock mode is enabled, text is fontified as you type it:
+
+ - Comments are displayed in `font-lock-comment-face';
+ - Strings are displayed in `font-lock-string-face';
+ - Certain other expressions are displayed in other faces according to the
+   value of the variable `font-lock-keywords'.
+
+To customize the faces (colors, fonts, etc.) used by Font Lock for
+fontifying different parts of buffer text, use \\[customize-face].
+
+You can enable Font Lock mode in any major mode automatically by turning on in
+the major mode's hook.  For example, put in your ~/.emacs:
+
+ (add-hook 'c-mode-hook 'turn-on-font-lock)
+
+Alternatively, you can use Global Font Lock mode to automagically turn on Font
+Lock mode in buffers whose major mode supports it and whose major mode is one
+of `font-lock-global-modes'.  For example, put in your ~/.emacs:
+
+ (global-font-lock-mode t)
+
+There are a number of support modes that may be used to speed up Font Lock mode
+in various ways, specified via the variable `font-lock-support-mode'.  Where
+major modes support different levels of fontification, you can use the variable
+`font-lock-maximum-decoration' to specify which level you generally prefer.
+When you turn Font Lock mode on/off the buffer is fontified/defontified, though
+fontification occurs only if the buffer is less than `font-lock-maximum-size'.
+
+For example, to specify that Font Lock mode use use Lazy Lock mode as a support
+mode and use maximum levels of fontification, put in your ~/.emacs:
+
+ (setq font-lock-support-mode 'lazy-lock-mode)
+ (setq font-lock-maximum-decoration t)
+
+To add your own highlighting for some major mode, and modify the highlighting
+selected automatically via the variable `font-lock-maximum-decoration', you can
+use `font-lock-add-keywords'.
+
+To fontify a buffer, without turning on Font Lock mode and regardless of buffer
+size, you can use \\[font-lock-fontify-buffer].
+
+To fontify a block (the function or paragraph containing point, or a number of
+lines around point), perhaps because modification on the current line caused
+syntactic change on other lines, you can use \\[font-lock-fontify-block].
+
+See the variable `font-lock-defaults-alist' for the Font Lock mode default
+settings.  You can set your own default settings for some mode, by setting a
+buffer local value for `font-lock-defaults', via its mode hook."
+  nil nil nil
+  ;; Don't turn on Font Lock mode if we don't have a display (we're running a
+  ;; batch job) or if the buffer is invisible (the name starts with a space).
+  (when (or noninteractive (eq (aref (buffer-name) 0) ?\ ))
+    (setq font-lock-mode nil))
+
+  ;; Turn on Font Lock mode.
+  (when font-lock-mode
+    (font-lock-set-defaults)
+    (dolist (elt font-lock-category-alist)
+      (put (car elt) 'face (cdr elt)))
+    (when font-lock-defaults
+      (add-hook 'after-change-functions 'font-lock-after-change-function t t)
+      (font-lock-turn-on-thing-lock)
+      ;; Fontify the buffer if we have to.
+      (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
+	(cond (font-lock-fontified
+	       nil)
+	      ((or (null max-size) (> max-size (buffer-size)))
+	       (font-lock-fontify-buffer))
+	      (font-lock-verbose
+	       (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
+			(buffer-name)))))))
+  ;; Turn off Font Lock mode.
+  (unless font-lock-mode
+    (dolist (elt font-lock-category-alist)
+      (put (car elt) 'face nil))
+    (when font-lock-defaults
+      (remove-hook 'after-change-functions 'font-lock-after-change-function t)
+      (font-lock-unfontify-buffer)
+      (font-lock-turn-off-thing-lock))))
+  
+(defun turn-on-font-lock ()
+  "Turn on Font Lock mode (only if the terminal can display it)."
+  (unless font-lock-mode
+    (font-lock-mode)))
+
+(defvar font-lock-set-defaults nil)	; Whether we have set up defaults.
+
+(defun font-lock-set-defaults ()
+  "Set fontification defaults appropriately for this mode.
+Sets various variables using `font-lock-defaults' (or, if nil, using
+`font-lock-defaults-alist') and `font-lock-maximum-decoration'."
+  (unless font-lock-set-defaults
+    (set (make-local-variable 'font-lock-set-defaults) t)
+    (make-local-variable 'font-lock-fontified)
+    (make-local-variable 'font-lock-multiline)
+    ;; Detect if this is a simple mode, which doesn't use any
+    ;; syntactic fontification functions.
+    (unless font-lock-category-alist
+      (require 'font-lock)
+      (font-lock-set-defaults-1))))
+
+;;; Global Font Lock mode.
+
+;; A few people have hassled in the past for a way to make it easier to turn on
+;; Font Lock mode, without the user needing to know for which modes s/he has to
+;; turn it on, perhaps the same way hilit19.el/hl319.el does.  I've always
+;; balked at that way, as I see it as just re-moulding the same problem in
+;; another form.  That is; some person would still have to keep track of which
+;; modes (which may not even be distributed with Emacs) support Font Lock mode.
+;; The list would always be out of date.  And that person might have to be me.
+
+;; Implementation.
+;;
+;; In a previous discussion the following hack came to mind.  It is a gross
+;; hack, but it generally works.  We use the convention that major modes start
+;; by calling the function `kill-all-local-variables', which in turn runs
+;; functions on the hook variable `change-major-mode-hook'.  We attach our
+;; function `font-lock-change-major-mode' to that hook.  Of course, when this
+;; hook is run, the major mode is in the process of being changed and we do not
+;; know what the final major mode will be.  So, `font-lock-change-major-mode'
+;; only (a) notes the name of the current buffer, and (b) adds our function
+;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
+;; `post-command-hook' (for buffers that are not visiting files).  By the time
+;; the functions on the first of these hooks to be run are run, the new major
+;; mode is assumed to be in place.  This way we get a Font Lock function run
+;; when a major mode is turned on, without knowing major modes or their hooks.
+;;
+;; Naturally this requires that (a) major modes run `kill-all-local-variables',
+;; as they are supposed to do, and (b) the major mode is in place after the
+;; file is visited or the command that ran `kill-all-local-variables' has
+;; finished, whichever the sooner.  Arguably, any major mode that does not
+;; follow the convension (a) is broken, and I can't think of any reason why (b)
+;; would not be met (except `gnudoit' on non-files).  However, it is not clean.
+;;
+;; Probably the cleanest solution is to have each major mode function run some
+;; hook, e.g., `major-mode-hook', but maybe implementing that change is
+;; impractical.  I am personally against making `setq' a macro or be advised,
+;; or have a special function such as `set-major-mode', but maybe someone can
+;; come up with another solution?
+
+;; User interface.
+;;
+;; Although Global Font Lock mode is a pseudo-mode, I think that the user
+;; interface should conform to the usual Emacs convention for modes, i.e., a
+;; command to toggle the feature (`global-font-lock-mode') with a variable for
+;; finer control of the mode's behaviour (`font-lock-global-modes').
+;;
+;; The feature should not be enabled by loading font-lock.el, since other
+;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
+;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
+;; turned on everywhere.  That would not be intuitive or informative because
+;; loading a file tells you nothing about the feature or how to control it.  It
+;; would also be contrary to the Principle of Least Surprise.  sm.
+
+(defcustom font-lock-global-modes t
+  "*Modes for which Font Lock mode is automagically turned on.
+Global Font Lock mode is controlled by the command `global-font-lock-mode'.
+If nil, means no modes have Font Lock mode automatically turned on.
+If t, all modes that support Font Lock mode have it automatically turned on.
+If a list, it should be a list of `major-mode' symbol names for which Font Lock
+mode should be automatically turned on.  The sense of the list is negated if it
+begins with `not'.  For example:
+ (c-mode c++-mode)
+means that Font Lock mode is turned on for buffers in C and C++ modes only."
+  :type '(choice (const :tag "none" nil)
+		 (const :tag "all" t)
+		 (set :menu-tag "mode specific" :tag "modes"
+		      :value (not)
+		      (const :tag "Except" not)
+		      (repeat :inline t (symbol :tag "mode"))))
+  :group 'font-lock)
+
+(defun turn-on-font-lock-if-enabled ()
+  (when (and (or font-lock-defaults
+		 font-lock-category-alist
+		 (assq major-mode font-lock-defaults-alist))
+	     (or (eq font-lock-global-modes t)
+		 (if (eq (car-safe font-lock-global-modes) 'not)
+		     (not (memq major-mode (cdr font-lock-global-modes)))
+		   (memq major-mode font-lock-global-modes))))
+    (let (inhibit-quit)
+      (turn-on-font-lock))))
+
+(easy-mmode-define-global-mode
+ global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
+ :extra-args (dummy))
+
+;;; End of Global Font Lock mode.
+
+(provide 'font-core)
+
+;;; font-core.el ends here
+
Index: lisp/comint.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/comint.el,v
retrieving revision 1.270
diff -u -d -u -r1.270 comint.el
--- lisp/comint.el	18 Apr 2002 19:41:57 -0000	1.270
+++ lisp/comint.el	16 May 2002 18:42:42 -0000
@@ -397,7 +397,7 @@
   :type 'boolean
   :group 'comint)
 
-(defcustom comint-mode-hook '()
+(defcustom comint-mode-hook '(font-lock-mode)
   "Called upon entry into `comint-mode'
 This is run before the process is cranked up."
   :type 'hook
@@ -503,6 +503,9 @@
       (setq comint-input-ring-index nil))
   (or (and (boundp 'comint-save-input-ring-index) comint-save-input-ring-index)
       (setq comint-save-input-ring-index nil))
+  (set (make-local-variable 'font-lock-category-alist)
+       '((comint-sent-output comint-highlight-input)
+	 (comint-prompt comint-highlight-prompt)))
   (make-local-variable 'comint-matching-input-from-input-string)
   (make-local-variable 'comint-input-autoexpand)
   (make-local-variable 'comint-input-ignoredups)
@@ -1460,6 +1463,7 @@
 	  (let ((beg (marker-position pmark))
 		(end (if no-newline (point) (1- (point)))))
 	    (when (not (> beg end))	; handle a special case
+	      (put-text-property beg end 'category 'comint-sent-output)
 	      ;; Make an overlay for the input field
 	      (let ((over (make-overlay beg end nil nil t)))
 		(unless comint-use-prompt-regexp-instead-of-fields
@@ -1470,7 +1474,6 @@
 		  ;; and output fields smoother.
 		  (overlay-put over 'field 'input))
 		(when comint-highlight-input
-		  (overlay-put over 'face 'comint-highlight-input)
 		  (overlay-put over 'mouse-face 'highlight)
 		  (overlay-put over
 			       'help-echo
@@ -1713,8 +1716,9 @@
 		    ;; Need to create the overlay
 		    (setq comint-last-prompt-overlay
 			  (make-overlay prompt-start (point)))
-		    (overlay-put comint-last-prompt-overlay
-				 'face 'comint-highlight-prompt)))))
+		    (put-text-property (overlay-start comint-last-prompt-overlay)
+				       (overlay-end comint-last-prompt-overlay)
+				       'category 'comint-prompt)))))
 
 	    (goto-char saved-point)
 
Index: lisp/font-lock.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/font-lock.el,v
retrieving revision 1.195
diff -u -d -u -r1.195 font-lock.el
--- lisp/font-lock.el	30 Mar 2002 08:08:54 -0000	1.195
+++ lisp/font-lock.el	16 May 2002 18:42:42 -0000
@@ -446,106 +446,6 @@
 Be careful when composing regexps for this list; a poorly written pattern can
 dramatically slow things down!")
 
-;; This variable is used by mode packages that support Font Lock mode by
-;; defining their own keywords to use for `font-lock-keywords'.  (The mode
-;; command should make it buffer-local and set it to provide the set up.)
-(defvar font-lock-defaults nil
-  "Defaults for Font Lock mode specified by the major mode.
-Defaults should be of the form:
-
- (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
-
-KEYWORDS may be a symbol (a variable or function whose value is the keywords to
-use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
-syntactic fontification (strings and comments) is not performed.
-If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
-If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
-\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
-keyword and syntactic fontification (see `modify-syntax-entry').
-
-If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
-backwards outside any enclosing syntactic block, for syntactic fontification.
-Typical values are `beginning-of-line' (i.e., the start of the line is known to
-be outside a syntactic block), or `beginning-of-defun' for programming modes or
-`backward-paragraph' for textual modes (i.e., the mode-dependent function is
-known to move outside a syntactic block).  If nil, the beginning of the buffer
-is used as a position outside of a syntactic block, in the worst case.
-
-These item elements are used by Font Lock mode to set the variables
-`font-lock-keywords', `font-lock-keywords-only',
-`font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
-`font-lock-beginning-of-syntax-function', respectively.
-
-Further item elements are alists of the form (VARIABLE . VALUE) and are in no
-particular order.  Each VARIABLE is made buffer-local before set to VALUE.
-
-Currently, appropriate variables include `font-lock-mark-block-function'.
-If this is non-nil, it should be a function with no args used to mark any
-enclosing block of text, for fontification via \\[font-lock-fontify-block].
-Typical values are `mark-defun' for programming modes or `mark-paragraph' for
-textual modes (i.e., the mode-dependent function is known to put point and mark
-around a text block relevant to that mode).
-
-Other variables include that for syntactic keyword fontification,
-`font-lock-syntactic-keywords'
-and those for buffer-specialised fontification functions,
-`font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function',
-`font-lock-fontify-region-function', `font-lock-unfontify-region-function',
-`font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.")
-;;;###autoload
-(make-variable-buffer-local 'font-lock-defaults)
-
-;; This variable is used where font-lock.el itself supplies the keywords.
-(defvar font-lock-defaults-alist
-  (let (;; We use `beginning-of-defun', rather than nil, for SYNTAX-BEGIN.
-	;; Thus the calculation of the cache is usually faster but not
-	;; infallible, so we risk mis-fontification.  sm.
-	(c-mode-defaults
-	 '((c-font-lock-keywords c-font-lock-keywords-1
-	    c-font-lock-keywords-2 c-font-lock-keywords-3)
-	   nil nil ((?_ . "w")) beginning-of-defun
-	   (font-lock-syntactic-face-function
-	    . c-font-lock-syntactic-face-function)
-	   (font-lock-mark-block-function . mark-defun)))
-	(c++-mode-defaults
-	 '((c++-font-lock-keywords c++-font-lock-keywords-1
-	    c++-font-lock-keywords-2 c++-font-lock-keywords-3)
-	   nil nil ((?_ . "w")) beginning-of-defun
-	   (font-lock-syntactic-face-function
-	    . c-font-lock-syntactic-face-function)
-	   (font-lock-mark-block-function . mark-defun)))
-	(objc-mode-defaults
-	 '((objc-font-lock-keywords objc-font-lock-keywords-1
-	    objc-font-lock-keywords-2 objc-font-lock-keywords-3)
-	   nil nil ((?_ . "w") (?$ . "w")) nil
-	   (font-lock-syntactic-face-function
-	    . c-font-lock-syntactic-face-function)
-	   (font-lock-mark-block-function . mark-defun)))
-	(java-mode-defaults
-	 '((java-font-lock-keywords java-font-lock-keywords-1
-	    java-font-lock-keywords-2 java-font-lock-keywords-3)
-	   nil nil ((?_ . "w") (?$ . "w")) nil
-	   (font-lock-syntactic-face-function
-	    . java-font-lock-syntactic-face-function)
-	   (font-lock-mark-block-function . mark-defun))))
-    (list
-     (cons 'c-mode			c-mode-defaults)
-     (cons 'c++-mode			c++-mode-defaults)
-     (cons 'objc-mode			objc-mode-defaults)
-     (cons 'java-mode			java-mode-defaults)))
-  "Alist of fall-back Font Lock defaults for major modes.
-
-This variable should not be used any more.
-Set the buffer-local `font-lock-keywords' in the major mode instead.
-
-Each item should be a list of the form:
-
- (MAJOR-MODE . FONT-LOCK-DEFAULTS)
-
-where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default
-settings.  See the variable `font-lock-defaults', which takes precedence.")
-(make-obsolete-variable 'font-lock-defaults-alist 'font-lock-defaults)
-
 (defvar font-lock-keywords-alist nil
   "*Alist of `font-lock-keywords' local to a `major-mode'.
 This is normally set via `font-lock-add-keywords' and
@@ -657,14 +557,6 @@
 Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
 `lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
 
-(defvar font-lock-multiline nil
-  "Whether font-lock should cater to multiline keywords.
-If nil, don't try to handle multiline patterns.
-If t, always handle multiline patterns.
-If `undecided', don't try to handle multiline patterns until you see one.
-Major/minor modes can set this variable if they know which option applies.")
-
-(defvar font-lock-fontified nil)	; Whether we have fontified the buffer.
 \f
 ;; Font Lock mode.
 
@@ -698,94 +590,6 @@
   (defvar font-lock-face-attributes))	; Obsolete but respected if set.
 
 ;;;###autoload
-(define-minor-mode font-lock-mode
-  "Toggle Font Lock mode.
-With arg, turn Font Lock mode off if and only if arg is a non-positive
-number; if arg is nil, toggle Font Lock mode; anything else turns Font
-Lock on.
-\(Font Lock is also known as \"syntax highlighting\".)
-
-When Font Lock mode is enabled, text is fontified as you type it:
-
- - Comments are displayed in `font-lock-comment-face';
- - Strings are displayed in `font-lock-string-face';
- - Certain other expressions are displayed in other faces according to the
-   value of the variable `font-lock-keywords'.
-
-To customize the faces (colors, fonts, etc.) used by Font Lock for
-fontifying different parts of buffer text, use \\[customize-face].
-
-You can enable Font Lock mode in any major mode automatically by turning on in
-the major mode's hook.  For example, put in your ~/.emacs:
-
- (add-hook 'c-mode-hook 'turn-on-font-lock)
-
-Alternatively, you can use Global Font Lock mode to automagically turn on Font
-Lock mode in buffers whose major mode supports it and whose major mode is one
-of `font-lock-global-modes'.  For example, put in your ~/.emacs:
-
- (global-font-lock-mode t)
-
-There are a number of support modes that may be used to speed up Font Lock mode
-in various ways, specified via the variable `font-lock-support-mode'.  Where
-major modes support different levels of fontification, you can use the variable
-`font-lock-maximum-decoration' to specify which level you generally prefer.
-When you turn Font Lock mode on/off the buffer is fontified/defontified, though
-fontification occurs only if the buffer is less than `font-lock-maximum-size'.
-
-For example, to specify that Font Lock mode use use Lazy Lock mode as a support
-mode and use maximum levels of fontification, put in your ~/.emacs:
-
- (setq font-lock-support-mode 'lazy-lock-mode)
- (setq font-lock-maximum-decoration t)
-
-To add your own highlighting for some major mode, and modify the highlighting
-selected automatically via the variable `font-lock-maximum-decoration', you can
-use `font-lock-add-keywords'.
-
-To fontify a buffer, without turning on Font Lock mode and regardless of buffer
-size, you can use \\[font-lock-fontify-buffer].
-
-To fontify a block (the function or paragraph containing point, or a number of
-lines around point), perhaps because modification on the current line caused
-syntactic change on other lines, you can use \\[font-lock-fontify-block].
-
-See the variable `font-lock-defaults-alist' for the Font Lock mode default
-settings.  You can set your own default settings for some mode, by setting a
-buffer local value for `font-lock-defaults', via its mode hook."
-  nil nil nil
-  ;; Don't turn on Font Lock mode if we don't have a display (we're running a
-  ;; batch job) or if the buffer is invisible (the name starts with a space).
-  (when (or noninteractive (eq (aref (buffer-name) 0) ?\ ))
-    (setq font-lock-mode nil))
-
-  ;; Turn on Font Lock mode.
-  (when font-lock-mode
-    (add-hook 'after-change-functions 'font-lock-after-change-function t t)
-    (font-lock-set-defaults)
-    (font-lock-turn-on-thing-lock)
-    ;; Fontify the buffer if we have to.
-    (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
-      (cond (font-lock-fontified
-	     nil)
-	    ((or (null max-size) (> max-size (buffer-size)))
-	     (font-lock-fontify-buffer))
-	    (font-lock-verbose
-	     (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
-		      (buffer-name))))))
-  ;; Turn off Font Lock mode.
-  (unless font-lock-mode
-    (remove-hook 'after-change-functions 'font-lock-after-change-function t)
-    (font-lock-unfontify-buffer)
-    (font-lock-turn-off-thing-lock)))
-
-;;;###autoload
-(defun turn-on-font-lock ()
-  "Turn on Font Lock mode (only if the terminal can display it)."
-  (unless font-lock-mode
-    (font-lock-mode)))
-
-;;;###autoload
 (defun font-lock-add-keywords (mode keywords &optional append)
   "Add highlighting KEYWORDS for MODE.
 MODE should be a symbol, the major mode command name, such as `c-mode'
@@ -937,94 +741,6 @@
 			 (delete (font-lock-compile-keyword keyword)
 				 font-lock-keywords)))))))
 \f
-;;; Global Font Lock mode.
-
-;; A few people have hassled in the past for a way to make it easier to turn on
-;; Font Lock mode, without the user needing to know for which modes s/he has to
-;; turn it on, perhaps the same way hilit19.el/hl319.el does.  I've always
-;; balked at that way, as I see it as just re-moulding the same problem in
-;; another form.  That is; some person would still have to keep track of which
-;; modes (which may not even be distributed with Emacs) support Font Lock mode.
-;; The list would always be out of date.  And that person might have to be me.
-
-;; Implementation.
-;;
-;; In a previous discussion the following hack came to mind.  It is a gross
-;; hack, but it generally works.  We use the convention that major modes start
-;; by calling the function `kill-all-local-variables', which in turn runs
-;; functions on the hook variable `change-major-mode-hook'.  We attach our
-;; function `font-lock-change-major-mode' to that hook.  Of course, when this
-;; hook is run, the major mode is in the process of being changed and we do not
-;; know what the final major mode will be.  So, `font-lock-change-major-mode'
-;; only (a) notes the name of the current buffer, and (b) adds our function
-;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
-;; `post-command-hook' (for buffers that are not visiting files).  By the time
-;; the functions on the first of these hooks to be run are run, the new major
-;; mode is assumed to be in place.  This way we get a Font Lock function run
-;; when a major mode is turned on, without knowing major modes or their hooks.
-;;
-;; Naturally this requires that (a) major modes run `kill-all-local-variables',
-;; as they are supposed to do, and (b) the major mode is in place after the
-;; file is visited or the command that ran `kill-all-local-variables' has
-;; finished, whichever the sooner.  Arguably, any major mode that does not
-;; follow the convension (a) is broken, and I can't think of any reason why (b)
-;; would not be met (except `gnudoit' on non-files).  However, it is not clean.
-;;
-;; Probably the cleanest solution is to have each major mode function run some
-;; hook, e.g., `major-mode-hook', but maybe implementing that change is
-;; impractical.  I am personally against making `setq' a macro or be advised,
-;; or have a special function such as `set-major-mode', but maybe someone can
-;; come up with another solution?
-
-;; User interface.
-;;
-;; Although Global Font Lock mode is a pseudo-mode, I think that the user
-;; interface should conform to the usual Emacs convention for modes, i.e., a
-;; command to toggle the feature (`global-font-lock-mode') with a variable for
-;; finer control of the mode's behaviour (`font-lock-global-modes').
-;;
-;; The feature should not be enabled by loading font-lock.el, since other
-;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
-;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
-;; turned on everywhere.  That would not be intuitive or informative because
-;; loading a file tells you nothing about the feature or how to control it.  It
-;; would also be contrary to the Principle of Least Surprise.  sm.
-
-(defcustom font-lock-global-modes t
-  "*Modes for which Font Lock mode is automagically turned on.
-Global Font Lock mode is controlled by the command `global-font-lock-mode'.
-If nil, means no modes have Font Lock mode automatically turned on.
-If t, all modes that support Font Lock mode have it automatically turned on.
-If a list, it should be a list of `major-mode' symbol names for which Font Lock
-mode should be automatically turned on.  The sense of the list is negated if it
-begins with `not'.  For example:
- (c-mode c++-mode)
-means that Font Lock mode is turned on for buffers in C and C++ modes only."
-  :type '(choice (const :tag "none" nil)
-		 (const :tag "all" t)
-		 (set :menu-tag "mode specific" :tag "modes"
-		      :value (not)
-		      (const :tag "Except" not)
-		      (repeat :inline t (symbol :tag "mode"))))
-  :group 'font-lock)
-
-(defun turn-on-font-lock-if-enabled ()
-  (when (and (or font-lock-defaults
-		 (assq major-mode font-lock-defaults-alist))
-	     (or (eq font-lock-global-modes t)
-		 (if (eq (car-safe font-lock-global-modes) 'not)
-		     (not (memq major-mode (cdr font-lock-global-modes)))
-		   (memq major-mode font-lock-global-modes))))
-    (let (inhibit-quit)
-      (turn-on-font-lock))))
-
-;;;###autoload
-(easy-mmode-define-global-mode
- global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
- :extra-args (dummy))
-
-;;; End of Global Font Lock mode.
-\f
 ;;; Font Lock Support mode.
 
 ;; This is the code used to interface font-lock.el with any of its add-on
@@ -1718,60 +1434,50 @@
 	(t
 	 (car keywords))))
 
-(defvar font-lock-set-defaults nil)	; Whether we have set up defaults.
-
-(defun font-lock-set-defaults ()
-  "Set fontification defaults appropriately for this mode.
-Sets various variables using `font-lock-defaults' (or, if nil, using
-`font-lock-defaults-alist') and `font-lock-maximum-decoration'."
-  ;; Set fontification defaults iff not previously set.
-  (unless font-lock-set-defaults
-    (set (make-local-variable 'font-lock-set-defaults)		t)
-    (make-local-variable 'font-lock-fontified)
-    (make-local-variable 'font-lock-multiline)
-    (let* ((defaults (or font-lock-defaults
-			 (cdr (assq major-mode font-lock-defaults-alist))))
-	   (keywords
-	    (font-lock-choose-keywords (nth 0 defaults)
-	     (font-lock-value-in-major-mode font-lock-maximum-decoration)))
-	   (local (cdr (assq major-mode font-lock-keywords-alist)))
-	   (removed-keywords
-	    (cdr-safe (assq major-mode font-lock-removed-keywords-alist))))
-      ;; Syntactic fontification?
-      (when (nth 1 defaults)
-	(set (make-local-variable 'font-lock-keywords-only) t))
-      ;; Case fold during regexp fontification?
-      (when (nth 2 defaults)
-	(set (make-local-variable 'font-lock-keywords-case-fold-search) t))
-      ;; Syntax table for regexp and syntactic fontification?
-      (when (nth 3 defaults)
-	(set (make-local-variable 'font-lock-syntax-table)
-	     (copy-syntax-table (syntax-table)))
-	(dolist (selem (nth 3 defaults))
-	  ;; The character to modify may be a single CHAR or a STRING.
-	  (let ((syntax (cdr selem)))
-	    (dolist (char (if (numberp (car selem))
-			      (list (car selem))
-			    (mapcar 'identity (car selem))))
-	      (modify-syntax-entry char syntax font-lock-syntax-table)))))
-      ;; Syntax function for syntactic fontification?
-      (when (nth 4 defaults)
-	(set (make-local-variable 'font-lock-beginning-of-syntax-function)
-	     (nth 4 defaults)))
-      ;; Variable alist?
-      (dolist (x (nthcdr 5 defaults))
-	(set (make-local-variable (car x)) (cdr x)))
-      ;; Setup `font-lock-keywords' last because its value might depend
-      ;; on other settings (e.g. font-lock-compile-keywords uses
-      ;; font-lock-beginning-of-syntax-function).
-      (set (make-local-variable 'font-lock-keywords)
-	   (font-lock-compile-keywords (font-lock-eval-keywords keywords) t))
-      ;; Local fontification?
-      (while local
-	(font-lock-add-keywords nil (car (car local)) (cdr (car local)))
-	(setq local (cdr local)))
-      (when removed-keywords
-	(font-lock-remove-keywords nil removed-keywords)))))
+(defun font-lock-set-defaults-1 ()
+  (let* ((defaults (or font-lock-defaults
+		       (cdr (assq major-mode font-lock-defaults-alist))))
+	 (keywords
+	  (font-lock-choose-keywords (nth 0 defaults)
+				     (font-lock-value-in-major-mode font-lock-maximum-decoration)))
+	 (local (cdr (assq major-mode font-lock-keywords-alist)))
+	 (removed-keywords
+	  (cdr-safe (assq major-mode font-lock-removed-keywords-alist))))
+    ;; Syntactic fontification?
+    (when (nth 1 defaults)
+      (set (make-local-variable 'font-lock-keywords-only) t))
+    ;; Case fold during regexp fontification?
+    (when (nth 2 defaults)
+      (set (make-local-variable 'font-lock-keywords-case-fold-search) t))
+    ;; Syntax table for regexp and syntactic fontification?
+    (when (nth 3 defaults)
+      (set (make-local-variable 'font-lock-syntax-table)
+	   (copy-syntax-table (syntax-table)))
+      (dolist (selem (nth 3 defaults))
+	;; The character to modify may be a single CHAR or a STRING.
+	(let ((syntax (cdr selem)))
+	  (dolist (char (if (numberp (car selem))
+			    (list (car selem))
+			  (mapcar 'identity (car selem))))
+	    (modify-syntax-entry char syntax font-lock-syntax-table)))))
+    ;; Syntax function for syntactic fontification?
+    (when (nth 4 defaults)
+      (set (make-local-variable 'font-lock-beginning-of-syntax-function)
+	   (nth 4 defaults)))
+    ;; Variable alist?
+    (dolist (x (nthcdr 5 defaults))
+      (set (make-local-variable (car x)) (cdr x)))
+    ;; Setup `font-lock-keywords' last because its value might depend
+    ;; on other settings (e.g. font-lock-compile-keywords uses
+    ;; font-lock-beginning-of-syntax-function).
+    (set (make-local-variable 'font-lock-keywords)
+	 (font-lock-compile-keywords (font-lock-eval-keywords keywords) t))
+    ;; Local fontification?
+    (while local
+      (font-lock-add-keywords nil (car (car local)) (cdr (car local)))
+      (setq local (cdr local)))
+    (when removed-keywords
+      (font-lock-remove-keywords nil removed-keywords))))
 \f
 ;;; Colour etc. support.
 
Index: lisp/info.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/info.el,v
retrieving revision 1.298
diff -u -d -u -r1.298 info.el
--- lisp/info.el	8 May 2002 14:38:30 -0000	1.298
+++ lisp/info.el	16 May 2002 18:42:43 -0000
@@ -55,11 +55,6 @@
 The Lisp code is executed when the node is selected.")
 (put 'Info-enable-active-nodes 'risky-local-variable t)
 
-(defcustom Info-fontify t
-  "*Non-nil enables highlighting and fonts in Info nodes."
-  :type 'boolean
-  :group 'info)
-
 (defface info-node
   '((((class color) (background light)) (:foreground "brown" :weight bold :slant italic))
     (((class color) (background dark)) (:foreground "white" :weight bold :slant italic))
@@ -150,6 +145,11 @@
   :type 'boolean
   :group 'info)
 
+(defcustom Info-mode-hook '(font-lock-mode)
+  "Hooks run when `info-mode' is called."
+  :type 'hook
+  :group 'info)
+
 (defvar Info-current-file nil
   "Info file that Info is now looking at, or nil.
 This is the name that was specified in Info, not the actual file name.
@@ -997,7 +997,7 @@
 					    (read (current-buffer))))))
 			    (point-max)))
 	(if Info-enable-active-nodes (eval active-expression))
-	(if Info-fontify (Info-fontify-node))
+	(Info-fontify-node)
 	(if Info-use-header-line
 	    (Info-setup-header-line)
 	  (setq Info-header-line nil)
@@ -2340,6 +2340,16 @@
   (setq Info-tag-table-marker (make-marker))
   (make-local-variable 'Info-tag-table-buffer)
   (setq Info-tag-table-buffer nil)
+  (set (make-local-variable 'font-lock-category-alist)
+       '((info-menu-header . info-menu-header)
+	 (info-header-node . info-header-node)
+	 (info-header-xref . info-header-xref)
+	 (Info-title-1-face . Info-title-1-face)
+	 (Info-title-2-face . Info-title-2-face)
+	 (Info-title-3-face . Info-title-3-face)
+	 (Info-title-4-face . Info-title-4-face)
+	 (info-menu-5 . info-menu-5)
+	 (info-xref . info-xref)))
   (make-local-variable 'Info-history)
   (make-local-variable 'Info-index-alternatives)
   (set (make-local-variable 'tool-bar-map) info-tool-bar-map)
@@ -2587,10 +2597,10 @@
     (goto-char (point-min))
     (when (re-search-forward "\\* Menu:" nil t)
       (put-text-property (match-beginning 0) (match-end 0)
-			 'face 'info-menu-header)
+			 'category 'info-menu-header)
       (while (re-search-forward "\n\n\\([^*\n ].*\\)\n\n?[*]" nil t)
 	(put-text-property (match-beginning 1) (match-end 1)
-			   'face 'info-menu-header)))))
+			   'category 'info-menu-header)))))
 
 (defun Info-fontify-node ()
   ;; Only fontify the node if it hasn't already been done.  [We pass in
@@ -2618,8 +2628,8 @@
 		   (tbeg (match-beginning 1))
 		   (tag (buffer-substring tbeg (match-end 1))))
 	      (if (string-equal tag "Node")
-		  (put-text-property nbeg nend 'face 'info-header-node)
-		(put-text-property nbeg nend 'face 'info-header-xref)
+		  (put-text-property nbeg nend 'category 'info-header-node)
+		(put-text-property nbeg nend 'category 'info-header-xref)
 		(put-text-property tbeg nend 'mouse-face 'highlight)
 		(put-text-property tbeg nend
 				   'help-echo
@@ -2646,14 +2656,14 @@
 	(goto-char (point-min))
 	(while (re-search-forward "\n\\([^ \t\n].+\\)\n\\(\\*+\\|=+\\|-+\\|\\.+\\)$"
 				  nil t)
-	  (let ((c (preceding-char))
-		face)
-	    (cond ((= c ?*) (setq face 'Info-title-1-face))
-		  ((= c ?=) (setq face 'Info-title-2-face))
-		  ((= c ?-) (setq face 'Info-title-3-face))
-		  (t        (setq face 'Info-title-4-face)))
+	  (let* ((c (preceding-char))
+		 (category
+		  (cond ((= c ?*) 'Info-title-1-face)
+			((= c ?=) 'Info-title-2-face)
+			((= c ?-) 'Info-title-3-face)
+			(t        'Info-title-4-face))))
 	    (put-text-property (match-beginning 1) (match-end 1)
-			       'face face))
+			       'category category))
 	  ;; This is a serious problem for trying to handle multiple
 	  ;; frame types at once.  We want this text to be invisible
 	  ;; on frames that can display the font above.
@@ -2665,7 +2675,7 @@
 	  (if (= (char-after (1- (match-beginning 0))) ?\") ; hack
 	      nil
 	    (add-text-properties (match-beginning 1) (match-end 1)
-				 '(face info-xref
+				 '(category info-xref
 				   mouse-face highlight
 				   help-echo "mouse-2: go to this node"))))
 	(goto-char (point-min))
@@ -2679,9 +2689,9 @@
 		(if (zerop (% n 3)) ; visual aids to help with 1-9 keys
 		    (put-text-property (match-beginning 0)
 				       (1+ (match-beginning 0))
-				       'face 'info-menu-5))
+				       'category 'info-menu-5))
 		(add-text-properties (match-beginning 1) (match-end 1)
-				     '(face info-xref
+				     '(category info-xref
 				       mouse-face highlight
 				       help-echo "mouse-2: go to this node")))))
 	(Info-fontify-menu-headers)
Index: lisp/replace.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/replace.el,v
retrieving revision 1.143
diff -u -d -u -r1.143 replace.el
--- lisp/replace.el	15 May 2002 19:35:54 -0000	1.143
+++ lisp/replace.el	16 May 2002 18:42:43 -0000
@@ -453,6 +453,11 @@
   "Arguments to pass to `occur-1' to revert an Occur mode buffer.
 See `occur-revert-function'.")
 
+(defcustom occur-mode-hook '(font-lock-mode)
+  "Hooks run when `occur' is called."
+  :type 'hook
+  :group 'matching)
+
 (put 'occur-mode 'mode-class 'special)
 (defun occur-mode ()
   "Major mode for output from \\[occur].
@@ -466,9 +471,9 @@
   (setq major-mode 'occur-mode)
   (setq mode-name "Occur")
   (make-local-variable 'revert-buffer-function)
-  (set (make-local-variable 'font-lock-defaults)
-       '(nil t nil nil nil
-	     (font-lock-fontify-region-function . occur-fontify-region-function)))
+  (set (make-local-variable 'font-lock-category-alist)
+       '((occur-match . bold)
+	 (occur-title . underline)))
   (setq revert-buffer-function 'occur-revert-function)
   (set (make-local-variable 'revert-buffer-function) 'occur-revert-function)
   (make-local-variable 'occur-revert-arguments)
@@ -785,7 +790,7 @@
 			(add-text-properties (match-beginning 0)
 					     (match-end 0)
 					     (append
-					      '(occur-match t)
+					      '(occur-match t category occur-match)
 					      (when match-face
 						`(face ,match-face)))
 					     curstring)
@@ -797,7 +802,7 @@
 				    (append
 				     (when prefix-face
 				       `(face prefix-face))
-				     '(occur-prefix t)))
+				     '(occur-prefix t category occur-prefix)))
 			     curstring
 			     "\n"))
 			   (data
@@ -842,35 +847,10 @@
 				       (append
 					(when title-face
 					  `(face ,title-face))
-					`(occur-title ,buf))))
+					`(occur-title t category occur-title))))
 		(goto-char (point-min)))))))
       ;; Return the number of matches
       globalcount)))
-
-(defun occur-fontify-on-property (prop face beg end)
-  (let ((prop-beg (or (and (get-text-property (point) prop) (point))
-		      (next-single-property-change (point) prop nil end))))
-    (when (and prop-beg (not (= prop-beg end)))
-      (let ((prop-end (next-single-property-change beg prop nil end)))
-	(when (and prop-end (not (= prop-end end)))
-	  (put-text-property prop-beg prop-end 'face face)
-	  prop-end)))))
-
-(defun occur-fontify-region-function (beg end &optional verbose)
-  (when verbose (message "Fontifying..."))
-  (let ((inhibit-read-only t))
-    (save-excursion
-      (dolist (e `((occur-title . ,list-matching-lines-buffer-name-face)
-		   (occur-match . ,list-matching-lines-face)))
-		   ; (occur-prefix . ,list-matching-lines-prefix-face)))
-	(goto-char beg)
-	(let ((change-end nil))
-	  (while (setq change-end (occur-fontify-on-property (car e)
-							     (cdr e)
-							     (point)
-							     end))
-	    (goto-char change-end))))))
-  (when verbose (message "Fontifying...done")))
 
 \f
 ;; It would be nice to use \\[...], but there is no reasonable way
Index: lisp/ibuffer.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/ibuffer.el,v
retrieving revision 1.29
diff -u -d -u -r1.29 ibuffer.el
--- lisp/ibuffer.el	13 May 2002 06:00:06 -0000	1.29
+++ lisp/ibuffer.el	16 May 2002 18:42:42 -0000
@@ -36,6 +36,8 @@
   (require 'ibuf-macs)
   (require 'dired))
 
+(require 'font-lock)
+
 ;;; Compatibility
 (eval-and-compile
   (if (fboundp 'window-list)
@@ -44,18 +46,7 @@
     (defun ibuffer-window-list ()
       (let ((ibuffer-window-list-result nil))
 	(walk-windows #'(lambda (win) (push win ibuffer-window-list-result)) 'nomini)
-	(nreverse ibuffer-window-list-result))))
-
-  (cond ((boundp 'global-font-lock-mode)
-	 (defsubst ibuffer-use-fontification ()
-	   (when (boundp 'font-lock-mode)
-	     font-lock-mode)))
-	((boundp 'font-lock-auto-fontify)
-	 (defsubst ibuffer-use-fontification ()
-	   font-lock-auto-fontify))
-	(t
-	 (defsubst ibuffer-use-fontification ()
-	   nil))))
+	(nreverse ibuffer-window-list-result)))))
 
 (defgroup ibuffer nil
   "An advanced replacement for `buffer-menu'.
@@ -67,7 +58,7 @@
 
 (defcustom ibuffer-formats '((mark modified read-only " " (name 16 16 :left :elide)
 				   " " (size 6 -1 :right)
-				   " " (mode 16 16 :right :elide) " " filename)
+				   " " (mode 16 16 :right :elide) " " filename-and-process)
 			     (mark " " (name 16 -1) " " filename))
   "A list of ways to display buffer lines.
 
@@ -152,7 +143,10 @@
 PRIORITY is an integer, FORM is an arbitrary form to evaluate in the
 buffer, and FACE is the face to use for fontification.  If the FORM
 evaluates to non-nil, then FACE will be put on the buffer name.  The
-element with the highest PRIORITY takes precedence."
+element with the highest PRIORITY takes precedence.
+
+If you change this variable, you must kill the ibuffer buffer and
+recreate it for the change to take effect."
   :type '(repeat
 	  (list (integer :tag "Priority")
 		(sexp :tag "Test Form")
@@ -1361,9 +1355,8 @@
     form))
   
 (defun ibuffer-compile-make-eliding-form (strvar elide from-end-p)
-  (let ((ellipsis (if (ibuffer-use-fontification) 
-		      (propertize ibuffer-eliding-string 'face 'bold)
-		    ibuffer-eliding-string)))
+  (let ((ellipsis (propertize ibuffer-eliding-string 'category
+			      'ibuffer-eliding-string)))
     (if (or elide ibuffer-elide-long-columns)
 	`(if (> strlen 5)
 	     ,(if from-end-p
@@ -1474,8 +1467,16 @@
 					(put ',sym 'ibuffer-column-summary
 					     (cons ret (get ',sym 'ibuffer-column-summary)))
 					ret)))
-				  (lambda (arg sym)
-				    `(insert ,arg))))
+				  ;; We handle the `name' column specially.
+				  (if (eq sym 'ibuffer-make-column-name)
+				      (lambda (arg sym)
+					`(let ((pt (point)))
+					   (insert ,arg)
+					   (put-text-property pt (point)
+							      'category
+							      (ibuffer-buffer-name-category buffer mark))))
+				    (lambda (arg sym)
+				      `(insert ,arg)))))
 		   (mincompform `(< strlen ,(if (integerp min)
 						min
 					      'min)))
@@ -1633,6 +1634,13 @@
 	      dired-directory)
 	 ""))))
 
+(define-ibuffer-column filename-and-process (:name "Filename/Process")
+  (let ((proc (get-buffer-process buffer))
+	(filename (ibuffer-make-column-filename buffer mark)))
+    (if proc
+	(format "(%s %s) %s" proc (process-status proc) filename)
+      filename)))
+
 (defun ibuffer-format-column (str width alignment)
   (let ((left (make-string (/ width 2) ? ))
 	(right (make-string (- width (/ width 2)) ? )))
@@ -1641,52 +1649,23 @@
       (:center (concat left str right))
       (t (concat str left right)))))
 
-(defun ibuffer-fontify-region-function (beg end &optional verbose)
-  (when verbose (message "Fontifying..."))
-  (let ((inhibit-read-only t))
-    (save-excursion
-      (goto-char beg)
-      (beginning-of-line)
-      (while (< (point) end)
-	(if (get-text-property (point) 'ibuffer-title-header)
-	    (put-text-property (point) (line-end-position) 'face ibuffer-title-face)
-	  (if (get-text-property (point) 'ibuffer-filter-group-name)
-	      (put-text-property (point) (line-end-position) 'face
-				 ibuffer-filter-group-name-face)
-	    (unless (or (get-text-property (point) 'ibuffer-title)
-			(get-text-property (point) 'ibuffer-summary))
-	      (multiple-value-bind (buf mark)
-		  (get-text-property (point) 'ibuffer-properties)
-		(let* ((namebeg (next-single-property-change (point) 'ibuffer-name-column
-							     nil (line-end-position)))
-		       (nameend (next-single-property-change namebeg 'ibuffer-name-column
-							     nil (line-end-position))))
-		  (put-text-property namebeg
-				     nameend
-				     'face
-				     (cond ((char-equal mark ibuffer-marked-char)
-					    ibuffer-marked-face)
-					   ((char-equal mark ibuffer-deletion-char)
-					    ibuffer-deletion-face)
-					   (t
-					    (let ((level -1)
-						  result)
-					      (dolist (e ibuffer-fontification-alist result)
-						(when (and (> (car e) level)
-							   (with-current-buffer buf
-							     (eval (cadr e))))
-						  (setq level (car e)
-							result
-							(if (symbolp (caddr e))
-							    (if (facep (caddr e))
-								(caddr e)
-							      (symbol-value (caddr e))))))))))))))))
-	(forward-line 1))))
-  (when verbose (message "Fontifying...done")))
-
-(defun ibuffer-unfontify-region-function (beg end)
-  (let ((inhibit-read-only t))
-    (remove-text-properties beg end '(face nil))))
+(defun ibuffer-buffer-name-category (buf mark)
+  (cond ((char-equal mark ibuffer-marked-char)
+	 'ibuffer-category-marked)
+	((char-equal mark ibuffer-deletion-char)
+	 'ibuffer-category-deleted)
+	(t
+	 (let ((counter 0)
+	       (level -1)
+	       result)
+	   (dolist (e ibuffer-fontification-alist result)
+	     (when (and (> (car e) level)
+			(with-current-buffer buf
+			  (eval (cadr e))))
+	       (setq level (car e)
+		     result
+		     (intern (format "ibuffer-category-%d" counter))))
+	     (incf counter))))))
 
 (defun ibuffer-insert-buffer-line (buffer mark format)
   "Insert a line describing BUFFER and MARK using FORMAT."
@@ -1898,7 +1877,7 @@
 		       (next-single-property-change
 			(point-min) 'ibuffer-title)))
     (goto-char (point-min))
-    (put-text-property
+    (add-text-properties
      (point)
      (progn
        (let ((opos (point)))
@@ -1922,7 +1901,8 @@
 					     (- min len)
 					     align)
 		    name))))))
-	 (put-text-property opos (point) 'ibuffer-title-header t)
+	 (add-text-properties opos (point) '(ibuffer-title-header
+					     t category ibuffer-title-header))
 	 (insert "\n")
 	 ;; Add the underlines
 	 (let ((str (save-excursion
@@ -1938,14 +1918,14 @@
 			    str)))
 	 (insert "\n"))
        (point))
-     'ibuffer-title t)
+     '(ibuffer-title t category ibuffer-title))
     ;; Now, insert the summary columns.
     (goto-char (point-max))
     (if (get-text-property (1- (point-max)) 'ibuffer-summary)
 	(delete-region (previous-single-property-change
 			(point-max) 'ibuffer-summary)
 		       (point-max)))
-    (put-text-property
+    (add-text-properties
      (point)
      (progn
        (insert "\n")
@@ -1972,7 +1952,7 @@
 					     align)
 		    summary)))))))
        (point))
-     'ibuffer-summary t)))
+     '(ibuffer-summary t category ibuffer-summary))))
 
 (defun ibuffer-update-mode-name ()
   (setq mode-name (format "Ibuffer by %s" (if ibuffer-sorting-mode
@@ -2080,9 +2060,11 @@
    (progn
      (insert "[ " display-name " ]")
      (point))
-   `(ibuffer-filter-group-name ,name keymap ,ibuffer-mode-filter-group-map
-			       mouse-face highlight
-			       help-echo ,(concat filter-string "mouse-1: toggle marks in this group\nmouse-2: hide/show this filtering group ")))
+   `(ibuffer-filter-group-name
+     ,name
+     category ibuffer-filter-group-name keymap ,ibuffer-mode-filter-group-map
+     mouse-face highlight
+     help-echo ,(concat filter-string "mouse-1: toggle marks in this group\nmouse-2: hide/show this filtering group ")))
   (insert "\n")
   (when bmarklist
     (put-text-property
@@ -2169,7 +2151,7 @@
 
 ;;;###autoload
 (defun ibuffer (&optional other-window-p name qualifiers noselect
-			  shrink filter-groups)
+			  shrink filter-groups formats)
   "Begin using `ibuffer' to edit a list of buffers.
 Type 'h' after entering ibuffer for more information.
 
@@ -2182,7 +2164,10 @@
 Optional argument SHRINK means shrink the buffer to minimal size.  The
 special value `onewindow' means always use another window.
 Optional argument FILTER-GROUPS is an initial set of filtering
-groups to use; see `ibuffer-filter-groups'."
+groups to use; see `ibuffer-filter-groups'.
+Optional argument FORMATS is the value to use for `ibuffer-formats'.
+If specified, then the variable `ibuffer-formats' will have that value
+locally in this buffer."
   (interactive "P")
   (when ibuffer-use-other-window
     (setq other-window-p t))
@@ -2200,8 +2185,6 @@
 	(unless (eq major-mode 'ibuffer-mode)
 	  (ibuffer-mode)
 	  (setq need-update t))
-	(when (ibuffer-use-fontification)
-	  (require 'font-lock))
 	(setq ibuffer-delete-window-on-quit other-window-p)
 	(when shrink
 	  (setq ibuffer-shrink-to-minimum-size shrink))
@@ -2211,6 +2194,8 @@
 	(when filter-groups
 	  (require 'ibuf-ext)
 	  (setq ibuffer-filter-groups filter-groups))
+	(when formats
+	  (set (make-local-variable 'ibuffer-formats) formats))
 	(ibuffer-update nil)
 	;; Skip the group name by default.
 	(ibuffer-forward-line 0 t)
@@ -2406,12 +2391,16 @@
   ;; This makes things less ugly for Emacs 21 users with a non-nil
   ;; `show-trailing-whitespace'.
   (setq show-trailing-whitespace nil)
-  ;; Dummy font-lock-defaults to make font-lock turn on.  We want this
-  ;; so we know when to enable ibuffer's internal fontification.
-  (set (make-local-variable 'font-lock-defaults)
-       '(nil t nil nil nil
-	     (font-lock-fontify-region-function . ibuffer-fontify-region-function)
-	     (font-lock-unfontify-region-function . ibuffer-unfontify-region-function)))
+
+  (set (make-local-variable 'font-lock-category-alist)
+       `((ibuffer-title . ,ibuffer-title-face)
+	 (ibuffer-filter-group-name . ,ibuffer-filter-group-name-face)
+	 (ibuffer-eliding-string . bold)))
+  (dotimes (i (length ibuffer-fontification-alist))
+    (push (cons (intern (format "ibuffer-category-%d" i))
+		(nth 2 (nth i ibuffer-fontification-alist)))
+	  font-lock-category-alist))
+
   (set (make-local-variable 'revert-buffer-function)
        #'ibuffer-update)
   (set (make-local-variable 'ibuffer-sorting-mode)

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 18:47                                   ` Colin Walters
@ 2002-05-16 19:12                                     ` Miles Bader
  2002-05-16 19:20                                       ` Colin Walters
  2002-05-16 20:12                                     ` Miles Bader
  1 sibling, 1 reply; 82+ messages in thread
From: Miles Bader @ 2002-05-16 19:12 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@gnu.org> writes:
> Please find attached a patch which implements it, and changes Info,
> shell (via comint), occur, and ibuffer to use it.  

The changes to comint, at least, are not correct (did you test them?).
Please just leave that unchanged, and I'll deal with it as soon as
any change to the core code gets checked in.

-Miles
-- 
Come now, if we were really planning to harm you, would we be waiting here, 
 beside the path, in the very darkest part of the forest?

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 19:12                                     ` Miles Bader
@ 2002-05-16 19:20                                       ` Colin Walters
  2002-05-16 19:36                                         ` Miles Bader
  0 siblings, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-16 19:20 UTC (permalink / raw)


On Thu, 2002-05-16 at 15:12, Miles Bader wrote:

> The changes to comint, at least, are not correct (did you test them?).
> Please just leave that unchanged, and I'll deal with it as soon as
> any change to the core code gets checked in.

Yes, I did; I'm running a `shell' with the changes now.  What problems
did you have?

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 19:20                                       ` Colin Walters
@ 2002-05-16 19:36                                         ` Miles Bader
  2002-05-16 19:45                                           ` Miles Bader
  2002-05-16 19:54                                           ` Colin Walters
  0 siblings, 2 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-16 19:36 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@gnu.org> writes:
> Yes, I did; I'm running a `shell' with the changes now.  What problems
> did you have?

There are a few problems (these are based on examination, since I don't
want to apply all those changes):

 1) The prompt face on the `active' prompt doesn't properly interact
    with input (that is, if the prompt is extended because the process
    outputs more, it should get the prompt face, but something the user
    types shouldn't inherit it).  You can see this by doing something
    like:  `for x in 1 2 3 4 5; do echo -n $x; sleep 1; done' and then
    typing while it's outputting.

 2) The prompt face incorrectly gets left on non-prompt output text if
    the output occurs in multiple chunks where the first one doesn't
    end with a newline (e.g., try `echo -n hello; sleep 1; echo world').

 3) The name of one of the categories is wrong -- `comint-sent-output'
    is used on input!

[and also ....
 4) The changes appear rather shoehorned in; if comint is going to be
    changed to use text properties instead of overlays (and I think it
    should be, now that cutting and pasting discards `field' properties),
    it ought to be done properly.
]

-Miles
-- 
Love is a snowmobile racing across the tundra.  Suddenly it flips over,
pinning you underneath.  At night the ice weasels come.  --Nietzsche

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 19:36                                         ` Miles Bader
@ 2002-05-16 19:45                                           ` Miles Bader
  2002-05-16 19:54                                           ` Colin Walters
  1 sibling, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-16 19:45 UTC (permalink / raw)
  Cc: emacs-devel

... oh, and to be complete, a personal request:

 5) Just as a matter of courtesy, let me make the change to comint.

Thanks,

-Miles
-- 
[|nurgle|]  ddt- demonic? so quake will have an evil kinda setting? one that 
            will  make every christian in the world foamm at the mouth? 
[iddt]      nurg, that's the goal 

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 19:36                                         ` Miles Bader
  2002-05-16 19:45                                           ` Miles Bader
@ 2002-05-16 19:54                                           ` Colin Walters
  1 sibling, 0 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-16 19:54 UTC (permalink / raw)


On Thu, 2002-05-16 at 15:36, Miles Bader wrote:

>  4) The changes appear rather shoehorned in; if comint is going to be
>     changed to use text properties instead of overlays (and I think it
>     should be, now that cutting and pasting discards `field' properties),
>     it ought to be done properly.

Yeah, I agree.  The main goal with the changes to comint.el was to prove
the concept.

>  5) Just as a matter of courtesy, let me make the change to comint.

Ok.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 18:47                                   ` Colin Walters
  2002-05-16 19:12                                     ` Miles Bader
@ 2002-05-16 20:12                                     ` Miles Bader
  2002-05-16 20:17                                       ` Colin Walters
  2002-05-17 19:29                                       ` Richard Stallman
  1 sibling, 2 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-16 20:12 UTC (permalink / raw)
  Cc: emacs-devel

Incidentally, I notice what seems to be a big problem with this method
(using `category' properties) -- properties are not buffer local, so
just adding or removing `face' properties will affect every buffer that
uses the same categories.

You could cons up unique symbols for each buffer, but that would
probably eliminate the simplicity of this approach...

-Miles
-- 
Yo mama's so fat when she gets on an elevator it HAS to go down.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 20:12                                     ` Miles Bader
@ 2002-05-16 20:17                                       ` Colin Walters
  2002-05-16 20:23                                         ` Miles Bader
  2002-05-17 19:29                                       ` Richard Stallman
  1 sibling, 1 reply; 82+ messages in thread
From: Colin Walters @ 2002-05-16 20:17 UTC (permalink / raw)


On Thu, 2002-05-16 at 16:12, Miles Bader wrote:
> Incidentally, I notice what seems to be a big problem with this method
> (using `category' properties) -- properties are not buffer local, so
> just adding or removing `face' properties will affect every buffer that
> uses the same categories.

Well, since categories are just symbols, we use the usual elisp
technique to avoid namespace clashes: a (hopefully) unique prefix.  All
the occur category symbols start with `occur-', all the ibuffer ones
start with `ibuffer-', etc. 

Doesn't this solve the problem, or is there something I'm missing?

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 20:17                                       ` Colin Walters
@ 2002-05-16 20:23                                         ` Miles Bader
  2002-05-16 21:47                                           ` Colin Walters
  2002-05-16 21:54                                           ` Kim F. Storm
  0 siblings, 2 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-16 20:23 UTC (permalink / raw)
  Cc: emacs-devel

Colin Walters <walters@gnu.org> writes:
> Well, since categories are just symbols, we use the usual elisp
> technique to avoid namespace clashes: a (hopefully) unique prefix.  All
> the occur category symbols start with `occur-', all the ibuffer ones
> start with `ibuffer-', etc. 

They're not buffer local.

font-lock is supposed to turn on or off faces in the _current buffer_.
With your current code, doing `M-x font-lock' in, say, a shell buffer,
will turn on or off faces in _every_ shell buffer (because they all
use the same category properties).

-Miles
-- 
Fast, small, soon; pick any 2.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 21:54                                           ` Kim F. Storm
@ 2002-05-16 21:15                                             ` Miles Bader
  0 siblings, 0 replies; 82+ messages in thread
From: Miles Bader @ 2002-05-16 21:15 UTC (permalink / raw)
  Cc: Colin Walters, emacs-devel

storm@cua.dk (Kim F. Storm) writes:
> What would it take to make categories buffer local ?
> 
> At least, it seems (without having looked at the code lately) an order
> of magnitude simpler than making faces buffer local...

I think it would be quite hard to make categories buffer local if you
keep the same programmer interface, because they are just ordinary
symbol properties, and there's no concept of context for those.

-Miles
-- 
Saa, shall we dance?  (from a dance-class advertisement)

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 20:23                                         ` Miles Bader
@ 2002-05-16 21:47                                           ` Colin Walters
  2002-05-16 21:54                                           ` Kim F. Storm
  1 sibling, 0 replies; 82+ messages in thread
From: Colin Walters @ 2002-05-16 21:47 UTC (permalink / raw)


On Thu, 2002-05-16 at 16:23, Miles Bader wrote:

> font-lock is supposed to turn on or off faces in the _current buffer_.
> With your current code, doing `M-x font-lock' in, say, a shell buffer,
> will turn on or off faces in _every_ shell buffer (because they all
> use the same category properties).

Ok, I see.  That is indeed a very big problem.   Hmmm.

My first thought was to make the symbol plist buffer-local if its
variable value is buffer-local, but that's bound to break something...

I'll need to think about this some more; the best solution is not
obvious to me.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 20:23                                         ` Miles Bader
  2002-05-16 21:47                                           ` Colin Walters
@ 2002-05-16 21:54                                           ` Kim F. Storm
  2002-05-16 21:15                                             ` Miles Bader
  1 sibling, 1 reply; 82+ messages in thread
From: Kim F. Storm @ 2002-05-16 21:54 UTC (permalink / raw)
  Cc: Colin Walters, emacs-devel

Miles Bader <miles@gnu.org> writes:

> Colin Walters <walters@gnu.org> writes:
> > Well, since categories are just symbols, we use the usual elisp
> > technique to avoid namespace clashes: a (hopefully) unique prefix.  All
> > the occur category symbols start with `occur-', all the ibuffer ones
> > start with `ibuffer-', etc. 
> 
> They're not buffer local.
> 
> font-lock is supposed to turn on or off faces in the _current buffer_.
> With your current code, doing `M-x font-lock' in, say, a shell buffer,
> will turn on or off faces in _every_ shell buffer (because they all
> use the same category properties).

What would it take to make categories buffer local ?

At least, it seems (without having looked at the code lately) an order
of magnitude simpler than making faces buffer local...

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: kill ring menu
  2002-05-16 20:12                                     ` Miles Bader
  2002-05-16 20:17                                       ` Colin Walters
@ 2002-05-17 19:29                                       ` Richard Stallman
  1 sibling, 0 replies; 82+ messages in thread
From: Richard Stallman @ 2002-05-17 19:29 UTC (permalink / raw)
  Cc: walters, emacs-devel

    Incidentally, I notice what seems to be a big problem with this method
    (using `category' properties) -- properties are not buffer local, so
    just adding or removing `face' properties will affect every buffer that
    uses the same categories.

    You could cons up unique symbols for each buffer, but that would
    probably eliminate the simplicity of this approach...

It will add a little complexity, but it is still simpler
than the alternatives.

^ permalink raw reply	[flat|nested] 82+ messages in thread

end of thread, other threads:[~2002-05-17 19:29 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-04-28 19:41 kill ring menu Colin Walters
2002-04-28 20:06 ` Colin Walters
2002-04-29  5:05   ` Richard Stallman
2002-04-29 18:40     ` Richard Stallman
2002-04-28 22:53 ` Miles Bader
2002-04-28 23:36 ` Stefan Monnier
2002-04-28 23:42   ` Miles Bader
2002-04-29  4:34   ` Colin Walters
2002-04-30  4:49     ` Eli Zaretskii
2002-04-29  3:35 ` Miles Bader
2002-04-29  4:37   ` Colin Walters
2002-04-29  4:56     ` Miles Bader
2002-04-29  5:37       ` Colin Walters
2002-04-29  7:09         ` Miles Bader
2002-04-30  5:18           ` Richard Stallman
2002-04-30 10:18             ` Per Abrahamsen
2002-04-29  9:22         ` CC (was: Re: kill ring menu) Per Abrahamsen
2002-04-29 15:11           ` Benjamin Rutt
2002-04-29 15:31             ` Miles Bader
2002-04-30  5:19             ` Richard Stallman
2002-04-30 10:14           ` Per Abrahamsen
2002-04-30 11:08             ` Simon Josefsson
2002-04-29 10:10         ` Addressing email (was: " Eli Zaretskii
2002-04-29 13:13         ` kill ring menu Stefan Monnier
2002-04-29 18:40   ` Richard Stallman
     [not found] ` <200204290505.g3T55t006146@aztec.santafe.edu>
     [not found]   ` <1020059236.31789.358.camel@space-ghost>
     [not found]     ` <200204300519.g3U5Js306727@aztec.santafe.edu>
     [not found]       ` <1020212569.27106.2246.camel@space-ghost>
     [not found]         ` <200205011926.g41JQBC07690@aztec.santafe.edu>
     [not found]           ` <1020284783.27106.3417.camel@space-ghost>
2002-05-03 18:25             ` Richard Stallman
2002-05-03 18:46               ` Miles Bader
2002-05-03 19:05               ` Miles Bader
2002-05-03 20:20                 ` Colin Walters
2002-05-04  1:34                   ` Miles Bader
2002-05-04  3:36                 ` Richard Stallman
2002-05-04  3:49                   ` Miles Bader
2002-05-05  5:34                     ` Richard Stallman
2002-05-04  6:04                 ` Eli Zaretskii
     [not found]       ` <1020320725.27616.54.camel@space-ghost>
     [not found]         ` <200205031825.g43IPuD00768@aztec.santafe.edu>
     [not found]           ` <1020502030.5286.25.camel@space-ghost>
2002-05-05 17:46             ` Richard Stallman
2002-05-06  5:15               ` Colin Walters
2002-05-06  6:39                 ` Miles Bader
2002-05-06 22:55                   ` Colin Walters
2002-05-07  1:35                     ` Miles Bader
2002-05-07  3:55                       ` Colin Walters
2002-05-07  4:18                         ` Miles Bader
2002-05-07 20:07                         ` Richard Stallman
2002-05-07 20:38                           ` Colin Walters
2002-05-08  0:20                             ` Miles Bader
2002-05-08  6:05                               ` Colin Walters
2002-05-08  6:50                                 ` Miles Bader
2002-05-08  7:36                                   ` Colin Walters
2002-05-08  7:48                                     ` Miles Bader
2002-05-08  8:57                                     ` Colin Walters
2002-05-08 13:14                                       ` Stefan Monnier
2002-05-09  4:29                                         ` Colin Walters
2002-05-09 10:08                                           ` Kim F. Storm
2002-05-09  2:45                             ` Richard Stallman
2002-05-09  4:28                               ` Colin Walters
2002-05-10  0:30                                 ` Richard Stallman
2002-05-16 18:47                                   ` Colin Walters
2002-05-16 19:12                                     ` Miles Bader
2002-05-16 19:20                                       ` Colin Walters
2002-05-16 19:36                                         ` Miles Bader
2002-05-16 19:45                                           ` Miles Bader
2002-05-16 19:54                                           ` Colin Walters
2002-05-16 20:12                                     ` Miles Bader
2002-05-16 20:17                                       ` Colin Walters
2002-05-16 20:23                                         ` Miles Bader
2002-05-16 21:47                                           ` Colin Walters
2002-05-16 21:54                                           ` Kim F. Storm
2002-05-16 21:15                                             ` Miles Bader
2002-05-17 19:29                                       ` Richard Stallman
2002-05-07 19:22                     ` Alex Schroeder
2002-05-09 20:09                       ` Colin Walters
2002-05-11  6:30                       ` Richard Stallman
2002-05-13 22:17                         ` Colin Walters
2002-05-14  8:36                           ` Miles Bader
2002-05-14 12:49                           ` Emacs 21.4 (was: kill ring menu) Eli Zaretskii
2002-05-15  7:01                           ` kill ring menu Richard Stallman
2002-05-06  6:46                 ` Stephen J. Turnbull
2002-05-06 22:46                   ` Colin Walters
2002-05-08 10:06                     ` Francesco Potorti`
2002-05-08 10:20                       ` Eli Zaretskii
2002-05-06 19:32                 ` Richard Stallman
2002-05-07  4:03                   ` Colin Walters
2002-05-07  5:27                     ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).