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