erc-goodies.el 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. ;; erc-goodies.el --- Collection of ERC modules
  2. ;; Copyright (C) 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: Jorgen Schaefer <forcer@forcix.cx>
  4. ;; Most code is taken verbatim from erc.el, see there for the original
  5. ;; authors.
  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. ;; This provides some small but still useful modes for ERC.
  19. ;;; Code:
  20. (require 'erc)
  21. ;;; Imenu support
  22. (defun erc-imenu-setup ()
  23. "Setup Imenu support in an ERC buffer."
  24. (set (make-local-variable 'imenu-create-index-function)
  25. 'erc-create-imenu-index))
  26. (add-hook 'erc-mode-hook 'erc-imenu-setup)
  27. (autoload 'erc-create-imenu-index "erc-imenu" "Imenu index creation function")
  28. ;;; Automatically scroll to bottom
  29. (defcustom erc-input-line-position nil
  30. "Specify where to position the input line when using `erc-scroll-to-bottom'.
  31. This should be an integer specifying the line of the buffer on which
  32. the input line should stay. A value of \"-1\" would keep the input
  33. line positioned on the last line in the buffer. This is passed as an
  34. argument to `recenter'."
  35. :group 'erc-display
  36. :type '(choice integer (const nil)))
  37. (define-erc-module scrolltobottom nil
  38. "This mode causes the prompt to stay at the end of the window."
  39. ((add-hook 'erc-mode-hook 'erc-add-scroll-to-bottom)
  40. (dolist (buffer (erc-buffer-list))
  41. (with-current-buffer buffer
  42. (erc-add-scroll-to-bottom))))
  43. ((remove-hook 'erc-mode-hook 'erc-add-scroll-to-bottom)
  44. (dolist (buffer (erc-buffer-list))
  45. (with-current-buffer buffer
  46. (remove-hook 'post-command-hook 'erc-scroll-to-bottom t)))))
  47. (defun erc-add-scroll-to-bottom ()
  48. "A hook function for `erc-mode-hook' to recenter output at bottom of window.
  49. If you find that ERC hangs when using this function, try customizing
  50. the value of `erc-input-line-position'.
  51. This works whenever scrolling happens, so it's added to
  52. `window-scroll-functions' rather than `erc-insert-post-hook'."
  53. (add-hook 'post-command-hook 'erc-scroll-to-bottom nil t))
  54. (defun erc-scroll-to-bottom ()
  55. "Recenter WINDOW so that `point' is on the last line.
  56. This is added to `window-scroll-functions' by `erc-add-scroll-to-bottom'.
  57. You can control which line is recentered to by customizing the
  58. variable `erc-input-line-position'."
  59. ;; Temporarily bind resize-mini-windows to nil so that users who have it
  60. ;; set to a non-nil value will not suffer from premature minibuffer
  61. ;; shrinkage due to the below recenter call. I have no idea why this
  62. ;; works, but it solves the problem, and has no negative side effects.
  63. ;; (Fran Litterio, 2003/01/07)
  64. (let ((resize-mini-windows nil))
  65. (save-restriction
  66. (widen)
  67. (when (and erc-insert-marker
  68. ;; we're editing a line. Scroll.
  69. (> (point) erc-insert-marker))
  70. (save-excursion
  71. (goto-char (point-max))
  72. (recenter (or erc-input-line-position -1)))))))
  73. ;;; Make read only
  74. (define-erc-module readonly nil
  75. "This mode causes all inserted text to be read-only."
  76. ((add-hook 'erc-insert-post-hook 'erc-make-read-only)
  77. (add-hook 'erc-send-post-hook 'erc-make-read-only))
  78. ((remove-hook 'erc-insert-post-hook 'erc-make-read-only)
  79. (remove-hook 'erc-send-post-hook 'erc-make-read-only)))
  80. (defun erc-make-read-only ()
  81. "Make all the text in the current buffer read-only.
  82. Put this function on `erc-insert-post-hook' and/or `erc-send-post-hook'."
  83. (put-text-property (point-min) (point-max) 'read-only t)
  84. (put-text-property (point-min) (point-max) 'front-sticky t)
  85. (put-text-property (point-min) (point-max) 'rear-nonsticky t))
  86. ;;; Move to prompt when typing text
  87. (define-erc-module move-to-prompt nil
  88. "This mode causes the point to be moved to the prompt when typing text."
  89. ((add-hook 'erc-mode-hook 'erc-move-to-prompt-setup)
  90. (dolist (buffer (erc-buffer-list))
  91. (with-current-buffer buffer
  92. (erc-move-to-prompt-setup))))
  93. ((remove-hook 'erc-mode-hook 'erc-move-to-prompt-setup)
  94. (dolist (buffer (erc-buffer-list))
  95. (with-current-buffer buffer
  96. (remove-hook 'pre-command-hook 'erc-move-to-prompt t)))))
  97. (defun erc-move-to-prompt ()
  98. "Move the point to the ERC prompt if this is a self-inserting command."
  99. (when (and erc-input-marker (< (point) erc-input-marker)
  100. (eq 'self-insert-command this-command))
  101. (deactivate-mark)
  102. (push-mark)
  103. (goto-char (point-max))))
  104. (defun erc-move-to-prompt-setup ()
  105. "Initialize the move-to-prompt module for XEmacs."
  106. (add-hook 'pre-command-hook 'erc-move-to-prompt nil t))
  107. ;;; Keep place in unvisited channels
  108. (define-erc-module keep-place nil
  109. "Leave point above un-viewed text in other channels."
  110. ((add-hook 'erc-insert-pre-hook 'erc-keep-place))
  111. ((remove-hook 'erc-insert-pre-hook 'erc-keep-place)))
  112. (defun erc-keep-place (ignored)
  113. "Move point away from the last line in a non-selected ERC buffer."
  114. (when (and (not (eq (window-buffer (selected-window))
  115. (current-buffer)))
  116. (>= (point) erc-insert-marker))
  117. (deactivate-mark)
  118. (goto-char (erc-beg-of-input-line))
  119. (forward-line -1)))
  120. ;;; Distinguish non-commands
  121. (defvar erc-noncommands-list '(erc-cmd-ME
  122. erc-cmd-COUNTRY
  123. erc-cmd-SV
  124. erc-cmd-SM
  125. erc-cmd-SMV
  126. erc-cmd-LASTLOG)
  127. "List of commands that are aliases for CTCP ACTION or for ERC messages.
  128. If a command's function symbol is in this list, the typed command
  129. does not appear in the ERC buffer after the user presses ENTER.")
  130. (define-erc-module noncommands nil
  131. "This mode distinguishes non-commands.
  132. Commands listed in `erc-insert-this' know how to display
  133. themselves."
  134. ((add-hook 'erc-send-pre-hook 'erc-send-distinguish-noncommands))
  135. ((remove-hook 'erc-send-pre-hook 'erc-send-distinguish-noncommands)))
  136. (defun erc-send-distinguish-noncommands (str)
  137. "If STR is an ERC non-command, set `erc-insert-this' to nil."
  138. (let* ((command (erc-extract-command-from-line str))
  139. (cmd-fun (and command
  140. (car command))))
  141. (when (and cmd-fun
  142. (not (string-match "\n.+$" str))
  143. (memq cmd-fun erc-noncommands-list))
  144. (setq erc-insert-this nil))))
  145. ;;; IRC control character processing.
  146. (defgroup erc-control-characters nil
  147. "Dealing with control characters."
  148. :group 'erc)
  149. (defcustom erc-interpret-controls-p t
  150. "*If non-nil, display IRC colors and other highlighting effects.
  151. If this is set to the symbol `remove', ERC removes all IRC colors and
  152. highlighting effects. When this variable is non-nil, it can cause Emacs to run
  153. slowly on systems lacking sufficient CPU speed. In chatty channels, or in an
  154. emergency (message flood) it can be turned off to save processing time. See
  155. `erc-toggle-interpret-controls'."
  156. :group 'erc-control-characters
  157. :type '(choice (const :tag "Highlight control characters" t)
  158. (const :tag "Remove control characters" remove)
  159. (const :tag "Display raw control characters" nil)))
  160. (defcustom erc-interpret-mirc-color nil
  161. "*If non-nil, ERC will interpret mIRC color codes."
  162. :group 'erc-control-characters
  163. :type 'boolean)
  164. (defcustom erc-beep-p nil
  165. "Beep if C-g is in the server message.
  166. The value `erc-interpret-controls-p' must also be t for this to work."
  167. :group 'erc-control-characters
  168. :type 'boolean)
  169. (defface erc-bold-face '((t (:bold t)))
  170. "ERC bold face."
  171. :group 'erc-faces)
  172. (defface erc-inverse-face
  173. '((t (:foreground "White" :background "Black")))
  174. "ERC inverse face."
  175. :group 'erc-faces)
  176. (defface erc-underline-face '((t (:underline t)))
  177. "ERC underline face."
  178. :group 'erc-faces)
  179. (defface fg:erc-color-face0 '((t (:foreground "White")))
  180. "ERC face."
  181. :group 'erc-faces)
  182. (defface fg:erc-color-face1 '((t (:foreground "black")))
  183. "ERC face."
  184. :group 'erc-faces)
  185. (defface fg:erc-color-face2 '((t (:foreground "blue4")))
  186. "ERC face."
  187. :group 'erc-faces)
  188. (defface fg:erc-color-face3 '((t (:foreground "green4")))
  189. "ERC face."
  190. :group 'erc-faces)
  191. (defface fg:erc-color-face4 '((t (:foreground "red")))
  192. "ERC face."
  193. :group 'erc-faces)
  194. (defface fg:erc-color-face5 '((t (:foreground "brown")))
  195. "ERC face."
  196. :group 'erc-faces)
  197. (defface fg:erc-color-face6 '((t (:foreground "purple")))
  198. "ERC face."
  199. :group 'erc-faces)
  200. (defface fg:erc-color-face7 '((t (:foreground "orange")))
  201. "ERC face."
  202. :group 'erc-faces)
  203. (defface fg:erc-color-face8 '((t (:foreground "yellow")))
  204. "ERC face."
  205. :group 'erc-faces)
  206. (defface fg:erc-color-face9 '((t (:foreground "green")))
  207. "ERC face."
  208. :group 'erc-faces)
  209. (defface fg:erc-color-face10 '((t (:foreground "lightblue1")))
  210. "ERC face."
  211. :group 'erc-faces)
  212. (defface fg:erc-color-face11 '((t (:foreground "cyan")))
  213. "ERC face."
  214. :group 'erc-faces)
  215. (defface fg:erc-color-face12 '((t (:foreground "blue")))
  216. "ERC face."
  217. :group 'erc-faces)
  218. (defface fg:erc-color-face13 '((t (:foreground "deeppink")))
  219. "ERC face."
  220. :group 'erc-faces)
  221. (defface fg:erc-color-face14 '((t (:foreground "gray50")))
  222. "ERC face."
  223. :group 'erc-faces)
  224. (defface fg:erc-color-face15 '((t (:foreground "gray90")))
  225. "ERC face."
  226. :group 'erc-faces)
  227. (defface bg:erc-color-face0 '((t (:background "White")))
  228. "ERC face."
  229. :group 'erc-faces)
  230. (defface bg:erc-color-face1 '((t (:background "black")))
  231. "ERC face."
  232. :group 'erc-faces)
  233. (defface bg:erc-color-face2 '((t (:background "blue4")))
  234. "ERC face."
  235. :group 'erc-faces)
  236. (defface bg:erc-color-face3 '((t (:background "green4")))
  237. "ERC face."
  238. :group 'erc-faces)
  239. (defface bg:erc-color-face4 '((t (:background "red")))
  240. "ERC face."
  241. :group 'erc-faces)
  242. (defface bg:erc-color-face5 '((t (:background "brown")))
  243. "ERC face."
  244. :group 'erc-faces)
  245. (defface bg:erc-color-face6 '((t (:background "purple")))
  246. "ERC face."
  247. :group 'erc-faces)
  248. (defface bg:erc-color-face7 '((t (:background "orange")))
  249. "ERC face."
  250. :group 'erc-faces)
  251. (defface bg:erc-color-face8 '((t (:background "yellow")))
  252. "ERC face."
  253. :group 'erc-faces)
  254. (defface bg:erc-color-face9 '((t (:background "green")))
  255. "ERC face."
  256. :group 'erc-faces)
  257. (defface bg:erc-color-face10 '((t (:background "lightblue1")))
  258. "ERC face."
  259. :group 'erc-faces)
  260. (defface bg:erc-color-face11 '((t (:background "cyan")))
  261. "ERC face."
  262. :group 'erc-faces)
  263. (defface bg:erc-color-face12 '((t (:background "blue")))
  264. "ERC face."
  265. :group 'erc-faces)
  266. (defface bg:erc-color-face13 '((t (:background "deeppink")))
  267. "ERC face."
  268. :group 'erc-faces)
  269. (defface bg:erc-color-face14 '((t (:background "gray50")))
  270. "ERC face."
  271. :group 'erc-faces)
  272. (defface bg:erc-color-face15 '((t (:background "gray90")))
  273. "ERC face."
  274. :group 'erc-faces)
  275. (defun erc-get-bg-color-face (n)
  276. "Fetches the right face for background color N (0-15)."
  277. (if (stringp n) (setq n (string-to-number n)))
  278. (if (not (numberp n))
  279. (prog1 'default
  280. (erc-error "erc-get-bg-color-face: n is NaN: %S" n))
  281. (when (> n 16)
  282. (erc-log (format " Wrong color: %s" n))
  283. (setq n (mod n 16)))
  284. (cond
  285. ((and (>= n 0) (< n 16))
  286. (intern (concat "bg:erc-color-face" (number-to-string n))))
  287. (t (erc-log (format " Wrong color: %s" n)) 'default))))
  288. (defun erc-get-fg-color-face (n)
  289. "Fetches the right face for foreground color N (0-15)."
  290. (if (stringp n) (setq n (string-to-number n)))
  291. (if (not (numberp n))
  292. (prog1 'default
  293. (erc-error "erc-get-fg-color-face: n is NaN: %S" n))
  294. (when (> n 16)
  295. (erc-log (format " Wrong color: %s" n))
  296. (setq n (mod n 16)))
  297. (cond
  298. ((and (>= n 0) (< n 16))
  299. (intern (concat "fg:erc-color-face" (number-to-string n))))
  300. (t (erc-log (format " Wrong color: %s" n)) 'default))))
  301. (define-erc-module irccontrols nil
  302. "This mode enables the interpretation of IRC control chars."
  303. ((add-hook 'erc-insert-modify-hook 'erc-controls-highlight)
  304. (add-hook 'erc-send-modify-hook 'erc-controls-highlight))
  305. ((remove-hook 'erc-insert-modify-hook 'erc-controls-highlight)
  306. (remove-hook 'erc-send-modify-hook 'erc-controls-highlight)))
  307. (defun erc-controls-interpret (str)
  308. "Return a copy of STR after dealing with IRC control characters.
  309. See `erc-interpret-controls-p' and `erc-interpret-mirc-color' for options."
  310. (when str
  311. (let ((s str))
  312. (cond ((eq erc-interpret-controls-p 'remove)
  313. (erc-controls-strip s))
  314. (erc-interpret-controls-p
  315. (let ((boldp nil)
  316. (inversep nil)
  317. (underlinep nil)
  318. (fg nil)
  319. (bg nil))
  320. (while (string-match erc-controls-highlight-regexp s)
  321. (let ((control (match-string 1 s))
  322. (fg-color (match-string 2 s))
  323. (bg-color (match-string 4 s))
  324. (start (match-beginning 0))
  325. (end (+ (match-beginning 0)
  326. (length (match-string 5 s)))))
  327. (setq s (erc-replace-match-subexpression-in-string
  328. "" s control 1 start))
  329. (cond ((and erc-interpret-mirc-color (or fg-color bg-color))
  330. (setq fg fg-color)
  331. (setq bg bg-color))
  332. ((string= control "\C-b")
  333. (setq boldp (not boldp)))
  334. ((string= control "\C-v")
  335. (setq inversep (not inversep)))
  336. ((string= control "\C-_")
  337. (setq underlinep (not underlinep)))
  338. ((string= control "\C-c")
  339. (setq fg nil
  340. bg nil))
  341. ((string= control "\C-g")
  342. (when erc-beep-p
  343. (ding)))
  344. ((string= control "\C-o")
  345. (setq boldp nil
  346. inversep nil
  347. underlinep nil
  348. fg nil
  349. bg nil))
  350. (t nil))
  351. (erc-controls-propertize
  352. start end boldp inversep underlinep fg bg s)))
  353. s))
  354. (t s)))))
  355. (defun erc-controls-strip (str)
  356. "Return a copy of STR with all IRC control characters removed."
  357. (when str
  358. (let ((s str))
  359. (while (string-match erc-controls-remove-regexp s)
  360. (setq s (replace-match "" nil nil s)))
  361. s)))
  362. (defvar erc-controls-remove-regexp
  363. "\C-b\\|\C-_\\|\C-v\\|\C-g\\|\C-o\\|\C-c[0-9]?[0-9]?\\(,[0-9][0-9]?\\)?"
  364. "Regular expression which matches control characters to remove.")
  365. (defvar erc-controls-highlight-regexp
  366. (concat "\\(\C-b\\|\C-v\\|\C-_\\|\C-g\\|\C-o\\|"
  367. "\C-c\\([0-9][0-9]?\\)?\\(,\\([0-9][0-9]?\\)\\)?\\)"
  368. "\\([^\C-b\C-v\C-_\C-c\C-g\C-o\n]*\\)")
  369. "Regular expression which matches control chars and the text to highlight.")
  370. (defun erc-controls-highlight ()
  371. "Highlight IRC control chars in the buffer.
  372. This is useful for `erc-insert-modify-hook' and `erc-send-modify-hook'.
  373. Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
  374. (goto-char (point-min))
  375. (cond ((eq erc-interpret-controls-p 'remove)
  376. (while (re-search-forward erc-controls-remove-regexp nil t)
  377. (replace-match "")))
  378. (erc-interpret-controls-p
  379. (let ((boldp nil)
  380. (inversep nil)
  381. (underlinep nil)
  382. (fg nil)
  383. (bg nil))
  384. (while (re-search-forward erc-controls-highlight-regexp nil t)
  385. (let ((control (match-string 1))
  386. (fg-color (match-string 2))
  387. (bg-color (match-string 4))
  388. (start (match-beginning 0))
  389. (end (+ (match-beginning 0) (length (match-string 5)))))
  390. (replace-match "" nil nil nil 1)
  391. (cond ((and erc-interpret-mirc-color (or fg-color bg-color))
  392. (setq fg fg-color)
  393. (setq bg bg-color))
  394. ((string= control "\C-b")
  395. (setq boldp (not boldp)))
  396. ((string= control "\C-v")
  397. (setq inversep (not inversep)))
  398. ((string= control "\C-_")
  399. (setq underlinep (not underlinep)))
  400. ((string= control "\C-c")
  401. (setq fg nil
  402. bg nil))
  403. ((string= control "\C-g")
  404. (when erc-beep-p
  405. (ding)))
  406. ((string= control "\C-o")
  407. (setq boldp nil
  408. inversep nil
  409. underlinep nil
  410. fg nil
  411. bg nil))
  412. (t nil))
  413. (erc-controls-propertize start end
  414. boldp inversep underlinep fg bg)))))
  415. (t nil)))
  416. (defun erc-controls-propertize (from to boldp inversep underlinep fg bg
  417. &optional str)
  418. "Prepend properties from IRC control characters between FROM and TO.
  419. If optional argument STR is provided, apply to STR, otherwise prepend properties
  420. to a region in the current buffer."
  421. (font-lock-prepend-text-property
  422. from
  423. to
  424. 'face
  425. (append (if boldp
  426. '(erc-bold-face)
  427. nil)
  428. (if inversep
  429. '(erc-inverse-face)
  430. nil)
  431. (if underlinep
  432. '(erc-underline-face)
  433. nil)
  434. (if fg
  435. (list (erc-get-fg-color-face fg))
  436. nil)
  437. (if bg
  438. (list (erc-get-bg-color-face bg))
  439. nil))
  440. str)
  441. str)
  442. (defun erc-toggle-interpret-controls (&optional arg)
  443. "Toggle interpretation of control sequences in messages.
  444. If ARG is positive, interpretation is turned on.
  445. Else interpretation is turned off."
  446. (interactive "P")
  447. (cond ((and (numberp arg) (> arg 0))
  448. (setq erc-interpret-controls-p t))
  449. (arg (setq erc-interpret-controls-p nil))
  450. (t (setq erc-interpret-controls-p (not erc-interpret-controls-p))))
  451. (message "ERC color interpretation %s"
  452. (if erc-interpret-controls-p "ON" "OFF")))
  453. ;; Smiley
  454. (define-erc-module smiley nil
  455. "This mode translates text-smileys such as :-) into pictures.
  456. This requires the function `smiley-region', which is defined in
  457. smiley.el, which is part of Gnus."
  458. ((add-hook 'erc-insert-modify-hook 'erc-smiley)
  459. (add-hook 'erc-send-modify-hook 'erc-smiley))
  460. ((remove-hook 'erc-insert-modify-hook 'erc-smiley)
  461. (remove-hook 'erc-send-modify-hook 'erc-smiley)))
  462. (defun erc-smiley ()
  463. "Smilify a region.
  464. This function should be used with `erc-insert-modify-hook'."
  465. (when (fboundp 'smiley-region)
  466. (smiley-region (point-min) (point-max))))
  467. ;; Unmorse
  468. (define-erc-module unmorse nil
  469. "This mode causes morse code in the current channel to be unmorsed."
  470. ((add-hook 'erc-insert-modify-hook 'erc-unmorse))
  471. ((remove-hook 'erc-insert-modify-hook 'erc-unmorse)))
  472. (defun erc-unmorse ()
  473. "Unmorse some text.
  474. Add this to `erc-insert-modify-hook' if you happen to be on a
  475. channel that has weird people talking in morse to each other.
  476. See also `unmorse-region'."
  477. (goto-char (point-min))
  478. (when (re-search-forward "[.-]+\\([.-]*/? *\\)+[.-]+/?" nil t)
  479. (save-restriction
  480. (narrow-to-region (match-beginning 0) (match-end 0))
  481. ;; Turn " / " into " "
  482. (goto-char (point-min))
  483. (while (re-search-forward " / " nil t)
  484. (replace-match " "))
  485. ;; Turn "/ " into "/"
  486. (goto-char (point-min))
  487. (while (re-search-forward "/ " nil t)
  488. (replace-match "/"))
  489. ;; Unmorse region
  490. (unmorse-region (point-min) (point-max)))))
  491. ;;; erc-occur
  492. (defun erc-occur (string &optional proc)
  493. "Search for STRING in all buffers related to current server.
  494. If called interactively and prefix argument is given, search on all connected
  495. servers. If called from a program, PROC specifies the server process."
  496. (interactive
  497. (list (read-string "Search for: ")
  498. (if current-prefix-arg
  499. nil erc-server-process)))
  500. (if (fboundp 'multi-occur)
  501. (multi-occur (erc-buffer-list nil proc) string)
  502. (error "`multi-occur' is not defined as a function")))
  503. (provide 'erc-goodies)
  504. ;;; erc-goodies.el ends here