aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2008-04-03 22:03:01 +0000
committerStefan Monnier2008-04-03 22:03:01 +0000
commit7c655cf643671126b4c3aa3b574b8ac5efbd9bd3 (patch)
tree1efd62137ad0b6baf41147844d0d2144b3a8073a
parent79669f88b4ebe0672e836560d0e5006ec1f6cd49 (diff)
downloademacs-7c655cf643671126b4c3aa3b574b8ac5efbd9bd3.tar.gz
emacs-7c655cf643671126b4c3aa3b574b8ac5efbd9bd3.zip
(highlight-changes-mode): Rename from
highlight-changes; no longer uses sub-modes active and passive; implemented by define-minor-mode. (highlight-changes-toggle-visibility): New function, to replace the old passive/active submodes of global-highlight-changes-mode; implemented by define-minor-mode. (global-highlight-changes-mode'): Rename from global-highlight-changes; rewrite using define-globalized-minor-mode. (hilit-chg-major-mode-hook, hilit-chg-check-global) (hilit-chg-post-command-hook, hilit-chg-check-global) (hilit-chg-update-all-buffers, hilit-chg-turn-off-maybe): Remove due to use of define-globalized-minor-mode. (highlight-changes-global-initial-state): Change to be boolean. (highlight-changes-visible-string, highlight-changes-invisible-string): Rename from highlight-changes-active-string and highlight-changes-passive-string. (hilit-chg-update, hilit-chg-set): Use them. (global-highlight-changes-mode): Rename from global-highlight-changes. (hilit-chg-map-changes, hilit-chg-display-changes): Add arguments to docstring. (hilit-chg-hide-changes): Rewrite to use dolist. (hilit-chg-set-face-on-change, hilit-chg-update) (highlight-changes-rotate-faces): Use highlight-changes-visible-mode variable instead of testing highlight-changes-mode. (highlight-markup-buffers): Add reuire ediff-util; argument on calls to highlight-changes-mode changed. (highlight-compare-with-file): Fix problems with interactive call giving invalid default file.
-rw-r--r--lisp/ChangeLog31
-rw-r--r--lisp/hilit-chg.el614
2 files changed, 268 insertions, 377 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 315d489a4b0..ca6be0f0d1d 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,34 @@
12008-04-03 Richard Sharman <rsharman@pobox.com>
2
3 * hilit-chg.el (highlight-changes-mode): Rename from
4 highlight-changes; no longer uses sub-modes active and
5 passive; implemented by define-minor-mode.
6 (highlight-changes-toggle-visibility): New function, to replace
7 the old passive/active submodes of global-highlight-changes-mode;
8 implemented by define-minor-mode.
9 (global-highlight-changes-mode'): Rename from
10 global-highlight-changes; rewrite using define-globalized-minor-mode.
11 (hilit-chg-major-mode-hook, hilit-chg-check-global)
12 (hilit-chg-post-command-hook, hilit-chg-check-global)
13 (hilit-chg-update-all-buffers, hilit-chg-turn-off-maybe): Remove due
14 to use of define-globalized-minor-mode.
15 (highlight-changes-global-initial-state): Change to be boolean.
16 (highlight-changes-visible-string, highlight-changes-invisible-string):
17 Rename from highlight-changes-active-string and
18 highlight-changes-passive-string.
19 (hilit-chg-update, hilit-chg-set): Use them.
20 (global-highlight-changes-mode): Rename from global-highlight-changes.
21 (hilit-chg-map-changes, hilit-chg-display-changes): Add arguments to
22 docstring.
23 (hilit-chg-hide-changes): Rewrite to use dolist.
24 (hilit-chg-set-face-on-change, hilit-chg-update)
25 (highlight-changes-rotate-faces): Use highlight-changes-visible-mode
26 variable instead of testing highlight-changes-mode.
27 (highlight-markup-buffers): Add reuire ediff-util; argument on calls
28 to highlight-changes-mode changed.
29 (highlight-compare-with-file): Fix problems with interactive
30 call giving invalid default file.
31
12008-04-03 Nick Roberts <nickrob@snap.net.nz> 322008-04-03 Nick Roberts <nickrob@snap.net.nz>
2 33
3 * progmodes/gdb-ui.el (gdb-mouse-set-clear-breakpoint): 34 * progmodes/gdb-ui.el (gdb-mouse-set-clear-breakpoint):
diff --git a/lisp/hilit-chg.el b/lisp/hilit-chg.el
index e567e37354b..b7ad52d26a0 100644
--- a/lisp/hilit-chg.el
+++ b/lisp/hilit-chg.el
@@ -26,60 +26,48 @@
26;;; Commentary: 26;;; Commentary:
27 27
28;; A minor mode: "Highlight Changes mode". 28;; A minor mode: "Highlight Changes mode".
29;;
30 29
31;; Highlight Changes mode has 2 submodes: active and passive. 30;; When Highlight Changes mode is enabled changes to the buffer are
32;; When active, changes to the buffer are displayed in a different face. 31;; recorded with a text property. Normally these ranges of text are
33;; When passive, any existing displayed changes are saved and new ones 32;; displayed in a distinctive face. However, sometimes it is
34;; recorded but are not displayed differently. 33;; desirable to temporarily not see these changes. Instead of
35;; Why active and passive? Having the changes visible can be handy when you 34;; disabling Highlight Changes mode (which would remove the text property)
36;; want the information but very distracting otherwise. So, you can keep 35;; use the command highlight-changes-visible-mode.
37;; Highlight Changes mode in passive state while you make your changes, toggle 36
38;; it on to active mode to see them, then toggle it back off to avoid 37;; Two faces are supported: one for changed or inserted text and
39;; distraction. 38;; another for the first character after text has been deleted.
40;; 39
41;; When active, changes are displayed in the `highlight-changes' face. 40;; When Highlight Changes mode is on (even if changes are not visible)
42;; When text is deleted, the following character is displayed in the 41;; you can go to the next or previous change with
43;; `highlight-changes-delete' face. 42;; `highlight-changes-next-change' or `highlight-changes-previous-change'.
44;; 43
44;; Command highlight-compare-with-file shows changes in this file
45;; compared with another file (by default the previous version of the
46;; file).
45;; 47;;
48;; The command highlight-compare-buffers compares two buffers by
49;; highlighting their differences.
50
46;; You can "age" different sets of changes by using 51;; You can "age" different sets of changes by using
47;; `highlight-changes-rotate-faces'. This rotates through a series 52;; `highlight-changes-rotate-faces'. This rotates through a series
48;; of different faces, so you can distinguish "new" changes from "older" 53;; of different faces, so you can distinguish "new" changes from "older"
49;; changes. You can customize these "rotated" faces in two ways. You can 54;; changes. You can customize these "rotated" faces in two ways. You can
50;; either explicitly define each face by customizing 55;; either explicitly define each face by customizing
51;; `highlight-changes-face-list'. If, however, the faces differ from 56;; `highlight-changes-face-list'. If, however, the faces differ from
52;; the `highlight-changes' face only in the foreground color, you can simply set 57;; `highlight-changes-face' only in the foreground color, you can simply set
53;; `highlight-changes-colors'. If `highlight-changes-face-list' is nil when 58;; `highlight-changes-colors'. If `highlight-changes-face-list' is nil when
54;; the faces are required they will be constructed from 59;; the faces are required they will be constructed from
55;; `highlight-changes-colors'. 60;; `highlight-changes-colors'.
56;; 61
57;; 62;; You can automatically rotate faces when the buffer is saved;
58;; When a Highlight Changes mode is on (either active or passive) you can go 63;; see function `highlight-changes-rotate-faces' for how to do this.
59;; to the next or previous change with `highlight-changes-next-change' and 64
60;; `highlight-changes-previous-change'. 65;; There are two hooks used by `highlight-changes-mode':
61;;
62;;
63;; You can also use the command highlight-compare-with-file to show changes
64;; in this file compared with another file (typically the previous version
65;; of the file). The command highlight-compare-buffers can be used to
66;; compare two buffers.
67;;
68;;
69;; There are currently three hooks run by `highlight-changes-mode':
70;; `highlight-changes-enable-hook' - is run when Highlight Changes mode 66;; `highlight-changes-enable-hook' - is run when Highlight Changes mode
71;; is initially enabled for a buffer. 67;; is enabled for a buffer.
72;; `highlight-changes-disable-hook' - is run when Highlight Changes mode 68;; `highlight-changes-disable-hook' - is run when Highlight Changes mode
73;; is turned off. 69;; is disabled for a buffer.
74;; `highlight-changes-toggle-hook' - is run each time `highlight-changes-mode' 70
75;; is called. Typically this is when
76;; toggling between active and passive
77;; modes. The variable
78;; `highlight-changes-mode' contains the new
79;; state (`active' or `passive'.)
80;;
81;;
82;;
83;; Example usage: 71;; Example usage:
84;; (defun my-highlight-changes-enable-hook () 72;; (defun my-highlight-changes-enable-hook ()
85;; (add-hook 'write-file-functions 'highlight-changes-rotate-faces nil t) 73;; (add-hook 'write-file-functions 'highlight-changes-rotate-faces nil t)
@@ -94,67 +82,58 @@
94;; 'my-highlight-changes-disable-hook) 82;; 'my-highlight-changes-disable-hook)
95 83
96 84
97;; Explicit vs. Implicit 85;; Automatically enabling Highlight Changes mode
98;; 86;;
99 87
100;; Normally, Highlight Changes mode is turned on explicitly in a buffer. 88;; Normally, Highlight Changes mode is turned on explicitly in a buffer.
101;; 89;;
102;; If you prefer to have it automatically invoked you can do it as 90;; If you prefer to have it automatically invoked you can do it as
103;; follows. 91;; follows.
104;; 92
105;; 1. Most modes have a major-hook, typically called MODE-hook. You 93;; 1. Most modes have a major-hook, typically called MODE-hook. You
106;; can use `add-hook' to call `highlight-changes-mode'. 94;; can use `add-hook' to call `highlight-changes-mode'.
107;; 95
108;; Example: 96;; Example:
109;; (add-hook 'c-mode-hook 'highlight-changes-mode) 97;; (add-hook 'c-mode-hook 'highlight-changes-mode)
110;; 98
111;; If you want to make it start up in passive mode (regardless of the
112;; setting of highlight-changes-initial-state):
113;; (add-hook 'emacs-lisp-mode-hook
114;; (lambda ()
115;; (highlight-changes-mode 'passive)))
116;;
117;; However, this cannot be done for Fundamental mode for there is no 99;; However, this cannot be done for Fundamental mode for there is no
118;; such hook. 100;; such hook.
119;; 101
120;; 2. You can use the function `global-highlight-changes' 102;; 2. You can use the function `global-highlight-changes-mode'
121;; 103;;
122;; This function, which is fashioned after the way `global-font-lock' works, 104;; This function, which is fashioned after the way `global-font-lock' works,
123;; toggles on or off global Highlight Changes mode. When activated, it turns 105;; toggles on or off global Highlight Changes mode. When activated, it turns
124;; on Highlight Changes mode in all "suitable" existing buffers and will turn 106;; on Highlight Changes mode in all "suitable" existing buffers and will turn
125;; it on in new "suitable" buffers to be created. 107;; it on in new "suitable" buffers to be created.
126;; 108
127;; A buffer's "suitability" is determined by variable 109;; A buffer's "suitability" is determined by variable
128;; `highlight-changes-global-modes', as follows. If the variable is 110;; `highlight-changes-global-modes', as follows. If it is
129;; * nil -- then no buffers are suitable; 111;; * nil -- then no buffers are suitable;
130;; * a function -- this function is called and the result is used. As 112;; * a function -- this function is called and the result is used. As
131;; an example, if the value is `buffer-file-name' then all buffers 113;; an example, if the value is `buffer-file-name' then all buffers
132;; who are visiting files are suitable, but others (like dired 114;; who are visiting files are suitable, but others (like dired
133;; buffers) are not; 115;; buffers) are not;
134;; * a list -- then the buffer is suitable if its mode is in the 116;; * a list -- then the buffer is suitable if and only if its mode is in the
135;; list, except if the first element is `not', in which case the test 117;; list, except if the first element is `not', in which case the test
136;; is reversed (i.e. it is a list of unsuitable modes). 118;; is reversed (i.e. it is a list of unsuitable modes).
137;; * Otherwise, the buffer is suitable if its name does not begin with 119;; * Otherwise, the buffer is suitable if its name does not begin with
138;; ` ' or `*' and if `buffer-file-name' returns true. 120;; ` ' or `*' and if `buffer-file-name' returns true.
139;;
140 121
122;; To enable it for future sessions put this in your ~/.emacs file:
123;; (global-highlight-changes-mode t)
141 124
142 125
143;; Possible bindings: 126;; Possible bindings:
144;; (global-set-key '[C-right] 'highlight-changes-next-change) 127;; (global-set-key '[C-right] 'highlight-changes-next-change)
145;; (global-set-key '[C-left] 'highlight-changes-previous-change) 128;; (global-set-key '[C-left] 'highlight-changes-previous-change)
146;; 129;;
147;; Other interactive functions (which could be bound if desired): 130;; Other interactive functions (that could be bound if desired):
148;; highlight-changes-mode 131;; highlight-changes-mode
132;; highlight-changes-toggle-visibility
149;; highlight-changes-remove-highlight 133;; highlight-changes-remove-highlight
150;; highlight-changes-rotate-faces
151;; highlight-compare-with-file 134;; highlight-compare-with-file
152;; highlight-compare-buffers 135;; highlight-compare-buffers
153 136;; highlight-changes-rotate-faces
154;;
155;; You can automatically rotate faces when the buffer is saved;
156;; see function `highlight-changes-rotate-faces' for how to do this.
157;;
158 137
159 138
160;;; Bugs: 139;;; Bugs:
@@ -168,11 +147,8 @@
168 147
169;; - having different faces for deletion and non-deletion: is it 148;; - having different faces for deletion and non-deletion: is it
170;; really worth the hassle? 149;; really worth the hassle?
171;; - should have better hooks: when should they be run?
172;; - highlight-compare-with-file should allow RCS files - e.g. nice to be 150;; - highlight-compare-with-file should allow RCS files - e.g. nice to be
173;; able to say show changes compared with version 2.1. 151;; able to say show changes compared with version 2.1.
174;; - Maybe we should have compare-with-buffer as well. (When I tried
175;; a while back I ran into a problem with ediff-buffers-internal.)
176 152
177 153
178;;; History: 154;;; History:
@@ -193,6 +169,13 @@
193;; Dec 2003 169;; Dec 2003
194;; - Use require for ediff stuff 170;; - Use require for ediff stuff
195;; - Added highlight-compare-buffers 171;; - Added highlight-compare-buffers
172;; Mar 2008
173;; - Made highlight-changes-mode like other modes (toggle on/off)
174;; - Added new command highlight-changes-visible-mode to replace the
175;; previous active/passive aspect of highlight-changes-mode.
176;; - Removed highlight-changes-toggle-hook
177;; - Put back eval-and-compile inadvertently dropped
178
196 179
197;;; Code: 180;;; Code:
198 181
@@ -257,42 +240,51 @@ colors then use this, if you want fancier faces then set
257 'highlight-changes-colors "22.1") 240 'highlight-changes-colors "22.1")
258 241
259 242
260;; If you invoke highlight-changes-mode with no argument, should it start in 243;; When you invoke highlight-changes-mode, should highlight-changes-visible-mode
261;; active or passive mode? 244;; be on or off?
262;; 245
263(defcustom highlight-changes-initial-state 'active 246(define-obsolete-variable-alias 'highlight-changes-initial-state
264 "What state (active or passive) Highlight Changes mode should start in. 247 'highlight-changes-visibility-initial-state)
265This is used when `highlight-changes-mode' is called with no argument.
266This variable must be set to one of the symbols `active' or `passive'."
267 :type '(choice (const :tag "Active" active)
268 (const :tag "Passive" passive))
269 :group 'highlight-changes)
270 248
271(defcustom highlight-changes-global-initial-state 'passive 249(defcustom highlight-changes-visibility-initial-state t
272 "What state global Highlight Changes mode should start in. 250 "Controls whether changes are initially be visible in Highlight Changes mode.
273This is used if `global-highlight-changes' is called with no argument. 251
274This variable must be set to either `active' or `passive'." 252This controls the initial value of highlght-changes-visibile-mode.
275 :type '(choice (const :tag "Active" active) 253When a buffer is in Highlight Changes mode the function
276 (const :tag "Passive" passive)) 254highlght-changes-visibile-mode is used to toggle the mode on or off."
255 :type 'boolean
277 :group 'highlight-changes) 256 :group 'highlight-changes)
278 257
279;; The strings displayed in the mode-line for the minor mode: 258;; highlight-changes-global-initial-state has been removed
280(defcustom highlight-changes-active-string " +Chg" 259
281 "The string used when Highlight Changes mode is in the active state. 260
261
262;; These are the strings displayed in the mode-line for the minor mode:
263
264(defcustom highlight-changes-visible-string " +Chg"
265 "The string used when in Highlight Changes mode and changes are visible.
282This should be set to nil if no indication is desired, or to 266This should be set to nil if no indication is desired, or to
283a string with a leading space." 267a string with a leading space."
284 :type '(choice string 268 :type '(choice string
285 (const :tag "None" nil)) 269 (const :tag "None" nil))
286 :group 'highlight-changes) 270 :group 'highlight-changes)
287 271
288(defcustom highlight-changes-passive-string " -Chg" 272(define-obsolete-variable-alias 'highlight-changes-active-string
289 "The string used when Highlight Changes mode is in the passive state. 273 'highlight-changes-visible-string "22.1")
274
275(defcustom highlight-changes-invisible-string " -Chg"
276 "The string used when in Highlight Changes mode and changes are hidden.
290This should be set to nil if no indication is desired, or to 277This should be set to nil if no indication is desired, or to
291a string with a leading space." 278a string with a leading space."
292 :type '(choice string 279 :type '(choice string
293 (const :tag "None" nil)) 280 (const :tag "None" nil))
294 :group 'highlight-changes) 281 :group 'highlight-changes)
295 282
283(define-obsolete-variable-alias 'highlight-changes-passive-string
284 'highlight-changes-invisible-string "22.1")
285
286
287
296(defcustom highlight-changes-global-modes t 288(defcustom highlight-changes-global-modes t
297 "Determine whether a buffer is suitable for global Highlight Changes mode. 289 "Determine whether a buffer is suitable for global Highlight Changes mode.
298 290
@@ -306,11 +298,11 @@ modes which are not suitable.
306A value of t means the buffer is suitable if it is visiting a file and 298A value of t means the buffer is suitable if it is visiting a file and
307its name does not begin with ` ' or `*'. 299its name does not begin with ` ' or `*'.
308 300
309A value of nil means no buffers are suitable for `global-highlight-changes' 301A value of nil means no buffers are suitable for `global-highlight-changes-mode'
310\(effectively disabling the mode). 302\(effectively disabling the mode).
311 303
312Example: 304Example:
313 (c-mode c++-mode) 305 (c-mode c++-mode)
314means that Highlight Changes mode is turned on for buffers in C and C++ 306means that Highlight Changes mode is turned on for buffers in C and C++
315modes only." 307modes only."
316 :type '(choice 308 :type '(choice
@@ -325,8 +317,6 @@ modes only."
325 ) 317 )
326 :group 'highlight-changes) 318 :group 'highlight-changes)
327 319
328(defvar global-highlight-changes nil)
329
330(defcustom highlight-changes-global-changes-existing-buffers nil 320(defcustom highlight-changes-global-changes-existing-buffers nil
331 "If non-nil, toggling global Highlight Changes mode affects existing buffers. 321 "If non-nil, toggling global Highlight Changes mode affects existing buffers.
332Normally, `global-highlight-changes' affects only new buffers (to be 322Normally, `global-highlight-changes' affects only new buffers (to be
@@ -337,6 +327,84 @@ remove it from existing buffers."
337 :type 'boolean 327 :type 'boolean
338 :group 'highlight-changes) 328 :group 'highlight-changes)
339 329
330;; These are for internal use.
331
332(defvar hilit-chg-list nil)
333(defvar hilit-chg-string " ??")
334
335(make-variable-buffer-local 'hilit-chg-string)
336
337
338
339;;; Functions...
340
341;;;###autoload
342(define-minor-mode highlight-changes-mode
343 "Toggle Highlight Changes mode.
344
345With ARG, turn Highlight Changes mode on if and only if arg is positive.
346
347In Highlight Changes mode changes are recorded with a text property.
348Normally they are displayed in a distinctive face, but command
349\\[highlight-changes-visible-mode] can be used to toggles this
350on and off.
351
352Other functions for buffers in this mode include:
353\\[highlight-changes-next-change] - move point to beginning of next change
354\\[highlight-changes-previous-change] - move to beginning of previous change
355\\[highlight-changes-remove-highlight] - remove the change face from the region
356\\[highlight-changes-rotate-faces] - rotate different \"ages\" of changes
357through various faces.
358\\[highlight-compare-with-file] - mark text as changed by comparing this
359buffer with the contents of a file
360\\[highlight-compare-buffers] highlights differences between two buffers.
361
362Hook variables:
363`highlight-changes-enable-hook': called when enabling Highlight Changes mode.
364`highlight-changes-disable-hook': called when disabling Highlight Changes mode."
365 nil ;; init-value
366 hilit-chg-string ;; lighter
367 nil ;; keymap
368 (if (or (display-color-p)
369 (and (fboundp 'x-display-grayscale-p) (x-display-grayscale-p)))
370 (progn
371 (if (and (eq this-command 'global-highlight-changes-mode)
372 (not highlight-changes-global-changes-existing-buffers))
373 ;; The global mode has toggled the value of the mode variable,
374 ;; but not other changes have been mode, so we are safe
375 ;; to retoggle it.
376 (setq highlight-changes-mode (not highlight-changes-mode)))
377 (if highlight-changes-mode
378 ;; it is being turned on
379 ;; the hook has been moved into hilit-chg-set
380 ;; (run-hooks 'highlight-changes-enable-hook))
381 (hilit-chg-set)
382 ;; mode is turned off
383 (hilit-chg-clear)))
384 (message "Highlight Changes mode requires color or grayscale display")))
385
386
387;;;###autoload
388(define-minor-mode highlight-changes-visible-mode
389 "Toggle visiblility of changes when buffer is in Highlight Changes mode.
390
391This mode only has an effect when Highlight Changes mode is on.
392It allows toggling between whether or not the changed text is displayed
393in a distinctive face.
394
395The default value can be customized with variable
396`highlight-changes-visibility-initial-state'
397
398This command does not itself set highlight-changes mode."
399
400 t ;; init-value
401 nil ;; lighter
402 nil ;; keymap
403
404 (hilit-chg-update)
405 )
406
407
340(defun hilit-chg-cust-fix-changes-face-list (w wc &optional event) 408(defun hilit-chg-cust-fix-changes-face-list (w wc &optional event)
341 ;; When customization function `highlight-changes-face-list' inserts a new 409 ;; When customization function `highlight-changes-face-list' inserts a new
342 ;; face it uses the default face. We don't want the user to modify this 410 ;; face it uses the default face. We don't want the user to modify this
@@ -398,32 +466,12 @@ Otherwise, this list will be constructed when needed from
398 ) 466 )
399 :group 'highlight-changes) 467 :group 'highlight-changes)
400 468
401;; ========================================================================
402 469
403;; These shouldn't be changed! 470(defun hilit-chg-map-changes (func &optional start-position end-position)
404 471 "Call function FUNC for each region used by Highlight Changes mode.
405(defvar highlight-changes-mode nil) 472If START-POSITION is nil, (point-min) is used.
406(defvar hilit-chg-list nil) 473If END-POSITION is nil, (point-max) is used.
407(defvar hilit-chg-string " ??") 474FUNC is called with 3 params: PROPERTY START STOP."
408(or (assq 'highlight-changes-mode minor-mode-alist)
409 (setq minor-mode-alist
410 (cons '(highlight-changes-mode hilit-chg-string) minor-mode-alist)
411 ))
412(make-variable-buffer-local 'highlight-changes-mode)
413(make-variable-buffer-local 'hilit-chg-string)
414
415
416(require 'ediff-init)
417(require 'ediff-util)
418
419
420;;; Functions...
421
422(defun hilit-chg-map-changes (func &optional start-position end-position)
423 "Call function FUNC for each region used by Highlight Changes mode."
424 ;; if start-position is nil, (point-min) is used
425 ;; if end-position is nil, (point-max) is used
426 ;; FUNC is called with 3 params: property start stop
427 (let ((start (or start-position (point-min))) 475 (let ((start (or start-position (point-min)))
428 (limit (or end-position (point-max))) 476 (limit (or end-position (point-max)))
429 prop end) 477 prop end)
@@ -438,8 +486,8 @@ Otherwise, this list will be constructed when needed from
438(defun hilit-chg-display-changes (&optional beg end) 486(defun hilit-chg-display-changes (&optional beg end)
439 "Display face information for Highlight Changes mode. 487 "Display face information for Highlight Changes mode.
440 488
441An overlay containing a change face is added from the information 489An overlay from BEG to END containing a change face is added from the
442in the text property of type `hilit-chg'. 490information in the text property of type `hilit-chg'.
443 491
444This is the opposite of `hilit-chg-hide-changes'." 492This is the opposite of `hilit-chg-hide-changes'."
445 (hilit-chg-map-changes 'hilit-chg-make-ov beg end)) 493 (hilit-chg-map-changes 'hilit-chg-make-ov beg end))
@@ -448,15 +496,15 @@ This is the opposite of `hilit-chg-hide-changes'."
448(defun hilit-chg-make-ov (prop start end) 496(defun hilit-chg-make-ov (prop start end)
449 (or prop 497 (or prop
450 (error "hilit-chg-make-ov: prop is nil")) 498 (error "hilit-chg-make-ov: prop is nil"))
451 ;; for the region make change overlays corresponding to 499 ;; For the region create overlays with a distincive face
452 ;; the text property 'hilit-chg 500 ;; and the text property 'hilit-chg.
453 (let ((ov (make-overlay start end)) 501 (let ((ov (make-overlay start end))
454 (face (if (eq prop 'hilit-chg-delete) 502 (face (if (eq prop 'hilit-chg-delete)
455 'highlight-changes-delete 503 'highlight-changes-delete
456 (nth 1 (member prop hilit-chg-list))))) 504 (nth 1 (member prop hilit-chg-list)))))
457 (if face 505 (if face
458 (progn 506 (progn
459 ;; We must mark the face, that is the purpose of the overlay 507 ;; We must mark the face, that is the purpose of the overlay.
460 (overlay-put ov 'face face) 508 (overlay-put ov 'face face)
461 ;; I don't think we need to set evaporate since we should 509 ;; I don't think we need to set evaporate since we should
462 ;; be controlling them! 510 ;; be controlling them!
@@ -475,14 +523,12 @@ containing the change information is retained.
475 523
476This is the opposite of `hilit-chg-display-changes'." 524This is the opposite of `hilit-chg-display-changes'."
477 (let ((start (or beg (point-min))) 525 (let ((start (or beg (point-min)))
478 (limit (or end (point-max))) 526 (limit (or end (point-max))))
479 p ov) 527 (dolist (p (overlays-in start limit))
480 (setq p (overlays-in start limit))
481 (while p
482 ;; don't delete the overlay if it isn't ours! 528 ;; don't delete the overlay if it isn't ours!
483 (if (overlay-get (car p) 'hilit-chg) 529 (if (overlay-get p 'hilit-chg)
484 (delete-overlay (car p))) 530 (delete-overlay p)))))
485 (setq p (cdr p))))) 531
486 532
487(defun hilit-chg-fixup (beg end) 533(defun hilit-chg-fixup (beg end)
488 "Fix change overlays in region between BEG and END. 534 "Fix change overlays in region between BEG and END.
@@ -535,7 +581,8 @@ This allows you to manually remove highlighting from uninteresting changes."
535 (type 'hilit-chg) 581 (type 'hilit-chg)
536 old) 582 old)
537 (if undo-in-progress 583 (if undo-in-progress
538 (if (eq highlight-changes-mode 'active) 584 (if (and highlight-changes-mode
585 highlight-changes-visible-mode)
539 (hilit-chg-fixup beg end)) 586 (hilit-chg-fixup beg end))
540 (highlight-save-buffer-state 587 (highlight-save-buffer-state
541 (if (and (= beg end) (> leng-before 0)) 588 (if (and (= beg end) (> leng-before 0))
@@ -563,36 +610,43 @@ This allows you to manually remove highlighting from uninteresting changes."
563 (if (eq (get-text-property end 'hilit-chg) 'hilit-chg-delete) 610 (if (eq (get-text-property end 'hilit-chg) 'hilit-chg-delete)
564 (progn 611 (progn
565 (put-text-property end (+ end 1) 'hilit-chg 'hilit-chg) 612 (put-text-property end (+ end 1) 'hilit-chg 'hilit-chg)
566 (if (eq highlight-changes-mode 'active) 613 (if highlight-changes-visible-mode
567 (hilit-chg-fixup beg (+ end 1)))))) 614 (hilit-chg-fixup beg (+ end 1))))))
568 (unless no-property-change 615 (unless no-property-change
569 (put-text-property beg end 'hilit-chg type)) 616 (put-text-property beg end 'hilit-chg type))
570 (if (or (eq highlight-changes-mode 'active) no-property-change) 617 (if (or highlight-changes-visible-mode no-property-change)
571 (hilit-chg-make-ov type beg end))))))) 618 (hilit-chg-make-ov type beg end)))))))
572 619
573(defun hilit-chg-set (value) 620(defun hilit-chg-update ()
574 "Turn on Highlight Changes mode for this buffer." 621 "Update a buffer's highlight changes when visibiility changed."
575 (setq highlight-changes-mode value) 622 (if highlight-changes-visible-mode
576 (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t) 623 ;; changes are visible
577 (hilit-chg-make-list)
578 (if (eq highlight-changes-mode 'active)
579 (progn 624 (progn
580 (setq hilit-chg-string highlight-changes-active-string) 625 (setq hilit-chg-string highlight-changes-visible-string)
581 (or buffer-read-only 626 (or buffer-read-only
582 (hilit-chg-display-changes))) 627 (hilit-chg-display-changes)))
583 ;; mode is passive 628 ;; changes are invisible
584 (setq hilit-chg-string highlight-changes-passive-string) 629 (setq hilit-chg-string highlight-changes-invisible-string)
585 (or buffer-read-only 630 (or buffer-read-only
586 (hilit-chg-hide-changes))) 631 (hilit-chg-hide-changes))))
632
633(defun hilit-chg-set ()
634 "Turn on Highlight Changes mode for this buffer."
635 (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t)
636 (hilit-chg-make-list)
637 (setq highlight-changes-mode t)
638 (setq highlight-changes-visible-mode highlight-changes-visibility-initial-state)
639 (hilit-chg-update)
587 (force-mode-line-update) 640 (force-mode-line-update)
588 (add-hook 'after-change-functions 'hilit-chg-set-face-on-change nil t)) 641 (add-hook 'after-change-functions 'hilit-chg-set-face-on-change nil t)
642 (run-hooks 'highlight-changes-enable-hook))
589 643
590(defun hilit-chg-clear () 644(defun hilit-chg-clear ()
591 "Remove Highlight Changes mode for this buffer. 645 "Remove Highlight Changes mode for this buffer.
592This removes all saved change information." 646This removes all saved change information."
593 (if buffer-read-only 647 (if buffer-read-only
594 ;; We print the buffer name because this function could be called 648 ;; We print the buffer name because this function could be called
595 ;; on many buffers from `global-highlight-changes'. 649 ;; on many buffers from `global-highlight-changes-mode'.
596 (message "Cannot remove highlighting from read-only mode buffer %s" 650 (message "Cannot remove highlighting from read-only mode buffer %s"
597 (buffer-name)) 651 (buffer-name))
598 (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t) 652 (remove-hook 'after-change-functions 'hilit-chg-set-face-on-change t)
@@ -602,79 +656,8 @@ This removes all saved change information."
602 (lambda (prop start stop) 656 (lambda (prop start stop)
603 (remove-text-properties start stop '(hilit-chg nil))))) 657 (remove-text-properties start stop '(hilit-chg nil)))))
604 (setq highlight-changes-mode nil) 658 (setq highlight-changes-mode nil)
605 (force-mode-line-update) 659 (force-mode-line-update)))
606 ;; If we type: C-u -1 M-x highlight-changes-mode
607 ;; we want to turn it off, but hilit-chg-post-command-hook
608 ;; runs and that turns it back on!
609 (remove-hook 'post-command-hook 'hilit-chg-post-command-hook)))
610
611;;;###autoload
612(defun highlight-changes-mode (&optional arg)
613 "Toggle (or initially set) Highlight Changes mode.
614
615Without an argument:
616 If Highlight Changes mode is not enabled, then enable it (in either active
617 or passive state as determined by the variable
618 `highlight-changes-initial-state'); otherwise, toggle between active
619 and passive state.
620
621With an argument ARG:
622 If ARG is positive, set state to active;
623 If ARG is zero, set state to passive;
624 If ARG is negative, disable Highlight Changes mode completely.
625
626Active state - means changes are shown in a distinctive face.
627Passive state - means changes are kept and new ones recorded but are
628 not displayed in a different face.
629
630Functions:
631\\[highlight-changes-next-change] - move point to beginning of next change
632\\[highlight-changes-previous-change] - move to beginning of previous change
633\\[highlight-compare-with-file] - mark text as changed by comparing this
634 buffer with the contents of a file
635\\[highlight-changes-remove-highlight] - remove the change face from the region
636\\[highlight-changes-rotate-faces] - rotate different \"ages\" of changes \
637through
638 various faces
639 660
640Hook variables:
641`highlight-changes-enable-hook' - when enabling Highlight Changes mode
642`highlight-changes-toggle-hook' - when entering active or passive state
643`highlight-changes-disable-hook' - when turning off Highlight Changes mode"
644 (interactive "P")
645 (if (or (display-color-p)
646 (and (fboundp 'x-display-grayscale-p) (x-display-grayscale-p)))
647 (let ((was-on highlight-changes-mode)
648 (new-highlight-changes-mode
649 (cond
650 ((null arg)
651 ;; no arg => toggle (or set to active initially)
652 (if highlight-changes-mode
653 (if (eq highlight-changes-mode 'active) 'passive 'active)
654 highlight-changes-initial-state))
655 ;; an argument is given
656 ((eq arg 'active)
657 'active)
658 ((eq arg 'passive)
659 'passive)
660 ((> (prefix-numeric-value arg) 0)
661 'active)
662 ((< (prefix-numeric-value arg) 0)
663 nil)
664 (t
665 'passive))))
666 (if new-highlight-changes-mode
667 ;; mode is turned on -- but may be passive
668 (progn
669 (hilit-chg-set new-highlight-changes-mode)
670 (or was-on
671 ;; run highlight-changes-enable-hook once
672 (run-hooks 'highlight-changes-enable-hook))
673 (run-hooks 'highlight-changes-toggle-hook))
674 ;; mode is turned off
675 (run-hooks 'highlight-changes-disable-hook)
676 (hilit-chg-clear)))
677 (message "Highlight Changes mode requires color or grayscale display")))
678 661
679;;;###autoload 662;;;###autoload
680(defun highlight-changes-next-change () 663(defun highlight-changes-next-change ()
@@ -768,7 +751,7 @@ Hook variables:
768 751
769;;;###autoload 752;;;###autoload
770(defun highlight-changes-rotate-faces () 753(defun highlight-changes-rotate-faces ()
771 "Rotate the faces used by Highlight Changes mode. 754 "Rotate the faces if in Highlight Changes mode and the changes are visible.
772 755
773Current changes are displayed in the face described by the first element 756Current changes are displayed in the face described by the first element
774of `highlight-changes-face-list', one level older changes are shown in 757of `highlight-changes-face-list', one level older changes are shown in
@@ -781,9 +764,7 @@ this, eval the following in the buffer to be saved:
781 764
782 \(add-hook 'write-file-functions 'highlight-changes-rotate-faces nil t)" 765 \(add-hook 'write-file-functions 'highlight-changes-rotate-faces nil t)"
783 (interactive) 766 (interactive)
784 ;; If not in active mode do nothing but don't complain because this 767 (when (and highlight-changes-mode highlight-changes-visible-mode)
785 ;; may be bound to a hook.
786 (when (eq highlight-changes-mode 'active)
787 (let ((modified (buffer-modified-p)) 768 (let ((modified (buffer-modified-p))
788 (inhibit-modification-hooks t)) 769 (inhibit-modification-hooks t))
789 ;; The `modified' related code tries to combine two goals: (1) Record the 770 ;; The `modified' related code tries to combine two goals: (1) Record the
@@ -805,9 +786,8 @@ this, eval the following in the buffer to be saved:
805 (hilit-chg-hide-changes) 786 (hilit-chg-hide-changes)
806 ;; for each change text property, increment it 787 ;; for each change text property, increment it
807 (hilit-chg-map-changes 'hilit-chg-bump-change) 788 (hilit-chg-map-changes 'hilit-chg-bump-change)
808 ;; and display them all if active 789 ;; and display them
809 (if (eq highlight-changes-mode 'active) 790 (hilit-chg-display-changes))
810 (hilit-chg-display-changes)))
811 (unless modified 791 (unless modified
812 ;; Install the "after" entry. FIXME: See above. 792 ;; Install the "after" entry. FIXME: See above.
813 ;; (push '(apply restore-buffer-modified-p nil) buffer-undo-list) 793 ;; (push '(apply restore-buffer-modified-p nil) buffer-undo-list)
@@ -825,6 +805,8 @@ this, eval the following in the buffer to be saved:
825 "Get differences between two buffers and set highlight changes. 805 "Get differences between two buffers and set highlight changes.
826Both buffers are done unless optional parameter MARKUP-A-ONLY 806Both buffers are done unless optional parameter MARKUP-A-ONLY
827is non-nil." 807is non-nil."
808 (eval-and-compile
809 (require 'ediff-util))
828 (save-window-excursion 810 (save-window-excursion
829 (let* (change-info 811 (let* (change-info
830 change-a change-b 812 change-a change-b
@@ -853,9 +835,9 @@ is non-nil."
853 (or file-b 835 (or file-b
854 (setq temp-b (setq file-b (ediff-make-temp-file buf-b nil)))) 836 (setq temp-b (setq file-b (ediff-make-temp-file buf-b nil))))
855 (set-buffer buf-a) 837 (set-buffer buf-a)
856 (highlight-changes-mode 'active) 838 (highlight-changes-mode 1)
857 (or markup-a-only (with-current-buffer buf-b 839 (or markup-a-only (with-current-buffer buf-b
858 (highlight-changes-mode 'active))) 840 (highlight-changes-mode 1)))
859 (setq change-info (hilit-chg-get-diff-info buf-a file-a buf-b file-b)) 841 (setq change-info (hilit-chg-get-diff-info buf-a file-a buf-b file-b))
860 842
861 843
@@ -929,20 +911,23 @@ read in temporarily but the buffer is deleted.
929If the buffer is read-only, differences will be highlighted but no property 911If the buffer is read-only, differences will be highlighted but no property
930changes are made, so \\[highlight-changes-next-change] and 912changes are made, so \\[highlight-changes-next-change] and
931\\[highlight-changes-previous-change] will not work." 913\\[highlight-changes-previous-change] will not work."
932 (interactive (list 914 (interactive
933 (read-file-name 915 (let ((file buffer-file-name)
934 "File to compare with? " ;; prompt 916 (file-name nil)
935 "" ;; directory 917 (file-dir nil))
936 nil ;; default 918 (and file
937 'yes ;; must exist 919 (setq file-name (file-name-nondirectory file)
938 (let ((f (buffer-file-name (current-buffer)))) 920 file-dir (file-name-directory file)))
939 (if f 921 (setq file-name (make-backup-file-name file-name))
940 (progn 922 (unless (file-exists-p file-name)
941 (setq f (make-backup-file-name f)) 923 (setq file-name nil))
942 (or (file-exists-p f) 924 (list (read-file-name
943 (setq f nil))) 925 "Find to compare with: " ;; prompt
944 ) 926 file-dir ;; directory
945 f)))) 927 nil ;; default
928 nil ;; existing
929 file-name) ;; initial
930 )))
946 (let* ((buf-a (current-buffer)) 931 (let* ((buf-a (current-buffer))
947 (file-a (buffer-file-name)) 932 (file-a (buffer-file-name))
948 (existing-buf (get-file-buffer file-b)) 933 (existing-buf (get-file-buffer file-b))
@@ -1010,125 +995,19 @@ changes are made, so \\[highlight-changes-next-change] and
1010 ;; No point in returning a value, since this is a hook function. 995 ;; No point in returning a value, since this is a hook function.
1011 )) 996 ))
1012 997
1013;; ======================= automatic stuff ============== 998;; ======================= global-highlight-changes-mode ==============
1014
1015;; Global Highlight Changes mode is modeled after Global Font-lock mode.
1016;; Three hooks are used to gain control. When Global Changes Mode is
1017;; enabled, `find-file-hook' and `change-major-mode-hook' are set.
1018;; `find-file-hook' is called when visiting a file, the new mode is
1019;; known at this time.
1020;; `change-major-mode-hook' is called when a buffer is changing mode.
1021;; This could be because of finding a file in which case
1022;; `find-file-hook' has already been called and has done its work.
1023;; However, it also catches the case where a new mode is being set by
1024;; the user. However, it is called from `kill-all-variables' and at
1025;; this time the mode is the old mode, which is not what we want.
1026;; So, our function temporarily sets `post-command-hook' which will
1027;; be called after the buffer has been completely set up (with the new
1028;; mode). It then removes the `post-command-hook'.
1029;; One other wrinkle - every M-x command runs the `change-major-mode-hook'
1030;; so we ignore this by examining the buffer name.
1031
1032
1033(defun hilit-chg-major-mode-hook ()
1034 (add-hook 'post-command-hook 'hilit-chg-post-command-hook))
1035
1036(defun hilit-chg-post-command-hook ()
1037 ;; This is called after changing a major mode, but also after each
1038 ;; M-x command, in which case the current buffer is a minibuffer.
1039 ;; In that case, do not act on it here, but don't turn it off
1040 ;; either, we will get called here again soon-after.
1041 ;; Also, don't enable it for other special buffers.
1042 (if (string-match "^[ *]" (buffer-name))
1043 nil ;; (message "ignoring this post-command-hook")
1044 (remove-hook 'post-command-hook 'hilit-chg-post-command-hook)
1045 ;; The following check isn't necessary, since
1046 ;; hilit-chg-turn-on-maybe makes this check too.
1047 (or highlight-changes-mode ;; don't turn it on if it already is
1048 (hilit-chg-turn-on-maybe highlight-changes-global-initial-state))))
1049
1050(defun hilit-chg-check-global ()
1051 ;; This is called from the find file hook.
1052 (hilit-chg-turn-on-maybe highlight-changes-global-initial-state))
1053
1054 999
1055;;;###autoload 1000;;;###autoload
1056(defun global-highlight-changes (&optional arg) 1001(define-globalized-minor-mode global-highlight-changes-mode
1057 "Turn on or off global Highlight Changes mode. 1002 highlight-changes-mode highlight-changes-mode-turn-on)
1058
1059When called interactively:
1060- if no prefix, toggle global Highlight Changes mode on or off
1061- if called with a positive prefix (or just C-u) turn it on in active mode
1062- if called with a zero prefix turn it on in passive mode
1063- if called with a negative prefix turn it off
1064
1065When called from a program:
1066- if ARG is nil or omitted, turn it off
1067- if ARG is `active', turn it on in active mode
1068- if ARG is `passive', turn it on in passive mode
1069- otherwise just turn it on
1070
1071When global Highlight Changes mode is enabled, Highlight Changes mode is turned
1072on for future \"suitable\" buffers (and for \"suitable\" existing buffers if
1073variable `highlight-changes-global-changes-existing-buffers' is non-nil).
1074\"Suitability\" is determined by variable `highlight-changes-global-modes'."
1075 1003
1076 (interactive 1004(define-obsolete-function-alias
1077 (list 1005 'global-highlight-changes
1078 (cond 1006 'global-highlight-changes-mode "22.1")
1079 ((null current-prefix-arg) 1007
1080 ;; no arg => toggle it on/off 1008(defun highlight-changes-mode-turn-on ()
1081 (setq global-highlight-changes (not global-highlight-changes))) 1009 "See if highlight-changes-mode should be turned on for this buffer.
1082 ;; positive interactive arg - turn it on as active 1010This is called when global-highlight-changes-mode is turned on."
1083 ((> (prefix-numeric-value current-prefix-arg) 0)
1084 (setq global-highlight-changes t)
1085 'active)
1086 ;; zero interactive arg - turn it on as passive
1087 ((= (prefix-numeric-value current-prefix-arg) 0)
1088 (setq global-highlight-changes t)
1089 'passive)
1090 ;; negative interactive arg - turn it off
1091 (t
1092 (setq global-highlight-changes nil)
1093 nil))))
1094
1095 (if arg
1096 (progn
1097 (if (eq arg 'active)
1098 (setq highlight-changes-global-initial-state 'active)
1099 (if (eq arg 'passive)
1100 (setq highlight-changes-global-initial-state 'passive)))
1101 (setq global-highlight-changes t)
1102 (message "Turning ON Global Highlight Changes mode in %s state"
1103 highlight-changes-global-initial-state)
1104 ;; FIXME: Not sure what this was intended to do. --Stef
1105 ;; (add-hook 'hilit-chg-major-mode-hook 'hilit-chg-major-mode-hook)
1106 (add-hook 'find-file-hook 'hilit-chg-check-global)
1107 (if highlight-changes-global-changes-existing-buffers
1108 (hilit-chg-update-all-buffers
1109 highlight-changes-global-initial-state)))
1110
1111 (message "Turning OFF global Highlight Changes mode")
1112 ;; FIXME: Not sure what this was intended to do. --Stef
1113 ;; (remove-hook 'hilit-chg-major-mode-hook 'hilit-chg-major-mode-hook)
1114 (remove-hook 'post-command-hook 'hilit-chg-post-command-hook)
1115 (remove-hook 'find-file-hook 'hilit-chg-check-global)
1116 (if highlight-changes-global-changes-existing-buffers
1117 (hilit-chg-update-all-buffers nil))))
1118
1119
1120(defun hilit-chg-turn-on-maybe (value)
1121 "Turn on Highlight Changes mode if it is appropriate for this buffer.
1122
1123A buffer is appropriate for Highlight Changes mode if all these are true:
1124- the buffer is not a special buffer (one whose name begins with
1125 `*' or ` '),
1126- the buffer's mode is suitable as per variable
1127 `highlight-changes-global-modes',
1128- Highlight Changes mode is not already on for this buffer.
1129
1130This function is called from `hilit-chg-update-all-buffers' or
1131from `global-highlight-changes' when turning on global Highlight Changes mode."
1132 (or highlight-changes-mode ; do nothing if already on 1011 (or highlight-changes-mode ; do nothing if already on
1133 (if 1012 (if
1134 (cond 1013 (cond
@@ -1144,29 +1023,10 @@ from `global-highlight-changes' when turning on global Highlight Changes mode."
1144 (and 1023 (and
1145 (not (string-match "^[ *]" (buffer-name))) 1024 (not (string-match "^[ *]" (buffer-name)))
1146 (buffer-file-name)))) 1025 (buffer-file-name))))
1147 (progn 1026 (highlight-changes-mode 1))
1148 (hilit-chg-set value) 1027 ))
1149 (run-hooks 'highlight-changes-enable-hook)))))
1150 1028
1151 1029
1152(defun hilit-chg-turn-off-maybe ()
1153 (if highlight-changes-mode
1154 (progn
1155 (run-hooks 'highlight-changes-disable-hook)
1156 (hilit-chg-clear))))
1157
1158
1159(defun hilit-chg-update-all-buffers (value)
1160 (mapc
1161 (function (lambda (buffer)
1162 (with-current-buffer buffer
1163 (if value
1164 (hilit-chg-turn-on-maybe value)
1165 (hilit-chg-turn-off-maybe))
1166 )))
1167 (buffer-list))
1168 nil)
1169
1170;;;; Desktop support. 1030;;;; Desktop support.
1171 1031
1172;; Called by `desktop-create-buffer' to restore `highlight-changes-mode'. 1032;; Called by `desktop-create-buffer' to restore `highlight-changes-mode'.