Spelling fixes.
[bpt/emacs.git] / lisp / erc / erc-track.el
index 15de209..e2e5fa1 100644 (file)
@@ -1,7 +1,6 @@
 ;;; erc-track.el --- Track modified channel buffers
 
-;; Copyright (C) 2002, 2003, 2004, 2005, 2006,
-;;   2007 Free Software Foundation, Inc.
+;; Copyright (C) 2002-2011 Free Software Foundation, Inc.
 
 ;; Author: Mario Lang <mlang@delysid.org>
 ;; Keywords: comm, faces
@@ -9,10 +8,10 @@
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; 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 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, 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
@@ -20,9 +19,7 @@
 ;; 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., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
@@ -87,8 +84,8 @@ Activity means that there was no user input in the last 10 seconds."
   :type  '(choice (const :tag "All frames" t)
                  (const :tag "All visible frames" visible)
                  (const :tag "Only the selected frame" nil)
-                 (const :tag "Only the selected frame if it was active"
-                        active)))
+                 (const :tag "Only the selected frame if it is visible"
+                        selected-visible)))
 
 (defcustom erc-track-exclude nil
   "A list targets (channel names or query targets) which should not be tracked."
@@ -101,9 +98,13 @@ disconnected from `erc-modified-channels-alist'."
   :group 'erc-track
   :type 'boolean)
 
-(defcustom erc-track-exclude-types '("NICK")
+(defcustom erc-track-exclude-types '("NICK" "333" "353")
   "*List of message types to be ignored.
-This list could look like '(\"JOIN\" \"PART\")."
+This list could look like '(\"JOIN\" \"PART\").
+
+By default, exclude changes of nicknames (NICK), display of who
+set the channel topic (333), and listing of users on the current
+channel (353)."
   :group 'erc-track
   :type 'erc-message-type)
 
@@ -175,15 +176,32 @@ The faces used are the same as used for text in the buffers.
   :type 'boolean)
 
 (defcustom erc-track-faces-priority-list
-  '(erc-error-face erc-current-nick-face erc-keyword-face erc-pal-face
-    erc-nick-msg-face erc-direct-msg-face erc-button erc-dangerous-host-face
-    erc-default-face erc-action-face erc-nick-default-face erc-fool-face
-    erc-notice-face erc-input-face erc-prompt-face)
+  '(erc-error-face
+    (erc-nick-default-face erc-current-nick-face)
+    erc-current-nick-face
+    erc-keyword-face
+    (erc-nick-default-face erc-pal-face)
+    erc-pal-face
+    erc-nick-msg-face
+    erc-direct-msg-face
+    (erc-button erc-default-face)
+    (erc-nick-default-face erc-dangerous-host-face)
+    erc-dangerous-host-face
+    erc-nick-default-face
+    (erc-nick-default-face erc-default-face)
+    erc-default-face
+    erc-action-face
+    (erc-nick-default-face erc-fool-face)
+    erc-fool-face
+    erc-notice-face
+    erc-input-face
+    erc-prompt-face)
   "A list of faces used to highlight active buffer names in the modeline.
 If a message contains one of the faces in this list, the buffer name will
 be highlighted using that face.  The first matching face is used."
   :group 'erc-track
-  :type '(repeat face))
+  :type '(repeat (choice face
+                        (repeat :tag "Combination" face))))
 
 (defcustom erc-track-priority-faces-only nil
   "Only track text highlighted with a priority face.
@@ -193,6 +211,7 @@ this variable.  You can set a list of channel name strings, so those
 will be ignored while all other channels will be tracked as normal.
 Other options are 'all, to apply this to all channels or nil, to disable
 this feature.
+
 Note: If you have a lot of faces listed in `erc-track-faces-priority-list',
 setting this variable might not be very useful."
   :group 'erc-track
@@ -200,17 +219,38 @@ setting this variable might not be very useful."
                 (repeat string)
                 (const all)))
 
+(defcustom erc-track-faces-normal-list
+  '((erc-button erc-default-face)
+    (erc-nick-default-face erc-dangerous-host-face)
+    erc-dangerous-host-face
+    erc-nick-default-face
+    (erc-nick-default-face erc-default-face)
+    erc-default-face
+    erc-action-face)
+  "A list of faces considered to be part of normal conversations.
+This list is used to highlight active buffer names in the modeline.
+
+If a message contains one of the faces in this list, and the
+previous modeline face for this buffer is also in this list, then
+the buffer name will be highlighted using the face from the
+message.  This gives a rough indication that active conversations
+are occurring in these channels.
+
+The effect may be disabled by setting this variable to nil."
+  :group 'erc-track
+  :type '(repeat (choice face
+                        (repeat :tag "Combination" face))))
+
 (defcustom erc-track-position-in-mode-line 'before-modes
   "Where to show modified channel information in the mode-line.
 
 Setting this variable only has effects in GNU Emacs versions above 21.3.
 
 Choices are:
-'before-modes - add to the beginning of `mode-line-modes'
-'after-modes  - add to the end of `mode-line-modes'
-t             - add to the end of `global-mode-string'.
-nil           - don't add to mode line
-"
+'before-modes - add to the beginning of `mode-line-modes',
+'after-modes  - add to the end of `mode-line-modes',
+t             - add to the end of `global-mode-string',
+nil           - don't add to mode line."
   :group 'erc-track
   :type '(choice (const :tag "Just before mode information" before-modes)
                 (const :tag "Just after mode information" after-modes)
@@ -443,7 +483,7 @@ START is the minimum length of the name used."
 
 ;;; Test:
 
-(erc-assert
+(assert
  (and
   ;; verify examples from the doc strings
   (equal (let ((erc-track-shorten-aggressively nil))
@@ -548,25 +588,30 @@ START is the minimum length of the name used."
 
 ;;;###autoload
 (define-minor-mode erc-track-minor-mode
-  "Global minor mode for tracking ERC buffers and showing activity in the
-mode line.
-
-This exists for the sole purpose of providing the C-c C-SPC and
-C-c C-@ keybindings.  Make sure that you have enabled the track
-module, otherwise the keybindings will not do anything useful."
+  "Toggle mode line display of ERC activity (ERC Track minor mode).
+With a prefix argument ARG, enable ERC Track minor mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
+ERC Track minor mode is a global minor mode.  It exists for the
+sole purpose of providing the C-c C-SPC and C-c C-@ keybindings.
+Make sure that you have enabled the track module, otherwise the
+keybindings will not do anything useful."
   :init-value nil
   :lighter ""
   :keymap erc-track-minor-mode-map
   :global t
   :group 'erc-track)
 
-(defun erc-track-minor-mode-maybe ()
+(defun erc-track-minor-mode-maybe (&optional buffer)
   "Enable `erc-track-minor-mode', depending on `erc-track-enable-keybindings'."
-  (unless (or erc-track-minor-mode
-             ;; don't start the minor mode until we have an ERC
-             ;; process running, because we don't want to prompt the
-             ;; user while starting Emacs
-             (null (erc-buffer-list)))
+  (when (and (not erc-track-minor-mode)
+            ;; don't start the minor mode until we have an ERC
+            ;; process running, because we don't want to prompt the
+            ;; user while starting Emacs
+            (or (and (buffer-live-p buffer)
+                     (with-current-buffer buffer (eq major-mode 'erc-mode)))
+                (erc-buffer-list)))
     (cond ((eq erc-track-enable-keybindings 'ask)
           (let ((key (or (and (key-binding (kbd "C-c C-SPC")) "C-SPC")
                          (and (key-binding (kbd "C-c C-@")) "C-@"))))
@@ -606,16 +651,16 @@ module, otherwise the keybindings will not do anything useful."
           (add-hook 'erc-send-completed-hook 'erc-user-is-active)
           (add-hook 'erc-server-001-functions 'erc-user-is-active))
        (erc-track-add-to-mode-line erc-track-position-in-mode-line)
-       (setq erc-modified-channels-object (erc-modified-channels-object nil))
        (erc-update-mode-line)
        (if (featurep 'xemacs)
           (defadvice switch-to-buffer (after erc-update (&rest args) activate)
             (erc-modified-channels-update))
         (add-hook 'window-configuration-change-hook
-                  'erc-modified-channels-update))
+                  'erc-window-configuration-change))
        (add-hook 'erc-insert-post-hook 'erc-track-modified-channels)
        (add-hook 'erc-disconnected-hook 'erc-modified-channels-update))
      ;; enable the tracking keybindings
+     (add-hook 'erc-connect-pre-hook 'erc-track-minor-mode-maybe)
      (erc-track-minor-mode-maybe)))
   ;; Disable:
   ((when (boundp 'erc-track-when-inactive)
@@ -633,10 +678,11 @@ module, otherwise the keybindings will not do anything useful."
        (if (featurep 'xemacs)
           (ad-disable-advice 'switch-to-buffer 'after 'erc-update)
         (remove-hook 'window-configuration-change-hook
-                     'erc-modified-channels-update))
+                     'erc-window-configuration-change))
        (remove-hook 'erc-disconnected-hook 'erc-modified-channels-update)
        (remove-hook 'erc-insert-post-hook 'erc-track-modified-channels))
      ;; disable the tracking keybindings
+     (remove-hook 'erc-connect-pre-hook 'erc-track-minor-mode-maybe)
      (when erc-track-minor-mode
        (erc-track-minor-mode -1)))))
 
@@ -687,6 +733,12 @@ only consider active buffers visible.")
 
 ;;; Tracking the channel modifications
 
+(defun erc-window-configuration-change ()
+  (unless (minibuffer-window-active-p (minibuffer-window))
+    ;; delay this until command has finished to make sure window is
+    ;; actually visible before clearing activity
+    (add-hook 'post-command-hook 'erc-modified-channels-update)))
+
 (defvar erc-modified-channels-update-inside nil
   "Variable to prevent running `erc-modified-channels-update' multiple
 times.  Without it, you cannot debug `erc-modified-channels-display',
@@ -714,8 +766,9 @@ ARGS are ignored."
                  (erc-modified-channels-remove-buffer buffer))))
            erc-modified-channels-alist)
       (when removed-channel
-      (erc-modified-channels-display)
-       (force-mode-line-update t)))))
+       (erc-modified-channels-display)
+       (force-mode-line-update t)))
+    (remove-hook 'post-command-hook 'erc-modified-channels-update)))
 
 (defvar erc-track-mouse-face (if (featurep 'xemacs)
                                 'modeline-mousable
@@ -807,7 +860,7 @@ Use `erc-make-mode-line-buffer-name' to create buttons."
       (when (featurep 'xemacs)
        (erc-modified-channels-object nil))
       (setq erc-modified-channels-object
-             (erc-modified-channels-object strings))))))
+           (erc-modified-channels-object strings))))))
 
 (defun erc-modified-channels-remove-buffer (buffer)
   "Remove BUFFER from `erc-modified-channels-alist'."
@@ -820,16 +873,36 @@ Use `erc-make-mode-line-buffer-name' to create buttons."
 
 (defun erc-track-find-face (faces)
   "Return the face to use in the modeline from the faces in FACES.
-If `erc-track-faces-priority-list' is set, the one from FACES who is
-first in that list will be used."
-  (let ((candidates erc-track-faces-priority-list)
-       candidate face)
-    (while (and candidates (not face))
-      (setq candidate (car candidates)
-           candidates (cdr candidates))
-      (when (memq candidate faces)
-       (setq face candidate)))
-    face))
+If `erc-track-faces-priority-list' is set, the one from FACES who
+is first in that list will be used.  If nothing matches or if
+`erc-track-faces-priority-list' is not set, the default mode-line
+faces will be used.
+
+If `erc-track-faces-normal-list' is non-nil, use it to produce a
+blinking effect that indicates channel activity when the first
+element in FACES and the highest-ranking face among the rest of
+FACES are both members of `erc-track-faces-normal-list'.
+
+If one of the faces is a list, then it will be ranked according
+to its highest-tanking face member.  A list of faces including
+that member will take priority over just the single member
+element."
+  (let ((choice (catch 'face
+                 (dolist (candidate erc-track-faces-priority-list)
+                   (when (member candidate faces)
+                     (throw 'face candidate)))))
+       (no-first (and erc-track-faces-normal-list
+                      (catch 'face
+                        (dolist (candidate erc-track-faces-priority-list)
+                          (when (member candidate (cdr faces))
+                            (throw 'face candidate)))))))
+    (cond ((null choice)
+          nil)
+         ((and (member choice erc-track-faces-normal-list)
+               (member no-first erc-track-faces-normal-list))
+          no-first)
+         (t
+          choice))))
 
 (defun erc-track-modified-channels ()
   "Hook function for `erc-insert-post-hook' to check if the current
@@ -898,14 +971,15 @@ is in `erc-mode'."
   "Return a list of all faces used in STR."
   (let ((i 0)
        (m (length str))
-       (faces (erc-list (get-text-property 0 'face str))))
+       (faces (erc-list (get-text-property 0 'face str)))
+       cur)
     (while (and (setq i (next-single-property-change i 'face str m))
                (not (= i m)))
-      (dolist (face (erc-list (get-text-property i 'face str)))
-       (add-to-list 'faces face)))
+      (when (setq cur (get-text-property i 'face str))
+       (add-to-list 'faces cur)))
     faces))
 
-(erc-assert
+(assert
  (let ((str "is bold"))
    (put-text-property 3 (length str)
                      'face '(bold erc-current-nick-face)
@@ -935,7 +1009,7 @@ higher number than any other face in that list."
   (let ((count 0))
     (catch 'done
       (dolist (item erc-track-faces-priority-list)
-       (if (eq item face)
+       (if (equal item face)
            (throw 'done t)
          (setq count (1+ count)))))
     count))
@@ -966,7 +1040,7 @@ relative to `erc-track-switch-direction'"
                   ((oldest leastactive)
                    (- (length erc-modified-channels-alist) arg))
                   (t (1- arg))))
-    ;; normalise out of range user input
+    ;; normalize out of range user input
     (cond ((>= offset (length erc-modified-channels-alist))
           (setq offset (1- (length erc-modified-channels-alist))))
          ((< offset 0)
@@ -1001,5 +1075,3 @@ switch back to the last non-ERC buffer visited.  Next is defined by
 ;; indent-tabs-mode: t
 ;; tab-width: 8
 ;; End:
-
-;; arch-tag: 11b439f5-e5d7-4c6c-bb3f-eda98f9b0ac1