1;;; erc-autoaway.el --- Provides autoaway for ERC 2 3;; Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. 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 10;; GNU Emacs is free software; you can redistribute it and/or modify 11;; it under the terms of the GNU General Public License as published by 12;; the Free Software Foundation; either version 2, or (at your option) 13;; any later version. 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 21;; along with GNU Emacs; see the file COPYING. If not, write to the 22;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23;; Boston, MA 02110-1301, USA. 24 25;;; Commentary: 26 27;; TODO: 28;; - Legacy names: erc-auto-discard-away, erc-auto-set-away 29 30;;; Code: 31 32(require 'erc) 33 34(defgroup erc-autoaway nil 35 "Set yourself automatically away after some idletime and set 36yourself back when you type something." 37 :group 'erc) 38 39(defvar erc-autoaway-idletimer nil 40 "The Emacs idletimer. 41This is only used when `erc-autoaway-idle-method' is set to 'emacs.") 42 43(defvar erc-autoaway-last-sent-time (erc-current-time) 44 "The last time the user sent something.") 45 46(defvar erc-autoaway-caused-away nil 47 "Indicates whether this module was responsible for setting the 48user's away status.") 49 50(eval-when-compile (defvar erc-autoaway-idle-seconds)) 51 52(defun erc-autoaway-reestablish-idletimer () 53 "Reestablish the Emacs idletimer. 54If `erc-autoaway-idle-method' is 'emacs, you must call this 55function each time you change `erc-autoaway-idle-seconds'." 56 (interactive) 57 (when erc-autoaway-idletimer 58 (erc-cancel-timer erc-autoaway-idletimer)) 59 (setq erc-autoaway-idletimer 60 (run-with-idle-timer erc-autoaway-idle-seconds 61 t 62 'erc-autoaway-set-away 63 erc-autoaway-idle-seconds))) 64 65(defun erc-autoaway-some-server-buffer () 66 "Return some ERC server buffer if its connection is alive. 67If none is found, return nil." 68 (car (erc-buffer-list #'erc-open-server-buffer-p))) 69 70(defun erc-autoaway-insinuate-maybe (&optional server &rest ignored) 71 "Add autoaway reset function to `post-command-hook' if at least one 72ERC process is alive. 73 74This is used when `erc-autoaway-idle-method' is 'user." 75 (when (or server (erc-autoaway-some-server-buffer)) 76 (add-hook 'post-command-hook 'erc-autoaway-reset-idle-user))) 77 78(defun erc-autoaway-remove-maybe (&rest ignored) 79 "Remove the autoaway reset function from `post-command-hook' if 80no ERC process is alive. 81 82This is used when `erc-autoaway-idle-method' is 'user." 83 (unless (erc-autoaway-some-server-buffer) 84 (remove-hook 'post-command-hook 'erc-autoaway-reset-idle-user))) 85 86;;;###autoload (autoload 'erc-autoaway-mode "erc-autoaway") 87(define-erc-module autoaway nil 88 "In ERC autoaway mode, you can be set away automatically. 89If `erc-auto-set-away' is set, then you will be set away after 90the number of seconds specified in `erc-autoaway-idle-seconds'. 91 92There are several kinds of being idle: 93 94User idle time measures how long you have not been sending any 95commands to Emacs. This is the default. 96 97Emacs idle time measures how long Emacs has been idle. This is 98currently not useful, since Emacs is non-idle when it handles 99ping-pong with IRC servers. See `erc-autoaway-idle-method' 100for more information. 101 102IRC idle time measures how long since you last sent something (see 103`erc-autoaway-last-sent-time'). 104 105If `erc-auto-discard-away' is set, then typing anything, will 106set you no longer away. 107 108Related variables: `erc-public-away-p' and `erc-away-nickname'." 109 ;; Enable: 110 ((when (boundp 'erc-autoaway-idle-method) 111 (add-hook 'erc-connect-pre-hook 'erc-autoaway-reset-indicators) 112 (setq erc-autoaway-last-sent-time (erc-current-time)) 113 (cond 114 ((eq erc-autoaway-idle-method 'irc) 115 (add-hook 'erc-send-completed-hook 'erc-autoaway-reset-idle-irc) 116 (add-hook 'erc-server-001-functions 'erc-autoaway-reset-idle-irc)) 117 ((eq erc-autoaway-idle-method 'user) 118 (add-hook 'erc-after-connect 'erc-autoaway-insinuate-maybe) 119 (add-hook 'erc-disconnected-hook 'erc-autoaway-remove-maybe) 120 (erc-autoaway-insinuate-maybe)) 121 ((eq erc-autoaway-idle-method 'emacs) 122 (erc-autoaway-reestablish-idletimer))) 123 (add-hook 'erc-timer-hook 'erc-autoaway-possibly-set-away) 124 (add-hook 'erc-server-305-functions 'erc-autoaway-reset-indicators))) 125 ;; Disable: 126 ((when (boundp 'erc-autoaway-idle-method) 127 (remove-hook 'erc-connect-pre-hook 'erc-autoaway-reset-indicators) 128 (cond 129 ((eq erc-autoaway-idle-method 'irc) 130 (remove-hook 'erc-send-completed-hook 'erc-autoaway-reset-idle-irc) 131 (remove-hook 'erc-server-001-functions 'erc-autoaway-reset-idle-irc)) 132 ((eq erc-autoaway-idle-method 'user) 133 (remove-hook 'post-command-hook 'erc-autoaway-reset-idle-user) 134 (remove-hook 'erc-after-connect 'erc-autoaway-insinuate-maybe) 135 (remove-hook 'erc-disconnected-hook 'erc-autoaway-remove-maybe)) 136 ((eq erc-autoaway-idle-method 'emacs) 137 (erc-cancel-timer erc-autoaway-idletimer) 138 (setq erc-autoaway-idletimer nil))) 139 (remove-hook 'erc-timer-hook 'erc-autoaway-possibly-set-away) 140 (remove-hook 'erc-server-305-functions 'erc-autoaway-reset-indicators)))) 141 142(defcustom erc-autoaway-idle-method 'user 143 "*The method used to determine how long you have been idle. 144If 'user, the time of the last command sent to Emacs is used. 145If 'emacs, the idle time in Emacs is used. 146If 'irc, the time of the last IRC command is used. 147 148The time itself is specified by `erc-autoaway-idle-seconds'. 149 150See `erc-autoaway-mode' for more information on the various 151definitions of being idle." 152 :group 'erc-autoaway 153 :type '(choice (const :tag "User idle time" user) 154 (const :tag "Emacs idle time" emacs) 155 (const :tag "Last IRC action" irc)) 156 :set (lambda (sym val) 157 (if erc-autoaway-mode 158 (progn 159 (erc-autoaway-disable) 160 (set sym val) 161 (erc-autoaway-enable)) 162 (set sym val)))) 163 164(defcustom erc-auto-set-away t 165 "*If non-nil, set away after `erc-autoaway-idle-seconds' seconds of idling. 166ERC autoaway mode can set you away when you idle, and set you no 167longer away when you type something. This variable controls whether 168you will be set away when you idle. See `erc-auto-discard-away' for 169the other half." 170 :group 'erc-autoaway 171 :type 'boolean) 172 173(defcustom erc-auto-discard-away t 174 "*If non-nil, sending anything when away automatically discards away state. 175ERC autoaway mode can set you away when you idle, and set you no 176longer away when you type something. This variable controls whether 177you will be set no longer away when you type something. See 178`erc-auto-set-away' for the other half. 179See also `erc-autoaway-no-auto-discard-regexp'." 180 :group 'erc-autoaway 181 :type 'boolean) 182 183(defcustom erc-autoaway-no-auto-discard-regexp "^/g?away.*$" 184 "*Input that matches this will not automatically discard away status. 185See `erc-auto-discard-away'." 186 :group 'erc-autoaway 187 :type 'regexp) 188 189(defcustom erc-autoaway-idle-seconds 1800 190 "*Number of seconds after which ERC will set you automatically away. 191If you are changing this variable using lisp instead of customizing it, 192you have to run `erc-autoaway-reestablish-idletimer' afterwards." 193 :group 'erc-autoaway 194 :set (lambda (sym val) 195 (set-default sym val) 196 (when (eq erc-autoaway-idle-method 'emacs) 197 (erc-autoaway-reestablish-idletimer))) 198 :type 'number) 199 200(defcustom erc-autoaway-message 201 "I'm gone (autoaway after %i seconds of idletime)" 202 "*Message ERC will use when setting you automatically away. 203It is used as a `format' string with the argument of the idletime 204in seconds." 205 :group 'erc-autoaway 206 :type 'string) 207 208(defun erc-autoaway-reset-idle-user (&rest stuff) 209 "Reset the stored user idle time. 210This is one global variable since a user talking on one net can 211talk on another net too." 212 (when erc-auto-discard-away 213 (erc-autoaway-set-back #'erc-autoaway-remove-maybe)) 214 (setq erc-autoaway-last-sent-time (erc-current-time))) 215 216(defun erc-autoaway-reset-idle-irc (line &rest stuff) 217 "Reset the stored IRC idle time. 218This is one global variable since a user talking on one net can 219talk on another net too." 220 (when (and erc-auto-discard-away 221 (stringp line) 222 (not (string-match erc-autoaway-no-auto-discard-regexp line))) 223 (erc-autoaway-set-back)) 224 (setq erc-autoaway-last-sent-time (erc-current-time))) 225 226(defun erc-autoaway-set-back (&optional none-alive-func) 227 "Discard the away state globally. 228 229NONE-ALIVE-FUNC is the function to call if no ERC processes are alive." 230 (let ((server-buffer (erc-autoaway-some-server-buffer))) 231 (if (and erc-autoaway-caused-away 232 (buffer-live-p server-buffer) 233 (with-current-buffer server-buffer erc-away)) 234 (erc-cmd-GAWAY "") 235 (when none-alive-func (funcall none-alive-func))))) 236 237(defun erc-autoaway-some-open-server-buffer () 238 "Return some ERC server buffer if its connection is alive and the 239user is not away. 240If none is found, return nil." 241 (car (erc-buffer-list (lambda () 242 (and (erc-open-server-buffer-p) 243 (not erc-away)))))) 244 245(defun erc-autoaway-possibly-set-away (current-time) 246 "Set autoaway when `erc-auto-set-away' is true and the idletime is 247exceeds `erc-autoaway-idle-seconds'." 248 ;; A test for (erc-server-process-alive) is not necessary, because 249 ;; this function is called from `erc-timer-hook', which is called 250 ;; whenever the server sends something to the client. 251 (when (and erc-auto-set-away 252 (not erc-autoaway-caused-away) 253 (erc-autoaway-some-open-server-buffer)) 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)) 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. 265 266If NOTEST is specified, do not check to see whether there is an 267activer server buffer available." 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. 271 (when (or notest (erc-autoaway-some-open-server-buffer)) 272 (setq erc-autoaway-caused-away t) 273 (erc-cmd-GAWAY (format erc-autoaway-message idle-time)))) 274 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 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: 288 289;; arch-tag: 16fc241e-8358-4b56-9fe2-116bdd0ba3bc 290