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