erc-autoaway.el 11 KB

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