Commit | Line | Data |
---|---|---|
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. | |
55 | Every element in the alist has the form (SERVER . CHANNELS). | |
56 | SERVER is a regexp matching the server, and channels is the | |
57 | list of channels to join. | |
58 | ||
59 | Customize this variable to set the value for your first connect. | |
60 | Once you are connected and join and part channels, this alist | |
61 | keeps track of what channels you are on, and will join them | |
62 | again when you get disconnected. When you restart Emacs, however, | |
63 | those changes are lost, and the customization you saved the last | |
64 | time 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. | |
73 | If the value is `connect', autojoin immediately on connecting. | |
74 | If the value is `ident', autojoin after successful NickServ | |
75 | identification, or after `erc-autojoin-delay' seconds. | |
76 | Any 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. | |
83 | This only takes effect if `erc-autojoin-timing' is `ident'. | |
84 | If NickServ identification occurs before this delay expires, ERC | |
85 | autojoins 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. | |
91 | If non-nil, and a channel on the server a.b.c is joined, then | |
92 | only b.c is used as the server for `erc-autojoin-channels-alist'. | |
93 | This is important for networks that redirect you to other | |
94 | servers, 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. | |
103 | This 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'. | |
117 | This 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 |