;;; erc-track.el --- Track modified channel buffers
;; Copyright (C) 2002, 2003, 2004, 2005, 2006,
-;; 2007 Free Software Foundation, Inc.
+;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Mario Lang <mlang@delysid.org>
;; Keywords: comm, faces
;; 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
;; 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:
: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)
: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.
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
(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)
;;; Test:
-(erc-assert
+(assert
(and
;; verify examples from the doc strings
(equal (let ((erc-track-shorten-aggressively nil))
: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-@"))))
(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)
(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)))))
(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'."
(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
"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)
(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))