Commit | Line | Data |
---|---|---|
597993cf MB |
1 | ;;; erc-autoaway.el --- Provides autoaway for ERC |
2 | ||
95df8112 | 3 | ;; Copyright (C) 2002-2004, 2006-2011 Free Software Foundation, Inc. |
597993cf MB |
4 | |
5 | ;; Author: Jorgen Schaefer <forcer@forcix.cx> | |
6 | ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcAutoAway | |
7 | ||
8 | ;; This file is part of GNU Emacs. | |
9 | ||
4ee57b2a | 10 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
597993cf | 11 | ;; it under the terms of the GNU General Public License as published by |
4ee57b2a GM |
12 | ;; the Free Software Foundation, either version 3 of the License, or |
13 | ;; (at your option) any later version. | |
597993cf MB |
14 | |
15 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ;; GNU General Public License for more details. | |
19 | ||
20 | ;; You should have received a copy of the GNU General Public License | |
4ee57b2a | 21 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
597993cf MB |
22 | |
23 | ;;; Commentary: | |
24 | ||
25 | ;; TODO: | |
26 | ;; - Legacy names: erc-auto-discard-away, erc-auto-set-away | |
27 | ||
28 | ;;; Code: | |
29 | ||
30 | (require 'erc) | |
31 | ||
32 | (defgroup erc-autoaway nil | |
33 | "Set yourself automatically away after some idletime and set | |
34 | yourself back when you type something." | |
35 | :group 'erc) | |
36 | ||
37 | (defvar erc-autoaway-idletimer nil | |
38 | "The Emacs idletimer. | |
83dc6995 | 39 | This is only used when `erc-autoaway-idle-method' is set to 'emacs.") |
597993cf | 40 | |
ff59d266 MB |
41 | (defvar erc-autoaway-last-sent-time (erc-current-time) |
42 | "The last time the user sent something.") | |
43 | ||
44 | (defvar erc-autoaway-caused-away nil | |
45 | "Indicates whether this module was responsible for setting the | |
46 | user's away status.") | |
47 | ||
07da87e9 | 48 | (defvar erc-autoaway-idle-seconds) |
ff59d266 MB |
49 | |
50 | (defun erc-autoaway-reestablish-idletimer () | |
51 | "Reestablish the Emacs idletimer. | |
52 | If `erc-autoaway-idle-method' is 'emacs, you must call this | |
53 | function each time you change `erc-autoaway-idle-seconds'." | |
54 | (interactive) | |
55 | (when erc-autoaway-idletimer | |
56 | (erc-cancel-timer erc-autoaway-idletimer)) | |
57 | (setq erc-autoaway-idletimer | |
58 | (run-with-idle-timer erc-autoaway-idle-seconds | |
59 | t | |
60 | 'erc-autoaway-set-away | |
61 | erc-autoaway-idle-seconds))) | |
62 | ||
63 | (defun erc-autoaway-some-server-buffer () | |
64 | "Return some ERC server buffer if its connection is alive. | |
65 | If none is found, return nil." | |
66 | (car (erc-buffer-list #'erc-open-server-buffer-p))) | |
67 | ||
68 | (defun erc-autoaway-insinuate-maybe (&optional server &rest ignored) | |
69 | "Add autoaway reset function to `post-command-hook' if at least one | |
70 | ERC process is alive. | |
71 | ||
72 | This is used when `erc-autoaway-idle-method' is 'user." | |
73 | (when (or server (erc-autoaway-some-server-buffer)) | |
74 | (add-hook 'post-command-hook 'erc-autoaway-reset-idle-user))) | |
75 | ||
76 | (defun erc-autoaway-remove-maybe (&rest ignored) | |
77 | "Remove the autoaway reset function from `post-command-hook' if | |
78 | no ERC process is alive. | |
79 | ||
80 | This is used when `erc-autoaway-idle-method' is 'user." | |
81 | (unless (erc-autoaway-some-server-buffer) | |
82 | (remove-hook 'post-command-hook 'erc-autoaway-reset-idle-user))) | |
83 | ||
597993cf MB |
84 | ;;;###autoload (autoload 'erc-autoaway-mode "erc-autoaway") |
85 | (define-erc-module autoaway nil | |
86 | "In ERC autoaway mode, you can be set away automatically. | |
87 | If `erc-auto-set-away' is set, then you will be set away after | |
88 | the number of seconds specified in `erc-autoaway-idle-seconds'. | |
89 | ||
90 | There are several kinds of being idle: | |
91 | ||
0b6bb130 MB |
92 | User idle time measures how long you have not been sending any |
93 | commands to Emacs. This is the default. | |
597993cf MB |
94 | |
95 | Emacs idle time measures how long Emacs has been idle. This is | |
96 | currently not useful, since Emacs is non-idle when it handles | |
0b6bb130 MB |
97 | ping-pong with IRC servers. See `erc-autoaway-idle-method' |
98 | for more information. | |
597993cf | 99 | |
0b6bb130 MB |
100 | IRC idle time measures how long since you last sent something (see |
101 | `erc-autoaway-last-sent-time'). | |
597993cf MB |
102 | |
103 | If `erc-auto-discard-away' is set, then typing anything, will | |
104 | set you no longer away. | |
105 | ||
106 | Related variables: `erc-public-away-p' and `erc-away-nickname'." | |
107 | ;; Enable: | |
0b6bb130 | 108 | ((when (boundp 'erc-autoaway-idle-method) |
ff59d266 MB |
109 | (add-hook 'erc-connect-pre-hook 'erc-autoaway-reset-indicators) |
110 | (setq erc-autoaway-last-sent-time (erc-current-time)) | |
0b6bb130 MB |
111 | (cond |
112 | ((eq erc-autoaway-idle-method 'irc) | |
113 | (add-hook 'erc-send-completed-hook 'erc-autoaway-reset-idle-irc) | |
114 | (add-hook 'erc-server-001-functions 'erc-autoaway-reset-idle-irc)) | |
115 | ((eq erc-autoaway-idle-method 'user) | |
ff59d266 MB |
116 | (add-hook 'erc-after-connect 'erc-autoaway-insinuate-maybe) |
117 | (add-hook 'erc-disconnected-hook 'erc-autoaway-remove-maybe) | |
118 | (erc-autoaway-insinuate-maybe)) | |
0b6bb130 MB |
119 | ((eq erc-autoaway-idle-method 'emacs) |
120 | (erc-autoaway-reestablish-idletimer))) | |
121 | (add-hook 'erc-timer-hook 'erc-autoaway-possibly-set-away) | |
122 | (add-hook 'erc-server-305-functions 'erc-autoaway-reset-indicators))) | |
597993cf | 123 | ;; Disable: |
0b6bb130 | 124 | ((when (boundp 'erc-autoaway-idle-method) |
ff59d266 | 125 | (remove-hook 'erc-connect-pre-hook 'erc-autoaway-reset-indicators) |
0b6bb130 MB |
126 | (cond |
127 | ((eq erc-autoaway-idle-method 'irc) | |
128 | (remove-hook 'erc-send-completed-hook 'erc-autoaway-reset-idle-irc) | |
129 | (remove-hook 'erc-server-001-functions 'erc-autoaway-reset-idle-irc)) | |
130 | ((eq erc-autoaway-idle-method 'user) | |
ff59d266 MB |
131 | (remove-hook 'post-command-hook 'erc-autoaway-reset-idle-user) |
132 | (remove-hook 'erc-after-connect 'erc-autoaway-insinuate-maybe) | |
133 | (remove-hook 'erc-disconnected-hook 'erc-autoaway-remove-maybe)) | |
0b6bb130 MB |
134 | ((eq erc-autoaway-idle-method 'emacs) |
135 | (erc-cancel-timer erc-autoaway-idletimer) | |
136 | (setq erc-autoaway-idletimer nil))) | |
137 | (remove-hook 'erc-timer-hook 'erc-autoaway-possibly-set-away) | |
138 | (remove-hook 'erc-server-305-functions 'erc-autoaway-reset-indicators)))) | |
139 | ||
140 | (defcustom erc-autoaway-idle-method 'user | |
141 | "*The method used to determine how long you have been idle. | |
142 | If 'user, the time of the last command sent to Emacs is used. | |
143 | If 'emacs, the idle time in Emacs is used. | |
144 | If 'irc, the time of the last IRC command is used. | |
145 | ||
146 | The time itself is specified by `erc-autoaway-idle-seconds'. | |
147 | ||
148 | See `erc-autoaway-mode' for more information on the various | |
149 | definitions of being idle." | |
150 | :group 'erc-autoaway | |
151 | :type '(choice (const :tag "User idle time" user) | |
152 | (const :tag "Emacs idle time" emacs) | |
153 | (const :tag "Last IRC action" irc)) | |
154 | :set (lambda (sym val) | |
ff59d266 MB |
155 | (if erc-autoaway-mode |
156 | (progn | |
157 | (erc-autoaway-disable) | |
158 | (set sym val) | |
159 | (erc-autoaway-enable)) | |
160 | (set sym val)))) | |
597993cf MB |
161 | |
162 | (defcustom erc-auto-set-away t | |
163 | "*If non-nil, set away after `erc-autoaway-idle-seconds' seconds of idling. | |
164 | ERC autoaway mode can set you away when you idle, and set you no | |
165 | longer away when you type something. This variable controls whether | |
166 | you will be set away when you idle. See `erc-auto-discard-away' for | |
167 | the other half." | |
168 | :group 'erc-autoaway | |
169 | :type 'boolean) | |
170 | ||
171 | (defcustom erc-auto-discard-away t | |
172 | "*If non-nil, sending anything when away automatically discards away state. | |
173 | ERC autoaway mode can set you away when you idle, and set you no | |
174 | longer away when you type something. This variable controls whether | |
175 | you will be set no longer away when you type something. See | |
176 | `erc-auto-set-away' for the other half. | |
177 | See also `erc-autoaway-no-auto-discard-regexp'." | |
178 | :group 'erc-autoaway | |
179 | :type 'boolean) | |
180 | ||
181 | (defcustom erc-autoaway-no-auto-discard-regexp "^/g?away.*$" | |
182 | "*Input that matches this will not automatically discard away status. | |
183 | See `erc-auto-discard-away'." | |
184 | :group 'erc-autoaway | |
185 | :type 'regexp) | |
186 | ||
597993cf MB |
187 | (defcustom erc-autoaway-idle-seconds 1800 |
188 | "*Number of seconds after which ERC will set you automatically away. | |
189 | If you are changing this variable using lisp instead of customizing it, | |
190 | you have to run `erc-autoaway-reestablish-idletimer' afterwards." | |
191 | :group 'erc-autoaway | |
192 | :set (lambda (sym val) | |
193 | (set-default sym val) | |
0b6bb130 | 194 | (when (eq erc-autoaway-idle-method 'emacs) |
597993cf MB |
195 | (erc-autoaway-reestablish-idletimer))) |
196 | :type 'number) | |
197 | ||
198 | (defcustom erc-autoaway-message | |
199 | "I'm gone (autoaway after %i seconds of idletime)" | |
0b6bb130 MB |
200 | "*Message ERC will use when setting you automatically away. |
201 | It is used as a `format' string with the argument of the idletime | |
202 | in seconds." | |
597993cf MB |
203 | :group 'erc-autoaway |
204 | :type 'string) | |
205 | ||
0b6bb130 MB |
206 | (defun erc-autoaway-reset-idle-user (&rest stuff) |
207 | "Reset the stored user idle time. | |
208 | This is one global variable since a user talking on one net can | |
209 | talk on another net too." | |
210 | (when erc-auto-discard-away | |
ff59d266 | 211 | (erc-autoaway-set-back #'erc-autoaway-remove-maybe)) |
0b6bb130 MB |
212 | (setq erc-autoaway-last-sent-time (erc-current-time))) |
213 | ||
214 | (defun erc-autoaway-reset-idle-irc (line &rest stuff) | |
215 | "Reset the stored IRC idle time. | |
216 | This is one global variable since a user talking on one net can | |
217 | talk on another net too." | |
597993cf MB |
218 | (when (and erc-auto-discard-away |
219 | (stringp line) | |
220 | (not (string-match erc-autoaway-no-auto-discard-regexp line))) | |
0b6bb130 | 221 | (erc-autoaway-set-back)) |
597993cf MB |
222 | (setq erc-autoaway-last-sent-time (erc-current-time))) |
223 | ||
ff59d266 MB |
224 | (defun erc-autoaway-set-back (&optional none-alive-func) |
225 | "Discard the away state globally. | |
226 | ||
227 | NONE-ALIVE-FUNC is the function to call if no ERC processes are alive." | |
228 | (let ((server-buffer (erc-autoaway-some-server-buffer))) | |
229 | (if (and erc-autoaway-caused-away | |
230 | (buffer-live-p server-buffer) | |
231 | (with-current-buffer server-buffer erc-away)) | |
232 | (erc-cmd-GAWAY "") | |
233 | (when none-alive-func (funcall none-alive-func))))) | |
234 | ||
235 | (defun erc-autoaway-some-open-server-buffer () | |
236 | "Return some ERC server buffer if its connection is alive and the | |
237 | user is not away. | |
238 | If none is found, return nil." | |
239 | (car (erc-buffer-list (lambda () | |
240 | (and (erc-open-server-buffer-p) | |
241 | (not erc-away)))))) | |
597993cf MB |
242 | |
243 | (defun erc-autoaway-possibly-set-away (current-time) | |
244 | "Set autoaway when `erc-auto-set-away' is true and the idletime is | |
245 | exceeds `erc-autoaway-idle-seconds'." | |
246 | ;; A test for (erc-server-process-alive) is not necessary, because | |
247 | ;; this function is called from `erc-timer-hook', which is called | |
248 | ;; whenever the server sends something to the client. | |
2131c501 MO |
249 | (when (and erc-server-connected |
250 | erc-auto-set-away | |
83dc6995 | 251 | (not erc-autoaway-caused-away) |
ff59d266 | 252 | (erc-autoaway-some-open-server-buffer)) |
597993cf MB |
253 | (let ((idle-time (erc-time-diff erc-autoaway-last-sent-time |
254 | current-time))) | |
255 | (when (>= idle-time erc-autoaway-idle-seconds) | |
256 | (erc-display-message | |
257 | nil 'notice nil | |
258 | (format "Setting automatically away after %i seconds of idle-time" | |
259 | idle-time)) | |
ff59d266 MB |
260 | (erc-autoaway-set-away idle-time t))))) |
261 | ||
262 | (defun erc-autoaway-set-away (idle-time &optional notest) | |
263 | "Set the away state globally. | |
597993cf | 264 | |
ff59d266 MB |
265 | If NOTEST is specified, do not check to see whether there is an |
266 | activer server buffer available." | |
597993cf MB |
267 | ;; Note that the idle timer runs, even when Emacs is inactive. In |
268 | ;; order to prevent flooding when we connect, we test for an | |
269 | ;; existing process. | |
ff59d266 | 270 | (when (or notest (erc-autoaway-some-open-server-buffer)) |
0b6bb130 | 271 | (setq erc-autoaway-caused-away t) |
597993cf MB |
272 | (erc-cmd-GAWAY (format erc-autoaway-message idle-time)))) |
273 | ||
0b6bb130 MB |
274 | (defun erc-autoaway-reset-indicators (&rest stuff) |
275 | "Reset indicators used by the erc-autoaway module." | |
276 | (setq erc-autoaway-last-sent-time (erc-current-time)) | |
277 | (setq erc-autoaway-caused-away nil)) | |
278 | ||
597993cf MB |
279 | (provide 'erc-autoaway) |
280 | ||
281 | ;;; erc-autoaway.el ends here | |
282 | ;; | |
283 | ;; Local Variables: | |
284 | ;; indent-tabs-mode: t | |
285 | ;; tab-width: 8 | |
286 | ;; End: | |
287 |