[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ERC notification area support: erc-status.el 0.1

From: Tom Tromey
Subject: ERC notification area support: erc-status.el 0.1
Date: 25 Mar 2007 17:52:19 -0600
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.4

This is erc-status.el, a notification area icon module for ERC.

This requires status.el, which I just posted.

This is an ordinary ERC module named 'status'.  Just add it to your
module list; I use:

    (if window-system
        (add-to-list 'erc-modules 'status))

With this module active, you will see a Gnu icon in your notification
area.  It will blink when you get a private message or when someone
pings you in a channel.  If you left-click on the blinking Gnu, the
channel holding the message will be shown in an existing frame (which
will be raised).  If you get multiple pings at once, each click will
show the next channel.

In theory right-clicking on the icon should show a menu of all the
open channels, but this isn't working and I haven't debugged it.

This module will also post a notification via the icon when you
connect to or disconnect from a server.

Since status.el itself isn't in ELPA, I'm not uploading this either.
Hopefully someday this will all go away, and we'll have notification
support directly in Emacs and this module directly in ERC :-)

This code pretty much assumes you are using auto-query, and it has a
hook which must be run after auto-query does its thing.  This is gross
but I didn't delve deeply enough into ERC to figure out what would be


;;; erc-status.el --- notification area support for ERC

;; Copyright (C) 2007 Tom Tromey <address@hidden>

;; Author: Tom Tromey <address@hidden>
;; Version: 0.1
;; Keywords: comm

;; This file is not (yet) part of GNU Emacs.
;; However, it is distributed under the same license.

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

;;; Commentary:

;; This provides nice support for the notification area to ERC.  In
;; particular it:
;; * Will blink the icon when you get a private message or are paged
;;   in a channel.
;; * Left-click on the blinking icon will show the appropriate channel
;;   buffer in some frame (which is then raised).  If there are
;;   multiple pages at once, it will show one and you can click again
;;   to go to the next one.
;; * Will show a menu of all the channels on the right button menu.
;;   (Though... this doesn't work and I haven't debugged it.)
;; * Will pop up notification bubbles when you connect to or
;;   disconnect from a server.
;; This is regular erc module named 'status'; you can enable it as you
;; would any other module.

;;; Change log:

;; 2007-02-15  raise frame on left click
;; 2007-02-13  make sure priv message added after auto-query
;; 2007-02-08  turn into an ERC module
;; 2007-02-08  another try at private messages
;; 2007-01-29  try to make private messages work.  show buffer on click

;; TO DO:
;; - make tool tip show some kind of real status ...?
;; - use a nicer icon
;; - menu?  (tried but it isn't working yet)
;; - integrate with auto-query a bit better
;; - let left click use specified frame or make a new frame?

;; Probably not its final name, but this is the name it was posted
;; under.
(require 'status)

(require 'erc)

;; The status icon object.
(defvar erc-status-status-icon nil)

;; List of ERC buffers that caused the status icon to blink.
(defvar erc-status-buffer-list nil)

(defun erc-status-remove-buffer (buffer)
  ;; If the list is not empty, and removing an element makes the list
  ;; empty, stop blinking.
  (and erc-status-buffer-list
       (not (setq erc-status-buffer-list (delq buffer erc-status-buffer-list)))
       (status-set-blink erc-status-status-icon nil)))

(defun erc-status-add-buffer (buffer)
  (and (not (erc-buffer-visible buffer))
         (status-set-blink erc-status-status-icon t)
         (or (memq buffer erc-status-buffer-list)
             (setq erc-status-buffer-list (cons buffer

(defun erc-status-match-hook (match-type nick message)
  ;; Look for user's nick and make the icon blink.
  (if (eq match-type 'current-nick)
      (erc-status-add-buffer (current-buffer))))

(defun erc-status-buffer-killed ()
  ;; If one of our buffers was killed, remove it.
  (erc-status-remove-buffer (current-buffer)))

(defun erc-status-window-configuration-changed ()
  (let ((new-list)
        (iter erc-status-buffer-list))
    (while iter
      (or (erc-buffer-visible (car iter))
          (setq new-list (cons (car iter) new-list)))
      (setq iter (cdr iter)))
    (or (setq erc-status-buffer-list new-list)
        (status-set-blink erc-status-status-icon nil))))

(defun erc-status-disconnected (nick ip reason)
  (status-post-message erc-status-status-icon
                       (concat "Disconnected: " reason)))

(defun erc-status-after-connect (server nick)
  (status-post-message erc-status-status-icon
                       (concat "Connected to " server " as " nick)))

(defun erc-status-select-first-buffer ()
  "Switch to the first ERC buffer requiring your attention.
If there is no such buffer, do nothing."
  (when erc-status-buffer-list
    (switch-to-buffer (car erc-status-buffer-list))

(defun erc-status-update-menu ()
  (status-set-menu erc-status-status-icon
                   (mapcar (lambda (buffer)
                             (cons (buffer-name buffer)
                                   ;; Couldn't figure out how to do
                                   ;; this with backquote :(
                                   (eval (list 'lambda '()
                                               (list 'switch-to-buffer 


;; From:
;; Then modified to suit.

(defun erc-status-PRIVMSG (proc parsed)
  (let* ((nick (car (erc-parse-user (erc-response.sender parsed))))
         (target (car (erc-response.command-args parsed)))
         (msg (erc-response.contents parsed))
         (query  (if (not erc-query-on-unjoined-chan-privmsg)
                   (if (erc-current-nick-p target)
    (when (and (erc-current-nick-p target)
               (not (erc-is-message-ctcp-and-not-action-p msg)))
      ;; Note: assumes you are using auto-query.
      (erc-status-add-buffer (erc-get-buffer query proc))))
  ;; Always return nil.


(define-erc-module status nil
  "Notification area support for ERC."
  ;; Enable.
  ((unless erc-status-status-icon
     (setq erc-status-status-icon (status-new))
     (status-set-tooltip erc-status-status-icon
                         "ERC - IRC client for Emacs")
     (status-set-click-callback erc-status-status-icon
   (add-hook 'erc-text-matched-hook 'erc-status-match-hook)
   (add-hook 'kill-buffer-hook 'erc-status-buffer-killed)
   (add-hook 'window-configuration-change-hook
   (add-hook 'erc-after-connect 'erc-status-after-connect)
   (add-hook 'erc-disconnected-hook 'erc-status-disconnected)
   ;; FIXME: Must come *after* erc-auto-query.  Some sort of
   ;; auto-query hook or the like would be good here.
   (add-hook 'erc-server-PRIVMSG-functions 'erc-status-PRIVMSG t))

  ;; Disable.
  ((when erc-status-status-icon
     (kill-process erc-status-status-icon)
     (setq erc-status-status-icon nil))
   (remove-hook 'erc-text-matched-hook 'erc-status-match-hook)
   (remove-hook 'kill-buffer-hook 'erc-status-buffer-killed)
   (remove-hook 'window-configuration-change-hook
   (remove-hook 'erc-after-connect 'erc-status-after-connect)
   (remove-hook 'erc-disconnected-hook 'erc-status-disconnected)
   (remove-hook 'erc-server-PRIVMSG-functions 'erc-status-PRIVMSG)))

;;; erc-status.el ends here

reply via email to

[Prev in Thread] Current Thread [Next in Thread]