;;; hilit-chg.el --- minor mode displaying buffer changes with special face
-;; Copyright (C) 1998, 2000, 2002, 2003, 2004,
-;; 2005 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004,
+;; 2005, 2006, 2007 Free Software Foundation, Inc.
;; Author: Richard Sharman <rsharman@pobox.com>
;; Keywords: faces
;; 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)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; 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
+;; * a list -- then the buffer is suitable if 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
;; active or passive mode?
;;
(defcustom highlight-changes-initial-state 'active
- "*What state (active or passive) `highlight-changes' should start in.
-This is used when `highlight-changes' is called with no argument.
+ "*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' should start in.
+ "*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)
A value of nil means no buffers are suitable for `global-highlight-changes'
\(effectively disabling the mode).
-Examples:
+Example:
(c-mode c++-mode)
means that Highlight Changes mode is turned on for buffers in C and C++
modes only."
(copy-face 'highlight-changes new-name)
(copy-face old-name new-name)
))
- (setq new-list (append (list new-name) new-list))
+ (setq new-list (append (list new-name) new-list))
(setq n (1- n))
(setq p (cdr p)))
(if (equal new-list (widget-value w))
;;; Functions...
-(defun hilit-chg-map-changes (func &optional start-position end-position)
+(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
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))
+ (remove-text-properties beg end '(hilit-chg nil))
(hilit-chg-fixup beg end)))
(defun hilit-chg-set-face-on-change (beg end leng-before
;; an argument is given
((eq arg 'active)
'active)
- ((eq arg 'passive)
+ ((eq arg 'passive)
'passive)
((> (prefix-numeric-value arg) 0)
'active)
(if new-highlight-changes-mode
;; mode is turned on -- but may be passive
(progn
- (add-to-list 'desktop-locals-to-save 'highlight-changes-mode)
(hilit-chg-set new-highlight-changes-mode)
(or was-on
;; run highlight-changes-enable-hook once
(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)
- ;; 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 active
- (if (eq highlight-changes-mode 'active)
- (hilit-chg-display-changes))))
+ (when (eq highlight-changes-mode 'active)
+ (let ((modified (buffer-modified-p))
+ (inhibit-modification-hooks t))
+ ;; The `modified' related code tries to combine two goals: (1) Record the
+ ;; rotation in `buffer-undo-list' and (2) avoid setting the modified flag
+ ;; of the current buffer due to the rotation. We do this by inserting (in
+ ;; `buffer-undo-list') entries restoring buffer-modified-p to nil before
+ ;; and after the entry for the rotation.
+ (unless modified
+ ;; Install the "before" entry.
+ (setq buffer-undo-list
+ (cons '(apply restore-buffer-modified-p nil)
+ buffer-undo-list)))
+ (unwind-protect
+ (progn
+ ;; 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 active
+ (if (eq highlight-changes-mode 'active)
+ (hilit-chg-display-changes)))
+ (unless modified
+ ;; Install the "after" entry.
+ (setq buffer-undo-list
+ (cons '(apply restore-buffer-modified-p nil)
+ buffer-undo-list))
+
+ (restore-buffer-modified-p nil)))))
;; This always returns nil so it is safe to use in write-file-functions
nil)
;; which calls this function as a hook
(defvar x) ;; placate the byte-compiler
(defvar y)
- (setq e (current-buffer))
+ (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
+ (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))
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 zero prefix turn it on in passive mode
- if called with a negative prefix turn it off
When called from a program:
(progn
(if (eq arg 'active)
(setq highlight-changes-global-initial-state 'active)
- (if (eq arg 'passive)
+ (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"
(memq major-mode highlight-changes-global-modes)))
(t
(and
- (not (string-match "^[ *]" (buffer-name)))
+ (not (string-match "^[ *]" (buffer-name)))
(buffer-file-name))))
(progn
(hilit-chg-set value)
(defun hilit-chg-update-all-buffers (value)
- (mapcar
+ (mapc
(function (lambda (buffer)
(with-current-buffer buffer
(if value
(hilit-chg-turn-on-maybe value)
(hilit-chg-turn-off-maybe))
)))
- (buffer-list)))
+ (buffer-list))
+ nil)
;;;; Desktop support.
(add-to-list 'desktop-minor-mode-handlers
'(highlight-changes-mode . hilit-chg-desktop-restore))
+(add-to-list 'desktop-locals-to-save 'highlight-changes-mode)
+
;; ===================== debug ==================
;; For debug & test use:
;;