1 ;;; erc-notify.el --- Online status change notification -*- lexical-binding:t -*-
3 ;; Copyright (C) 2002-2004, 2006-2017 Free Software Foundation, Inc.
5 ;; Author: Mario Lang <mlang@lexx.delysid.org>
6 ;; Maintainer: emacs-devel@gnu.org
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
26 ;; This module defines a new command, /NOTIFY
27 ;; See the docstring of `erc-cmd-NOTIFY' for details.
32 (require 'erc-networks
)
33 (eval-when-compile (require 'pcomplete
))
35 ;;;; Customizable variables
37 (defgroup erc-notify nil
38 "Track online status of certain nicknames."
41 (defcustom erc-notify-list nil
42 "List of nicknames you want to be notified about online/offline
45 :type
'(repeat string
))
47 (defcustom erc-notify-interval
60
48 "Time interval (in seconds) for checking online status of notified
53 (defcustom erc-notify-signon-hook nil
54 "Hook run after someone on `erc-notify-list' has signed on.
55 Two arguments are passed to the function, SERVER and NICK, both
59 :options
'(erc-notify-signon))
61 (defcustom erc-notify-signoff-hook nil
62 "Hook run after someone on `erc-notify-list' has signed off.
63 Two arguments are passed to the function, SERVER and NICK, both
67 :options
'(erc-notify-signoff))
69 (defun erc-notify-signon (server nick
)
70 (message "%s signed on at %s" nick server
))
72 (defun erc-notify-signoff (server nick
)
73 (message "%s signed off from %s" nick server
))
75 ;;;; Internal variables
77 (defvar erc-last-ison nil
78 "Last ISON information received through `erc-notify-timer'.")
79 (make-variable-buffer-local 'erc-last-ison
)
81 (defvar erc-last-ison-time
0
82 "Last time ISON was sent to the server in `erc-notify-timer'.")
83 (make-variable-buffer-local 'erc-last-ison-time
)
87 (defun erc-notify-install-message-catalogs ()
90 '((notify_current .
"Notified people online: %l")
91 (notify_list .
"Current notify list: %l")
92 (notify_on .
"Detected %n on IRC network %m")
93 (notify_off .
"%n has left IRC network %m"))))
95 ;;;###autoload (autoload 'erc-notify-mode "erc-notify" nil t)
96 (define-erc-module notify nil
97 "Periodically check for the online status of certain users and report
99 ((add-hook 'erc-timer-hook
'erc-notify-timer
)
100 (add-hook 'erc-server-JOIN-functions
'erc-notify-JOIN
)
101 (add-hook 'erc-server-NICK-functions
'erc-notify-NICK
)
102 (add-hook 'erc-server-QUIT-functions
'erc-notify-QUIT
))
103 ((remove-hook 'erc-timer-hook
'erc-notify-timer
)
104 (remove-hook 'erc-server-JOIN-functions
'erc-notify-JOIN
)
105 (remove-hook 'erc-server-NICK-functions
'erc-notify-NICK
)
106 (remove-hook 'erc-server-QUIT-functions
'erc-notify-QUIT
)))
110 (defun erc-notify-timer (now)
111 (when (and erc-server-connected
114 erc-last-ison-time now
)
115 erc-notify-interval
))
116 (erc-once-with-server-event
118 (lambda (proc parsed
)
119 (let* ((server (erc-response.sender parsed
))
120 (ison-list (delete "" (split-string
121 (erc-response.contents parsed
))))
123 (old-list (erc-with-server-buffer erc-last-ison
)))
125 (when (not (erc-member-ignore-case (car new-list
) old-list
))
126 (run-hook-with-args 'erc-notify-signon-hook server
(car new-list
))
129 'notify_on ?n
(car new-list
) ?m
(erc-network-name)))
130 (setq new-list
(cdr new-list
)))
132 (when (not (erc-member-ignore-case (car old-list
) ison-list
))
133 (run-hook-with-args 'erc-notify-signoff-hook server
(car old-list
))
136 'notify_off ?n
(car old-list
) ?m
(erc-network-name)))
137 (setq old-list
(cdr old-list
)))
138 (setq erc-last-ison ison-list
)
141 (concat "ISON " (mapconcat 'identity erc-notify-list
" ")))
142 (setq erc-last-ison-time now
)))
144 (defun erc-notify-JOIN (proc parsed
)
145 "Check if channel joiner is on `erc-notify-list' and not on `erc-last-ison'.
146 If this condition is satisfied, produce a notify_on message and add the nick
147 to `erc-last-ison' to prevent any further notifications."
148 (let ((nick (erc-extract-nick (erc-response.sender parsed
))))
149 (when (and (erc-member-ignore-case nick erc-notify-list
)
150 (not (erc-member-ignore-case nick erc-last-ison
)))
151 (add-to-list 'erc-last-ison nick
)
152 (run-hook-with-args 'erc-notify-signon-hook
153 (or erc-server-announced-name erc-session-server
)
157 'notify_on ?n nick ?m
(erc-network-name)))
160 (defun erc-notify-NICK (proc parsed
)
161 "Check if new nick is on `erc-notify-list' and not on `erc-last-ison'.
162 If this condition is satisfied, produce a notify_on message and add the nick
163 to `erc-last-ison' to prevent any further notifications."
164 (let ((nick (erc-response.contents parsed
)))
165 (when (and (erc-member-ignore-case nick erc-notify-list
)
166 (not (erc-member-ignore-case nick erc-last-ison
)))
167 (add-to-list 'erc-last-ison nick
)
168 (run-hook-with-args 'erc-notify-signon-hook
169 (or erc-server-announced-name erc-session-server
)
173 'notify_on ?n nick ?m
(erc-network-name)))
176 (defun erc-notify-QUIT (proc parsed
)
177 "Check if quitter is on `erc-notify-list' and on `erc-last-ison'.
178 If this condition is satisfied, produce a notify_off message and remove the
179 nick from `erc-last-ison' to prevent any further notifications."
180 (let ((nick (erc-extract-nick (erc-response.sender parsed
))))
181 (when (and (erc-member-ignore-case nick erc-notify-list
)
182 (erc-member-ignore-case nick erc-last-ison
))
183 (setq erc-last-ison
(erc-delete-if
184 (let ((nick-down (erc-downcase nick
)))
186 (string= nick-down
(erc-downcase el
))))
188 (run-hook-with-args 'erc-notify-signoff-hook
189 (or erc-server-announced-name erc-session-server
)
193 'notify_off ?n nick ?m
(erc-network-name)))
196 ;;;; User level command
199 (defun erc-cmd-NOTIFY (&rest args
)
200 "Change `erc-notify-list' or list current notify-list members online.
201 Without args, list the current list of notified people online,
202 with args, toggle notify status of people."
205 ;; Print current notified people (online)
206 (let ((ison (erc-with-server-buffer erc-last-ison
)))
209 nil
'notice
'active
"No ison-list yet!")
212 'notify_current ?l ison
))))
213 ((string= (car args
) "-l")
214 (erc-display-message nil
'notice
'active
215 'notify_list ?l
(mapconcat 'identity erc-notify-list
219 (if (erc-member-ignore-case (car args
) erc-notify-list
)
221 (setq erc-notify-list
(delete (car args
) erc-notify-list
))
222 ;; Remove the nick from the value of erc-last-ison in
223 ;; every server buffer. This prevents seeing a signoff
224 ;; notification for a nick that you have just _removed_
225 ;; from your notify list.
226 (dolist (buf (erc-buffer-list))
227 (with-current-buffer buf
228 (if (erc-server-buffer-p)
229 (setq erc-last-ison
(delete (car args
) erc-last-ison
))))))
230 (setq erc-notify-list
(cons (erc-string-no-properties (car args
))
232 (setq args
(cdr args
)))
235 'notify_list ?l
(mapconcat 'identity erc-notify-list
" "))))
238 (autoload 'pcomplete-erc-all-nicks
"erc-pcomplete")
240 ;; "--" is not a typo.
241 (declare-function pcomplete--here
"pcomplete"
242 (&optional form stub paring form-only
))
245 (defun pcomplete/erc-mode
/NOTIFY
()
247 (pcomplete-here (pcomplete-erc-all-nicks)))
249 (erc-notify-install-message-catalogs)
251 (provide 'erc-notify
)
253 ;;; erc-notify.el ends here
256 ;; indent-tabs-mode: t