unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: highlight-changes-mode
       [not found] <17721.60660.980363.609046@kahikatea.snap.net.nz>
@ 2006-10-23  5:11 ` Richard Stallman
  2006-10-23 18:39   ` highlight-changes-mode Richard Stallman
  0 siblings, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-10-23  5:11 UTC (permalink / raw)
  Cc: emacs-devel

    highlight-changes-mode in mode-line-mode-menu doesn't toggle on the mode-line
    because it has three values:

      With an argument ARG:
	If ARG is positive, set state to active;
	If ARG is zero, set state to passive;
	If ARG is negative, disable Highlight Changes mode completely.

I think we should change the interface, because it is really bad for a
minor mode to be inconsistent with the standard for minor modes.

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

* Re: highlight-changes-mode
  2006-10-23  5:11 ` highlight-changes-mode Richard Stallman
@ 2006-10-23 18:39   ` Richard Stallman
  2006-10-24  0:16     ` highlight-changes-mode rsharman
  0 siblings, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-10-23 18:39 UTC (permalink / raw)
  Cc: Richard Sharman

Is there an important reason to overload M-x highlight-changes-mode
for toggling between active and passive mode?  Would it be
inconvenient to make that a separate command, so that M-x
highlight-changes-mode could follow the conventions for minor modes?

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

* Re: highlight-changes-mode
  2006-10-23 18:39   ` highlight-changes-mode Richard Stallman
@ 2006-10-24  0:16     ` rsharman
  2006-10-24 17:43       ` highlight-changes-mode Richard Stallman
  0 siblings, 1 reply; 57+ messages in thread
From: rsharman @ 2006-10-24  0:16 UTC (permalink / raw)
  Cc: nickrob, Richard Sharman, emacs-devel

Richard Stallman writes:
 > Is there an important reason to overload M-x highlight-changes-mode
 > for toggling between active and passive mode?  Would it be
 > inconvenient to make that a separate command, so that M-x
 > highlight-changes-mode could follow the conventions for minor modes?


I'm sure there's no good reason that it has to work the way it does.
I think it just "seemed like a good idea at the time",  but as you say
it isn't consistent with other modes.

I can take a look into it in a couple of days.

Richard

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

* Re: highlight-changes-mode
  2006-10-24  0:16     ` highlight-changes-mode rsharman
@ 2006-10-24 17:43       ` Richard Stallman
  2006-11-27  1:57         ` highlight-changes-mode rsharman
  0 siblings, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-10-24 17:43 UTC (permalink / raw)
  Cc: nickrob, rsharman, emacs-devel

    I'm sure there's no good reason that it has to work the way it does.
    I think it just "seemed like a good idea at the time",  but as you say
    it isn't consistent with other modes.

    I can take a look into it in a couple of days.

That would be appreciated; thanks in advance.

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

* Re: highlight-changes-mode
  2006-10-24 17:43       ` highlight-changes-mode Richard Stallman
@ 2006-11-27  1:57         ` rsharman
  2006-11-27  6:43           ` highlight-changes-mode Nick Roberts
  2006-11-27 15:38           ` highlight-changes-mode Richard Stallman
  0 siblings, 2 replies; 57+ messages in thread
From: rsharman @ 2006-11-27  1:57 UTC (permalink / raw)
  Cc: nickrob, rsharman, emacs-devel

[-- Attachment #1: message body text --]
[-- Type: text/plain, Size: 1377 bytes --]

Richard Stallman writes:
 >     I'm sure there's no good reason that it has to work the way it does.
 >     I think it just "seemed like a good idea at the time",  but as you say
 >     it isn't consistent with other modes.
 > 
 >     I can take a look into it in a couple of days.
 > 
 > That would be appreciated; thanks in advance.

I have made the changes so that command highlight-changes-mode simply
toggles the mode on and off, and so have introduced a new command
highlight-changes-toggle-visibility to toggle between what was
previously called active and passive modes.

At first I wasn't very happy with the changes, because now toggling
the main highlight changes mode loses information [the changes].
However, I now think it does seem a reasonable way of doing things.

A side effect of the new highlight-changes-toggle-visibility command
is that it enables highlight changes mode.  I was going to correct
this "bug" by making it only operate if the mode was active, but then
realized that the current behaviour is better.  People that wanted the
old method of one function to turn it on and toggle between active and
passive can basically just use the new command.

Attached is the new version;  please let me know what you think.

As well as the above change and some minor cleanup is a new command
highlight-compare-buffers that I think is occasionally useful.


[-- Attachment #2: hilit-chg.el --]
[-- Type: application/octet-stream, Size: 42038 bytes --]

;;; hilit-chg.el --- minor mode displaying buffer changes with special face

;; Copyright (C) 1998, 2000, 2006 Free Software Foundation, Inc.
;; Author: Richard Sharman <rsharman@pobox.com>
;; Keywords: 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.

;;; Commentary:

;; A minor mode: "Highlight Changes mode".

;; When Highlight Changes mode is enabled changes to the buffer are
;; recorded with a text property.  Normally these ranges of text are
;; displayed in a distinctive face.  However, sometimes it is
;; desirable to temporarily not see these changes.  Rather than
;; disabling Highlight Changes mode (which removes the text property)
;; the command highlight-changes-toggle-visibility toggles the use of
;; distinctive face for the changed text ranges.

;; Two faces are supported: one for changed or inserted text and
;; another for the first character after text has been deleted.

;; When Highlight Changes mode is on (even if changes are not visible) 
;; you can go to the next or previous change with
;; `highlight-changes-next-change' or `highlight-changes-previous-change'.

;; Command highlight-compare-with-file shows changes in this file
;; compared with another file (by default the previous version of the
;; file).  
;;
;; The command highlight-compare-buffers compares two buffers by
;; highlighting their differences.

;; You can "age" different sets of changes by using
;; `highlight-changes-rotate-faces'.  This rotates through a series
;; of different faces, so you can distinguish "new" changes from "older"
;; changes.  You can customize these "rotated" faces in two ways.  You can
;; either explicitly define each face by customizing
;; `highlight-changes-face-list'.  If, however, the faces differ from
;; `highlight-changes-face' only in the foreground color, you can simply set
;; `highlight-changes-colours'.  If `highlight-changes-face-list' is nil when
;; the faces are required they will be constructed from
;; `highlight-changes-colours'.

;; You can automatically rotate faces when the buffer is saved;
;; see function `highlight-changes-rotate-faces' for how to do this.

;; There are currently two hooks run by `highlight-changes-mode':
;; `highlight-changes-enable-hook'  - is run when Highlight Changes mode
;;				    is initially enabled for a buffer.
;; `highlight-changes-disable-hook' - is run when Highlight Changes mode

;; Example usage:
;; (defun my-highlight-changes-enable-hook ()
;;   (add-hook 'local-write-file-hooks 'highlight-changes-rotate-faces)
;; )
;;
;; (defun my-highlight-changes-disable-hook ()
;;   (remove-hook 'local-write-file-hooks 'highlight-changes-rotate-faces)
;; )
;;
;; (add-hook 'highlight-changes-enable-hook 'my-highlight-changes-enable-hook)
;; (add-hook 'highlight-changes-disable-hook
;;		'my-highlight-changes-disable-hook)



;;           Automatically enabling Highlight Changes mode


;; Normally, Highlight Changes mode is turned on explicitly in a buffer.

;; If you prefer to have it automatically invoked you can do it as
;; follows.

;; 1. Most modes have a major-hook, typically called MODE-hook.  You
;; can use `add-hook' to call `highlight-changes-mode'.

;;   Example:
;;	(add-hook 'c-mode-hook 'highlight-changes-mode)

;; However, this cannot be done for Fundamental mode for there is no
;; such hook.

;; 2. You can use the function `global-highlight-changes'

;; This function, which is fashioned after the way `global-font-lock' works,
;; toggles on or off global Highlight Changes mode.  When activated, it turns
;; on Highlight Changes mode in all "suitable" existing buffers and will turn
;; it on in new "suitable" buffers to be created.

;; A buffer's "suitability" is determined by variable
;; `highlight-changes-global-modes' as follows.  If this variable is
;; * nil  -- then no buffers are suitable;
;; * a function -- this function is called and the result is used.  As
;;   an example, if the value is `buffer-file-name' then all buffers
;;   who are visiting files are suitable, but others (like dired
;;   buffers) are not;
;; * a list -- then the buffer is suitable if and only if its mode is in the
;;   list, unless the first element is `not' in which case the test
;;   is reversed (i.e. it is a list of unsuitable modes).
;; * Otherwise, the buffer is suitable if its name does not begin with
;;   ` ' or `*' and if `buffer-file-name' returns true.

;; Normally toggling on or off Global Highlight Changes mode does not
;; change whether Highlight Changes mode is turned on or off for
;; existing buffers, but a user option can cause it to do so.

;; To enable it for future sessions put this in your ~/.emacs file:
;;		(global-highlight-changes t)


;;	Possible bindings:

;; (global-set-key '[C-right] 'highlight-changes-next-change)
;; (global-set-key '[C-left]  'highlight-changes-previous-change)
;;
;;     Other interactive functions (that could be bound if desired):
;; highlight-changes-mode
;; highlight-changes-toggle-visibility
;; highlight-changes-remove-highlight
;; highlight-compare-with-file
;; highlight-compare-buffers
;; highlight-changes-rotate-faces


;;; Bugs:

;; - the next-change and previous-change functions are too literal;
;;   they should find the next "real" change, in other words treat
;;   consecutive changes as one.


;;; To do (maybe), notes, ...

;; - having different faces for deletion and non-deletion: is it
;;   really worth the hassle?
;; - highlight-compare-with-file should allow RCS files - e.g. nice to be
;;   able to say show changes compared with version 2.1.


;;; History:

;; R Sharman (rsharman@pobox.com) Feb 1998:
;; - initial release as change-mode.
;; Jari Aalto <jari.aalto@ntc.nokia.com> Mar 1998
;; - fixes for byte compile errors
;; - use eval-and-compile for autoload
;; Marijn Ros <J.M.Ros@fys.ruu.nl> Mar 98
;; - suggested turning it on by default
;; Eric Ludlam <zappo@gnu.org> Suggested using overlays.
;; July 98
;; - global mode and various stuff added
;; - Changed to use overlays
;; August 98
;; - renamed to Highlight Changes mode.
;; Dec 2003
;; - Use require for ediff stuff to prevent problems with
;; highlight-compare-with-file when byte compiled in std directory
;; Nov 2006
;; - Made highlight-changes-mode like other modes (toggle on/off)
;; - Added new command highlight-changes-toggle-visibility to replace the
;;   previous active/passive aspect of highlight-changes-mode.
;; - Removed highlight-changes-toggle-hook
;; - Added highlight-compare-buffers

;;; Code:

(require 'wid-edit)

;; ====================== Customization =======================
(defgroup highlight-changes nil
  "Highlight Changes mode."
  :version "20.4"
  :group 'faces)


;; Face information: How the changes appear.

;; Defaults for face: red foreground, no change to background,
;; and underlined if a change is because of a deletion.
;; Note: underlining is helpful in that it shows up changes in white space.
;; However, having it set for non-delete changes can be annoying because all
;; indentation on inserts gets underlined (which can look pretty ugly!).

(defface highlight-changes-face
  '((((class color)) (:foreground "red" ))
    (t (:inverse-video t)))
  "Face used for highlighting changes."
  :group 'highlight-changes)

;; This looks pretty ugly, actually.  Maybe the underline should be removed.
(defface highlight-changes-delete-face
  '((((class color)) (:foreground "red" :underline t))
    (t (:inverse-video t)))
  "Face used for highlighting deletions."
  :group 'highlight-changes)



;; A (not very good) default list of colours to rotate through.
;;
(defcustom highlight-changes-colours
  (if (eq (frame-parameter nil 'background-mode) 'light)
      ;; defaults for light background:
      '( "magenta" "blue" "darkgreen" "chocolate" "sienna4" "NavyBlue")
      ;; defaults for dark background:
    '("yellow" "magenta" "blue" "maroon" "firebrick" "green4" "DarkOrchid"))
  "*Colours used by `highlight-changes-rotate-faces'.
The newest rotated change will be displayed in the first element of this list,
the next older will be in the second element etc.

This list is used if `highlight-changes-face-list' is nil, otherwise that
variable overrides this list.  If you only care about foreground
colours then use this, if you want fancier faces then set
`highlight-changes-face-list'."
  :type '(repeat color)
  :group 'highlight-changes)



;; highlight-changes-initial-state has been removed

;; highlight-changes-global-initial-state has been removed

;; The strings displayed in the mode-line for the minor mode:
(defcustom highlight-changes-active-string nil
  "*The string used when Highlight Changes mode and changes are visible.
This should be set to nil if no indication is desired, or to
a string with a leading space."
  :type '(choice string
		 (const :tag "None"  nil))
  :group 'highlight-changes)

(defcustom highlight-changes-passive-string " Chg"
  "*The string used when Highlight Changes mode but changes are not visible.
This should be set to nil if no indication is desired, or to
a string with a leading space."
  :type '(choice string
		 (const :tag "None"  nil))
  :group 'highlight-changes)

(defcustom highlight-changes-global-modes t
  "*Determine whether a buffer is suitable for global Highlight Changes mode.

A function means that function is called:  if it returns non-nil, the
buffer is suitable.

A list is a list of modes for which it is suitable, or a list whose
first element is `not' followed by modes which are not suitable.

t means the buffer is suitable if its name does not begin with ` ' nor
`*' and the buffer has a filename.

A value of nil means no buffers are suitable for
`global-highlight-changes-mode' (effectively disabling the mode).

Examples:
        (c-mode c++-mode)
means that Highlight Changes mode is turned on for buffers in C and C++
modes only."
  :type '(choice
	  (const :tag "all non-special buffers visiting files" t)
	  (set :menu-tag "specific modes" :tag "modes"
	       :value (not)
	       (const :tag "All except these" not)
	       (repeat :tag "Modes" :inline t (symbol :tag "mode")))
	  (function :menu-tag "determined by function"
			   :value buffer-file-name)
	  (const :tag "none" nil)
	  )
  :group 'highlight-changes)

(defvar global-highlight-changes nil)

(defcustom highlight-changes-global-changes-existing-buffers nil
  "*If non-nil, toggling global Highlight Changes mode affects existing buffers.
Normally, `global-highlight-changes' affects only new buffers (to be
created).  However, if `highlight-changes-global-changes-existing-buffers'
is non-nil, then turning on `global-highlight-changes' will turn on
Highlight Changes mode in suitable buffers, and turning the mode off will
remove it from existing buffers."
  :type 'boolean
  :group 'highlight-changes)

(defun hilit-chg-cust-fix-changes-face-list (w wc &optional event)
  ;; When customization function `highlight-changes-face-list' inserts a new
  ;; face it uses the default face.   We don't want the user to modify this
  ;; face, so we rename the faces in the list on an insert.  The rename is
  ;; actually done by copying the faces so user-defined faces still remain
  ;; in the same order.
  ;; The notifying the parent is needed because without it changes to the
  ;; faces are saved but not to the actual list itself.
  (let ((old-list (widget-value w)))
    (if (member 'default old-list)
	(let
	    ((p (reverse old-list))
	     (n (length old-list))
	     new-name old-name
	     (new-list nil)
	     )
	  (while p
	    (setq old-name (car p))
	    (setq new-name (intern (format "highlight-changes-face-%d" n)))
	    (if (eq old-name new-name)
		nil
	      ;; A new face has been inserted: we don't want to modify the
	      ;; default face so copy it.   Better, though, (I think) is to
	      ;; make a new face have the same attributes as
	      ;; highlight-changes-face .
	      (if (eq old-name 'default)
		  (copy-face 'highlight-changes-face  new-name)
		(copy-face old-name new-name)
		))
	    (setq new-list (append  (list new-name) new-list))
	    (setq n (1- n))
	    (setq p (cdr p)))
	  (if (equal new-list (widget-value w))
	      nil ;; (message "notify: no change!")
	    (widget-value-set w new-list)
	    (widget-setup)
	    )
	  )
      ;; (message "notify: no default here!")
      ))
  (let ((parent (widget-get w :parent)))
    (when parent
      (widget-apply parent :notify w event))))


(defcustom highlight-changes-face-list nil
  "*A list of faces used when rotating changes.
Normally the variable is initialized to nil and the list is created from
`highlight-changes-colours' when needed.  However, you can set this variable
to any list of faces.  You will have to do this if you want faces which
don't just differ from `highlight-changes-face' by the foreground colour.
Otherwise, this list will be constructed when needed from
`highlight-changes-colours'."
  :type '(choice
	  (repeat
	    :notify hilit-chg-cust-fix-changes-face-list
	    face  )
	  (const :tag "Derive from highlight-changes-colours"  nil)
	  )
  :group 'highlight-changes)

(defvar highlight-changes-visible-p t
  "*This controls the appearance of changes when Highlight Changes mode is on.
If non-nil, the changes are displayed using distinctive faces.

This variable is buffer-local when set.

Do not set this variable directly.  Instead,  use
\\[highlight-changes-toggle-visibility] to change this variable in a
buffer,  or use the Lisp function `setq-default' to change the default
value that is used for new buffers visited when Global Highlight Changes
mode is active.")

;; ========================================================================

;; These shouldn't be changed!

;; Autoload for the benefit of `make-mode-line-mouse-sensitive'.
;;;###autoload
(defvar highlight-changes-mode nil)

(defvar hilit-chg-list nil)
(defvar hilit-chg-string " ??")
(or (assq 'highlight-changes-mode minor-mode-alist)
    (setq minor-mode-alist
	  (cons '(highlight-changes-mode hilit-chg-string) minor-mode-alist)
	  ))
(make-variable-buffer-local 'highlight-changes-mode)
(make-variable-buffer-local 'highlight-changes-visible-p)
(make-variable-buffer-local 'hilit-chg-string)



;;; Functions...

(defun hilit-chg-map-changes  (func &optional start-position end-position)
  "Call function FUNC for each region used by Highlight Changes mode.
If START-POSITION is nil, (point-min) is used.
If END-POSITION is nil, (point-max) is used.
FUNC is called with 3 params: PROPERTY START STOP."
  (let ((start (or start-position (point-min)))
	(limit (or end-position (point-max)))
	prop end)
    (while (and start (< start limit))
      (setq prop (get-text-property start 'hilit-chg))
      (setq end (text-property-not-all start limit 'hilit-chg prop))
      (if prop
	  (funcall func prop start (or end limit)))
      (setq start end))))


(defun hilit-chg-display-changes (&optional beg end)
  "Display face information for Highlight Changes mode.

An overlay from BEG to END containing a change face is added from the
information in the text property of type `hilit-chg'.

This is the opposite of `hilit-chg-hide-changes'."
  (hilit-chg-map-changes 'hilit-chg-make-ov beg end))


(defun hilit-chg-make-ov (prop start end)
  ;; Put a highlight-changes overlay in the region.
  ;; PROP is the property type, either 'hilit-chg or 'hilit-chg-delete.\
  ;; The face used is determined from PROP.
  ;; the text property 'hilit-chg
  (let ((ov (make-overlay start end))
	face)
    (or prop
	(error "hilit-chg-make-ov: prop is nil"))
    (if (eq prop 'hilit-chg-delete)
	(setq face 'highlight-changes-delete-face)
      (setq face (nth 1 (member prop hilit-chg-list))))
    (if face
	(progn
	  ;; We must mark the face, that is the purpose of the overlay
	  (overlay-put ov 'face face)
	  ;; I don't think we need to set evaporate since we should
	  ;; be controlling them!
	  (overlay-put ov 'evaporate t)
	  ;; We set the change property so we can tell this is one
	  ;; of our overlays (so we don't delete someone else's).
	  (overlay-put ov 'hilit-chg t)
	  )
      (error "hilit-chg-make-ov: no face for prop: %s" prop))))

(defun hilit-chg-hide-changes (&optional beg end)
  "Remove face information for Highlight Changes mode.

The overlay containing the face is removed, but the text property
containing the change information is retained.

This is the opposite of `hilit-chg-display-changes'."
  (let ((start (or beg (point-min)))
	(limit (or end (point-max)))
	p)
    (setq p (overlays-in start limit))
    (while p
      ;; don't delete the overlay if it isn't ours!
      (if (overlay-get (car p) 'hilit-chg)
	  (delete-overlay (car p)))
      (setq p (cdr p)))))

(defun hilit-chg-fixup (beg end)
  "Fix change overlays in region between BEG and END.

Ensure the overlays agree with the changes as determined from
the text properties of type `hilit-chg' ."
  ;; Remove or alter overlays in region beg..end
  (let (p ov ov-start ov-end
	 props q)
    (setq p (overlays-in beg end))
    ;; temp for debugging:
    (unless (and highlight-changes-mode
		 highlight-changes-visible-p)
      ;; This can happen if the highlight-changes-mode variable was
      ;; manually set to nil without using the command 
      (error "hilit-chg-fixup called but Highlight Changes mode not active"))
    (while p
      (setq ov (car p))
      (setq ov-start (overlay-start ov))
      (setq ov-end (overlay-end ov))
      (if (< ov-start beg)
	  (progn
	    (move-overlay ov ov-start beg)
	    (if (> ov-end end)
		(progn
		  (setq props (overlay-properties ov))
		  (setq ov (make-overlay end ov-end))
		  (while props
		    (overlay-put ov (car props)(car (cdr props)))
		    (setq props (cdr (cdr props)))))))
	(if (> ov-end end)
	    (move-overlay ov end ov-end)
	  (delete-overlay ov)))
      (setq p (cdr p)))
    (hilit-chg-display-changes beg end)))

;;;###autoload
(defun highlight-changes-remove-highlight (beg end)
  "Remove the change face from the region between BEG and END.
This allows you to manually remove highlighting from uninteresting changes."
  (interactive "r")
  (let ((after-change-functions nil))
    (remove-text-properties beg end  '(hilit-chg nil))
    (hilit-chg-fixup beg end)))

(defun hilit-chg-set-face-on-change (beg end leng-before
	&optional no-proerty-change)
  "Record changes and optionally display them in a distinctive face.
`hilit-chg-set' adds this function to the `after-change-functions' hook."
  ;;
  ;; This function is called by the `after-change-functions' hook, which
  ;; is how we are notified when text is changed.
  ;; It is also called from `highlight-compare-with-file'.
  ;;
  ;; We do NOT want to simply do this if this is an undo command, because
  ;; otherwise an undone change shows up as changed.  While the properties
  ;; are automatically restored by undo, we must fix up the overlay.
  (save-match-data
    (let ((beg-decr 1) (end-incr 1)
	  (type 'hilit-chg)
	  old)
      (if undo-in-progress
	  (if (and highlight-changes-mode
		   highlight-changes-visible-p)
	      (hilit-chg-fixup beg end))
	(if (and (= beg end) (> leng-before 0))
	    ;; deletion
	    (progn
	      ;; The eolp and bolp tests are a kludge!  But they prevent
	      ;; rather nasty looking displays when deleting text at the end
	      ;; of line, such as normal corrections as one is typing and
	      ;; immediately makes a correction, and when deleting first
	      ;; character of a line.
;;;	      (if (= leng-before 1)
;;;		  (if (eolp)
;;;		      (setq beg-decr 0 end-incr 0)
;;;		    (if (bolp)
;;;			(setq beg-decr 0))))
;;;	      (setq beg (max (- beg beg-decr) (point-min)))
	      (setq end (min (+ end end-incr) (point-max)))
	      (setq type 'hilit-chg-delete))
	  ;; Not a deletion.
	  ;; Most of the time the following is not necessary, but
	  ;; if the current text was marked as a deletion then
	  ;; the old overlay is still in effect, so if we add some
	  ;; text then remove the deletion marking, but set it to
	  ;; changed otherwise its highlighting disappears.
	  (if (eq (get-text-property end 'hilit-chg) 'hilit-chg-delete)
	      (progn
		(remove-text-properties end (+ end 1) '(hilit-chg nil))
		(put-text-property end (+ end 1) 'hilit-chg 'hilit-chg)
		(if highlight-changes-visible-p
		    (hilit-chg-fixup beg (+ end 1))))))
	(unless no-proerty-change
		(put-text-property beg end 'hilit-chg type))
	(if (or highlight-changes-visible-p no-proerty-change)
	    (hilit-chg-make-ov type beg end))))))

(defun hilit-chg-set ()
  "Turn on Highlight Changes mode for this buffer."
  (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t)
  (hilit-chg-make-list)
  (setq highlight-changes-mode t)
  (if highlight-changes-visible-p
      (progn
	(setq hilit-chg-string highlight-changes-active-string)
	(or buffer-read-only
	    (hilit-chg-display-changes)))
    ;; changes are invisible
    (setq hilit-chg-string highlight-changes-passive-string)
    (or buffer-read-only
	(hilit-chg-hide-changes)))
  (force-mode-line-update)
  (make-local-hook 'after-change-functions)
  (add-hook 'after-change-functions 'hilit-chg-set-face-on-change nil t)
  (run-hooks 'highlight-changes-enable-hook)
  )

(defun hilit-chg-clear ()
  "Remove Highlight Changes mode for this buffer.
This removes all saved change information."
  (if buffer-read-only
      ;; We print the buffer name because this function could be called
      ;; on many buffers from `global-highlight-changes'.
      (message "Cannot remove highlighting from read-only mode buffer %s"
	       (buffer-name))
    (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t)
    (let ((after-change-functions nil))
      (hilit-chg-hide-changes)
      (hilit-chg-map-changes
       '(lambda (prop start stop)
	  (remove-text-properties start stop '(hilit-chg nil))))
      )
    (setq highlight-changes-mode nil)
    (force-mode-line-update)
    ;; If we type:  C-u -1 M-x highlight-changes-mode
    ;; we want to turn it off, but hilit-chg-post-command-hook
    ;; runs and that turns it back on!
    (remove-hook 'post-command-hook 'hilit-chg-post-command-hook))
  (run-hooks 'highlight-changes-disable-hook)
  )

;;;###autoload
(defun highlight-changes-mode (&optional arg)
  "Toggle Highlight Changes mode.

With ARG, turn Highlight Changes mode on if and only if arg is positive.

In Highlight Changes mode changes are recorded with a text property.
Normally they are displayed in a distinctive face, but command
\\[highlight-changes-toggle-visibility] can be used to toggles this
on and off.

Other functions for buffers in this mode include:
\\[highlight-changes-next-change] - move point to beginning of next change
\\[highlight-changes-previous-change] - move to beginning of previous change
\\[highlight-changes-remove-highlight] - remove the change face from the region
\\[highlight-changes-rotate-faces] - rotate different \"ages\" of changes
through	various faces.
\\[highlight-compare-with-file] - mark text as changed by comparing this
buffer with the contents of a file
\\[highlight-compare-buffers] highlights differences between two buffers.

Hook variables:
`highlight-changes-enable-hook'  - called when enabling Highlight Changes mode.
`highlight-changes-disable-hook' - called when disabling off Highlight Changes mode."
  (interactive "P")
  (if (or (display-color-p)
	  (and (fboundp 'x-display-grayscale-p) (x-display-grayscale-p)))
      (let ((was-on highlight-changes-mode))
	(setq highlight-changes-mode
	      (if (null arg)
		  (not highlight-changes-mode)
		(> (prefix-numeric-value arg) 0)))
	(if (eq was-on highlight-changes-mode)
	    (message "highlight-changes-mode - already %s"
		     (if highlight-changes-mode "on" "off"))
	  (message "highlight-changes-mode is now %s"
		   (if highlight-changes-mode "on" "off"))
	  (if highlight-changes-mode
	      ;; it is being turned on
	      ;; the hook has been moved into hilit-chg-set
	      ;; (run-hooks 'highlight-changes-enable-hook))
	      (hilit-chg-set)
	    ;; mode is turned off
	  (hilit-chg-clear))))
    (message "Highlight Changes mode requires color or grayscale display")))

;;;###autoload
(defun highlight-changes-next-change ()
  "Move to the beginning of the next change, if in Highlight Changes mode."
  (interactive)
  (if highlight-changes-mode
      (let ((start (point))
	    prop)
	(setq prop (get-text-property (point) 'hilit-chg))
	(if prop
	    ;; we are in a change
	    (setq start (next-single-property-change (point) 'hilit-chg)))
	(if start
	    (setq start (next-single-property-change start 'hilit-chg)))
	(if start
	    (goto-char start)
	  (message "no next change")))
    (message "This buffer is not in Highlight Changes mode.")))


;;;###autoload
(defun highlight-changes-previous-change ()
  "Move to the beginning of the previous change, if in Highlight Changes mode."
  (interactive)
  (if highlight-changes-mode
      (let ( (start (point)) (prop nil) )
	(or (bobp)
	    (setq prop (get-text-property (1- (point)) 'hilit-chg)))
	(if prop
	    ;; we are in a change
	    (setq start (previous-single-property-change (point) 'hilit-chg)))
	(if start
	    (setq start (previous-single-property-change start 'hilit-chg)))
	;; special handling for the case where (point-min) is a change
	(if start
	    (setq start (or (previous-single-property-change start 'hilit-chg)
			    (if (get-text-property (point-min) 'hilit-chg)
				(point-min)))))
	(if start
	    (goto-char start)
	  (message "no previous change")))
    (message "This buffer is not in Highlight Changes mode.")))


;;;###autoload
(defun highlight-changes-toggle-visibility (&optional arg)
  "Toggle whether changes are visible in Highlight Changes modes.
While the changes are still kept (and new ones recorded) as long as
Highlight Changes modes is on, their distinctive display can be
toggled on and off using this command.  With ARG,  enable the
distinctive display if and only if the arg is positive.

Set variable `highlight-changes-visible-p' if you want to change the default
behaviour.

This command turns on highlight-changes mode."
  (interactive "P")
  (let ((old-value highlight-changes-visible-p))
    (setq highlight-changes-visible-p
	  (if (null arg)
	      (not highlight-changes-visible-p)
	    (> (prefix-numeric-value arg) 0)))
    (unless (eq old-value highlight-changes-visible-p)
      (message "changes will now be %s"
	       (if highlight-changes-visible-p "visible" "invisible"))
      (hilit-chg-set))
    ))
	  
      
;; ========================================================================

(defun hilit-chg-make-list (&optional force)
  "Construct `hilit-chg-list' and `highlight-changes-face-list'."
  ;; Constructs highlight-changes-face-list if necessary,
  ;; and hilit-chg-list always:
  ;; Maybe this should always be called when rotating a face
  ;; so we pick up any changes?
  (if (or (null highlight-changes-face-list)  ; Don't do it if it
	  force) ; already exists unless FORCE non-nil.
      (let ((p highlight-changes-colours)
	    (n 1) name)
	(setq highlight-changes-face-list nil)
	(while p
	  (setq name (intern (format "highlight-changes-face-%d" n)))
	  (copy-face 'highlight-changes-face name)
	  (set-face-foreground name (car p))
	  (setq highlight-changes-face-list
		(append highlight-changes-face-list (list name)))
	  (setq p (cdr p))
	  (setq n (1+ n)))))
  (setq hilit-chg-list (list 'hilit-chg 'highlight-changes-face))
  (let ((p highlight-changes-face-list)
	(n 1)
	last-category last-face)
    (while p
      (setq last-category (intern (format "change-%d" n)))
      ;; (setq last-face (intern (format "highlight-changes-face-%d" n)))
      (setq last-face (car p))
      (setq hilit-chg-list
	    (append hilit-chg-list
		    (list last-category last-face)))
      (setq p (cdr p))
      (setq n (1+ n)))
    (setq hilit-chg-list
	  (append hilit-chg-list
		  (list last-category last-face)))))

(defun hilit-chg-bump-change (prop start end)
  "Increment (age) the Highlight Changes mode text property."
  (let ( new-prop )
    (if (eq prop 'hilit-chg-delete)
	(setq new-prop (nth 2 hilit-chg-list))
      (setq new-prop (nth 2 (member prop hilit-chg-list))))
    (if prop
	(put-text-property start end 'hilit-chg new-prop)
      (message "%d-%d unknown property %s not changed" start end prop))))

;;;###autoload
(defun highlight-changes-rotate-faces ()
  "Rotate the faces used by Highlight Changes mode.

Current changes are displayed in the face described by the first element
of `highlight-changes-face-list', one level older changes are shown in
face described by the second element, and so on.  Very old changes remain
shown in the last face in the list.

You can automatically rotate colours when the buffer is saved
by adding the following to `local-write-file-hooks', by evaling it in the
buffer to be saved):

  \(add-hook 'local-write-file-hooks 'highlight-changes-rotate-faces)"
  (interactive)
  ;; If not in active mode do nothing but don't complain because this
  ;; may be bound to a hook.
  (if (and highlight-changes-mode
	   highlight-changes-visible-p)
      (let ((after-change-functions nil))
	;; ensure hilit-chg-list is made and up to date
	(hilit-chg-make-list)
	;; remove our existing overlays
	(hilit-chg-hide-changes)
	;; for each change text property, increment it
	(hilit-chg-map-changes 'hilit-chg-bump-change)
	;; and display them all if visible
	(if highlight-changes-visible-p
	    (hilit-chg-display-changes))))
  ;; This always returns nil so it is safe to use in
  ;; local-write-file-hook
  nil)

;; ========================================================================
;; Comparing buffers/files
;; These use ediff to find the differences.

(defun highlight-markup-buffers
  (buf-a file-a buf-b file-b &optional markup-a-only)
  "Get differences between two buffers and set highlight changes.
Both buffers are done unless optional parameter MARKUP-A-ONLY
is non-nil."
  (require 'ediff-util)
  (save-window-excursion
    (let* (change-info
	   change-a change-b
	   a-start a-end len-a
	   b-start b-end len-b
	   (bufa-modified (buffer-modified-p buf-a))
	   (bufb-modified (buffer-modified-p buf-b))
	   (buf-a-read-only (with-current-buffer buf-a buffer-read-only))
	   (buf-b-read-only (with-current-buffer buf-b buffer-read-only))
	   temp-a temp-b)
      (if (and file-a bufa-modified)
	  (if (y-or-n-p (format "Save buffer %s?  " buf-a))
	      (with-current-buffer buf-a
		(save-buffer)
		(setq bufa-modified (buffer-modified-p buf-a)))
	    (setq file-a nil)))
      (or file-a
	  (setq temp-a (setq file-a (ediff-make-temp-file buf-a nil))))

      (if (and file-b bufb-modified)
	  (if (y-or-n-p (format "Save buffer %s?  " buf-b))
	      (with-current-buffer buf-b
		(save-buffer)
		(setq bufb-modified (buffer-modified-p buf-b)))
	    (setq file-b nil)))
      (or file-b
	  (setq temp-b (setq file-b (ediff-make-temp-file buf-b nil))))
      (set-buffer buf-a)
      (highlight-changes-mode 'active)
      (or markup-a-only (with-current-buffer buf-b
			  (highlight-changes-mode 'active)))
      (setq change-info (hilit-chg-get-diff-info buf-a file-a buf-b file-b))


      (setq change-a (car change-info))
      (setq change-b (car (cdr change-info)))
      
      (hilit-chg-make-list)
      (while change-a
	(setq a-start (nth 0 (car change-a)))
	(setq a-end (nth 1 (car change-a)))
	(setq b-start (nth 0 (car change-b)))
	(setq b-end (nth 1 (car change-b)))
	(setq len-a (- a-end a-start))
	(setq len-b (- b-end b-start))
	(set-buffer buf-a)
	(hilit-chg-set-face-on-change a-start a-end len-b buf-a-read-only)
	(or markup-a-only
	    (with-current-buffer buf-b
	      (hilit-chg-set-face-on-change b-start b-end len-a
					    buf-b-read-only)
	      ))
	(setq change-a (cdr change-a))
	(setq change-b (cdr change-b)))
      (or bufa-modified
	  (with-current-buffer buf-a (set-buffer-modified-p nil)))
      (or bufb-modified
	  (with-current-buffer buf-b (set-buffer-modified-p nil)))
      (if temp-a
	  (delete-file temp-a))
      (if temp-b
	  (delete-file temp-b)))
    ))

;;;###autoload
(defun highlight-compare-buffers (buf-a buf-b)
"Compare two buffers and highlight the differences.

The default is the current buffer and the one in the next window.

If either buffer is modified and is visiting a file, you are prompted
to save the file.

Unless the buffer is unmodified and visiting a file,  the buffer is
written to a temporary file for comparison.

If a buffer is read-only, differences will be highlighted but no property
changes are made, so \\[highlight-changes-next-change] and
\\[highlight-changes-previous-change] will not work."
  (interactive
   (list
    (get-buffer (read-buffer "buffer-a " (current-buffer) t))
    (get-buffer
     (read-buffer "buffer-b "
		  (window-buffer (next-window (selected-window))) t))))
  (let ((file-a (buffer-file-name buf-a))
	(file-b (buffer-file-name buf-b)))
    (highlight-markup-buffers buf-a file-a buf-b file-b)
    ))

;;;###autoload
(defun highlight-compare-with-file (file-b)
  "Compare this buffer with a file, and highlight differences.

If the buffer has a backup filename, it is used as the default when
this function is called interactively.

If the current buffer is visiting the file being compared against, it
also will have its differences highlighted.  Otherwise, the file is
read in temporarily but the buffer is deleted.

If the buffer is read-only, differences will be highlighted but no property
changes are made, so \\[highlight-changes-next-change] and
\\[highlight-changes-previous-change] will not work."
  (interactive (list
	      (read-file-name
	       "File to compare with? " ;; prompt
	       ""			;; directory
	       nil			;; default
	       'yes			;; must exist
	       (let ((f (buffer-file-name (current-buffer)))) ;; initial
		 (if f
		     (progn
		       (setq f (make-backup-file-name f))
		       (or (file-exists-p f)
			   (setq f nil))))
		 f))))
  (let* ((buf-a (current-buffer))
	 (file-a (buffer-file-name))
	 (existing-buf (get-file-buffer file-b))
	 (buf-b (or existing-buf
		    (find-file-noselect file-b)))
	 (buf-b-read-only (with-current-buffer buf-b buffer-read-only)))
    (highlight-markup-buffers buf-a file-a buf-b file-b (not existing-buf))
    (unless existing-buf
      (kill-buffer buf-b))
    ))


(defun hilit-chg-get-diff-info (buf-a file-a buf-b file-b)
  (let ((e nil) x y)   ;; e is set by function hilit-chg-get-diff-list-hk
    (ediff-setup buf-a file-a buf-b file-b
	       nil nil   ; buf-c file-C
	       'hilit-chg-get-diff-list-hk
	       (list (cons 'ediff-job-name 'something))
	       )
    (ediff-with-current-buffer e (ediff-really-quit nil))
    (list x y)))


(defun hilit-chg-get-diff-list-hk ()
  ;; x and y are dynamically bound by hilit-chg-get-diff-info
  ;; which calls this function as a hook
  (defvar x)  ;; placate the byte-compiler
  (defvar y)
  (setq  e (current-buffer))
  (let ((n 0) extent p va vb a b)
    (setq  x nil  y nil)    ;; x and y are bound by hilit-chg-get-diff-info
    (while (< n ediff-number-of-differences)
      (ediff-make-fine-diffs n)
      (setq va (ediff-get-fine-diff-vector n 'A))
      ;; va is a vector if there are fine differences
      (if va
	  (setq a (append va nil))
	;; if not, get the unrefined difference
	(setq va (ediff-get-difference n 'A))
	(setq a (list (elt va 0))))
      ;; a list a list
      (setq p a)
      (while p
	(setq extent (list (overlay-start (car p))
			   (overlay-end (car p))))
	(setq p (cdr p))
	(setq x (append x (list extent) )));; while p
      ;;
      (setq vb (ediff-get-fine-diff-vector n 'B))
      ;; vb is a vector
      (if vb
	  (setq b (append vb nil))
	;; if not, get the unrefined difference
	(setq vb (ediff-get-difference n 'B))
	(setq b (list (elt vb 0))))
      ;; b list a list
      (setq p b)
      (while p
	(setq extent (list (overlay-start (car p))
			   (overlay-end (car p))))
	(setq p (cdr p))
	(setq y (append y (list extent) )))
      (setq n (1+ n)));; while
    ;; ediff-quit doesn't work here.
    ;; No point in returning a value, since this is a hook function.
    ))

;; ======================= automatic stuff ==============

;; Global Highlight Changes mode is modeled after Global Font-lock mode.
;; Three hooks are used to gain control.  When Global Changes Mode is
;; enabled, `find-file-hooks' and `change-major-mode-hook' are set.
;; `find-file-hooks' is called when visiting a file, the new mode is
;; known at this time.
;; `change-major-mode-hook' is called when a buffer is changing mode.
;; This could be because of finding a file in which case
;; `find-file-hooks' has already been called and has done its work.
;; However, it also catches the case where a new mode is being set by
;; the user.  However, it is called from `kill-all-variables' and at
;; this time the mode is the old mode, which is not what we want.
;; So, our function temporarily sets `post-command-hook' which will
;; be called after the buffer has been completely set up (with the new
;; mode).  It then removes the `post-command-hook'.
;; One other wrinkle - every M-x command runs the `change-major-mode-hook'
;; so we ignore this by examining the buffer name.


(defun hilit-chg-major-mode-hook ()
  (add-hook 'post-command-hook 'hilit-chg-post-command-hook))

(defun hilit-chg-post-command-hook ()
  ;; This is called after changing a major mode, but also after each
  ;; M-x command, in which case the current buffer is a minibuffer.
  ;; In that case, do not act on it here, but don't turn it off
  ;; either, we will get called here again soon-after.
  ;; Also, don't enable it for other special buffers.
  (if (string-match "^[ *]"  (buffer-name))
      nil ;; (message "ignoring this post-command-hook")
    (remove-hook 'post-command-hook 'hilit-chg-post-command-hook)
    ;; The following check isn't necessary, since
    ;; hilit-chg-turn-on-maybe makes this check too.
    (or highlight-changes-mode	;; don't turn it on if it already is
	(hilit-chg-turn-on-maybe))))

(defun hilit-chg-check-global ()
  ;; This is called from the find file hook.
  (hilit-chg-turn-on-maybe))


;;;###autoload
(defun global-highlight-changes (&optional arg)
  "Turn on or off Global Highlight Changes mode.
With ARG, turn Global Highlight Changes mode on if and only if arg is positive.
When global Highlight Changes mode is enabled, Highlight Changes mode is turned
on for future \"suitable\" buffers (and for \"suitable\" existing buffers if
variable `highlight-changes-global-changes-existing-buffers' is non-nil).
\"Suitability\" is determined by variable `highlight-changes-global-modes'."
  (interactive "P")
  (setq global-highlight-changes
	(if (null arg)
	    (not global-highlight-changes)
	  (> (prefix-numeric-value arg) 0)))
  (if global-highlight-changes
      (progn
	(message "Turning ON Global Highlight Changes mode")
	(add-hook 'hilit-chg-major-mode-hook 'hilit-chg-major-mode-hook)
	(add-hook 'find-file-hooks 'hilit-chg-check-global)
	(if highlight-changes-global-changes-existing-buffers
	    (hilit-chg-update-all-buffers t)))
    (message "Turning OFF global Highlight Changes mode")
    (remove-hook 'hilit-chg-major-mode-hook 'hilit-chg-major-mode-hook)
    (remove-hook 'find-file-hooks 'hilit-chg-check-global)
    (remove-hook 'post-command-hook
		 'hilit-chg-post-command-hook)
    (remove-hook 'find-file-hooks 'hilit-chg-check-global)
    (if highlight-changes-global-changes-existing-buffers
	(hilit-chg-update-all-buffers nil))))


(defun hilit-chg-turn-on-maybe ()
  "Turn on Highlight Changes mode if it is appropriate for this buffer.

A buffer is appropriate for Highlight Changes mode if all these are true:
- the buffer is not a special buffer (one whose name begins with
  `*' or ` ')
- the buffer's mode is suitable as per variable
  `highlight-changes-global-modes'
- Highlight Changes mode is not already on for this buffer.

This function is called from `hilit-chg-update-all-buffers' or
from `global-highlight-changes' when turning on global Highlight Changes mode."
  (or highlight-changes-mode			; do nothing if already on
      (if
	  (cond
	   ((null highlight-changes-global-modes)
	    nil)
	   ((functionp highlight-changes-global-modes)
	    (funcall highlight-changes-global-modes))
	    ((listp highlight-changes-global-modes)
	     (if (eq (car-safe highlight-changes-global-modes) 'not)
		 (not (memq major-mode (cdr highlight-changes-global-modes)))
	       (memq major-mode highlight-changes-global-modes)))
	    (t
	     (and
	      (not (string-match "^[ *]"  (buffer-name)))
	      (buffer-file-name))))
	  (progn
	    (hilit-chg-set))
	)))


(defun hilit-chg-turn-off-maybe ()
  (if highlight-changes-mode
      (hilit-chg-clear)))


(defun hilit-chg-update-all-buffers (value)
  (mapcar
   (function (lambda (buffer)
	       (with-current-buffer buffer
		 (if value
		     (hilit-chg-turn-on-maybe)
		   (hilit-chg-turn-off-maybe))
		 )))
   (buffer-list)))

;; ===================== debug ==================
;; For debug & test use:
;;
;; (defun hilit-chg-debug-show (&optional beg end)
;;   (interactive)
;;   (message "--- hilit-chg-debug-show ---")
;;   (hilit-chg-map-changes '(lambda (prop start end)
;; 			      (message "%d-%d: %s" start end prop)
;; 			      )
;; 			   beg end
;; 			   ))
;;
;; ================== end of debug ===============

(provide 'hilit-chg)

;;; hilit-chg.el ends here

[-- Attachment #3: message body text --]
[-- Type: text/plain, Size: 9 bytes --]


Richard

[-- Attachment #4: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

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

* Re: highlight-changes-mode
  2006-11-27  1:57         ` highlight-changes-mode rsharman
@ 2006-11-27  6:43           ` Nick Roberts
  2006-11-28  2:15             ` highlight-changes-mode rsharman
  2006-12-06  6:25             ` highlight-changes-mode rsharman
  2006-11-27 15:38           ` highlight-changes-mode Richard Stallman
  1 sibling, 2 replies; 57+ messages in thread
From: Nick Roberts @ 2006-11-27  6:43 UTC (permalink / raw)
  Cc: rms, emacs-devel


> Attached is the new version;  please let me know what you think.

I don't use highlight-changes-mode but the mode line indicator doesn't appear
to toggle unless you do "M-x highlight-changes-toggle-visibility" first.  The
manual just says:

  Use `M-x highlight-changes-mode' to enable (or disable) Highlight
  Changes mode, a minor mode that uses faces (colors, typically) to
  indicate which parts of the buffer were changed most recently.

Perhaps that needs updating.  Also it might be a good idea to use
define-minor-mode to define highlight-changes-mode.

-- 
Nick                                           http://www.inet.net.nz/~nickrob

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

* Re: highlight-changes-mode
  2006-11-27  1:57         ` highlight-changes-mode rsharman
  2006-11-27  6:43           ` highlight-changes-mode Nick Roberts
@ 2006-11-27 15:38           ` Richard Stallman
  2006-11-28  2:04             ` highlight-changes-mode rsharman
  1 sibling, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-11-27 15:38 UTC (permalink / raw)
  Cc: nickrob, rsharman, emacs-devel

It looks like you started from something other than the current
version of the file.  (I will mail you the current version
separately.)  Would you please adapt your changes into the current
version?  Please send a diff -c file to show us the changes.

Also, would you please send a change log entry?

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

* Re: highlight-changes-mode
  2006-11-27 15:38           ` highlight-changes-mode Richard Stallman
@ 2006-11-28  2:04             ` rsharman
  2006-12-05  2:42               ` highlight-changes-mode rsharman
  0 siblings, 1 reply; 57+ messages in thread
From: rsharman @ 2006-11-28  2:04 UTC (permalink / raw)
  Cc: nickrob, rsharman, emacs-devel

Richard Stallman writes:
 > It looks like you started from something other than the current
 > version of the file.  (I will mail you the current version
 > separately.)  Would you please adapt your changes into the current
 > version?  Please send a diff -c file to show us the changes.
 > 
 > Also, would you please send a change log entry?

Hi.

I received the other message first which was bewildering for a second
but I figured out that the version you sent me was the one I should
merge into.

I didn't have emacs-22 and it looks like I need that for
define-obsolete-variable-alias.  It wasn't easy finding out how to
download emacs-22 (thank heavens for search engines!)  and I'd never
used CVS before but I was amazed how simple it was.  One command and
the entire source code came over.   Brilliant!

I will try and get it done within a week.
Richard

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

* Re: highlight-changes-mode
  2006-11-27  6:43           ` highlight-changes-mode Nick Roberts
@ 2006-11-28  2:15             ` rsharman
  2006-12-06  6:25             ` highlight-changes-mode rsharman
  1 sibling, 0 replies; 57+ messages in thread
From: rsharman @ 2006-11-28  2:15 UTC (permalink / raw)
  Cc: rsharman, rms, emacs-devel

Nick Roberts writes:
 > 
 > > Attached is the new version;  please let me know what you think.
 > 
 > I don't use highlight-changes-mode but the mode line indicator doesn't appear
 > to toggle unless you do "M-x highlight-changes-toggle-visibility"
 > first.


Yes,  originally I had the mode line displaying either "CHG" or "chg"
depending if the submide was active or passive.  (Those terms refer toe
the old version; I've now called the visible on invisible.)
But Richard Stallman said there was no point in having a modeline
indicator when in "active" sub-mode because it would be obvious.

So there are [in both the old and the new versions] two variables that
can be customized:

highlight-changes-active-string - defaults to nil,  but you could
				set it to " CHG" for example.

highlight-changes-passive-string - defaults to " Chg".


 >  The manual just says:
 > 
 >   Use `M-x highlight-changes-mode' to enable (or disable) Highlight
 >   Changes mode, a minor mode that uses faces (colors, typically) to
 >   indicate which parts of the buffer were changed most recently.
 > 
 > Perhaps that needs updating. 

I think that paragraph is still true.   Any changed text should have
been displayed differently when you turned on highlight-changes-mode
(even though the mode indicator hadn't changed).



 Also it might be a good idea to use
 > define-minor-mode to define highlight-changes-mode.
 > 

OK, I'll take a look into that.

Thanks for the feedback.
Richard

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

* Re: highlight-changes-mode
  2006-11-28  2:04             ` highlight-changes-mode rsharman
@ 2006-12-05  2:42               ` rsharman
  0 siblings, 0 replies; 57+ messages in thread
From: rsharman @ 2006-12-05  2:42 UTC (permalink / raw)
  Cc: rsharman

rsharman@pobox.com writes:

  > Richard Stallman writes:
  >  > It looks like you started from something other than the current
  >  > version of the file. ... Would you please adapt your changes
  >  > into the current version?  

> I will try and get it done within a week.
> Richard

Sorry, it took longer than I'd expected and I had less time to spend
on it than I expacted, so it will be another few days yet.

Richard

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

* Re: highlight-changes-mode
  2006-11-27  6:43           ` highlight-changes-mode Nick Roberts
  2006-11-28  2:15             ` highlight-changes-mode rsharman
@ 2006-12-06  6:25             ` rsharman
  2006-12-06  6:37               ` highlight-changes-mode rsharman
  2006-12-06 18:44               ` highlight-changes-mode Richard Stallman
  1 sibling, 2 replies; 57+ messages in thread
From: rsharman @ 2006-12-06  6:25 UTC (permalink / raw)
  Cc: emacs-devel, rms, rsharman

Nick Roberts writes:
 > 
 >  Also it might be a good idea to use
 > define-minor-mode to define highlight-changes-mode.
 > 

Thanks,  that's nice.

It looks as if I could simplify a lot by using define-global-minor-mode 
for global-highlight-changes.  However, to keep the existing functionality
where variable highlight-changes-global-changes-existing-buffers
allows existing buffers to be left alone and only new ones changed,
I need a minor change to define-global-minor-mode.

I added a new keyword :only-new EXPR which allows restricting
a change of mode to new only new buffers if EXPR is non-nil.
(So the default behaviour, without this keyword, is unchanged.)

With this I can remove nearly all the code for the global
highlight-changes.

Is this acceptable?  Here's the change to easy-mmode.el that
implements what I need:


 
========================================================================
*** easy-mmode.el.orig	Thu Aug 31 19:14:26 2006
--- easy-mmode.el	Wed Dec  6 01:16:35 2006
***************
*** 278,290 ****
  TURN-ON is a function that will be called with no args in every buffer
    and that should try to turn MODE on if applicable for that buffer.
  KEYS is a list of CL-style keyword arguments.  As the minor mode
!   defined by this function is always global, any :global keyword is
!   ignored.  Other keywords have the same meaning as in `define-minor-mode',
!   which see.  In particular, :group specifies the custom group.
!   The most useful keywords are those that are passed on to the
!   `defcustom'.  It normally makes no sense to pass the :lighter
!   or :keymap keywords to `define-global-minor-mode', since these
!   are usually passed to the buffer-local version of the minor mode.
  
  If MODE's set-up depends on the major mode in effect when it was
  enabled, then disabling and reenabling MODE should make MODE work
--- 278,292 ----
  TURN-ON is a function that will be called with no args in every buffer
    and that should try to turn MODE on if applicable for that buffer.
  KEYS is a list of CL-style keyword arguments.  As the minor mode
!   defined by this function is always global, any :global keyword
!   is ignored.  Keyword :only-new EXPR means don't change existing
!   buffers if EXPR is non-nil.  Other keywords have the same
!   meaning as in `define-minor-mode', which see.  In particular, 
!   :group specifies the custom group.  The most useful keywords
!   are those that are passed on to the `defcustom'.  It normally
!   makes no sense to pass the :lighter or :keymap keywords to
!   `define-global-minor-mode', since these are usually passed to
!   the buffer-local version of the minor mode.
  
  If MODE's set-up depends on the major mode in effect when it was
  enabled, then disabling and reenabling MODE should make MODE work
***************
*** 304,309 ****
--- 306,312 ----
  	  (intern (concat global-mode-name "-check-buffers")))
  	 (MODE-cmhh (intern (concat global-mode-name "-cmhh")))
  	 (MODE-major-mode (intern (concat (symbol-name mode) "-major-mode")))
+ 	 (only-new nil)
  	 keyw)
  
      ;; Check keys.
***************
*** 312,317 ****
--- 315,321 ----
        (case keyw
  	(:group (setq group (nconc group (list :group (pop keys)))))
  	(:global (setq keys (cdr keys)))
+ 	(:only-new (setq only-new (pop keys)))
  	(t (push keyw extra-keywords) (push (pop keys) extra-keywords))))
  
      (unless group
***************
*** 344,352 ****
  	   (remove-hook 'change-major-mode-hook ',MODE-cmhh))
  
  	 ;; Go through existing buffers.
! 	 (dolist (buf (buffer-list))
! 	   (with-current-buffer buf
! 	     (if ,global-mode (,turn-on) (when ,mode (,mode -1))))))
  
         ;; Autoloading define-global-minor-mode autoloads everything
         ;; up-to-here.
--- 348,357 ----
  	   (remove-hook 'change-major-mode-hook ',MODE-cmhh))
  
  	 ;; Go through existing buffers.
! 	 (unless ,only-new
! 	   (dolist (buf (buffer-list))
! 	     (with-current-buffer buf
! 	       (if ,global-mode (,turn-on) (when ,mode (,mode -1)))))))
  
         ;; Autoloading define-global-minor-mode autoloads everything
         ;; up-to-here.
========================================================================

Richard

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

* Re: highlight-changes-mode
  2006-12-06  6:25             ` highlight-changes-mode rsharman
@ 2006-12-06  6:37               ` rsharman
  2006-12-06 18:44               ` highlight-changes-mode Richard Stallman
  1 sibling, 0 replies; 57+ messages in thread
From: rsharman @ 2006-12-06  6:37 UTC (permalink / raw)
  Cc: rsharman

A few minutes ago I wrote:
 > 
 > I added a new keyword :only-new EXPR which allows restricting
 > a change of mode to new only new buffers if EXPR is non-nil.
 > (So the default behaviour, without this keyword, is unchanged.)
 > 
 > With this I can remove nearly all the code for the global
 > highlight-changes.
 > 
 > Is this acceptable?  Here's the change to easy-mmode.el that
 > implements what I need:
 > 

If you folks don't think that this is a generally useful change to
define-global-minor-mode, I think I could do what I need if there was
an optional turn-off function.  Suppose instead of adding :only-new
EXPR the macro was changed to allow an optional :turn-off FUNC
keyword.  Would this be deemed more acceptable?  If this function were
supplied then instead of arbitrarily turning off the mode in all
exsiting buffers, it would call the function to possibly do so.

Richard

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

* Re: highlight-changes-mode
  2006-12-06  6:25             ` highlight-changes-mode rsharman
  2006-12-06  6:37               ` highlight-changes-mode rsharman
@ 2006-12-06 18:44               ` Richard Stallman
  2006-12-06 19:58                 ` highlight-changes-mode Drew Adams
  2006-12-06 23:39                 ` highlight-changes-mode rsharman
  1 sibling, 2 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-06 18:44 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

    I added a new keyword :only-new EXPR which allows restricting
    a change of mode to new only new buffers if EXPR is non-nil.
    (So the default behaviour, without this keyword, is unchanged.)

If we want that functionality, this is a clean way of providing it.  I
think the real question is which way we want global minor modes to
work.  Do we want the global mode command to affect only buffers
created subsequently?  Do we want it to affect all existing buffers?
Only existing buffers in which the user has not specified any
setting for the mode?

Is there a good reason why global-highlight-changes should
not be like Global Font Lock mode, and affect all buffers
where it is applicable?

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

* RE: highlight-changes-mode
  2006-12-06 18:44               ` highlight-changes-mode Richard Stallman
@ 2006-12-06 19:58                 ` Drew Adams
  2006-12-07 21:02                   ` highlight-changes-mode Richard Stallman
  2006-12-06 23:39                 ` highlight-changes-mode rsharman
  1 sibling, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-06 19:58 UTC (permalink / raw)


> I think the real question is which way we want global minor modes to
> work.  Do we want the global mode command to affect only buffers
> created subsequently?  Do we want it to affect all existing buffers?
> Only existing buffers in which the user has not specified any
> setting for the mode?

My opinion:

I want turning on or off a global minor mode to affect all existing and all
future buffers (until another explicit mode change). Anything else would be
a nuisance, in addition to being confusing.

There may be some particular global minor modes that one doesn't want to
turn on or off in particular buffers, but they should be handled as special
cases. The general case should be to treat a global minor mode as, well,
global - to have it do for all buffers what a local minor mode does for the
current buffer.

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

* Re: highlight-changes-mode
  2006-12-06 18:44               ` highlight-changes-mode Richard Stallman
  2006-12-06 19:58                 ` highlight-changes-mode Drew Adams
@ 2006-12-06 23:39                 ` rsharman
  2006-12-07 21:03                   ` highlight-changes-mode Richard Stallman
  1 sibling, 1 reply; 57+ messages in thread
From: rsharman @ 2006-12-06 23:39 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

Richard Stallman writes:
 >     I added a new keyword :only-new EXPR which allows restricting
 >     a change of mode to new only new buffers if EXPR is non-nil.
 >     (So the default behaviour, without this keyword, is unchanged.)
 > 
 > If we want that functionality, this is a clean way of providing it.  I
 > think the real question is which way we want global minor modes to
 > work.  Do we want the global mode command to affect only buffers
 > created subsequently?  Do we want it to affect all existing buffers?
 > Only existing buffers in which the user has not specified any
 > setting for the mode?
 > 
 > Is there a good reason why global-highlight-changes should
 > not be like Global Font Lock mode, and affect all buffers
 > where it is applicable?


That wouldn't be a problem when the global mode is turned _on_;
the problem occurs when the global mode is turned _off_.

The current implementation allows the situation where a user no longer
wants it turned on by default, but has an existing buffer that has
some changes already highlighted.  If disabling the global mode
automatically disables highlight changes modes in that buffer, then
the highlighting of the changes disappears; we have lost information.

I don't remember if that _was_ the reason why it was done that way;
that's the only reason I can think of for keeping that behaviour.

One could argue against this, however, by noting that there are now
[in the new version] two commands to markup the changes; one works by
comparing against a file, the other against a buffer.  So in some
cases - probably most - this "lost" information could be recovered.

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

* Re: highlight-changes-mode
  2006-12-06 19:58                 ` highlight-changes-mode Drew Adams
@ 2006-12-07 21:02                   ` Richard Stallman
  2006-12-07 21:13                     ` highlight-changes-mode Drew Adams
  0 siblings, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-12-07 21:02 UTC (permalink / raw)
  Cc: emacs-devel

    I want turning on or off a global minor mode to affect all existing and all
    future buffers (until another explicit mode change). Anything else would be
    a nuisance, in addition to being confusing.

Do you use highlight-changes-mode?  Would you say that this
change would be an improvement for you, in highlight-changes-mode?

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

* Re: highlight-changes-mode
  2006-12-06 23:39                 ` highlight-changes-mode rsharman
@ 2006-12-07 21:03                   ` Richard Stallman
  2006-12-09 19:40                     ` highlight-changes-mode rsharman
  0 siblings, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-12-07 21:03 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

    The current implementation allows the situation where a user no longer
    wants it turned on by default, but has an existing buffer that has
    some changes already highlighted.  If disabling the global mode
    automatically disables highlight changes modes in that buffer, then
    the highlighting of the changes disappears; we have lost information.

That is clearly true.  The question is whether this is a useful feature
that we want, or whether it is better to make this mode like the others.

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

* RE: highlight-changes-mode
  2006-12-07 21:02                   ` highlight-changes-mode Richard Stallman
@ 2006-12-07 21:13                     ` Drew Adams
  2006-12-09 18:55                       ` global minor modes that can be overridden locally? [was: highlight-changes-mode] Drew Adams
  0 siblings, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-07 21:13 UTC (permalink / raw)


>     I want turning on or off a global minor mode to affect all 
>     existing and all future buffers (until another explicit
>     mode change). Anything else would be
>     a nuisance, in addition to being confusing.
> 
> Do you use highlight-changes-mode?  Would you say that this
> change would be an improvement for you, in highlight-changes-mode?

No, I haven't used it. I can't speak to that.

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

* global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-07 21:13                     ` highlight-changes-mode Drew Adams
@ 2006-12-09 18:55                       ` Drew Adams
  2006-12-11  1:06                         ` Richard Stallman
  0 siblings, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-09 18:55 UTC (permalink / raw)


> > >    I think the real question is which way we want global
> > >    minor modes to work.  Do we want the global mode command
> > >    to affect only buffers created subsequently?  Do we want
> > >    it to affect all existing buffers? Only existing buffers
> > >    in which the user has not specified any setting for the mode?
> >
> >     I want turning on or off a global minor mode to affect all
> >     existing and all future buffers (until another explicit
> >     mode change). Anything else would be
> >     a nuisance, in addition to being confusing.
> >
> > Do you use highlight-changes-mode?  Would you say that this
> > change would be an improvement for you, in highlight-changes-mode?
>
> No, I haven't used it. I can't speak to that.

Some thoughts on global minor modes (for after the release). I'm no expert
on minor modes, so please correct any misunderstandings; it's quite possible
this makes no sense at all.

1. Assumption: global minor modes should, generally, let you turn on/off the
mode everywhere at once: all existing and future buffers. This should be the
most direct and easiest thing to do.

2. A minority of global minor modes might want to let you also turn on/off
the mode differently in a particular buffer. IOW, for such modes, you might
want to locally override the global setting (on or off).

3. Perhaps this could be treated analogously to setq-default and setq? For
example, toggling the mode normally would set the default value of the mode
variable everywhere. In buffers that had no different local value, this
would also set the mode. But you could set the local value of the mode
variable differently, if you wanted.

4. Perhaps an interface for #3 something like this?

- M-x foo-mode toggles the mode everywhere (including in buffers that have
local values?) - it is like using setq-default (should it also change the
local values?).

- C-u M-x foo-mode toggles the mode in the current buffer only - it is like
using setq with a local variable.

- C-9 M-x foo-mode turns the mode on globally. M-- M-x foo-mode turns it off
globally. That is, you use a numeric prefix to explicitly turn it on or off
globally (vs toggling).

- C-u C-u foo-mode turns it on locally; C-u C-u C-u turns it off locally.
That is, you use an non-numeric prefix to explicitly turn it on or off
locally (vs toggling). Perhaps someone has a better idea here?

Would this work also for minor modes that are not meant to be changed just
by setting the mode variable? Is there even a need for such a feature
(global modes that can be overridden locally)? Should global minor modes
that use this feature be declared differently - e.g. via :global-local
instead of :global, or should all global minor modes be open to such a use?

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

* Re: highlight-changes-mode
  2006-12-07 21:03                   ` highlight-changes-mode Richard Stallman
@ 2006-12-09 19:40                     ` rsharman
  2006-12-11  1:06                       ` highlight-changes-mode Richard Stallman
  0 siblings, 1 reply; 57+ messages in thread
From: rsharman @ 2006-12-09 19:40 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

Richard Stallman writes:
 >     The current implementation allows the situation where a user no longer
 >     wants it turned on by default, but has an existing buffer that has
 >     some changes already highlighted.  If disabling the global mode
 >     automatically disables highlight changes modes in that buffer, then
 >     the highlighting of the changes disappears; we have lost information.
 > 
 > That is clearly true.  The question is whether this is a useful feature
 > that we want, or whether it is better to make this mode like the others.


Personally I think it is useful. 

I certainly have no problems with global-highlight-changes always
turning on the mode in all buffers.  It is only the unconditional
turning off that I have qualms with.

Can I suggest a compromise?

The default behaviour is changed to always affect existing buffers in
both enabling and disabling.  All references to the variable 
highlight-changes-global-changes-existing-buffers are removed.

A new variable highlight-changes-mode-turn-off-fn can be set to a
function to be called to [optionally] turn off the mode in a buffer.
If set to nil (the default) the mode is turned off unconditionally.

This is implemented by a different change to define-global-minor-mode
from what I'd suggested earlier.  Instead of the :only-new keyword 
there is a :turn-off keyword.  If specified this function is called
instead of the mode being turned off directly.  It is a
more symmetric change than the previous one.


(defvar highlight-changes-mode-turn-off-fn nil
  "*If non-nil, a function to maybe turn off highlight changes mode.
It is called by global-highlight-changes when the mode is turned off.
The default setting of nil causes highlight changes mode to be
disabled in all buffers.")

(defun highlight-changes-mode-turn-off ()
  (if highlight-changes-mode-turn-off-fn
      (funcall highlight-changes-mode-turn-off-fn)
    (highlight-changes-mode -1)))


So to summarize,  the default behaviour is as you prefer, but we allow
a user to override it

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

* Re: highlight-changes-mode
  2006-12-09 19:40                     ` highlight-changes-mode rsharman
@ 2006-12-11  1:06                       ` Richard Stallman
  2006-12-11  9:15                         ` highlight-changes-mode Kim F. Storm
  2006-12-12  3:16                         ` highlight-changes-mode rsharman
  0 siblings, 2 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-11  1:06 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

    A new variable highlight-changes-mode-turn-off-fn can be set to a
    function to be called to [optionally] turn off the mode in a buffer.
    If set to nil (the default) the mode is turned off unconditionally.

I don't object to that mechanism, but the hard question is to choose
the user interface.

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

* Re: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-09 18:55                       ` global minor modes that can be overridden locally? [was: highlight-changes-mode] Drew Adams
@ 2006-12-11  1:06                         ` Richard Stallman
  2006-12-11  1:16                           ` Lennart Borgman
  2006-12-11  1:40                           ` global minor modes that can be overridden locally? [was:highlight-changes-mode] Drew Adams
  0 siblings, 2 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-11  1:06 UTC (permalink / raw)
  Cc: emacs-devel

    4. Perhaps an interface for #3 something like this?

    - M-x foo-mode toggles the mode everywhere (including in buffers that have
    local values?) - it is like using setq-default (should it also change the
    local values?).

    - C-u M-x foo-mode toggles the mode in the current buffer only - it is like
    using setq with a local variable.

That might be good.  However, I'd rather have the simplest call
affect only the current buffer and use C-u to make it global.

    - C-9 M-x foo-mode turns the mode on globally. M-- M-x foo-mode turns it off
    globally. That is, you use a numeric prefix to explicitly turn it on or off
    globally (vs toggling).

That would fit the current scheme (except that these should operate locally).

    - C-u C-u foo-mode turns it on locally; C-u C-u C-u turns it off locally.
    That is, you use an non-numeric prefix to explicitly turn it on or off
    locally (vs toggling). Perhaps someone has a better idea here?

these might be ok for global turn on and off.

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

* Re: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-11  1:06                         ` Richard Stallman
@ 2006-12-11  1:16                           ` Lennart Borgman
  2006-12-11  1:45                             ` Drew Adams
  2006-12-12  2:57                             ` Richard Stallman
  2006-12-11  1:40                           ` global minor modes that can be overridden locally? [was:highlight-changes-mode] Drew Adams
  1 sibling, 2 replies; 57+ messages in thread
From: Lennart Borgman @ 2006-12-11  1:16 UTC (permalink / raw)
  Cc: Drew Adams, emacs-devel

Richard Stallman wrote:
>     4. Perhaps an interface for #3 something like this?
>
>     - M-x foo-mode toggles the mode everywhere (including in buffers that have
>     local values?) - it is like using setq-default (should it also change the
>     local values?).
>
>     - C-u M-x foo-mode toggles the mode in the current buffer only - it is like
>     using setq with a local variable.
>
> That might be good.  However, I'd rather have the simplest call
> affect only the current buffer and use C-u to make it global.
>   
Why not define a new sub foo-mode-locally to toggle it in current buffer 
when it is a global minor mode? IMO that would be more easy to remember. 
Would it be harder to do it that way?

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

* RE: global minor modes that can be overridden locally? [was:highlight-changes-mode]
  2006-12-11  1:06                         ` Richard Stallman
  2006-12-11  1:16                           ` Lennart Borgman
@ 2006-12-11  1:40                           ` Drew Adams
  2006-12-12  2:58                             ` Richard Stallman
  1 sibling, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-11  1:40 UTC (permalink / raw)


>     - M-x foo-mode toggles the mode everywhere (including in
>       buffers that have local values?) - it is like using
>       setq-default (should it also change the local values?).
>
>     - C-u M-x foo-mode toggles the mode in the current buffer
>       only - it is like using setq with a local variable.
>
> That might be good.  However, I'd rather have the simplest call
> affect only the current buffer and use C-u to make it global.

I think I disagree, if you mean that M-x foo-mode should toggle locally.
With that design:

. If there were no buffers where it was defined locally, then M-x foo-mode
would still toggle everywhere (global).

. If there were buffers where it was defined locally, then M-x foo-mode
would toggle differently, depending on where it was invoked:

  - toggle only locally, if invoked in a buffer with a local value
  - toggle globally, if invoked in a buffer with no local value

This inconsistency would be quite confusing. I think the best approach is to
let M-x foo-mode always toggle the global value and C-u M-x foo-mode always
toggle the local value. The latter could even be used to _define_ a local
override of the global value, requiring nothing extra for that.

>     - C-9 M-x foo-mode turns the mode on globally. M-- M-x
>       foo-mode turns it off globally. That is, you use a
>       numeric prefix to explicitly turn it on or off
>       globally (vs toggling).
>
> That would fit the current scheme (except that these should
> operate locally).

Not sure what you mean by the last part, but if it is similar to the
previous, see above.

>     - C-u C-u foo-mode turns it on locally; C-u C-u C-u turns it
>       off locally.  That is, you use an non-numeric prefix to
>       explicitly turn it on or off locally (vs toggling). Perhaps
>       someone has a better idea here?
>
> these might be ok for global turn on and off.

I guess we agree on the essential: allow for local overrides of a global
mode. But we disagree on the key bindings (UI). Please examine all cases and
then make a proposal.

My preference would be to keep the current treatment for a global minor mode
that is not overridden anywhere. This is the most common case, so it should
be the easiest to use.

I would want toggling the global (and the local) value to always use the
same key bindings (just M-x for global, with numeric arg to turn on or off
explicitly). I would not want the bindings to change, depending on whether
or not I'm in a buffer that has a local override.

If you are saying that the global toggle would sometimes (if no local value)
be via M-x and sometimes (if local values exist) be via C-u M-x, then I am
against that inconsistency.

If you are saying that the global toggle would always be C-u M-x, then I am
against that too, because the _common_ global case is (the current one)
where there are no local overrides, and it is inconvenient to use C-u each
time just to toggle the mode.

My assumption is that local overrides of global minor modes will not be too
common, and that the common cases will be a) global minor modes with no
local overrides and b) local minor modes.

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

* RE: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-11  1:16                           ` Lennart Borgman
@ 2006-12-11  1:45                             ` Drew Adams
  2006-12-11  1:52                               ` Lennart Borgman
  2006-12-12  2:57                             ` Richard Stallman
  1 sibling, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-11  1:45 UTC (permalink / raw)


> Why not define a new sub foo-mode-locally to toggle it in current buffer 
> when it is a global minor mode?

Not clear to me what you mean.

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

* Re: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-11  1:45                             ` Drew Adams
@ 2006-12-11  1:52                               ` Lennart Borgman
  2006-12-11  1:58                                 ` Drew Adams
  0 siblings, 1 reply; 57+ messages in thread
From: Lennart Borgman @ 2006-12-11  1:52 UTC (permalink / raw)
  Cc: emacs-devel

Drew Adams wrote:
>> Why not define a new sub foo-mode-locally to toggle it in current buffer 
>> when it is a global minor mode?
>>     
>
> Not clear to me what you mean.
>   

That makes me wonder if I am misunderstanding something ... Are we not 
talking about global minor mode and how to turn them on or off both 
globally in all buffers and locally in just one buffer?

I meant that foo-mode should toggle the global minor mode in all buffers 
and foo-mode-locally should toggle it in just the current buffer. Should 
not that be possible?

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

* RE: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-11  1:52                               ` Lennart Borgman
@ 2006-12-11  1:58                                 ` Drew Adams
  0 siblings, 0 replies; 57+ messages in thread
From: Drew Adams @ 2006-12-11  1:58 UTC (permalink / raw)


> >> Why not define a new sub foo-mode-locally to toggle it in
> >> current buffer when it is a global minor mode?
> >
> > Not clear to me what you mean.
>
> That makes me wonder if I am misunderstanding something ... Are we not
> talking about global minor mode and how to turn them on or off both
> globally in all buffers and locally in just one buffer?

Yes. Currently, there is no way to do the latter; a global minor mode is not
overridden locally. This would be a possible new feature.

> I meant that foo-mode should toggle the global minor mode in all buffers
> and foo-mode-locally should toggle it in just the current buffer. Should
> not that be possible?

Yes. The advantage of that would be that it would avoid using C-u. The
disadvantage would be that it would be a separate command.

You might be right that that would be simpler. I assume that it would act
just like foo-mode does wrt turning on and off explicitly (i.e. with a
prefix arg).

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

* Re: highlight-changes-mode
  2006-12-11  1:06                       ` highlight-changes-mode Richard Stallman
@ 2006-12-11  9:15                         ` Kim F. Storm
  2006-12-12  2:58                           ` highlight-changes-mode Richard Stallman
  2006-12-12  3:16                         ` highlight-changes-mode rsharman
  1 sibling, 1 reply; 57+ messages in thread
From: Kim F. Storm @ 2006-12-11  9:15 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

Richard Stallman <rms@gnu.org> writes:

>     A new variable highlight-changes-mode-turn-off-fn can be set to a
>     function to be called to [optionally] turn off the mode in a buffer.
>     If set to nil (the default) the mode is turned off unconditionally.
>
> I don't object to that mechanism, but the hard question is to choose
> the user interface.

So let it rest until after the release.  Please!

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

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

* Re: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-11  1:16                           ` Lennart Borgman
  2006-12-11  1:45                             ` Drew Adams
@ 2006-12-12  2:57                             ` Richard Stallman
  2006-12-12  3:27                               ` Lennart Borgman
  2006-12-12  4:06                               ` Drew Adams
  1 sibling, 2 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-12  2:57 UTC (permalink / raw)
  Cc: drew.adams, emacs-devel

    Why not define a new sub foo-mode-locally to toggle it in current buffer 
    when it is a global minor mode?

Two different commands is the way we do it now.
In the current scheme; foo-mode is the local toggle
and global-foo-mode is the global toggle.

I think the current scheme is better than making foo-mode the global
command.

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

* Re: highlight-changes-mode
  2006-12-11  9:15                         ` highlight-changes-mode Kim F. Storm
@ 2006-12-12  2:58                           ` Richard Stallman
  0 siblings, 0 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-12  2:58 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

    >     A new variable highlight-changes-mode-turn-off-fn can be set to a
    >     function to be called to [optionally] turn off the mode in a buffer.
    >     If set to nil (the default) the mode is turned off unconditionally.
    >
    > I don't object to that mechanism, but the hard question is to choose
    > the user interface.

    So let it rest until after the release.  Please!

Certainly this is for after the release, and we don't have to discuss
it now either.

The only question for now is what global-highlight-changes-mode
should do when turning the mode off.  Should we go to trouble
to maintain its peculiar behavior, or should we make it like
most global major modes.

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

* Re: global minor modes that can be overridden locally? [was:highlight-changes-mode]
  2006-12-11  1:40                           ` global minor modes that can be overridden locally? [was:highlight-changes-mode] Drew Adams
@ 2006-12-12  2:58                             ` Richard Stallman
  2006-12-12  4:08                               ` global minor modes that can be overridden locally?[was:highlight-changes-mode] Drew Adams
  0 siblings, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-12-12  2:58 UTC (permalink / raw)
  Cc: emacs-devel

    I think I disagree, if you mean that M-x foo-mode should toggle locally.
    With that design:

    . If there were no buffers where it was defined locally, then M-x foo-mode
    would still toggle everywhere (global).

    . If there were buffers where it was defined locally, then M-x foo-mode
    would toggle differently, depending on where it was invoked:

      - toggle only locally, if invoked in a buffer with a local value
      - toggle globally, if invoked in a buffer with no local value

I never advocated anything where the same command sequence would
sometimes be local and sometimes be global, so I think there is a
misunderstanding somewhere.

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

* Re: highlight-changes-mode
  2006-12-11  1:06                       ` highlight-changes-mode Richard Stallman
  2006-12-11  9:15                         ` highlight-changes-mode Kim F. Storm
@ 2006-12-12  3:16                         ` rsharman
  2006-12-12 21:45                           ` highlight-changes-mode Richard Stallman
  1 sibling, 1 reply; 57+ messages in thread
From: rsharman @ 2006-12-12  3:16 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

[-- Attachment #1: message body text --]
[-- Type: text/plain, Size: 37 bytes --]

Here are the changes to hilit-chg.el

[-- Attachment #2: lisp/hilit-chg.el.cdif --]
[-- Type: application/octet-stream, Size: 46576 bytes --]

*** hilit-chg.el.orig	Thu Feb  9 16:00:54 2006
--- hilit-chg.el	Mon Dec 11 21:13:17 2006
***************
*** 26,85 ****
  ;;; Commentary:
  
  ;; A minor mode: "Highlight Changes mode".
- ;;
  
! ;; Highlight Changes mode has 2 submodes: active and passive.
! ;; When active, changes to the buffer are displayed in a different face.
! ;; When passive, any existing displayed changes are saved and new ones
! ;; recorded but are not displayed differently.
! ;; Why active and passive?  Having the changes visible can be handy when you
! ;; want the information but very distracting otherwise.  So, you can keep
! ;; Highlight Changes mode in passive state while you make your changes, toggle
! ;; it on to active mode to see them, then toggle it back off to avoid
! ;; distraction.
! ;;
! ;; When active, changes are displayed in the `highlight-changes' face.
! ;; When text is deleted, the following character is displayed in the
! ;; `highlight-changes-delete' face.
! ;;
  ;;
  ;; You can "age" different sets of changes by using
  ;; `highlight-changes-rotate-faces'.  This rotates through a series
  ;; of different faces, so you can distinguish "new" changes from "older"
  ;; changes.  You can customize these "rotated" faces in two ways.  You can
  ;; either explicitly define each face by customizing
  ;; `highlight-changes-face-list'.  If, however, the faces differ from
! ;; the `highlight-changes' face only in the foreground color, you can simply set
! ;; `highlight-changes-colors'.  If `highlight-changes-face-list' is nil when
  ;; the faces are required they will be constructed from
! ;; `highlight-changes-colors'.
! ;;
! ;;
! ;; When a Highlight Changes mode is on (either active or passive) you can go
! ;; to the next or previous change with `highlight-changes-next-change' and
! ;; `highlight-changes-previous-change'.
! ;;
! ;;
! ;; You can also use the command highlight-compare-with-file to show changes
! ;; in this file compared with another file (typically the previous version
! ;; of the file).  The command highlight-compare-buffers can be used to
! ;; compare two buffers.
! ;;
! ;;
! ;; There are currently three hooks run by `highlight-changes-mode':
  ;; `highlight-changes-enable-hook'  - is run when Highlight Changes mode
! ;;				    is initially enabled for a buffer.
  ;; `highlight-changes-disable-hook' - is run when Highlight Changes mode
! ;;				    is turned off.
! ;; `highlight-changes-toggle-hook'  - is run each time `highlight-changes-mode'
! ;;				    is called.  Typically this is when
! ;;				    toggling between active and passive
! ;;				    modes.  The variable
! ;;				    `highlight-changes-mode' contains the new
! ;;				    state (`active' or `passive'.)
! ;;
! ;;
! ;;
  ;; Example usage:
  ;; (defun my-highlight-changes-enable-hook ()
  ;;   (add-hook 'write-file-functions 'highlight-changes-rotate-faces nil t)
--- 26,73 ----
  ;;; Commentary:
  
  ;; A minor mode: "Highlight Changes mode".
  
! ;; When Highlight Changes mode is enabled changes to the buffer are
! ;; recorded with a text property.  Normally these ranges of text are
! ;; displayed in a distinctive face.  However, sometimes it is
! ;; desirable to temporarily not see these changes.  Rather than
! ;; disabling Highlight Changes mode (thus removing the text property)
! ;; use the command highlight-changes-toggle-visibility.
! 
! ;; Two faces are supported: one for changed or inserted text and
! ;; another for the first character after text has been deleted.
! 
! ;; When Highlight Changes mode is on (even if changes are not visible)
! ;; you can go to the next or previous change with
! ;; `highlight-changes-next-change' or `highlight-changes-previous-change'.
! 
! ;; Command highlight-compare-with-file shows changes in this file
! ;; compared with another file (by default the previous version of the
! ;; file).
  ;;
+ ;; The command highlight-compare-buffers compares two buffers by
+ ;; highlighting their differences.
+ 
  ;; You can "age" different sets of changes by using
  ;; `highlight-changes-rotate-faces'.  This rotates through a series
  ;; of different faces, so you can distinguish "new" changes from "older"
  ;; changes.  You can customize these "rotated" faces in two ways.  You can
  ;; either explicitly define each face by customizing
  ;; `highlight-changes-face-list'.  If, however, the faces differ from
! ;; `highlight-changes-face' only in the foreground color, you can simply set
! ;; `highlight-changes-colours'.  If `highlight-changes-face-list' is nil when
  ;; the faces are required they will be constructed from
! ;; `highlight-changes-colours'.
! 
! ;; You can automatically rotate faces when the buffer is saved;
! ;; see function `highlight-changes-rotate-faces' for how to do this.
! 
! ;; There are two hooks used by `highlight-changes-mode':
  ;; `highlight-changes-enable-hook'  - is run when Highlight Changes mode
! ;;				    is enabled for a buffer.
  ;; `highlight-changes-disable-hook' - is run when Highlight Changes mode
! ;;				    is disabled for a buffer.
! 
  ;; Example usage:
  ;; (defun my-highlight-changes-enable-hook ()
  ;;   (add-hook 'write-file-functions 'highlight-changes-rotate-faces nil t)
***************
*** 94,142 ****
  ;;		'my-highlight-changes-disable-hook)
  
  
! ;;           Explicit vs. Implicit
! ;;
  
  ;; Normally, Highlight Changes mode is turned on explicitly in a buffer.
! ;;
  ;; If you prefer to have it automatically invoked you can do it as
  ;; follows.
! ;;
  ;; 1. Most modes have a major-hook, typically called MODE-hook.  You
  ;; can use `add-hook' to call `highlight-changes-mode'.
! ;;
  ;;   Example:
  ;;	(add-hook 'c-mode-hook 'highlight-changes-mode)
! ;;
! ;;  If you want to make it start up in passive mode (regardless of the
! ;;  setting of highlight-changes-initial-state):
! ;;      (add-hook 'emacs-lisp-mode-hook
! ;; 	    (lambda ()
! ;; 	      (highlight-changes-mode 'passive)))
! ;;
  ;; However, this cannot be done for Fundamental mode for there is no
  ;; such hook.
! ;;
! ;; 2. You can use the function `global-highlight-changes'
! ;;
  ;; This function, which is fashioned after the way `global-font-lock' works,
  ;; toggles on or off global Highlight Changes mode.  When activated, it turns
  ;; on Highlight Changes mode in all "suitable" existing buffers and will turn
  ;; it on in new "suitable" buffers to be created.
! ;;
  ;; A buffer's "suitability" is determined by variable
! ;; `highlight-changes-global-modes', as follows.  If the variable is
  ;; * nil  -- then no buffers are suitable;
  ;; * a function -- this function is called and the result is used.  As
  ;;   an example, if the value is `buffer-file-name' then all buffers
  ;;   who are visiting files are suitable, but others (like dired
  ;;   buffers) are not;
! ;; * a list -- then the buffer is suitable iff its mode is in the
! ;;   list, except if the first element is `not', in which case the test
  ;;   is reversed (i.e. it is a list of unsuitable modes).
  ;; * Otherwise, the buffer is suitable if its name does not begin with
  ;;   ` ' or `*' and if `buffer-file-name' returns true.
! ;;
  
  
  
--- 82,127 ----
  ;;		'my-highlight-changes-disable-hook)
  
  
! 
! ;;           Automatically enabling Highlight Changes mode
! 
  
  ;; Normally, Highlight Changes mode is turned on explicitly in a buffer.
! 
  ;; If you prefer to have it automatically invoked you can do it as
  ;; follows.
! 
  ;; 1. Most modes have a major-hook, typically called MODE-hook.  You
  ;; can use `add-hook' to call `highlight-changes-mode'.
! 
  ;;   Example:
  ;;	(add-hook 'c-mode-hook 'highlight-changes-mode)
! 
  ;; However, this cannot be done for Fundamental mode for there is no
  ;; such hook.
! 
! ;; 2. You can use the function `global-highlight-changes-mode'
! 
  ;; This function, which is fashioned after the way `global-font-lock' works,
  ;; toggles on or off global Highlight Changes mode.  When activated, it turns
  ;; on Highlight Changes mode in all "suitable" existing buffers and will turn
  ;; it on in new "suitable" buffers to be created.
! 
  ;; A buffer's "suitability" is determined by variable
! ;; `highlight-changes-global-modes' as follows.  If this variable is
  ;; * nil  -- then no buffers are suitable;
  ;; * a function -- this function is called and the result is used.  As
  ;;   an example, if the value is `buffer-file-name' then all buffers
  ;;   who are visiting files are suitable, but others (like dired
  ;;   buffers) are not;
! ;; * a list -- then the buffer is suitable if and only if its mode is in the
! ;;   list, unless the first element is `not' in which case the test
  ;;   is reversed (i.e. it is a list of unsuitable modes).
  ;; * Otherwise, the buffer is suitable if its name does not begin with
  ;;   ` ' or `*' and if `buffer-file-name' returns true.
! 
! ;; To enable it for future sessions put this in your ~/.emacs file:
! ;;		(global-highlight-changes-mode t)
  
  
  
***************
*** 144,160 ****
  ;; (global-set-key '[C-right] 'highlight-changes-next-change)
  ;; (global-set-key '[C-left]  'highlight-changes-previous-change)
  ;;
! ;;     Other interactive functions (which could be bound if desired):
  ;; highlight-changes-mode
  ;; highlight-changes-remove-highlight
- ;; highlight-changes-rotate-faces
  ;; highlight-compare-with-file
  ;; highlight-compare-buffers
! 
! ;;
! ;; You can automatically rotate faces when the buffer is saved;
! ;; see function `highlight-changes-rotate-faces' for how to do this.
! ;;
  
  
  ;;; Bugs:
--- 129,141 ----
  ;; (global-set-key '[C-right] 'highlight-changes-next-change)
  ;; (global-set-key '[C-left]  'highlight-changes-previous-change)
  ;;
! ;;     Other interactive functions (that could be bound if desired):
  ;; highlight-changes-mode
+ ;; highlight-changes-toggle-visibility
  ;; highlight-changes-remove-highlight
  ;; highlight-compare-with-file
  ;; highlight-compare-buffers
! ;; highlight-changes-rotate-faces
  
  
  ;;; Bugs:
***************
*** 168,178 ****
  
  ;; - having different faces for deletion and non-deletion: is it
  ;;   really worth the hassle?
- ;; - should have better hooks:  when should they be run?
  ;; - highlight-compare-with-file should allow RCS files - e.g. nice to be
  ;;   able to say show changes compared with version 2.1.
- ;; - Maybe we should have compare-with-buffer as well.  (When I tried
- ;;   a while back I ran into a problem with ediff-buffers-internal.)
  
  
  ;;; History:
--- 149,156 ----
***************
*** 190,198 ****
  ;; - Changed to use overlays
  ;; August 98
  ;; - renamed to Highlight Changes mode.
! ;; Dec 2003
! ;; - Use require for ediff stuff
  ;; - Added highlight-compare-buffers
  
  ;;; Code:
  
--- 168,181 ----
  ;; - Changed to use overlays
  ;; August 98
  ;; - renamed to Highlight Changes mode.
! ;; Nov 2006
! ;; - Made highlight-changes-mode like other modes (toggle on/off)
! ;; - Added new command highlight-changes-toggle-visibility to replace the
! ;;   previous active/passive aspect of highlight-changes-mode.
! ;; - Removed highlight-changes-toggle-hook
  ;; - Added highlight-compare-buffers
+ ;; - Put back eval-and-compile inadvertently dropped
+ 
  
  ;;; Code:
  
***************
*** 254,298 ****
    :group 'highlight-changes)
  
  (define-obsolete-variable-alias 'highlight-changes-colours
!                                 'highlight-changes-colors "22.1")
  
  
! ;; If you invoke highlight-changes-mode with no argument, should it start in
! ;; active or passive mode?
! ;;
! (defcustom highlight-changes-initial-state 'active
!   "*What state (active or passive) Highlight Changes mode should start in.
! This is used when `highlight-changes-mode' is called with no argument.
! This variable must be set to one of the symbols `active' or `passive'."
!   :type '(choice (const :tag "Active" active)
! 		 (const :tag "Passive" passive))
!   :group 'highlight-changes)
  
- (defcustom highlight-changes-global-initial-state 'passive
-   "*What state global Highlight Changes mode should start in.
- This is used if `global-highlight-changes' is called with no argument.
- This variable must be set to either `active' or `passive'."
-   :type '(choice (const :tag "Active" active)
- 		 (const :tag "Passive" passive))
-   :group 'highlight-changes)
  
! ;; The strings displayed in the mode-line for the minor mode:
! (defcustom highlight-changes-active-string " +Chg"
!   "*The string used when Highlight Changes mode is in the active state.
  This should be set to nil if no indication is desired, or to
  a string with a leading space."
    :type '(choice string
  		 (const :tag "None"  nil))
    :group 'highlight-changes)
  
! (defcustom highlight-changes-passive-string " -Chg"
!   "*The string used when Highlight Changes mode is in the passive state.
  This should be set to nil if no indication is desired, or to
  a string with a leading space."
    :type '(choice string
  		 (const :tag "None"  nil))
    :group 'highlight-changes)
  
  (defcustom highlight-changes-global-modes t
    "*Determine whether a buffer is suitable for global Highlight Changes mode.
  
--- 237,278 ----
    :group 'highlight-changes)
  
  (define-obsolete-variable-alias 'highlight-changes-colours
! 				'highlight-changes-colors "22.1")
  
+ (make-obsolete-variable 'highlight-changes-global-changes-existing-buffers
+ 			"global-highlight-changes-mode
+ affects all buffers now.  See variables `highlight-changes-global-modes' and
+ `highlight-changes-mode-turn-off-fn'." "22.1")
  
! ;; highlight-changes-initial-state has been removed
! ;; highlight-changes-global-initial-state has been removed
  
  
! ;; These are the strings displayed in the mode-line for the minor mode:
! 
! (defcustom highlight-changes-visible-string " +Chg"
!   "*The string used when in Highlight Changes mode and changes are visible.
  This should be set to nil if no indication is desired, or to
  a string with a leading space."
    :type '(choice string
  		 (const :tag "None"  nil))
    :group 'highlight-changes)
  
! (define-obsolete-variable-alias 'highlight-changes-active-string
! 			'highlight-changes-visible-string "22.1")
! 
! (defcustom highlight-changes-invisible-string " -Chg"
!   "*The string used when in Highlight Changes mode and changes are hidden.
  This should be set to nil if no indication is desired, or to
  a string with a leading space."
    :type '(choice string
  		 (const :tag "None"  nil))
    :group 'highlight-changes)
  
+ (define-obsolete-variable-alias 'highlight-changes-passive-string
+ 			'highlight-changes-invisible-string "22.1")
+ 
+ 
  (defcustom highlight-changes-global-modes t
    "*Determine whether a buffer is suitable for global Highlight Changes mode.
  
***************
*** 306,316 ****
  A value of t means the buffer is suitable if it is visiting a file and
  its name does not begin with ` ' or `*'.
  
! A value of nil means no buffers are suitable for `global-highlight-changes'
  \(effectively disabling the mode).
  
  Example:
!         (c-mode c++-mode)
  means that Highlight Changes mode is turned on for buffers in C and C++
  modes only."
    :type '(choice
--- 286,296 ----
  A value of t means the buffer is suitable if it is visiting a file and
  its name does not begin with ` ' or `*'.
  
! A value of nil means no buffers are suitable for `global-highlight-changes-mode'
  \(effectively disabling the mode).
  
  Example:
! 	(c-mode c++-mode)
  means that Highlight Changes mode is turned on for buffers in C and C++
  modes only."
    :type '(choice
***************
*** 325,341 ****
  	  )
    :group 'highlight-changes)
  
- (defvar global-highlight-changes nil)
- 
- (defcustom highlight-changes-global-changes-existing-buffers nil
-   "*If non-nil, toggling global Highlight Changes mode affects existing buffers.
- Normally, `global-highlight-changes' affects only new buffers (to be
- created).  However, if `highlight-changes-global-changes-existing-buffers'
- is non-nil, then turning on `global-highlight-changes' will turn on
- Highlight Changes mode in suitable buffers, and turning the mode off will
- remove it from existing buffers."
-   :type 'boolean
-   :group 'highlight-changes)
  
  (defun hilit-chg-cust-fix-changes-face-list (w wc &optional event)
    ;; When customization function `highlight-changes-face-list' inserts a new
--- 305,310 ----
***************
*** 398,403 ****
--- 367,384 ----
  	  )
    :group 'highlight-changes)
  
+ (defvar highlight-changes-visible-p t
+   "*This controls the appearance of changes when Highlight Changes mode is on.
+ If non-nil, the changes are displayed using distinctive faces.
+ 
+ This variable is buffer-local when set.
+ 
+ Do not set this variable directly.  Instead,  use
+ \\[highlight-changes-toggle-visibility] to change this variable in a
+ buffer,  or use the Lisp function `setq-default' to change the default
+ value that is used for new buffers visited when Global Highlight Changes
+ mode is active.")
+ 
  ;; ========================================================================
  
  ;; These shouldn't be changed!
***************
*** 405,429 ****
  (defvar highlight-changes-mode nil)
  (defvar hilit-chg-list nil)
  (defvar hilit-chg-string " ??")
! (or (assq 'highlight-changes-mode minor-mode-alist)
!     (setq minor-mode-alist
! 	  (cons '(highlight-changes-mode hilit-chg-string) minor-mode-alist)
! 	  ))
  (make-variable-buffer-local 'highlight-changes-mode)
  (make-variable-buffer-local 'hilit-chg-string)
  
  
- (require 'ediff-init)
- (require 'ediff-util)
- 
  
  ;;; Functions...
  
! (defun hilit-chg-map-changes (func &optional start-position end-position)
!   "Call function FUNC for each region used by Highlight Changes mode."
!   ;; if start-position is nil, (point-min) is used
!   ;; if end-position is nil, (point-max) is used
!   ;; FUNC is called with 3 params: property start stop
    (let ((start (or start-position (point-min)))
  	(limit (or end-position (point-max)))
  	prop end)
--- 386,406 ----
  (defvar highlight-changes-mode nil)
  (defvar hilit-chg-list nil)
  (defvar hilit-chg-string " ??")
! 
! 
  (make-variable-buffer-local 'highlight-changes-mode)
+ (make-variable-buffer-local 'highlight-changes-visible-p)
  (make-variable-buffer-local 'hilit-chg-string)
  
  
  
  ;;; Functions...
  
! (defun hilit-chg-map-changes  (func &optional start-position end-position)
!   "Call function FUNC for each region used by Highlight Changes mode.
! If START-POSITION is nil, (point-min) is used.
! If END-POSITION is nil, (point-max) is used.
! FUNC is called with 3 params: PROPERTY START STOP."
    (let ((start (or start-position (point-min)))
  	(limit (or end-position (point-max)))
  	prop end)
***************
*** 438,445 ****
  (defun hilit-chg-display-changes (&optional beg end)
    "Display face information for Highlight Changes mode.
  
! An overlay containing a change face is added from the information
! in the text property of type `hilit-chg'.
  
  This is the opposite of `hilit-chg-hide-changes'."
    (hilit-chg-map-changes 'hilit-chg-make-ov beg end))
--- 415,422 ----
  (defun hilit-chg-display-changes (&optional beg end)
    "Display face information for Highlight Changes mode.
  
! An overlay from BEG to END containing a change face is added from the
! information in the text property of type `hilit-chg'.
  
  This is the opposite of `hilit-chg-hide-changes'."
    (hilit-chg-map-changes 'hilit-chg-make-ov beg end))
***************
*** 448,455 ****
  (defun hilit-chg-make-ov (prop start end)
    (or prop
        (error "hilit-chg-make-ov: prop is nil"))
!   ;; for the region make change overlays corresponding to
!   ;; the text property 'hilit-chg
    (let ((ov (make-overlay start end))
  	face)
      (if (eq prop 'hilit-chg-delete)
--- 425,432 ----
  (defun hilit-chg-make-ov (prop start end)
    (or prop
        (error "hilit-chg-make-ov: prop is nil"))
!   ;; For the region create overlays with a distincive face
!   ;; and the text property 'hilit-chg.
    (let ((ov (make-overlay start end))
  	face)
      (if (eq prop 'hilit-chg-delete)
***************
*** 457,463 ****
        (setq face (nth 1 (member prop hilit-chg-list))))
      (if face
  	(progn
! 	  ;; We must mark the face, that is the purpose of the overlay
  	  (overlay-put ov 'face face)
  	  ;; I don't think we need to set evaporate since we should
  	  ;; be controlling them!
--- 434,440 ----
        (setq face (nth 1 (member prop hilit-chg-list))))
      (if face
  	(progn
! 	  ;; We must mark the face, that is the purpose of the overlay.
  	  (overlay-put ov 'face face)
  	  ;; I don't think we need to set evaporate since we should
  	  ;; be controlling them!
***************
*** 476,489 ****
  
  This is the opposite of `hilit-chg-display-changes'."
    (let ((start (or beg (point-min)))
! 	(limit (or end (point-max)))
! 	p ov)
!     (setq p (overlays-in start limit))
!     (while p
        ;; don't delete the overlay if it isn't ours!
!       (if (overlay-get (car p) 'hilit-chg)
! 	  (delete-overlay (car p)))
!       (setq p (cdr p)))))
  
  (defun hilit-chg-fixup (beg end)
    "Fix change overlays in region between BEG and END.
--- 453,464 ----
  
  This is the opposite of `hilit-chg-display-changes'."
    (let ((start (or beg (point-min)))
! 	(limit (or end (point-max))))
!     (dolist (p (overlays-in start limit))
        ;; don't delete the overlay if it isn't ours!
!       (if (overlay-get p 'hilit-chg)
! 	  (delete-overlay p)))))
! 
  
  (defun hilit-chg-fixup (beg end)
    "Fix change overlays in region between BEG and END.
***************
*** 492,500 ****
  the text properties of type `hilit-chg'."
    ;; Remove or alter overlays in region beg..end
    (let (ov-start ov-end	 props q)
-     ;; temp for debugging:
-     ;; (or (eq highlight-changes-mode 'active)
-     ;;	 (error "hilit-chg-fixup called but Highlight Changes mode not active"))
      (dolist (ov (overlays-in beg end))
        ;; Don't alter overlays that are not ours.
        (when (overlay-get ov 'hilit-chg)
--- 467,472 ----
***************
*** 541,547 ****
  	  (type 'hilit-chg)
  	  old)
        (if undo-in-progress
! 	  (if (eq highlight-changes-mode 'active)
  	      (hilit-chg-fixup beg end))
  	(if (and (= beg end) (> leng-before 0))
  	    ;; deletion
--- 513,520 ----
  	  (type 'hilit-chg)
  	  old)
        (if undo-in-progress
! 	  (if (and highlight-changes-mode
! 		   highlight-changes-visible-p)
  	      (hilit-chg-fixup beg end))
  	(if (and (= beg end) (> leng-before 0))
  	    ;; deletion
***************
*** 569,686 ****
  	      (progn
  		(remove-text-properties end (+ end 1) '(hilit-chg nil))
  		(put-text-property end (+ end 1) 'hilit-chg 'hilit-chg)
! 		(if (eq highlight-changes-mode 'active)
  		    (hilit-chg-fixup beg (+ end 1))))))
  	(unless no-property-change
  		(put-text-property beg end 'hilit-chg type))
! 	(if (or (eq highlight-changes-mode 'active) no-property-change)
  	    (hilit-chg-make-ov type beg end))))))
  
! (defun hilit-chg-set (value)
    "Turn on Highlight Changes mode for this buffer."
-   (setq highlight-changes-mode value)
    (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t)
    (hilit-chg-make-list)
!   (if (eq highlight-changes-mode 'active)
        (progn
! 	(setq hilit-chg-string highlight-changes-active-string)
  	(or buffer-read-only
  	    (hilit-chg-display-changes)))
!     ;; mode is passive
!     (setq hilit-chg-string highlight-changes-passive-string)
      (or buffer-read-only
  	(hilit-chg-hide-changes)))
    (force-mode-line-update)
!   (add-hook 'after-change-functions 'hilit-chg-set-face-on-change nil t))
  
  (defun hilit-chg-clear ()
    "Remove Highlight Changes mode for this buffer.
  This removes all saved change information."
    (if buffer-read-only
        ;; We print the buffer name because this function could be called
!       ;; on many buffers from `global-highlight-changes'.
        (message "Cannot remove highlighting from read-only mode buffer %s"
  	       (buffer-name))
-     (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t)
      (let ((after-change-functions nil))
        (hilit-chg-hide-changes)
        (hilit-chg-map-changes
         '(lambda (prop start stop)
  	  (remove-text-properties start stop '(hilit-chg nil))))
!       )
!     (setq highlight-changes-mode nil)
!     (force-mode-line-update)
!     ;; If we type:  C-u -1 M-x highlight-changes-mode
!     ;; we want to turn it off, but hilit-chg-post-command-hook
!     ;; runs and that turns it back on!
!     (remove-hook 'post-command-hook 'hilit-chg-post-command-hook)))
  
  ;;;###autoload
! (defun highlight-changes-mode (&optional arg)
!   "Toggle (or initially set) Highlight Changes mode.
  
! Without an argument:
!   If Highlight Changes mode is not enabled, then enable it (in either active
!   or passive state as determined by the variable
!   `highlight-changes-initial-state'); otherwise, toggle between active
!   and passive state.
! 
! With an argument ARG:
!   If ARG is positive, set state to active;
!   If ARG is zero, set state to passive;
!   If ARG is negative, disable Highlight Changes mode completely.
! 
! Active state  - means changes are shown in a distinctive face.
! Passive state - means changes are kept and new ones recorded but are
! 		not displayed in a different face.
  
! Functions:
  \\[highlight-changes-next-change] - move point to beginning of next change
  \\[highlight-changes-previous-change] - move to beginning of previous change
- \\[highlight-compare-with-file] - mark text as changed by comparing this
- 	buffer with the contents of a file
  \\[highlight-changes-remove-highlight] - remove the change face from the region
! \\[highlight-changes-rotate-faces] - rotate different \"ages\" of changes \
! through
! 	various faces
  
  Hook variables:
! `highlight-changes-enable-hook'  - when enabling Highlight Changes mode
! `highlight-changes-toggle-hook'  - when entering active or passive state
! `highlight-changes-disable-hook' - when turning off Highlight Changes mode"
!   (interactive "P")
    (if (or (display-color-p)
  	  (and (fboundp 'x-display-grayscale-p) (x-display-grayscale-p)))
!       (let ((was-on highlight-changes-mode)
! 	    (new-highlight-changes-mode
! 	     (cond
! 	      ((null arg)
! 	       ;; no arg => toggle (or set to active initially)
! 	       (if highlight-changes-mode
! 		   (if (eq highlight-changes-mode 'active) 'passive 'active)
! 		 highlight-changes-initial-state))
! 	      ;; an argument is given
! 	      ((eq arg 'active)
! 	       'active)
! 	      ((eq arg 'passive)
! 	       'passive)
! 	      ((> (prefix-numeric-value arg) 0)
! 	       'active)
! 	      ((< (prefix-numeric-value arg) 0)
! 	       nil)
! 	      (t
! 	       'passive))))
! 	(if new-highlight-changes-mode
! 	    ;; mode is turned on -- but may be passive
! 	    (progn
! 	      (hilit-chg-set new-highlight-changes-mode)
! 	      (or was-on
! 		  ;; run highlight-changes-enable-hook once
! 		  (run-hooks 'highlight-changes-enable-hook))
! 	      (run-hooks 'highlight-changes-toggle-hook))
! 	  ;; mode is turned off
! 	  (run-hooks 'highlight-changes-disable-hook)
! 	  (hilit-chg-clear)))
      (message "Highlight Changes mode requires color or grayscale display")))
  
  ;;;###autoload
--- 542,629 ----
  	      (progn
  		(remove-text-properties end (+ end 1) '(hilit-chg nil))
  		(put-text-property end (+ end 1) 'hilit-chg 'hilit-chg)
! 		(if highlight-changes-visible-p
  		    (hilit-chg-fixup beg (+ end 1))))))
  	(unless no-property-change
  		(put-text-property beg end 'hilit-chg type))
! 	(if (or highlight-changes-visible-p no-property-change)
  	    (hilit-chg-make-ov type beg end))))))
  
! (defun hilit-chg-set ()
    "Turn on Highlight Changes mode for this buffer."
    (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t)
    (hilit-chg-make-list)
!   (setq highlight-changes-mode t)
!   (if highlight-changes-visible-p
!       ;; changes are visible
        (progn
! 	(setq hilit-chg-string highlight-changes-visible-string)
  	(or buffer-read-only
  	    (hilit-chg-display-changes)))
!     ;; changes are invisible
!     (setq hilit-chg-string highlight-changes-invisible-string)
      (or buffer-read-only
  	(hilit-chg-hide-changes)))
    (force-mode-line-update)
!   ;; (make-local-hook 'after-change-functions)
!   (add-hook 'after-change-functions 'hilit-chg-set-face-on-change nil t)
!   (run-hooks 'highlight-changes-enable-hook))
  
  (defun hilit-chg-clear ()
    "Remove Highlight Changes mode for this buffer.
  This removes all saved change information."
    (if buffer-read-only
        ;; We print the buffer name because this function could be called
!       ;; on many buffers from `global-highlight-changes-mode'.
        (message "Cannot remove highlighting from read-only mode buffer %s"
  	       (buffer-name))
      (let ((after-change-functions nil))
        (hilit-chg-hide-changes)
        (hilit-chg-map-changes
         '(lambda (prop start stop)
  	  (remove-text-properties start stop '(hilit-chg nil))))
!       ))
!   (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t)
!   (setq highlight-changes-mode nil)
!   (force-mode-line-update)
!   (run-hooks 'highlight-changes-disable-hook))
  
  ;;;###autoload
! (define-minor-mode highlight-changes-mode
!   "Toggle Highlight Changes mode.
  
! With ARG, turn Highlight Changes mode on if and only if arg is positive.
  
! In Highlight Changes mode changes are recorded with a text property.
! Normally they are displayed in a distinctive face, but command
! \\[highlight-changes-toggle-visibility] can be used to toggles this
! on and off.
! 
! Other functions for buffers in this mode include:
  \\[highlight-changes-next-change] - move point to beginning of next change
  \\[highlight-changes-previous-change] - move to beginning of previous change
  \\[highlight-changes-remove-highlight] - remove the change face from the region
! \\[highlight-changes-rotate-faces] - rotate different \"ages\" of changes
! through	various faces.
! \\[highlight-compare-with-file] - mark text as changed by comparing this
! buffer with the contents of a file
! \\[highlight-compare-buffers] highlights differences between two buffers.
  
  Hook variables:
! `highlight-changes-enable-hook': called when enabling Highlight Changes mode.
! `highlight-changes-disable-hook': called when disabling Highlight Changes mode."
!   nil			;; init-value
!   hilit-chg-string	;; lighter
!   nil			;; keymap
    (if (or (display-color-p)
  	  (and (fboundp 'x-display-grayscale-p) (x-display-grayscale-p)))
!       (if highlight-changes-mode
! 	  ;; it is being turned on
! 	  ;; the hook has been moved into hilit-chg-set
! 	  ;; (run-hooks 'highlight-changes-enable-hook))
! 	  (hilit-chg-set)
! 	;; mode is turned off
! 	(hilit-chg-clear))
      (message "Highlight Changes mode requires color or grayscale display")))
  
  ;;;###autoload
***************
*** 725,730 ****
--- 668,699 ----
  	  (message "no previous change")))
      (message "This buffer is not in Highlight Changes mode.")))
  
+ 
+ ;;;###autoload
+ (defun highlight-changes-toggle-visibility (&optional arg)
+   "Toggle whether changes are visible in Highlight Changes modes.
+ While the changes are still kept (and new ones recorded) as long as
+ Highlight Changes modes is on, their distinctive display can be
+ toggled on and off using this command.  With ARG,  enable the
+ distinctive display if and only if the arg is positive.
+ 
+ Set variable `highlight-changes-visible-p' if you want to change the default
+ behaviour.
+ 
+ This command turns on highlight-changes mode."
+   (interactive "P")
+   (let ((old-value highlight-changes-visible-p))
+     (setq highlight-changes-visible-p
+ 	  (if (null arg)
+ 	      (not highlight-changes-visible-p)
+ 	    (> (prefix-numeric-value arg) 0)))
+     (unless (eq old-value highlight-changes-visible-p)
+       (message "changes will now be %s"
+ 	       (if highlight-changes-visible-p "visible" "invisible"))
+       (hilit-chg-set))
+     ))
+ 
+ 
  ;; ========================================================================
  
  (defun hilit-chg-make-list (&optional force)
***************
*** 775,781 ****
  
  ;;;###autoload
  (defun highlight-changes-rotate-faces ()
!   "Rotate the faces used by Highlight Changes mode.
  
  Current changes are displayed in the face described by the first element
  of `highlight-changes-face-list', one level older changes are shown in
--- 744,750 ----
  
  ;;;###autoload
  (defun highlight-changes-rotate-faces ()
!   "Rotate the faces if in Highlight Changes mode and the changes are visible.
  
  Current changes are displayed in the face described by the first element
  of `highlight-changes-face-list', one level older changes are shown in
***************
*** 788,796 ****
  
    \(add-hook 'write-file-functions 'highlight-changes-rotate-faces nil t)"
    (interactive)
!   ;; If not in active mode do nothing but don't complain because this
!   ;; may be bound to a hook.
!   (if (eq highlight-changes-mode 'active)
        (let ((after-change-functions nil))
  	;; ensure hilit-chg-list is made and up to date
  	(hilit-chg-make-list)
--- 757,764 ----
  
    \(add-hook 'write-file-functions 'highlight-changes-rotate-faces nil t)"
    (interactive)
!   (if (and highlight-changes-mode
! 	   highlight-changes-visible-p)
        (let ((after-change-functions nil))
  	;; ensure hilit-chg-list is made and up to date
  	(hilit-chg-make-list)
***************
*** 798,808 ****
  	(hilit-chg-hide-changes)
  	;; for each change text property, increment it
  	(hilit-chg-map-changes 'hilit-chg-bump-change)
! 	;; and display them all if active
! 	(if (eq highlight-changes-mode 'active)
! 	    (hilit-chg-display-changes))))
!   ;; This always returns nil so it is safe to use in write-file-functions
!   nil)
  
  ;; ========================================================================
  ;; Comparing buffers/files
--- 766,776 ----
  	(hilit-chg-hide-changes)
  	;; for each change text property, increment it
  	(hilit-chg-map-changes 'hilit-chg-bump-change)
! 	;; and display them.
! 	(hilit-chg-display-changes)
! 	))
!    ;; This always returns nil so it is safe to use in write-file-functions
!    nil)
  
  ;; ========================================================================
  ;; Comparing buffers/files
***************
*** 813,818 ****
--- 781,788 ----
    "Get differences between two buffers and set highlight changes.
  Both buffers are done unless optional parameter MARKUP-A-ONLY
  is non-nil."
+   (eval-and-compile
+     (require 'ediff-util))
    (save-window-excursion
      (let* (change-info
  	   change-a change-b
***************
*** 841,849 ****
        (or file-b
  	  (setq temp-b (setq file-b (ediff-make-temp-file buf-b nil))))
        (set-buffer buf-a)
!       (highlight-changes-mode 'active)
        (or markup-a-only (with-current-buffer buf-b
! 			  (highlight-changes-mode 'active)))
        (setq change-info (hilit-chg-get-diff-info buf-a file-a buf-b file-b))
  
  
--- 811,819 ----
        (or file-b
  	  (setq temp-b (setq file-b (ediff-make-temp-file buf-b nil))))
        (set-buffer buf-a)
!       (highlight-changes-mode 1)
        (or markup-a-only (with-current-buffer buf-b
! 			  (highlight-changes-mode 1)))
        (setq change-info (hilit-chg-get-diff-info buf-a file-a buf-b file-b))
  
  
***************
*** 917,936 ****
  If the buffer is read-only, differences will be highlighted but no property
  changes are made, so \\[highlight-changes-next-change] and
  \\[highlight-changes-previous-change] will not work."
!   (interactive (list
! 	      (read-file-name
! 	       "File to compare with? " ;; prompt
! 	       ""			;; directory
! 	       nil			;; default
! 	       'yes			;; must exist
! 	       (let ((f (buffer-file-name (current-buffer))))
! 		 (if f
! 		     (progn
! 		       (setq f (make-backup-file-name f))
! 		       (or (file-exists-p f)
! 			   (setq f nil)))
! 		   )
! 		 f))))
    (let* ((buf-a (current-buffer))
  	 (file-a (buffer-file-name))
  	 (existing-buf (get-file-buffer file-b))
--- 887,909 ----
  If the buffer is read-only, differences will be highlighted but no property
  changes are made, so \\[highlight-changes-next-change] and
  \\[highlight-changes-previous-change] will not work."
!   (interactive
!    (let ((file buffer-file-name)
! 	 (file-name nil)
! 	 (file-dir nil))
!      (and file
! 	  (setq file-name (file-name-nondirectory file)
! 		file-dir (file-name-directory file)))
!      (setq file-name (make-backup-file-name file-name))
!      (unless (file-exists-p file-name)
! 	     (setq file-name nil))
!      (list (read-file-name
! 	    "Find alternate file: "	;; prompt
! 	    file-dir			;; directory
! 	    nil				;; default
! 	    nil				;; existing
! 	    file-name)			;; initial
! 	   )))
    (let* ((buf-a (current-buffer))
  	 (file-a (buffer-file-name))
  	 (existing-buf (get-file-buffer file-b))
***************
*** 998,1122 ****
      ;; No point in returning a value, since this is a hook function.
      ))
  
! ;; ======================= automatic stuff ==============
! 
! ;; Global Highlight Changes mode is modeled after Global Font-lock mode.
! ;; Three hooks are used to gain control.  When Global Changes Mode is
! ;; enabled, `find-file-hook' and `change-major-mode-hook' are set.
! ;; `find-file-hook' is called when visiting a file, the new mode is
! ;; known at this time.
! ;; `change-major-mode-hook' is called when a buffer is changing mode.
! ;; This could be because of finding a file in which case
! ;; `find-file-hook' has already been called and has done its work.
! ;; However, it also catches the case where a new mode is being set by
! ;; the user.  However, it is called from `kill-all-variables' and at
! ;; this time the mode is the old mode, which is not what we want.
! ;; So, our function temporarily sets `post-command-hook' which will
! ;; be called after the buffer has been completely set up (with the new
! ;; mode).  It then removes the `post-command-hook'.
! ;; One other wrinkle - every M-x command runs the `change-major-mode-hook'
! ;; so we ignore this by examining the buffer name.
! 
! 
! (defun hilit-chg-major-mode-hook ()
!   (add-hook 'post-command-hook 'hilit-chg-post-command-hook))
! 
! (defun hilit-chg-post-command-hook ()
!   ;; This is called after changing a major mode, but also after each
!   ;; M-x command, in which case the current buffer is a minibuffer.
!   ;; In that case, do not act on it here, but don't turn it off
!   ;; either, we will get called here again soon-after.
!   ;; Also, don't enable it for other special buffers.
!   (if (string-match "^[ *]"  (buffer-name))
!       nil ;; (message "ignoring this post-command-hook")
!     (remove-hook 'post-command-hook 'hilit-chg-post-command-hook)
!     ;; The following check isn't necessary, since
!     ;; hilit-chg-turn-on-maybe makes this check too.
!     (or highlight-changes-mode	;; don't turn it on if it already is
! 	(hilit-chg-turn-on-maybe highlight-changes-global-initial-state))))
! 
! (defun hilit-chg-check-global ()
!   ;; This is called from the find file hook.
!   (hilit-chg-turn-on-maybe highlight-changes-global-initial-state))
! 
  
  ;;;###autoload
! (defun global-highlight-changes (&optional arg)
!   "Turn on or off global Highlight Changes mode.
! 
! When called interactively:
! - if no prefix, toggle global Highlight Changes mode on or off
! - if called with a positive prefix (or just C-u) turn it on in active mode
! - if called with a zero prefix turn it on in passive mode
! - if called with a negative prefix turn it off
! 
! When called from a program:
! - if ARG is nil or omitted, turn it off
! - if ARG is `active', turn it on in active mode
! - if ARG is `passive', turn it on in passive mode
! - otherwise just turn it on
! 
! When global Highlight Changes mode is enabled, Highlight Changes mode is turned
! on for future \"suitable\" buffers (and for \"suitable\" existing buffers if
! variable `highlight-changes-global-changes-existing-buffers' is non-nil).
! \"Suitability\" is determined by variable `highlight-changes-global-modes'."
! 
!   (interactive
!    (list
!     (cond
!      ((null current-prefix-arg)
!       ;; no arg => toggle it on/off
!       (setq global-highlight-changes (not global-highlight-changes)))
!      ;; positive interactive arg - turn it on as active
!      ((> (prefix-numeric-value current-prefix-arg) 0)
!       (setq global-highlight-changes t)
!       'active)
!      ;; zero interactive arg - turn it on as passive
!      ((= (prefix-numeric-value current-prefix-arg) 0)
!       (setq global-highlight-changes t)
!       'passive)
!      ;; negative interactive arg - turn it off
!      (t
!       (setq global-highlight-changes nil)
!       nil))))
! 
!   (if arg
!       (progn
! 	(if (eq arg 'active)
! 	    (setq highlight-changes-global-initial-state 'active)
! 	  (if (eq arg 'passive)
! 	      (setq highlight-changes-global-initial-state 'passive)))
! 	(setq global-highlight-changes t)
! 	(message "Turning ON Global Highlight Changes mode in %s state"
! 		 highlight-changes-global-initial-state)
! 	;; FIXME: Not sure what this was intended to do.  --Stef
! 	;; (add-hook 'hilit-chg-major-mode-hook 'hilit-chg-major-mode-hook)
! 	(add-hook 'find-file-hook 'hilit-chg-check-global)
! 	(if highlight-changes-global-changes-existing-buffers
! 	    (hilit-chg-update-all-buffers
! 	     highlight-changes-global-initial-state)))
! 
!     (message "Turning OFF global Highlight Changes mode")
!     ;; FIXME: Not sure what this was intended to do.  --Stef
!     ;; (remove-hook 'hilit-chg-major-mode-hook 'hilit-chg-major-mode-hook)
!     (remove-hook 'post-command-hook 'hilit-chg-post-command-hook)
!     (remove-hook 'find-file-hook 'hilit-chg-check-global)
!     (if highlight-changes-global-changes-existing-buffers
! 	(hilit-chg-update-all-buffers nil))))
! 
! 
! (defun hilit-chg-turn-on-maybe (value)
!   "Turn on Highlight Changes mode if it is appropriate for this buffer.
! 
! A buffer is appropriate for Highlight Changes mode if all these are true:
! - the buffer is not a special buffer (one whose name begins with
!   `*' or ` '),
! - the buffer's mode is suitable as per variable
!   `highlight-changes-global-modes',
! - Highlight Changes mode is not already on for this buffer.
! 
! This function is called from `hilit-chg-update-all-buffers' or
! from `global-highlight-changes' when turning on global Highlight Changes mode."
    (or highlight-changes-mode			; do nothing if already on
        (if
  	  (cond
--- 971,1012 ----
      ;; No point in returning a value, since this is a hook function.
      ))
  
! ;; ======================= global-highlight-changes-mode ==============
  
  ;;;###autoload
! (define-global-minor-mode global-highlight-changes-mode highlight-changes-mode
!   highlight-changes-mode-turn-on
!   :turn-off highlight-changes-mode-turn-off)
! 
! (define-obsolete-function-alias 'global-highlight-changes
!   'global-highlight-changes-mode "22.1")
! 
! (defvar highlight-changes-mode-turn-off-fn nil
!   "*If non-nil, its value is a function to maybe turn off highlight changes mode.
! It is called by global-highlight-changes-mode when that mode is turned off.
! It will be called for each buffer that is in highlight changes mode.
! 
! To turn highlight changes mode off for that buffer it should call
! 	(highlight-changes-mode -1)
! To leave the buffer in highlight changes mode it need do nothing.
! 
! Example:  to have it leave all buffers in highlight changes mode:
! 	(defun nop ())
! 	(setq highlight-changes-mode-turn-off-fn 'nop)
! or using an anonymous function:
! 	(setq highlight-changes-mode-turn-off-fn '(lambda nil))")
! 
! (defun highlight-changes-mode-turn-off ()
!   "Turn off Highlight Changes mode in all buffers.
! If variable `highlight-changes-mode-turn-off-fn' is non-nil then that function
! is called;  otherwise highlight-changes-mode is turned off directly."
!   (if highlight-changes-mode-turn-off-fn
!       (funcall highlight-changes-mode-turn-off-fn)
!     (highlight-changes-mode -1)))
! 
! (defun highlight-changes-mode-turn-on ()
!   "See if highlight-changes-mode should be turned on for this buffer.
! This is called when global-highlight-changes-mode is turned on."
    (or highlight-changes-mode			; do nothing if already on
        (if
  	  (cond
***************
*** 1132,1159 ****
  	     (and
  	      (not (string-match "^[ *]" (buffer-name)))
  	      (buffer-file-name))))
! 	  (progn
! 	    (hilit-chg-set value)
! 	    (run-hooks 'highlight-changes-enable-hook)))))
! 
! 
! (defun hilit-chg-turn-off-maybe ()
!   (if highlight-changes-mode
!       (progn
! 	(run-hooks 'highlight-changes-disable-hook)
! 	(hilit-chg-clear))))
! 
  
- (defun hilit-chg-update-all-buffers (value)
-   (mapc
-    (function (lambda (buffer)
- 	       (with-current-buffer buffer
- 		 (if value
- 		     (hilit-chg-turn-on-maybe value)
- 		   (hilit-chg-turn-off-maybe))
- 		 )))
-    (buffer-list))
-   nil)
  
  ;;;; Desktop support.
  
--- 1022,1030 ----
  	     (and
  	      (not (string-match "^[ *]" (buffer-name)))
  	      (buffer-file-name))))
! 	  (highlight-changes-mode 1))
! 	))
  
  
  ;;;; Desktop support.
  
***************
*** 1163,1169 ****
     (or (cdr (assq 'highlight-changes-mode desktop-buffer-locals)) 1)))
  
  (add-to-list 'desktop-minor-mode-handlers
!              '(highlight-changes-mode . hilit-chg-desktop-restore))
  
  (add-to-list 'desktop-locals-to-save 'highlight-changes-mode)
  
--- 1034,1040 ----
     (or (cdr (assq 'highlight-changes-mode desktop-buffer-locals)) 1)))
  
  (add-to-list 'desktop-minor-mode-handlers
! 	     '(highlight-changes-mode . hilit-chg-desktop-restore))
  
  (add-to-list 'desktop-locals-to-save 'highlight-changes-mode)
  
***************
*** 1174,1183 ****
  ;;   (interactive)
  ;;   (message "--- hilit-chg-debug-show ---")
  ;;   (hilit-chg-map-changes '(lambda (prop start end)
! ;; 			      (message "%d-%d: %s" start end prop)
! ;; 			      )
! ;; 			   beg end
! ;; 			   ))
  ;;
  ;; ================== end of debug ===============
  
--- 1045,1054 ----
  ;;   (interactive)
  ;;   (message "--- hilit-chg-debug-show ---")
  ;;   (hilit-chg-map-changes '(lambda (prop start end)
! ;;			      (message "%d-%d: %s" start end prop)
! ;;			      )
! ;;			   beg end
! ;;			   ))
  ;;
  ;; ================== end of debug ===============
  

[-- Attachment #3: message body text --]
[-- Type: text/plain, Size: 51 bytes --]


they need this change to emacs-lisp/easy-mmode.el

[-- Attachment #4: lisp/emacs-lisp/easy-mmode.el.cdif --]
[-- Type: application/octet-stream, Size: 4574 bytes --]

*** easy-mmode.el.orig	Thu Aug 31 19:14:26 2006
--- easy-mmode.el	Wed Dec  6 20:46:14 2006
***************
*** 279,290 ****
    and that should try to turn MODE on if applicable for that buffer.
  KEYS is a list of CL-style keyword arguments.  As the minor mode
    defined by this function is always global, any :global keyword is
!   ignored.  Other keywords have the same meaning as in `define-minor-mode',
!   which see.  In particular, :group specifies the custom group.
!   The most useful keywords are those that are passed on to the
!   `defcustom'.  It normally makes no sense to pass the :lighter
!   or :keymap keywords to `define-global-minor-mode', since these
!   are usually passed to the buffer-local version of the minor mode.
  
  If MODE's set-up depends on the major mode in effect when it was
  enabled, then disabling and reenabling MODE should make MODE work
--- 279,294 ----
    and that should try to turn MODE on if applicable for that buffer.
  KEYS is a list of CL-style keyword arguments.  As the minor mode
    defined by this function is always global, any :global keyword is
!   ignored.  The turn-off keyword allows a function to be called to
!   conditionally turn off the mode in a buffer similar to TURN-ON;  if
!   omitted then the mode is unconditinoally turned off.  Other
!   keywords have the same meaning as in `define-minor-mode', which
!   see.  In particular,
!   :group specifies the custom group. The most useful keywords are
!   those that are passed on to the `defcustom'.  It normally makes no
!   sense to pass the :lighter  or :keymap keywords to
!   `define-global-minor-mode', since these are usually passed to the
!   buffer-local version of the minor mode.
  
  If MODE's set-up depends on the major mode in effect when it was
  enabled, then disabling and reenabling MODE should make MODE work
***************
*** 304,309 ****
--- 308,314 ----
  	  (intern (concat global-mode-name "-check-buffers")))
  	 (MODE-cmhh (intern (concat global-mode-name "-cmhh")))
  	 (MODE-major-mode (intern (concat (symbol-name mode) "-major-mode")))
+ 	 (turn-off nil)
  	 keyw)
  
      ;; Check keys.
***************
*** 312,317 ****
--- 317,323 ----
        (case keyw
  	(:group (setq group (nconc group (list :group (pop keys)))))
  	(:global (setq keys (cdr keys)))
+ 	(:turn-off (setq turn-off (pop keys)))
  	(t (push keyw extra-keywords) (push (pop keys) extra-keywords))))
  
      (unless group
***************
*** 320,335 ****
  	    `(:group ',(intern (replace-regexp-in-string
  				"-mode\\'" "" (symbol-name mode))))))
  
      `(progn
         (defvar ,MODE-major-mode nil)
         (make-variable-buffer-local ',MODE-major-mode)
         ;; The actual global minor-mode
         (define-minor-mode ,global-mode
! 	 ,(format "Toggle %s in every buffer.
  With prefix ARG, turn %s on if and only if ARG is positive.
  %s is actually not turned on in every buffer but only in those
! in which `%s' turns it on."
! 		  pretty-name pretty-global-name pretty-name turn-on)
  	 :global t ,@group ,@(nreverse extra-keywords)
  
  	 ;; Setup hook to handle future mode changes and new buffers.
--- 326,348 ----
  	    `(:group ',(intern (replace-regexp-in-string
  				"-mode\\'" "" (symbol-name mode))))))
  
+     (or turn-off
+ 	(setq turn-off `(,mode -1)))
      `(progn
         (defvar ,MODE-major-mode nil)
         (make-variable-buffer-local ',MODE-major-mode)
         ;; The actual global minor-mode
         (define-minor-mode ,global-mode
! 	 ,(concat (format 
! 	 "Toggle %s in every buffer.
  With prefix ARG, turn %s on if and only if ARG is positive.
  %s is actually not turned on in every buffer but only in those
! in which `%s' turns it on"
! 	 pretty-name pretty-global-name pretty-name turn-on)
! 	(if turn-off
! 	    (format 
! ", and is only turned off in those buffers where `%s' does so." turn-off)
! 	"."))
  	 :global t ,@group ,@(nreverse extra-keywords)
  
  	 ;; Setup hook to handle future mode changes and new buffers.
***************
*** 346,352 ****
  	 ;; Go through existing buffers.
  	 (dolist (buf (buffer-list))
  	   (with-current-buffer buf
! 	     (if ,global-mode (,turn-on) (when ,mode (,mode -1))))))
  
         ;; Autoloading define-global-minor-mode autoloads everything
         ;; up-to-here.
--- 359,365 ----
  	 ;; Go through existing buffers.
  	 (dolist (buf (buffer-list))
  	   (with-current-buffer buf
! 	     (if ,global-mode (,turn-on) (when ,mode (,turn-off))))))
  
         ;; Autoloading define-global-minor-mode autoloads everything
         ;; up-to-here.

[-- Attachment #5: message body text --]
[-- Type: text/plain, Size: 638 bytes --]




and here are the Changelog entries:

2006-12-11  Richard Sharman  <rsharman@pobox.com>

	* easy-mmode.el (define-global-minor-mode): added keyword `turn-off'.

	* hilit-chg.el (highlight-changes-mode): be more consistent with
	other minor modes, this function now just toggles. Removed 
	variable highlight-changes-toggle-hook.
	(highlight-changes-toggle-visibility): new function to allow
	toggling on/off the visibility of changes (previously done in
	highlight-changes-mode).
	(global-highlight-changes-mode): renamed from global-highlight-changes,
	be more consistent with other modes.
	(highlight-compare-buffers): new function.


[-- Attachment #6: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

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

* Re: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-12  2:57                             ` Richard Stallman
@ 2006-12-12  3:27                               ` Lennart Borgman
  2006-12-12 21:45                                 ` Richard Stallman
  2006-12-12  4:06                               ` Drew Adams
  1 sibling, 1 reply; 57+ messages in thread
From: Lennart Borgman @ 2006-12-12  3:27 UTC (permalink / raw)
  Cc: drew.adams, emacs-devel

Richard Stallman wrote:
>     Why not define a new sub foo-mode-locally to toggle it in current buffer 
>     when it is a global minor mode?
>
> Two different commands is the way we do it now.
> In the current scheme; foo-mode is the local toggle
> and global-foo-mode is the global toggle.
>
> I think the current scheme is better than making foo-mode the global
> command.
>   

The naming scheme does not matter to me very much. What I tried to argue 
about was that when we define a new global minor mode with 
define-minor-mode it should define functions for us for toggling both 
locally and globally.

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

* RE: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-12  2:57                             ` Richard Stallman
  2006-12-12  3:27                               ` Lennart Borgman
@ 2006-12-12  4:06                               ` Drew Adams
  2006-12-12  4:25                                 ` global minor modes that can be overridden locally? Miles Bader
  1 sibling, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-12  4:06 UTC (permalink / raw)


>     Why not define a new sub foo-mode-locally to toggle it in
> current buffer
>     when it is a global minor mode?
>
> Two different commands is the way we do it now.
> In the current scheme; foo-mode is the local toggle
> and global-foo-mode is the global toggle.

Uh, I never heard of global-*-mode. Is that documented?

I define a global minor mode using define-minor-mode with :global, and M-x
foo-mode is the global toggle for it. There is no global-foo-mode defined
for my mode by define-minor-mode with :global.

> I think the current scheme is better than making foo-mode the global
> command.

I think it is already the global command. At least that's what I see.

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

* RE: global minor modes that can be overridden locally?[was:highlight-changes-mode]
  2006-12-12  2:58                             ` Richard Stallman
@ 2006-12-12  4:08                               ` Drew Adams
  2006-12-12 21:45                                 ` Richard Stallman
  0 siblings, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-12  4:08 UTC (permalink / raw)


>     I think I disagree, if you mean that M-x foo-mode should
>     toggle locally. With that design:
>
>     . If there were no buffers where it was defined locally, then
>       M-x foo-mode would still toggle everywhere (global).
>
>     . If there were buffers where it was defined locally, then
>        M-x foo-mode would toggle differently, depending on where
>        it was invoked:
>
>       - toggle only locally, if invoked in a buffer with a local value
>       - toggle globally, if invoked in a buffer with no local value
>
> I never advocated anything where the same command sequence would
> sometimes be local and sometimes be global, so I think there is a
> misunderstanding somewhere.

Perhaps you can clear up the misunderstanding? What is it that you propose?
What is the command sequence for local and for global?

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

* Re: global minor modes that can be overridden locally?
  2006-12-12  4:06                               ` Drew Adams
@ 2006-12-12  4:25                                 ` Miles Bader
  2006-12-12  5:00                                   ` Drew Adams
  2006-12-12 11:08                                   ` Juanma Barranquero
  0 siblings, 2 replies; 57+ messages in thread
From: Miles Bader @ 2006-12-12  4:25 UTC (permalink / raw)
  Cc: emacs-devel

"Drew Adams" <drew.adams@oracle.com> writes:
>> Two different commands is the way we do it now.
>> In the current scheme; foo-mode is the local toggle
>> and global-foo-mode is the global toggle.
>
> Uh, I never heard of global-*-mode. Is that documented?

global-auto-composition-mode
global-auto-revert-mode
global-cwarn-mode
global-font-lock-mode
global-hi-lock-mode
global-hl-line-mode
global-reveal-mode
global-whitespace-mode

They are documented.

> I define a global minor mode using define-minor-mode with :global, and M-x
> foo-mode is the global toggle for it. There is no global-foo-mode defined
> for my mode by define-minor-mode with :global.

You are confusing two slightly different situations.

There are "true" global modes, which _only_ have a global effect, and
wouldn't make sense as a local mode; an example is `tool-bar-mode'.
Such modes are called FOO-mode because it is the obvious name (and
adding "global-" to the beginning would be pointless and annoying).

However there are global modes which are actually the effect of applying
a local mode globally, that is, they enable or disable the corresponding
local mode in all buffers.  Such modes are called global-FOO-mode,
because the fundamental mode in question is the local FOO-mode, and
global-FOO-mode is merely a convenient adjunct.

-Miles

-- 
`Life is a boundless sea of bitterness'

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

* RE: global minor modes that can be overridden locally?
  2006-12-12  4:25                                 ` global minor modes that can be overridden locally? Miles Bader
@ 2006-12-12  5:00                                   ` Drew Adams
  2006-12-29 16:25                                     ` Drew Adams
  2006-12-12 11:08                                   ` Juanma Barranquero
  1 sibling, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-12  5:00 UTC (permalink / raw)


> > Uh, I never heard of global-*-mode. Is that documented?
>
> global-auto-composition-mode ...

Actually, I had heard of (and used) global-font-lock-mode. I hadn't thought
about it.

> > I define a global minor mode using define-minor-mode with
> > :global, and M-x foo-mode is the global toggle for it.
> > There is no global-foo-mode defined
> > for my mode by define-minor-mode with :global.
>
> You are confusing two slightly different situations.
>
> There are "true" global modes, which _only_ have a global effect, and
> wouldn't make sense as a local mode; an example is `tool-bar-mode'.
> Such modes are called FOO-mode because it is the obvious name (and
> adding "global-" to the beginning would be pointless and annoying).

I sure agree about that last part.

> However there are global modes which are actually the effect of applying
> a local mode globally, that is, they enable or disable the corresponding
> local mode in all buffers.  Such modes are called global-FOO-mode,
> because the fundamental mode in question is the local FOO-mode, and
> global-FOO-mode is merely a convenient adjunct.

Ah, I didn't know that. Sorry if I confused things. I don't know if anything
I wrote on this earlier in this thread makes any sense for that context. I
had in mind only the other sort (the "truly" global sort) of global minor
mode. I thought that someone was asking to be able to locally override a
(truly) global mode locally, and I was proposing a way to perhaps do that.
>From what you say, there is probably no need for what I suggested. Sorry for
the noise.

In the version of Emacs 22 I was using, there was nothing about
define-global-minor-mode in the manual. I picked up a new Emacs binary today
(thanks to Lennart), however, and I see it there now.

I wonder, however, if the terminology might not be confusing. The "pseudo"
global minor modes are not the same thing as the "true" global minor modes,
but it is they that result from using the macro named
`define-global-minor-mode'. And the resulting mode names `global-*-mode'
also seem to hinder clarity in the same way. Couldn't this be made clearer
with some better choice of terminology? If the normal, "true" global minor
mode is not the one that has "global" written all over it, then aren't we
asking for trouble? And aren't we asking for trouble just by having two
different animals that are both referred to as "global" minor modes?

The local-turned-global beasts were not in my build of July, AFAICT.
Assuming that they fit a real need, shouldn't we perhaps revisit the
terminology? I don't have a good terminology suggestion (yet) - I'm still
not too clear on their raison d'etre. Maybe someone can suggest a better way
to talk about these different kinds of critters?

It sounds like the pseudo global modes are not global modes, but local modes
that are applied globally. If that's the case, then perhaps that's the best
way to speak of them: don't call them global, but speak of them being
applied globally. Perhaps rename `define-global-minor-mode' to
`make-minor-mode-global' (a la `make-variable-buffer-local'), since the
input is a minor mode and you are, in effect, making it serve globally
(IIUC). Even that characterization of being applied globally (vs being
inherently global) sounds like too fine a nuance and a possible source of
confusion, however.

One way or the other, I think there will need to be some distinction made in
the doc, to guide people toward using one or the other sort of global mode,
depending on their different needs. Miles's explanation is a start and
helped me, and that explanation is missing from the doc, AFAICT.

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

* Re: global minor modes that can be overridden locally?
  2006-12-12  4:25                                 ` global minor modes that can be overridden locally? Miles Bader
  2006-12-12  5:00                                   ` Drew Adams
@ 2006-12-12 11:08                                   ` Juanma Barranquero
  2006-12-12 11:15                                     ` Miles Bader
  1 sibling, 1 reply; 57+ messages in thread
From: Juanma Barranquero @ 2006-12-12 11:08 UTC (permalink / raw)
  Cc: emacs-devel

On 12/12/06, Miles Bader <miles.bader@necel.com> wrote:

> global-auto-composition-mode

What's that?

                    /L/e/k/t/u

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

* Re: global minor modes that can be overridden locally?
  2006-12-12 11:08                                   ` Juanma Barranquero
@ 2006-12-12 11:15                                     ` Miles Bader
  2006-12-12 11:25                                       ` Juanma Barranquero
  0 siblings, 1 reply; 57+ messages in thread
From: Miles Bader @ 2006-12-12 11:15 UTC (permalink / raw)
  Cc: emacs-devel

"Juanma Barranquero" <lekktu@gmail.com> writes:
>> global-auto-composition-mode
>
> What's that?

Not sure but it's the global variant of auto-composition-mode... :-)

auto-composition-mode seems to only be defined in Emacs 23:

   When Auto Composition is enabled, text characters are automatically composed
   by functions registered in `composition-function-table' (which see).

-miles
-- 
It wasn't the Exxon Valdez captain's driving that caused the Alaskan oil spill.
It was yours.  [Greenpeace advertisement, New York Times, 25 February 1990]

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

* Re: global minor modes that can be overridden locally?
  2006-12-12 11:15                                     ` Miles Bader
@ 2006-12-12 11:25                                       ` Juanma Barranquero
  2006-12-12 11:33                                         ` Miles Bader
  0 siblings, 1 reply; 57+ messages in thread
From: Juanma Barranquero @ 2006-12-12 11:25 UTC (permalink / raw)
  Cc: emacs-devel

On 12/12/06, Miles Bader <miles.bader@necel.com> wrote:

> auto-composition-mode seems to only be defined in Emacs 23:

I see a `thai-auto-composition-mode' in lisp/language/thai-util.el,
but no `auto-composition-mode'...

                    /L/e/k/t/u

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

* Re: global minor modes that can be overridden locally?
  2006-12-12 11:25                                       ` Juanma Barranquero
@ 2006-12-12 11:33                                         ` Miles Bader
  2006-12-12 11:59                                           ` Juanma Barranquero
  0 siblings, 1 reply; 57+ messages in thread
From: Miles Bader @ 2006-12-12 11:33 UTC (permalink / raw)
  Cc: emacs-devel

"Juanma Barranquero" <lekktu@gmail.com> writes:
>> auto-composition-mode seems to only be defined in Emacs 23:
>
> I see a `thai-auto-composition-mode' in lisp/language/thai-util.el,
> but no `auto-composition-mode'...

It's in lisp/composite.el (in Emacs 23).

-miles

-- 
Quidquid latine dictum sit, altum viditur.

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

* Re: global minor modes that can be overridden locally?
  2006-12-12 11:33                                         ` Miles Bader
@ 2006-12-12 11:59                                           ` Juanma Barranquero
  0 siblings, 0 replies; 57+ messages in thread
From: Juanma Barranquero @ 2006-12-12 11:59 UTC (permalink / raw)
  Cc: emacs-devel

On 12/12/06, Miles Bader <miles.bader@necel.com> wrote:

> It's in lisp/composite.el (in Emacs 23).

Hmm, you already said "Emacs 23" in your previous answer and I somehow
skipped it.

Sorry.

                    /L/e/k/t/u

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

* Re: highlight-changes-mode
  2006-12-12  3:16                         ` highlight-changes-mode rsharman
@ 2006-12-12 21:45                           ` Richard Stallman
  2006-12-12 23:33                             ` highlight-changes-mode rsharman
  0 siblings, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-12-12 21:45 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

Which way do these changes handle the question of the global mode command?
As far as I know we haven't yet decided what that should do.

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

* Re: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-12  3:27                               ` Lennart Borgman
@ 2006-12-12 21:45                                 ` Richard Stallman
  2006-12-12 23:02                                   ` Lennart Borgman
  0 siblings, 1 reply; 57+ messages in thread
From: Richard Stallman @ 2006-12-12 21:45 UTC (permalink / raw)
  Cc: drew.adams, emacs-devel

    The naming scheme does not matter to me very much. What I tried to argue 
    about was that when we define a new global minor mode with 
    define-minor-mode it should define functions for us for toggling both 
    locally and globally.

The easiest way to do this would be to add a call
to define-global-minor-mode for each call to define-minor-mode.
The arguments are not the same.

But I am not convinced every mode needs a global variant.

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

* Re: global minor modes that can be overridden locally?[was:highlight-changes-mode]
  2006-12-12  4:08                               ` global minor modes that can be overridden locally?[was:highlight-changes-mode] Drew Adams
@ 2006-12-12 21:45                                 ` Richard Stallman
  0 siblings, 0 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-12 21:45 UTC (permalink / raw)
  Cc: emacs-devel

    Perhaps you can clear up the misunderstanding? What is it that you propose?
    What is the command sequence for local and for global?

I don't propose anything about this, I just responded to your suggestion.

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

* Re: global minor modes that can be overridden locally? [was: highlight-changes-mode]
  2006-12-12 21:45                                 ` Richard Stallman
@ 2006-12-12 23:02                                   ` Lennart Borgman
  0 siblings, 0 replies; 57+ messages in thread
From: Lennart Borgman @ 2006-12-12 23:02 UTC (permalink / raw)
  Cc: drew.adams, emacs-devel

Richard Stallman wrote:
>     The naming scheme does not matter to me very much. What I tried to argue 
>     about was that when we define a new global minor mode with 
>     define-minor-mode it should define functions for us for toggling both 
>     locally and globally.
>
> The easiest way to do this would be to add a call
> to define-global-minor-mode for each call to define-minor-mode.
> The arguments are not the same.
>
> But I am not convinced every mode needs a global variant.
>   

To me it seems more plausible that a global minor mode needs a buffer 
local variant.

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

* Re: highlight-changes-mode
  2006-12-12 21:45                           ` highlight-changes-mode Richard Stallman
@ 2006-12-12 23:33                             ` rsharman
  2006-12-14  5:29                               ` highlight-changes-mode Richard Stallman
  0 siblings, 1 reply; 57+ messages in thread
From: rsharman @ 2006-12-12 23:33 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

Richard Stallman writes:
 > Which way do these changes handle the question of the global mode command?
 > As far as I know we haven't yet decided what that should do.

By default the global mode works like other global modes:
turning it off turns the mode off in all existing buffers.

There is a variable that can be set to a function (that is called when
the global mode is turned off) to actually turn off the mode in each
buffer.  This gives the ability for folks who really don't want that
behaviour to do something about it.

If you feel this is wrong then I will submit a version without
that variable [and thus no change to easymmode is required];
turning off the global mode would then be "final".

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

* Re: highlight-changes-mode
  2006-12-12 23:33                             ` highlight-changes-mode rsharman
@ 2006-12-14  5:29                               ` Richard Stallman
  0 siblings, 0 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-14  5:29 UTC (permalink / raw)
  Cc: nickrob, emacs-devel, rsharman

    By default the global mode works like other global modes:
    turning it off turns the mode off in all existing buffers.

    There is a variable that can be set to a function (that is called when
    the global mode is turned off) to actually turn off the mode in each
    buffer.  This gives the ability for folks who really don't want that
    behaviour to do something about it.

I have no complaints about this, so please let's install it.

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

* RE: global minor modes that can be overridden locally?
  2006-12-12  5:00                                   ` Drew Adams
@ 2006-12-29 16:25                                     ` Drew Adams
  2006-12-29 22:15                                       ` Stefan Monnier
  2006-12-30  6:23                                       ` Richard Stallman
  0 siblings, 2 replies; 57+ messages in thread
From: Drew Adams @ 2006-12-29 16:25 UTC (permalink / raw)


`define-global-minor-mode' is new in Emacs 22. I think we have the
opportunity now to correct its name to avoid confusing users.

There are minor modes that are truly global, defined with
`define-minor-mode' using `:global'. And there are minor modes defined with
`define-global-minor-mode', which are local minor modes that are made to act
globally. These two kinds of "global" minor mode are not the same. We should
change the way we refer to minor modes that are defined as local modes but
then made to act globally - we should not refer to them as global modes.

I wrote this earlier:

> It sounds like the pseudo global modes are not global modes, but
> local modes that are applied globally. If that's the case, then
> perhaps that's the best way to speak of them: don't call them
> global, but speak of them being applied globally. Perhaps rename
> `define-global-minor-mode' to `make-minor-mode-global' (a la
> `make-variable-buffer-local'), since the input is a minor mode
> and you are, in effect, making it serve globally (IIUC). Even
> that characterization of being applied globally (vs being
> inherently global) sounds like too fine a nuance and a possible
> source of confusion, however.

I don't see a good way to avoid the lesser confusion mentioned in the last
sentence, but I do think we should at least change the name of
`define-global-minor-mode' to something like `make-minor-mode-global'.

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

* Re: global minor modes that can be overridden locally?
  2006-12-29 16:25                                     ` Drew Adams
@ 2006-12-29 22:15                                       ` Stefan Monnier
  2006-12-29 22:40                                         ` Drew Adams
  2006-12-30  6:23                                       ` Richard Stallman
  1 sibling, 1 reply; 57+ messages in thread
From: Stefan Monnier @ 2006-12-29 22:15 UTC (permalink / raw)
  Cc: emacs-devel

> `define-global-minor-mode' is new in Emacs 22. I think we have the
> opportunity now to correct its name to avoid confusing users.

As the original inventor of the name (and code) of define-global-minor-mode,
I agree that it's not ideal.  I hope we can come up with something better.
But note that the operation really defines a new global minor mode whose
effect is to turn on in most buffers the other (buffer-local) minor-mode.
Calling it make-minor-mode-global would be wrong, because it would make it
seem like it will change the buffer-local minor-mode to a global one,
whereas the buffer-local minor-mode is actually unaffected.


        Stefan

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

* RE: global minor modes that can be overridden locally?
  2006-12-29 22:15                                       ` Stefan Monnier
@ 2006-12-29 22:40                                         ` Drew Adams
  2006-12-30  6:24                                           ` Richard Stallman
  0 siblings, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-29 22:40 UTC (permalink / raw)


> > `define-global-minor-mode' is new in Emacs 22. I think we have the
> > opportunity now to correct its name to avoid confusing users.
>
> As the original inventor of the name (and code) of
> define-global-minor-mode,
> I agree that it's not ideal.  I hope we can come up with something better.
> But note that the operation really defines a new global minor mode whose
> effect is to turn on in most buffers the other (buffer-local) minor-mode.
> Calling it make-minor-mode-global would be wrong, because it would make it
> seem like it will change the buffer-local minor-mode to a global one,
> whereas the buffer-local minor-mode is actually unaffected.

I see. So it is not quite analogous to `make-variable-buffer-local'.

I do think it's important that we come up with some name, now, that doesn't
encourage confusion of this with the true global minor mode (via :global t).
If we don't do that now, it will engender confusion that lasts, I fear.

I don't really have a better name suggestion than `make-minor-mode-global',
which I think is anyway better than `define-global-minor-mode'. BTW, I came
up with that name based on the first line of the doc string: "Make
global-mode out of the buffer-local minor mode." If that macro name is
misleading, for the reason you gave, then so is the first line of the doc
string, IMO. And the doc string should be at least as clear as the macro
name.

If a longer name can be tolerated, perhaps something like
`make-global-minor-mode-for-local-minor-mode' (ugh!) or
`make-global-for-local-minor-mode' (ugh) or `globally-extend-minor-mode'.
Maybe that last one is OK, but the doc string needs to explain well what the
nebulous "extend" means.

Anyone have a good idea? I really think we should try to come up with a good
name now, before the release.

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

* Re: global minor modes that can be overridden locally?
  2006-12-29 16:25                                     ` Drew Adams
  2006-12-29 22:15                                       ` Stefan Monnier
@ 2006-12-30  6:23                                       ` Richard Stallman
  1 sibling, 0 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-30  6:23 UTC (permalink / raw)
  Cc: emacs-devel

    There are minor modes that are truly global, defined with
    `define-minor-mode' using `:global'. And there are minor modes defined with
    `define-global-minor-mode', which are local minor modes that are made to act
    globally. These two kinds of "global" minor mode are not the same.

They both define global minor modes.  One defines a global minor mode
that only exists globally, and the other defines a global minor mode
that is a globalized version of a local minor mode.

We can still change the name if someone suggests a better name.
However, the name `make-minor-mode-global' does not fit the meaning.

This function defines something, so its name should start with
`define'.

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

* Re: global minor modes that can be overridden locally?
  2006-12-29 22:40                                         ` Drew Adams
@ 2006-12-30  6:24                                           ` Richard Stallman
  2006-12-30  8:25                                             ` Drew Adams
  2006-12-30 22:43                                             ` Kim F. Storm
  0 siblings, 2 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-30  6:24 UTC (permalink / raw)
  Cc: emacs-devel

Perhaps define-globalized-minor-mode would be a better name
than define-global-minor-mode.  Do people think that is better?

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

* RE: global minor modes that can be overridden locally?
  2006-12-30  6:24                                           ` Richard Stallman
@ 2006-12-30  8:25                                             ` Drew Adams
  2006-12-31  1:46                                               ` Richard Stallman
  2006-12-30 22:43                                             ` Kim F. Storm
  1 sibling, 1 reply; 57+ messages in thread
From: Drew Adams @ 2006-12-30  8:25 UTC (permalink / raw)


> Perhaps define-globalized-minor-mode would be a better name
> than define-global-minor-mode.  Do people think that is better?

You've got my vote.

And let's fix the doc string, if it is indeed inaccurate to say "Make
global-mode out of the buffer-local minor mode." At least that sounds an
awful lot like what some object to in the name `make-minor-mode-global'.

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

* Re: global minor modes that can be overridden locally?
  2006-12-30  6:24                                           ` Richard Stallman
  2006-12-30  8:25                                             ` Drew Adams
@ 2006-12-30 22:43                                             ` Kim F. Storm
  2006-12-30 23:27                                               ` Lennart Borgman (gmail)
  1 sibling, 1 reply; 57+ messages in thread
From: Kim F. Storm @ 2006-12-30 22:43 UTC (permalink / raw)
  Cc: Drew Adams, emacs-devel

Richard Stallman <rms@gnu.org> writes:

> Perhaps define-globalized-minor-mode would be a better name
> than define-global-minor-mode.  Do people think that is better?

Yes.

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

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

* Re: global minor modes that can be overridden locally?
  2006-12-30 22:43                                             ` Kim F. Storm
@ 2006-12-30 23:27                                               ` Lennart Borgman (gmail)
  0 siblings, 0 replies; 57+ messages in thread
From: Lennart Borgman (gmail) @ 2006-12-30 23:27 UTC (permalink / raw)
  Cc: rms, Drew Adams, emacs-devel

Kim F. Storm wrote:
> Richard Stallman <rms@gnu.org> writes:
>
>   
>> Perhaps define-globalized-minor-mode would be a better name
>> than define-global-minor-mode.  Do people think that is better?
>>     
>
> Yes.
>   

Me too.

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

* Re: global minor modes that can be overridden locally?
  2006-12-30  8:25                                             ` Drew Adams
@ 2006-12-31  1:46                                               ` Richard Stallman
  0 siblings, 0 replies; 57+ messages in thread
From: Richard Stallman @ 2006-12-31  1:46 UTC (permalink / raw)
  Cc: emacs-devel

I fixed the documentation of this function.
That may be enough.

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

end of thread, other threads:[~2006-12-31  1:46 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <17721.60660.980363.609046@kahikatea.snap.net.nz>
2006-10-23  5:11 ` highlight-changes-mode Richard Stallman
2006-10-23 18:39   ` highlight-changes-mode Richard Stallman
2006-10-24  0:16     ` highlight-changes-mode rsharman
2006-10-24 17:43       ` highlight-changes-mode Richard Stallman
2006-11-27  1:57         ` highlight-changes-mode rsharman
2006-11-27  6:43           ` highlight-changes-mode Nick Roberts
2006-11-28  2:15             ` highlight-changes-mode rsharman
2006-12-06  6:25             ` highlight-changes-mode rsharman
2006-12-06  6:37               ` highlight-changes-mode rsharman
2006-12-06 18:44               ` highlight-changes-mode Richard Stallman
2006-12-06 19:58                 ` highlight-changes-mode Drew Adams
2006-12-07 21:02                   ` highlight-changes-mode Richard Stallman
2006-12-07 21:13                     ` highlight-changes-mode Drew Adams
2006-12-09 18:55                       ` global minor modes that can be overridden locally? [was: highlight-changes-mode] Drew Adams
2006-12-11  1:06                         ` Richard Stallman
2006-12-11  1:16                           ` Lennart Borgman
2006-12-11  1:45                             ` Drew Adams
2006-12-11  1:52                               ` Lennart Borgman
2006-12-11  1:58                                 ` Drew Adams
2006-12-12  2:57                             ` Richard Stallman
2006-12-12  3:27                               ` Lennart Borgman
2006-12-12 21:45                                 ` Richard Stallman
2006-12-12 23:02                                   ` Lennart Borgman
2006-12-12  4:06                               ` Drew Adams
2006-12-12  4:25                                 ` global minor modes that can be overridden locally? Miles Bader
2006-12-12  5:00                                   ` Drew Adams
2006-12-29 16:25                                     ` Drew Adams
2006-12-29 22:15                                       ` Stefan Monnier
2006-12-29 22:40                                         ` Drew Adams
2006-12-30  6:24                                           ` Richard Stallman
2006-12-30  8:25                                             ` Drew Adams
2006-12-31  1:46                                               ` Richard Stallman
2006-12-30 22:43                                             ` Kim F. Storm
2006-12-30 23:27                                               ` Lennart Borgman (gmail)
2006-12-30  6:23                                       ` Richard Stallman
2006-12-12 11:08                                   ` Juanma Barranquero
2006-12-12 11:15                                     ` Miles Bader
2006-12-12 11:25                                       ` Juanma Barranquero
2006-12-12 11:33                                         ` Miles Bader
2006-12-12 11:59                                           ` Juanma Barranquero
2006-12-11  1:40                           ` global minor modes that can be overridden locally? [was:highlight-changes-mode] Drew Adams
2006-12-12  2:58                             ` Richard Stallman
2006-12-12  4:08                               ` global minor modes that can be overridden locally?[was:highlight-changes-mode] Drew Adams
2006-12-12 21:45                                 ` Richard Stallman
2006-12-06 23:39                 ` highlight-changes-mode rsharman
2006-12-07 21:03                   ` highlight-changes-mode Richard Stallman
2006-12-09 19:40                     ` highlight-changes-mode rsharman
2006-12-11  1:06                       ` highlight-changes-mode Richard Stallman
2006-12-11  9:15                         ` highlight-changes-mode Kim F. Storm
2006-12-12  2:58                           ` highlight-changes-mode Richard Stallman
2006-12-12  3:16                         ` highlight-changes-mode rsharman
2006-12-12 21:45                           ` highlight-changes-mode Richard Stallman
2006-12-12 23:33                             ` highlight-changes-mode rsharman
2006-12-14  5:29                               ` highlight-changes-mode Richard Stallman
2006-11-27 15:38           ` highlight-changes-mode Richard Stallman
2006-11-28  2:04             ` highlight-changes-mode rsharman
2006-12-05  2:42               ` highlight-changes-mode rsharman

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).