Convert consecutive FSF copyright years to ranges.
[bpt/emacs.git] / lisp / erc / erc-join.el
CommitLineData
c6b99621 1;;; erc-join.el --- autojoin channels on connect and reconnects
597993cf 2
73b0cd50 3;; Copyright (C) 2002-2004, 2006-2011 Free Software Foundation, Inc.
597993cf
MB
4
5;; Author: Alex Schroeder <alex@gnu.org>
6;; Keywords: irc
7;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcAutoJoin
8
9;; This file is part of GNU Emacs.
10
4ee57b2a 11;; GNU Emacs is free software: you can redistribute it and/or modify
597993cf 12;; it under the terms of the GNU General Public License as published by
4ee57b2a
GM
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
597993cf
MB
15
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.
20
21;; You should have received a copy of the GNU General Public License
4ee57b2a 22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
597993cf
MB
23
24;;; Commentary:
25
26;; This allows us to customize an `erc-autojoin-channels-alist'. As
27;; we /JOIN and /PART channels, this alist is updated to reflect our
28;; current setup, so that when we reconnect, we rejoin the same
29;; channels. The alist can be customized, so that the customized
30;; value will be used when we reconnect in our next Emacs session.
31
32;;; Code:
33
34(require 'erc)
8508e990 35(eval-when-compile (require 'cl))
597993cf
MB
36
37(defgroup erc-autojoin nil
38 "Enable autojoining."
39 :group 'erc)
40
c6b99621 41;;;###autoload (autoload 'erc-autojoin-mode "erc-join" nil t)
597993cf
MB
42(define-erc-module autojoin nil
43 "Makes ERC autojoin on connects and reconnects."
44 ((add-hook 'erc-after-connect 'erc-autojoin-channels)
8a8d54cd 45 (add-hook 'erc-nickserv-identified-hook 'erc-autojoin-after-ident)
597993cf
MB
46 (add-hook 'erc-server-JOIN-functions 'erc-autojoin-add)
47 (add-hook 'erc-server-PART-functions 'erc-autojoin-remove))
48 ((remove-hook 'erc-after-connect 'erc-autojoin-channels)
8a8d54cd 49 (remove-hook 'erc-nickserv-identified-hook 'erc-autojoin-after-ident)
597993cf
MB
50 (remove-hook 'erc-server-JOIN-functions 'erc-autojoin-add)
51 (remove-hook 'erc-server-PART-functions 'erc-autojoin-remove)))
52
53(defcustom erc-autojoin-channels-alist nil
54 "Alist of channels to autojoin on IRC networks.
55Every element in the alist has the form (SERVER . CHANNELS).
56SERVER is a regexp matching the server, and channels is the
57list of channels to join.
58
59Customize this variable to set the value for your first connect.
60Once you are connected and join and part channels, this alist
61keeps track of what channels you are on, and will join them
62again when you get disconnected. When you restart Emacs, however,
63those changes are lost, and the customization you saved the last
64time is used again."
65 :group 'erc-autojoin
66 :type '(repeat (cons :tag "Server"
67 (regexp :tag "Name")
68 (repeat :tag "Channels"
69 (string :tag "Name")))))
70
8a8d54cd
VD
71(defcustom erc-autojoin-timing 'connect
72 "When ERC should attempt to autojoin a channel.
73If the value is `connect', autojoin immediately on connecting.
74If the value is `ident', autojoin after successful NickServ
75identification, or after `erc-autojoin-delay' seconds.
76Any other value means the same as `connect'."
77 :group 'erc-autojoin
78 :type '(choice (const :tag "On Connection" 'connect)
79 (const :tag "When Identified" 'ident)))
80
81(defcustom erc-autojoin-delay 30
82 "Number of seconds to wait before attempting to autojoin channels.
83This only takes effect if `erc-autojoin-timing' is `ident'.
84If NickServ identification occurs before this delay expires, ERC
85autojoins immediately at that time."
86 :group 'erc-autojoin
87 :type 'integer)
88
597993cf
MB
89(defcustom erc-autojoin-domain-only t
90 "Truncate host name to the domain name when joining a server.
91If non-nil, and a channel on the server a.b.c is joined, then
92only b.c is used as the server for `erc-autojoin-channels-alist'.
93This is important for networks that redirect you to other
94servers, presumably in the same domain."
95 :group 'erc-autojoin
96 :type 'boolean)
97
8a8d54cd
VD
98(defvar erc--autojoin-timer nil)
99(make-variable-buffer-local 'erc--autojoin-timer)
100
101(defun erc-autojoin-channels-delayed (server nick buffer)
102 "Attempt to autojoin channels.
103This is called from a timer set up by `erc-autojoin-channels'."
104 (if erc--autojoin-timer
105 (setq erc--autojoin-timer
106 (erc-cancel-timer erc--autojoin-timer)))
107 (with-current-buffer buffer
108 ;; Don't kick of another delayed autojoin or try to wait for
109 ;; another ident response:
110 (let ((erc-autojoin-delay -1)
111 (erc-autojoin-timing 'connect))
112 (erc-log "Delayed autojoin started (no ident success detected yet)")
113 (erc-autojoin-channels server nick))))
114
115(defun erc-autojoin-after-ident (network nick)
116 "Autojoin channels in `erc-autojoin-channels-alist'.
117This function is run from `erc-nickserv-identified-hook'."
118 (if erc--autojoin-timer
119 (setq erc--autojoin-timer
120 (erc-cancel-timer erc--autojoin-timer)))
121 (when (eq erc-autojoin-timing 'ident)
122 (let ((server (or erc-server-announced-name erc-session-server))
123 (joined (mapcar (lambda (buf)
124 (with-current-buffer buf (erc-default-target)))
125 (erc-channel-list erc-server-process))))
126 ;; We may already be in these channels, e.g. because the
127 ;; autojoin timer went off.
128 (dolist (l erc-autojoin-channels-alist)
129 (when (string-match (car l) server)
130 (dolist (chan (cdr l))
131 (unless (erc-member-ignore-case chan joined)
132 (erc-server-send (concat "join " chan))))))))
133 nil)
134
597993cf
MB
135(defun erc-autojoin-channels (server nick)
136 "Autojoin channels in `erc-autojoin-channels-alist'."
8a8d54cd
VD
137 (if (eq erc-autojoin-timing 'ident)
138 ;; Prepare the delayed autojoin timer, in case ident doesn't
139 ;; happen within the allotted time limit:
140 (when (> erc-autojoin-delay 0)
141 (setq erc--autojoin-timer
142 (run-with-timer erc-autojoin-delay nil
143 'erc-autojoin-channels-delayed
144 server nick (current-buffer))))
145 ;; `erc-autojoin-timing' is `connect':
146 (dolist (l erc-autojoin-channels-alist)
147 (when (string-match (car l) server)
148 (dolist (chan (cdr l))
149 (erc-server-send (concat "join " chan))))))
150 ;; Return nil to avoid stomping on any other hook funcs.
151 nil)
597993cf
MB
152
153(defun erc-autojoin-add (proc parsed)
154 "Add the channel being joined to `erc-autojoin-channels-alist'."
155 (let* ((chnl (erc-response.contents parsed))
156 (nick (car (erc-parse-user (erc-response.sender parsed))))
157 (server (with-current-buffer (process-buffer proc)
158 (or erc-server-announced-name erc-session-server))))
159 (when (erc-current-nick-p nick)
160 (when (and erc-autojoin-domain-only
21bc768b 161 (string-match "[^.\n]+\\.\\([^.\n]+\\.[^.\n]+\\)$" server))
597993cf
MB
162 (setq server (match-string 1 server)))
163 (let ((elem (assoc server erc-autojoin-channels-alist)))
164 (if elem
165 (unless (member chnl (cdr elem))
166 (setcdr elem (cons chnl (cdr elem))))
167 (setq erc-autojoin-channels-alist
168 (cons (list server chnl)
169 erc-autojoin-channels-alist))))))
170 ;; We must return nil to tell ERC to continue running the other
171 ;; functions.
172 nil)
173
174;; (erc-parse-user "kensanata!~user@dclient217-162-233-228.hispeed.ch")
175
176(defun erc-autojoin-remove (proc parsed)
177 "Remove the channel being left from `erc-autojoin-channels-alist'."
178 (let* ((chnl (car (erc-response.command-args parsed)))
179 (nick (car (erc-parse-user (erc-response.sender parsed))))
180 (server (with-current-buffer (process-buffer proc)
181 (or erc-server-announced-name erc-session-server))))
182 (when (erc-current-nick-p nick)
183 (when (and erc-autojoin-domain-only
21bc768b 184 (string-match "[^.\n]+\\.\\([^.\n]+\\.[^.\n]+\\)$" server))
597993cf
MB
185 (setq server (match-string 1 server)))
186 (let ((elem (assoc server erc-autojoin-channels-alist)))
187 (when elem
188 (setcdr elem (delete chnl (cdr elem)))
189 (unless (cdr elem)
190 (setq erc-autojoin-channels-alist
191 (delete elem erc-autojoin-channels-alist)))))))
192 ;; We must return nil to tell ERC to continue running the other
193 ;; functions.
194 nil)
195
c6b99621 196(provide 'erc-join)
597993cf 197
c6b99621 198;;; erc-join.el ends here
597993cf
MB
199;;
200;; Local Variables:
201;; indent-tabs-mode: t
202;; tab-width: 8
203;; End:
204