aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKelvin White2014-06-19 12:56:18 -0400
committerKelvin White2014-06-19 12:56:18 -0400
commit7a4114e4e02fde96e76a519bc2b1848c02dd9517 (patch)
tree780cc3e4301db5b47d546833c8dd0c0548812907
parentd10a551d9d6b25de0f46c18a30b7399c993d498e (diff)
downloademacs-7a4114e4e02fde96e76a519bc2b1848c02dd9517.tar.gz
emacs-7a4114e4e02fde96e76a519bc2b1848c02dd9517.zip
ERC: Better user mode support
Fixes: debbugs:17755
-rw-r--r--lisp/erc/ChangeLog15
-rw-r--r--lisp/erc/erc-backend.el12
-rw-r--r--lisp/erc/erc.el3944
3 files changed, 2040 insertions, 1931 deletions
diff --git a/lisp/erc/ChangeLog b/lisp/erc/ChangeLog
index defa6f93e71..2e5d2772c58 100644
--- a/lisp/erc/ChangeLog
+++ b/lisp/erc/ChangeLog
@@ -1,3 +1,17 @@
12014-06-19 Kelvin White <kelvin.white77@gmail.com>
2
3 * erc-backend.el: Handle user modes in relevant server responses
4 * erc.el: Better user mode support.
5 (erc-channel-user): Add members for new modes.
6 (erc-channel-member-halfop-p, erc-channel-user-admin-p)
7 (erc-channel-user-owner-p): Use new struct members.
8 (erc-format-nick, erc-format-@nick): Display user modes as nick prefix.
9 (erc-nick-prefix-face, erc-my-nick-prefix-face): Add new faces
10 (erc-get-user-mode-prefix): Return symbol for mode prefix.
11 (erc-update-channel-member, erc-update-current-channel-member)
12 (erc-channel-receive-names): Update channel users.
13 (erc-nick-at-point): Return correct user info.
14
12014-04-04 Stefan Monnier <monnier@iro.umontreal.ca> 152014-04-04 Stefan Monnier <monnier@iro.umontreal.ca>
2 16
3 * erc.el (erc-invite-only-mode, erc-toggle-channel-mode): Simplify. 17 * erc.el (erc-invite-only-mode, erc-toggle-channel-mode): Simplify.
@@ -615,4 +629,3 @@ See ChangeLog.08 for earlier changes.
615;; coding: utf-8 629;; coding: utf-8
616;; add-log-time-zone-rule: t 630;; add-log-time-zone-rule: t
617;; End: 631;; End:
618
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index 01fdfc54d1d..8751a194e3b 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -679,7 +679,7 @@ Conditionally try to reconnect and take appropriate action."
679 (when (buffer-live-p buf) 679 (when (buffer-live-p buf)
680 (with-current-buffer buf 680 (with-current-buffer buf
681 (erc-log (format 681 (erc-log (format
682 "SENTINEL: proc: %S status: %S event: %S (quitting: %S)" 682 "SENTINEL: proc: %S status: %S event: %S (quitting: %S)"
683 cproc (process-status cproc) event erc-server-quitting)) 683 cproc (process-status cproc) event erc-server-quitting))
684 (if (string-match "^open" event) 684 (if (string-match "^open" event)
685 ;; newly opened connection (no wait) 685 ;; newly opened connection (no wait)
@@ -1208,7 +1208,6 @@ add things to `%s' instead."
1208 parsed 'notice 'active 1208 parsed 'notice 'active
1209 'INVITE ?n nick ?u login ?h host ?c chnl))))) 1209 'INVITE ?n nick ?u login ?h host ?c chnl)))))
1210 1210
1211
1212(define-erc-response-handler (JOIN) 1211(define-erc-response-handler (JOIN)
1213 "Handle join messages." 1212 "Handle join messages."
1214 nil 1213 nil
@@ -1244,7 +1243,7 @@ add things to `%s' instead."
1244 (erc-format-message 1243 (erc-format-message
1245 'JOIN ?n nick ?u login ?h host ?c chnl)))))) 1244 'JOIN ?n nick ?u login ?h host ?c chnl))))))
1246 (when buffer (set-buffer buffer)) 1245 (when buffer (set-buffer buffer))
1247 (erc-update-channel-member chnl nick nick t nil nil host login) 1246 (erc-update-channel-member chnl nick nick t nil nil nil nil nil host login)
1248 ;; on join, we want to stay in the new channel buffer 1247 ;; on join, we want to stay in the new channel buffer
1249 ;;(set-buffer ob) 1248 ;;(set-buffer ob)
1250 (erc-display-message parsed nil buffer str)))))) 1249 (erc-display-message parsed nil buffer str))))))
@@ -1413,7 +1412,7 @@ add things to `%s' instead."
1413 ;; message. We will accumulate private identities indefinitely 1412 ;; message. We will accumulate private identities indefinitely
1414 ;; at this point. 1413 ;; at this point.
1415 (erc-update-channel-member (if privp nick tgt) nick nick 1414 (erc-update-channel-member (if privp nick tgt) nick nick
1416 privp nil nil host login nil nil t) 1415 privp nil nil nil nil nil host login nil nil t)
1417 (let ((cdata (erc-get-channel-user nick))) 1416 (let ((cdata (erc-get-channel-user nick)))
1418 (setq fnick (funcall erc-format-nick-function 1417 (setq fnick (funcall erc-format-nick-function
1419 (car cdata) (cdr cdata)))))) 1418 (car cdata) (cdr cdata))))))
@@ -1470,7 +1469,7 @@ add things to `%s' instead."
1470 (current-time)))) 1469 (current-time))))
1471 (pcase-let ((`(,nick ,login ,host) 1470 (pcase-let ((`(,nick ,login ,host)
1472 (erc-parse-user (erc-response.sender parsed)))) 1471 (erc-parse-user (erc-response.sender parsed))))
1473 (erc-update-channel-member ch nick nick nil nil nil host login) 1472 (erc-update-channel-member ch nick nick nil nil nil nil nil nil host login)
1474 (erc-update-channel-topic ch (format "%s\C-o (%s, %s)" topic nick time)) 1473 (erc-update-channel-topic ch (format "%s\C-o (%s, %s)" topic nick time))
1475 (erc-display-message parsed 'notice (erc-get-buffer ch proc) 1474 (erc-display-message parsed 'notice (erc-get-buffer ch proc)
1476 'TOPIC ?n nick ?u login ?h host 1475 'TOPIC ?n nick ?u login ?h host
@@ -1800,8 +1799,7 @@ See `erc-display-server-message'." nil
1800 (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" full-name) 1799 (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" full-name)
1801 (setq hopcount (match-string 1 full-name)) 1800 (setq hopcount (match-string 1 full-name))
1802 (setq full-name (match-string 2 full-name))) 1801 (setq full-name (match-string 2 full-name)))
1803 (erc-update-channel-member channel nick nick nil nil nil host 1802 (erc-update-channel-member channel nick nick nil nil nil nil nil nil host user full-name)
1804 user full-name)
1805 (erc-display-message parsed 'notice 'active 's352 1803 (erc-display-message parsed 'notice 'active 's352
1806 ?c channel ?n nick ?a away-flag 1804 ?c channel ?n nick ?a away-flag
1807 ?u user ?h host ?f full-name)))) 1805 ?u user ?h host ?f full-name))))
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index dbbc37e1eb7..987c141d1ef 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -9,6 +9,7 @@
9;; Andreas Fuchs (afs@void.at) 9;; Andreas Fuchs (afs@void.at)
10;; Gergely Nagy (algernon@midgard.debian.net) 10;; Gergely Nagy (algernon@midgard.debian.net)
11;; David Edmondson (dme@dme.org) 11;; David Edmondson (dme@dme.org)
12;; Kelvin White <kelvin.white77@gmail.com>
12;; Maintainer: emacs-devel@gnu.org 13;; Maintainer: emacs-devel@gnu.org
13;; Keywords: IRC, chat, client, Internet 14;; Keywords: IRC, chat, client, Internet
14;; Version: 5.3 15;; Version: 5.3
@@ -143,7 +144,7 @@ See function `erc-compute-server' for more details on connection
143parameters and authentication." 144parameters and authentication."
144 :group 'erc 145 :group 'erc
145 :type '(choice (const :tag "None" nil) 146 :type '(choice (const :tag "None" nil)
146 (string :tag "Server"))) 147 (string :tag "Server")))
147 148
148(defcustom erc-port nil 149(defcustom erc-port nil
149 "IRC port to use if not specified. 150 "IRC port to use if not specified.
@@ -151,8 +152,8 @@ parameters and authentication."
151This can be either a string or a number." 152This can be either a string or a number."
152 :group 'erc 153 :group 'erc
153 :type '(choice (const :tag "None" nil) 154 :type '(choice (const :tag "None" nil)
154 (integer :tag "Port number") 155 (integer :tag "Port number")
155 (string :tag "Port string"))) 156 (string :tag "Port string")))
156 157
157(defcustom erc-nick nil 158(defcustom erc-nick nil
158 "Nickname to use if one is not provided. 159 "Nickname to use if one is not provided.
@@ -165,8 +166,8 @@ See function `erc-compute-nick' for more details on connection
165parameters and authentication." 166parameters and authentication."
166 :group 'erc 167 :group 'erc
167 :type '(choice (const :tag "None" nil) 168 :type '(choice (const :tag "None" nil)
168 (string :tag "Nickname") 169 (string :tag "Nickname")
169 (repeat (string :tag "Nickname")))) 170 (repeat (string :tag "Nickname"))))
170 171
171(defcustom erc-nick-uniquifier "`" 172(defcustom erc-nick-uniquifier "`"
172 "The string to append to the nick if it is already in use." 173 "The string to append to the nick if it is already in use."
@@ -190,10 +191,10 @@ See function `erc-compute-full-name' for more details on connection
190parameters and authentication." 191parameters and authentication."
191 :group 'erc 192 :group 'erc
192 :type '(choice (const :tag "No name" nil) 193 :type '(choice (const :tag "No name" nil)
193 (string :tag "Name") 194 (string :tag "Name")
194 (function :tag "Get from function")) 195 (function :tag "Get from function"))
195 :set (lambda (sym val) 196 :set (lambda (sym val)
196 (set sym (if (functionp val) (funcall val) val)))) 197 (set sym (if (functionp val) (funcall val) val))))
197 198
198(defvar erc-password nil 199(defvar erc-password nil
199 "Password to use when authenticating to an IRC server. 200 "Password to use when authenticating to an IRC server.
@@ -243,12 +244,12 @@ If nil, only \"> \" will be shown."
243(define-widget 'erc-message-type 'set 244(define-widget 'erc-message-type 'set
244 "A set of standard IRC Message types." 245 "A set of standard IRC Message types."
245 :args '((const "JOIN") 246 :args '((const "JOIN")
246 (const "KICK") 247 (const "KICK")
247 (const "NICK") 248 (const "NICK")
248 (const "PART") 249 (const "PART")
249 (const "QUIT") 250 (const "QUIT")
250 (const "MODE") 251 (const "MODE")
251 (repeat :inline t :tag "Others" (string :tag "IRC Message Type")))) 252 (repeat :inline t :tag "Others" (string :tag "IRC Message Type"))))
252 253
253(defcustom erc-hide-list nil 254(defcustom erc-hide-list nil
254 "List of IRC type messages to hide. 255 "List of IRC type messages to hide.
@@ -339,14 +340,14 @@ nicknames with erc-server-user struct instances.")
339(defun erc-downcase (string) 340(defun erc-downcase (string)
340 "Convert STRING to IRC standard conforming downcase." 341 "Convert STRING to IRC standard conforming downcase."
341 (let ((s (downcase string)) 342 (let ((s (downcase string))
342 (c '((?\[ . ?\{) 343 (c '((?\[ . ?\{)
343 (?\] . ?\}) 344 (?\] . ?\})
344 (?\\ . ?\|) 345 (?\\ . ?\|)
345 (?~ . ?^)))) 346 (?~ . ?^))))
346 (save-match-data 347 (save-match-data
347 (while (string-match "[]\\[~]" s) 348 (while (string-match "[]\\[~]" s)
348 (aset s (match-beginning 0) 349 (aset s (match-beginning 0)
349 (cdr (assq (aref s (match-beginning 0)) c))))) 350 (cdr (assq (aref s (match-beginning 0)) c)))))
350 s)) 351 s))
351 352
352(defmacro erc-with-server-buffer (&rest body) 353(defmacro erc-with-server-buffer (&rest body)
@@ -356,8 +357,8 @@ If no server buffer exists, return nil."
356 (let ((buffer (make-symbol "buffer"))) 357 (let ((buffer (make-symbol "buffer")))
357 `(let ((,buffer (erc-server-buffer))) 358 `(let ((,buffer (erc-server-buffer)))
358 (when (buffer-live-p ,buffer) 359 (when (buffer-live-p ,buffer)
359 (with-current-buffer ,buffer 360 (with-current-buffer ,buffer
360 ,@body))))) 361 ,@body)))))
361 362
362(cl-defstruct (erc-server-user (:type vector) :named) 363(cl-defstruct (erc-server-user (:type vector) :named)
363 ;; User data 364 ;; User data
@@ -370,7 +371,7 @@ If no server buffer exists, return nil."
370 ) 371 )
371 372
372(cl-defstruct (erc-channel-user (:type vector) :named) 373(cl-defstruct (erc-channel-user (:type vector) :named)
373 op voice 374 voice halfop op admin owner
374 ;; Last message time (in the form of the return value of 375 ;; Last message time (in the form of the return value of
375 ;; (current-time) 376 ;; (current-time)
376 ;; 377 ;;
@@ -419,11 +420,11 @@ other buffers are also changed."
419 (puthash (erc-downcase new-nick) user erc-server-users)) 420 (puthash (erc-downcase new-nick) user erc-server-users))
420 (dolist (buf (erc-server-user-buffers user)) 421 (dolist (buf (erc-server-user-buffers user))
421 (if (buffer-live-p buf) 422 (if (buffer-live-p buf)
422 (with-current-buffer buf 423 (with-current-buffer buf
423 (let ((cdata (erc-get-channel-user nick))) 424 (let ((cdata (erc-get-channel-user nick)))
424 (remhash (erc-downcase nick) erc-channel-users) 425 (remhash (erc-downcase nick) erc-channel-users)
425 (puthash (erc-downcase new-nick) cdata 426 (puthash (erc-downcase new-nick) cdata
426 erc-channel-users))))))) 427 erc-channel-users)))))))
427 428
428(defun erc-remove-channel-user (nick) 429(defun erc-remove-channel-user (nick)
429 "This function is for internal use only. 430 "This function is for internal use only.
@@ -437,12 +438,12 @@ See also: `erc-remove-server-user' and `erc-remove-user'."
437 (let ((channel-data (erc-get-channel-user nick))) 438 (let ((channel-data (erc-get-channel-user nick)))
438 (when channel-data 439 (when channel-data
439 (let ((user (car channel-data))) 440 (let ((user (car channel-data)))
440 (setf (erc-server-user-buffers user) 441 (setf (erc-server-user-buffers user)
441 (delq (current-buffer) 442 (delq (current-buffer)
442 (erc-server-user-buffers user))) 443 (erc-server-user-buffers user)))
443 (remhash (erc-downcase nick) erc-channel-users) 444 (remhash (erc-downcase nick) erc-channel-users)
444 (if (null (erc-server-user-buffers user)) 445 (if (null (erc-server-user-buffers user))
445 (erc-remove-server-user nick)))))) 446 (erc-remove-server-user nick))))))
446 447
447(defun erc-remove-user (nick) 448(defun erc-remove-user (nick)
448 "This function is for internal use only. 449 "This function is for internal use only.
@@ -455,11 +456,11 @@ See also: `erc-remove-server-user' and
455 (let ((user (erc-get-server-user nick))) 456 (let ((user (erc-get-server-user nick)))
456 (when user 457 (when user
457 (let ((buffers (erc-server-user-buffers user))) 458 (let ((buffers (erc-server-user-buffers user)))
458 (dolist (buf buffers) 459 (dolist (buf buffers)
459 (if (buffer-live-p buf) 460 (if (buffer-live-p buf)
460 (with-current-buffer buf 461 (with-current-buffer buf
461 (remhash (erc-downcase nick) erc-channel-users) 462 (remhash (erc-downcase nick) erc-channel-users)
462 (run-hooks 'erc-channel-members-changed-hook))))) 463 (run-hooks 'erc-channel-members-changed-hook)))))
463 (erc-remove-server-user nick)))) 464 (erc-remove-server-user nick))))
464 465
465(defun erc-remove-channel-users () 466(defun erc-remove-channel-users ()
@@ -468,28 +469,52 @@ See also: `erc-remove-server-user' and
468Removes all users in the current channel. This is called by 469Removes all users in the current channel. This is called by
469`erc-server-PART' and `erc-server-QUIT'." 470`erc-server-PART' and `erc-server-QUIT'."
470 (when (and erc-server-connected 471 (when (and erc-server-connected
471 (erc-server-process-alive) 472 (erc-server-process-alive)
472 (hash-table-p erc-channel-users)) 473 (hash-table-p erc-channel-users))
473 (maphash (lambda (nick _cdata) 474 (maphash (lambda (nick _cdata)
474 (erc-remove-channel-user nick)) 475 (erc-remove-channel-user nick))
475 erc-channel-users) 476 erc-channel-users)
476 (clrhash erc-channel-users))) 477 (clrhash erc-channel-users)))
477 478
479(defsubst erc-channel-user-owner-p (nick)
480 "Return non-nil if NICK is an owner of the current channel."
481 (and nick
482 (hash-table-p erc-channel-users)
483 (let ((cdata (erc-get-channel-user nick)))
484 (and cdata (cdr cdata)
485 (erc-channel-user-owner (cdr cdata))))))
486
487(defsubst erc-channel-user-admin-p (nick)
488 "Return non-nil if NICK is an admin in the current channel."
489 (and nick
490 (hash-table-p erc-channel-users)
491 (let ((cdata (erc-get-channel-user nick)))
492 (and cdata (cdr cdata)
493 (erc-channel-user-admin (cdr cdata))))))
494
478(defsubst erc-channel-user-op-p (nick) 495(defsubst erc-channel-user-op-p (nick)
479 "Return t if NICK is an operator in the current channel." 496 "Return non-nil if NICK is an operator in the current channel."
497 (and nick
498 (hash-table-p erc-channel-users)
499 (let ((cdata (erc-get-channel-user nick)))
500 (and cdata (cdr cdata)
501 (erc-channel-user-op (cdr cdata))))))
502
503(defsubst erc-channel-user-halfop-p (nick)
504 "Return non-nil if NICK is a half-operator in the current channel."
480 (and nick 505 (and nick
481 (hash-table-p erc-channel-users) 506 (hash-table-p erc-channel-users)
482 (let ((cdata (erc-get-channel-user nick))) 507 (let ((cdata (erc-get-channel-user nick)))
483 (and cdata (cdr cdata) 508 (and cdata (cdr cdata)
484 (erc-channel-user-op (cdr cdata)))))) 509 (erc-channel-user-halfop (cdr cdata))))))
485 510
486(defsubst erc-channel-user-voice-p (nick) 511(defsubst erc-channel-user-voice-p (nick)
487 "Return t if NICK has voice in the current channel." 512 "Return non-nil if NICK has voice in the current channel."
488 (and nick 513 (and nick
489 (hash-table-p erc-channel-users) 514 (hash-table-p erc-channel-users)
490 (let ((cdata (erc-get-channel-user nick))) 515 (let ((cdata (erc-get-channel-user nick)))
491 (and cdata (cdr cdata) 516 (and cdata (cdr cdata)
492 (erc-channel-user-voice (cdr cdata)))))) 517 (erc-channel-user-voice (cdr cdata))))))
493 518
494(defun erc-get-channel-user-list () 519(defun erc-get-channel-user-list ()
495 "Return a list of users in the current channel. Each element 520 "Return a list of users in the current channel. Each element
@@ -500,9 +525,9 @@ erc-channel-user struct.
500See also: `erc-sort-channel-users-by-activity'" 525See also: `erc-sort-channel-users-by-activity'"
501 (let (users) 526 (let (users)
502 (if (hash-table-p erc-channel-users) 527 (if (hash-table-p erc-channel-users)
503 (maphash (lambda (_nick cdata) 528 (maphash (lambda (_nick cdata)
504 (setq users (cons cdata users))) 529 (setq users (cons cdata users)))
505 erc-channel-users)) 530 erc-channel-users))
506 users)) 531 users))
507 532
508(defun erc-get-server-nickname-list () 533(defun erc-get-server-nickname-list ()
@@ -510,22 +535,22 @@ See also: `erc-sort-channel-users-by-activity'"
510 (erc-with-server-buffer 535 (erc-with-server-buffer
511 (let (nicks) 536 (let (nicks)
512 (when (hash-table-p erc-server-users) 537 (when (hash-table-p erc-server-users)
513 (maphash (lambda (_n user) 538 (maphash (lambda (_n user)
514 (setq nicks 539 (setq nicks
515 (cons (erc-server-user-nickname user) 540 (cons (erc-server-user-nickname user)
516 nicks))) 541 nicks)))
517 erc-server-users) 542 erc-server-users)
518 nicks)))) 543 nicks))))
519 544
520(defun erc-get-channel-nickname-list () 545(defun erc-get-channel-nickname-list ()
521 "Return a list of known nicknames on the current channel." 546 "Return a list of known nicknames on the current channel."
522 (let (nicks) 547 (let (nicks)
523 (when (hash-table-p erc-channel-users) 548 (when (hash-table-p erc-channel-users)
524 (maphash (lambda (_n cdata) 549 (maphash (lambda (_n cdata)
525 (setq nicks 550 (setq nicks
526 (cons (erc-server-user-nickname (car cdata)) 551 (cons (erc-server-user-nickname (car cdata))
527 nicks))) 552 nicks)))
528 erc-channel-users) 553 erc-channel-users)
529 nicks))) 554 nicks)))
530 555
531(defun erc-get-server-nickname-alist () 556(defun erc-get-server-nickname-alist ()
@@ -533,22 +558,22 @@ See also: `erc-sort-channel-users-by-activity'"
533 (erc-with-server-buffer 558 (erc-with-server-buffer
534 (let (nicks) 559 (let (nicks)
535 (when (hash-table-p erc-server-users) 560 (when (hash-table-p erc-server-users)
536 (maphash (lambda (_n user) 561 (maphash (lambda (_n user)
537 (setq nicks 562 (setq nicks
538 (cons (cons (erc-server-user-nickname user) nil) 563 (cons (cons (erc-server-user-nickname user) nil)
539 nicks))) 564 nicks)))
540 erc-server-users) 565 erc-server-users)
541 nicks)))) 566 nicks))))
542 567
543(defun erc-get-channel-nickname-alist () 568(defun erc-get-channel-nickname-alist ()
544 "Return an alist of known nicknames on the current channel." 569 "Return an alist of known nicknames on the current channel."
545 (let (nicks) 570 (let (nicks)
546 (when (hash-table-p erc-channel-users) 571 (when (hash-table-p erc-channel-users)
547 (maphash (lambda (_n cdata) 572 (maphash (lambda (_n cdata)
548 (setq nicks 573 (setq nicks
549 (cons (cons (erc-server-user-nickname (car cdata)) nil) 574 (cons (cons (erc-server-user-nickname (car cdata)) nil)
550 nicks))) 575 nicks)))
551 erc-channel-users) 576 erc-channel-users)
552 nicks))) 577 nicks)))
553 578
554(defun erc-sort-channel-users-by-activity (list) 579(defun erc-sort-channel-users-by-activity (list)
@@ -557,13 +582,13 @@ LIST must be of the form (USER . CHANNEL-DATA).
557 582
558See also: `erc-get-channel-user-list'." 583See also: `erc-get-channel-user-list'."
559 (sort list 584 (sort list
560 (lambda (x y) 585 (lambda (x y)
561 (when (and (cdr x) (cdr y)) 586 (when (and (cdr x) (cdr y))
562 (let ((tx (erc-channel-user-last-message-time (cdr x))) 587 (let ((tx (erc-channel-user-last-message-time (cdr x)))
563 (ty (erc-channel-user-last-message-time (cdr y)))) 588 (ty (erc-channel-user-last-message-time (cdr y))))
564 (and tx 589 (and tx
565 (or (not ty) 590 (or (not ty)
566 (time-less-p ty tx)))))))) 591 (time-less-p ty tx))))))))
567 592
568(defun erc-sort-channel-users-alphabetically (list) 593(defun erc-sort-channel-users-alphabetically (list)
569 "Sort LIST so that users' nicknames are in alphabetical order. 594 "Sort LIST so that users' nicknames are in alphabetical order.
@@ -571,13 +596,13 @@ LIST must be of the form (USER . CHANNEL-DATA).
571 596
572See also: `erc-get-channel-user-list'." 597See also: `erc-get-channel-user-list'."
573 (sort list 598 (sort list
574 (lambda (x y) 599 (lambda (x y)
575 (when (and (cdr x) (cdr y)) 600 (when (and (cdr x) (cdr y))
576 (let ((nickx (downcase (erc-server-user-nickname (car x)))) 601 (let ((nickx (downcase (erc-server-user-nickname (car x))))
577 (nicky (downcase (erc-server-user-nickname (car y))))) 602 (nicky (downcase (erc-server-user-nickname (car y)))))
578 (and nickx 603 (and nickx
579 (or (not nicky) 604 (or (not nicky)
580 (string-lessp nickx nicky)))))))) 605 (string-lessp nickx nicky))))))))
581 606
582(defvar erc-channel-topic nil 607(defvar erc-channel-topic nil
583 "A topic string for the channel. Should only be used in channel-buffers.") 608 "A topic string for the channel. Should only be used in channel-buffers.")
@@ -613,10 +638,10 @@ E.g. '(\"i\" \"m\" \"s\" \"b Quake!*@*\")
613 638
614See also the variable `erc-prompt'." 639See also the variable `erc-prompt'."
615 (let ((prompt (if (functionp erc-prompt) 640 (let ((prompt (if (functionp erc-prompt)
616 (funcall erc-prompt) 641 (funcall erc-prompt)
617 erc-prompt))) 642 erc-prompt)))
618 (if (> (length prompt) 0) 643 (if (> (length prompt) 0)
619 (concat prompt " ") 644 (concat prompt " ")
620 prompt))) 645 prompt)))
621 646
622(defcustom erc-command-indicator nil 647(defcustom erc-command-indicator nil
@@ -635,11 +660,11 @@ If nil, the prompt will be constructed from the variable `erc-prompt'."
635This only has any meaning if the variable `erc-command-indicator' is non-nil." 660This only has any meaning if the variable `erc-command-indicator' is non-nil."
636 (and erc-command-indicator 661 (and erc-command-indicator
637 (let ((prompt (if (functionp erc-command-indicator) 662 (let ((prompt (if (functionp erc-command-indicator)
638 (funcall erc-command-indicator) 663 (funcall erc-command-indicator)
639 erc-command-indicator))) 664 erc-command-indicator)))
640 (if (> (length prompt) 0) 665 (if (> (length prompt) 0)
641 (concat prompt " ") 666 (concat prompt " ")
642 prompt)))) 667 prompt))))
643 668
644(defcustom erc-notice-prefix "*** " 669(defcustom erc-notice-prefix "*** "
645 "Prefix for all notices." 670 "Prefix for all notices."
@@ -658,8 +683,8 @@ The following values are allowed:
658Any other value disables notice's highlighting altogether." 683Any other value disables notice's highlighting altogether."
659 :group 'erc-display 684 :group 'erc-display
660 :type '(choice (const :tag "highlight notice prefix only" prefix) 685 :type '(choice (const :tag "highlight notice prefix only" prefix)
661 (const :tag "highlight the entire notice" all) 686 (const :tag "highlight the entire notice" all)
662 (const :tag "don't highlight notices at all" nil))) 687 (const :tag "don't highlight notices at all" nil)))
663 688
664(defcustom erc-echo-notice-hook nil 689(defcustom erc-echo-notice-hook nil
665 "List of functions to call to echo a private notice. 690 "List of functions to call to echo a private notice.
@@ -682,14 +707,14 @@ See also: `erc-echo-notice-always-hook',
682 :group 'erc-hooks 707 :group 'erc-hooks
683 :type 'hook 708 :type 'hook
684 :options '(erc-echo-notice-in-default-buffer 709 :options '(erc-echo-notice-in-default-buffer
685 erc-echo-notice-in-target-buffer 710 erc-echo-notice-in-target-buffer
686 erc-echo-notice-in-minibuffer 711 erc-echo-notice-in-minibuffer
687 erc-echo-notice-in-server-buffer 712 erc-echo-notice-in-server-buffer
688 erc-echo-notice-in-active-non-server-buffer 713 erc-echo-notice-in-active-non-server-buffer
689 erc-echo-notice-in-active-buffer 714 erc-echo-notice-in-active-buffer
690 erc-echo-notice-in-user-buffers 715 erc-echo-notice-in-user-buffers
691 erc-echo-notice-in-user-and-target-buffers 716 erc-echo-notice-in-user-and-target-buffers
692 erc-echo-notice-in-first-user-buffer)) 717 erc-echo-notice-in-first-user-buffer))
693 718
694(defcustom erc-echo-notice-always-hook 719(defcustom erc-echo-notice-always-hook
695 '(erc-echo-notice-in-default-buffer) 720 '(erc-echo-notice-in-default-buffer)
@@ -713,14 +738,14 @@ See also: `erc-echo-notice-hook',
713 :group 'erc-hooks 738 :group 'erc-hooks
714 :type 'hook 739 :type 'hook
715 :options '(erc-echo-notice-in-default-buffer 740 :options '(erc-echo-notice-in-default-buffer
716 erc-echo-notice-in-target-buffer 741 erc-echo-notice-in-target-buffer
717 erc-echo-notice-in-minibuffer 742 erc-echo-notice-in-minibuffer
718 erc-echo-notice-in-server-buffer 743 erc-echo-notice-in-server-buffer
719 erc-echo-notice-in-active-non-server-buffer 744 erc-echo-notice-in-active-non-server-buffer
720 erc-echo-notice-in-active-buffer 745 erc-echo-notice-in-active-buffer
721 erc-echo-notice-in-user-buffers 746 erc-echo-notice-in-user-buffers
722 erc-echo-notice-in-user-and-target-buffers 747 erc-echo-notice-in-user-and-target-buffers
723 erc-echo-notice-in-first-user-buffer)) 748 erc-echo-notice-in-first-user-buffer))
724 749
725;; other tunable parameters 750;; other tunable parameters
726 751
@@ -747,7 +772,7 @@ Many consider it impolite to do so automatically."
747 "The nickname to take when you are marked as being away." 772 "The nickname to take when you are marked as being away."
748 :group 'erc 773 :group 'erc
749 :type '(choice (const nil) 774 :type '(choice (const nil)
750 string)) 775 string))
751 776
752(defcustom erc-paranoid nil 777(defcustom erc-paranoid nil
753 "If non-nil, then all incoming CTCP requests will be shown." 778 "If non-nil, then all incoming CTCP requests will be shown."
@@ -782,7 +807,7 @@ set if some hacker is trying to flood you away."
782If nil, ERC will call `system-name' to get this information." 807If nil, ERC will call `system-name' to get this information."
783 :group 'erc 808 :group 'erc
784 :type '(choice (const :tag "Default system name" nil) 809 :type '(choice (const :tag "Default system name" nil)
785 string)) 810 string))
786 811
787(defcustom erc-ignore-list nil 812(defcustom erc-ignore-list nil
788 "List of regexps matching user identifiers to ignore. 813 "List of regexps matching user identifiers to ignore.
@@ -824,8 +849,8 @@ See `erc-server-flood-margin' for other flood-related parameters.")
824 849
825(defcustom erc-startup-file-list 850(defcustom erc-startup-file-list
826 (list (concat erc-user-emacs-directory ".ercrc.el") 851 (list (concat erc-user-emacs-directory ".ercrc.el")
827 (concat erc-user-emacs-directory ".ercrc") 852 (concat erc-user-emacs-directory ".ercrc")
828 "~/.ercrc.el" "~/.ercrc" ".ercrc.el" ".ercrc") 853 "~/.ercrc.el" "~/.ercrc" ".ercrc.el" ".ercrc")
829 "List of files to try for a startup script. 854 "List of files to try for a startup script.
830The first existent and readable one will get executed. 855The first existent and readable one will get executed.
831 856
@@ -884,9 +909,9 @@ If no elements match, then the empty string is used.
884As an example: 909As an example:
885 (setq erc-quit-reason-various-alist 910 (setq erc-quit-reason-various-alist
886 '((\"xmms\" dme:now-playing) 911 '((\"xmms\" dme:now-playing)
887 (\"version\" erc-quit-reason-normal) 912 (\"version\" erc-quit-reason-normal)
888 (\"home\" \"Gone home !\") 913 (\"home\" \"Gone home !\")
889 (\"^$\" \"Default Reason\"))) 914 (\"^$\" \"Default Reason\")))
890If the user types \"/quit home\", then \"Gone home !\" will be used 915If the user types \"/quit home\", then \"Gone home !\" will be used
891as the quit message." 916as the quit message."
892 :group 'erc-quit-and-part 917 :group 'erc-quit-and-part
@@ -907,9 +932,9 @@ If no elements match, then the empty string is used.
907As an example: 932As an example:
908 (setq erc-part-reason-various-alist 933 (setq erc-part-reason-various-alist
909 '((\"xmms\" dme:now-playing) 934 '((\"xmms\" dme:now-playing)
910 (\"version\" erc-part-reason-normal) 935 (\"version\" erc-part-reason-normal)
911 (\"home\" \"Gone home !\") 936 (\"home\" \"Gone home !\")
912 (\"^$\" \"Default Reason\"))) 937 (\"^$\" \"Default Reason\")))
913If the user types \"/part home\", then \"Gone home !\" will be used 938If the user types \"/part home\", then \"Gone home !\" will be used
914as the part message." 939as the part message."
915 :group 'erc-quit-and-part 940 :group 'erc-quit-and-part
@@ -922,8 +947,8 @@ The function is passed a single argument, the string typed by the
922user after \"/quit\"." 947user after \"/quit\"."
923 :group 'erc-quit-and-part 948 :group 'erc-quit-and-part
924 :type '(choice (const erc-quit-reason-normal) 949 :type '(choice (const erc-quit-reason-normal)
925 (const erc-quit-reason-various) 950 (const erc-quit-reason-various)
926 (symbol))) 951 (symbol)))
927 952
928(defcustom erc-part-reason 'erc-part-reason-normal 953(defcustom erc-part-reason 'erc-part-reason-normal
929 "A function which returns the reason for parting a channel. 954 "A function which returns the reason for parting a channel.
@@ -932,8 +957,8 @@ The function is passed a single argument, the string typed by the
932user after \"/PART\"." 957user after \"/PART\"."
933 :group 'erc-quit-and-part 958 :group 'erc-quit-and-part
934 :type '(choice (const erc-part-reason-normal) 959 :type '(choice (const erc-part-reason-normal)
935 (const erc-part-reason-various) 960 (const erc-part-reason-various)
936 (symbol))) 961 (symbol)))
937 962
938(defvar erc-grab-buffer-name "*erc-grab*" 963(defvar erc-grab-buffer-name "*erc-grab*"
939 "The name of the buffer created by `erc-grab-region'.") 964 "The name of the buffer created by `erc-grab-region'.")
@@ -1017,8 +1042,8 @@ At this point, all modifications from prior hook functions are done."
1017 :group 'erc-hooks 1042 :group 'erc-hooks
1018 :type 'hook 1043 :type 'hook
1019 :options '(erc-truncate-buffer 1044 :options '(erc-truncate-buffer
1020 erc-make-read-only 1045 erc-make-read-only
1021 erc-save-buffer-in-logs)) 1046 erc-save-buffer-in-logs))
1022 1047
1023(defcustom erc-send-modify-hook nil 1048(defcustom erc-send-modify-hook nil
1024 "Sending hook for functions that will change the text's appearance. 1049 "Sending hook for functions that will change the text's appearance.
@@ -1048,8 +1073,8 @@ This function is called with narrowing, ala `erc-send-modify-hook'."
1048(defcustom erc-send-completed-hook 1073(defcustom erc-send-completed-hook
1049 (when (fboundp 'emacspeak-auditory-icon) 1074 (when (fboundp 'emacspeak-auditory-icon)
1050 (list (byte-compile 1075 (list (byte-compile
1051 (lambda (_str) 1076 (lambda (_str)
1052 (emacspeak-auditory-icon 'select-object))))) 1077 (emacspeak-auditory-icon 'select-object)))))
1053 "Hook called after a message has been parsed by ERC. 1078 "Hook called after a message has been parsed by ERC.
1054 1079
1055The single argument to the functions is the unmodified string 1080The single argument to the functions is the unmodified string
@@ -1122,6 +1147,14 @@ which the local user typed."
1122 "ERC default face." 1147 "ERC default face."
1123 :group 'erc-faces) 1148 :group 'erc-faces)
1124 1149
1150(defface erc-nick-prefix-face '((t :inherit erc-nick-default-face :weight bold))
1151 "ERC face used for user mode prefix."
1152 :group 'erc-faces)
1153
1154(defface erc-my-nick-prefix-face '((t :inherit erc-nick-default-face :weight bold))
1155 "ERC face used for my user mode prefix."
1156 :group 'erc-faces)
1157
1125(defface erc-direct-msg-face '((t :foreground "IndianRed")) 1158(defface erc-direct-msg-face '((t :foreground "IndianRed"))
1126 "ERC face used for messages you receive in the main erc buffer." 1159 "ERC face used for messages you receive in the main erc buffer."
1127 :group 'erc-faces) 1160 :group 'erc-faces)
@@ -1189,7 +1222,7 @@ See also `erc-show-my-nick'."
1189(make-variable-buffer-local 'erc-dbuf) 1222(make-variable-buffer-local 'erc-dbuf)
1190 1223
1191(defmacro define-erc-module (name alias doc enable-body disable-body 1224(defmacro define-erc-module (name alias doc enable-body disable-body
1192 &optional local-p) 1225 &optional local-p)
1193 "Define a new minor mode using ERC conventions. 1226 "Define a new minor mode using ERC conventions.
1194Symbol NAME is the name of the module. 1227Symbol NAME is the name of the module.
1195Symbol ALIAS is the alias to use, or nil. 1228Symbol ALIAS is the alias to use, or nil.
@@ -1209,50 +1242,50 @@ Example:
1209 (define-erc-module replace nil 1242 (define-erc-module replace nil
1210 \"This mode replaces incoming text according to `erc-replace-alist'.\" 1243 \"This mode replaces incoming text according to `erc-replace-alist'.\"
1211 ((add-hook 'erc-insert-modify-hook 1244 ((add-hook 'erc-insert-modify-hook
1212 'erc-replace-insert)) 1245 'erc-replace-insert))
1213 ((remove-hook 'erc-insert-modify-hook 1246 ((remove-hook 'erc-insert-modify-hook
1214 'erc-replace-insert)))" 1247 'erc-replace-insert)))"
1215 (declare (doc-string 3)) 1248 (declare (doc-string 3))
1216 (let* ((sn (symbol-name name)) 1249 (let* ((sn (symbol-name name))
1217 (mode (intern (format "erc-%s-mode" (downcase sn)))) 1250 (mode (intern (format "erc-%s-mode" (downcase sn))))
1218 (group (intern (format "erc-%s" (downcase sn)))) 1251 (group (intern (format "erc-%s" (downcase sn))))
1219 (enable (intern (format "erc-%s-enable" (downcase sn)))) 1252 (enable (intern (format "erc-%s-enable" (downcase sn))))
1220 (disable (intern (format "erc-%s-disable" (downcase sn))))) 1253 (disable (intern (format "erc-%s-disable" (downcase sn)))))
1221 `(progn 1254 `(progn
1222 (erc-define-minor-mode 1255 (erc-define-minor-mode
1223 ,mode 1256 ,mode
1224 ,(format "Toggle ERC %S mode. 1257 ,(format "Toggle ERC %S mode.
1225With a prefix argument ARG, enable %s if ARG is positive, 1258With a prefix argument ARG, enable %s if ARG is positive,
1226and disable it otherwise. If called from Lisp, enable the mode 1259and disable it otherwise. If called from Lisp, enable the mode
1227if ARG is omitted or nil. 1260if ARG is omitted or nil.
1228%s" name name doc) 1261%s" name name doc)
1229 nil nil nil 1262 nil nil nil
1230 :global ,(not local-p) :group (quote ,group) 1263 :global ,(not local-p) :group (quote ,group)
1231 (if ,mode 1264 (if ,mode
1232 (,enable) 1265 (,enable)
1233 (,disable))) 1266 (,disable)))
1234 (defun ,enable () 1267 (defun ,enable ()
1235 ,(format "Enable ERC %S mode." 1268 ,(format "Enable ERC %S mode."
1236 name) 1269 name)
1237 (interactive) 1270 (interactive)
1238 (add-to-list 'erc-modules (quote ,name)) 1271 (add-to-list 'erc-modules (quote ,name))
1239 (setq ,mode t) 1272 (setq ,mode t)
1240 ,@enable-body) 1273 ,@enable-body)
1241 (defun ,disable () 1274 (defun ,disable ()
1242 ,(format "Disable ERC %S mode." 1275 ,(format "Disable ERC %S mode."
1243 name) 1276 name)
1244 (interactive) 1277 (interactive)
1245 (setq erc-modules (delq (quote ,name) erc-modules)) 1278 (setq erc-modules (delq (quote ,name) erc-modules))
1246 (setq ,mode nil) 1279 (setq ,mode nil)
1247 ,@disable-body) 1280 ,@disable-body)
1248 ,(when (and alias (not (eq name alias))) 1281 ,(when (and alias (not (eq name alias)))
1249 `(defalias 1282 `(defalias
1250 (quote 1283 (quote
1251 ,(intern 1284 ,(intern
1252 (format "erc-%s-mode" 1285 (format "erc-%s-mode"
1253 (downcase (symbol-name alias))))) 1286 (downcase (symbol-name alias)))))
1254 (quote 1287 (quote
1255 ,mode))) 1288 ,mode)))
1256 ;; For find-function and find-variable. 1289 ;; For find-function and find-variable.
1257 (put ',mode 'definition-name ',name) 1290 (put ',mode 'definition-name ',name)
1258 (put ',enable 'definition-name ',name) 1291 (put ',enable 'definition-name ',name)
@@ -1278,13 +1311,13 @@ capabilities."
1278 (error 1311 (error
1279 "You should only run `erc-once-with-server-event' in a server buffer")) 1312 "You should only run `erc-once-with-server-event' in a server buffer"))
1280 (let ((fun (make-symbol "fun")) 1313 (let ((fun (make-symbol "fun"))
1281 (hook (erc-get-hook event))) 1314 (hook (erc-get-hook event)))
1282 (put fun 'erc-original-buffer (current-buffer)) 1315 (put fun 'erc-original-buffer (current-buffer))
1283 (fset fun (lambda (proc parsed) 1316 (fset fun (lambda (proc parsed)
1284 (with-current-buffer (get fun 'erc-original-buffer) 1317 (with-current-buffer (get fun 'erc-original-buffer)
1285 (remove-hook hook fun t)) 1318 (remove-hook hook fun t))
1286 (fmakunbound fun) 1319 (fmakunbound fun)
1287 (funcall f proc parsed))) 1320 (funcall f proc parsed)))
1288 (add-hook hook fun nil t) 1321 (add-hook hook fun nil t)
1289 fun)) 1322 fun))
1290 1323
@@ -1311,7 +1344,7 @@ the process buffer."
1311If BUFFER is nil, the current buffer is used." 1344If BUFFER is nil, the current buffer is used."
1312 (with-current-buffer (or buffer (current-buffer)) 1345 (with-current-buffer (or buffer (current-buffer))
1313 (and (eq major-mode 'erc-mode) 1346 (and (eq major-mode 'erc-mode)
1314 (null (erc-default-target))))) 1347 (null (erc-default-target)))))
1315 1348
1316(defun erc-open-server-buffer-p (&optional buffer) 1349(defun erc-open-server-buffer-p (&optional buffer)
1317 "Return non-nil if argument BUFFER is an ERC server buffer that 1350 "Return non-nil if argument BUFFER is an ERC server buffer that
@@ -1327,8 +1360,8 @@ If BUFFER is nil, the current buffer is used."
1327 (with-current-buffer (or buffer (current-buffer)) 1360 (with-current-buffer (or buffer (current-buffer))
1328 (let ((target (erc-default-target))) 1361 (let ((target (erc-default-target)))
1329 (and (eq major-mode 'erc-mode) 1362 (and (eq major-mode 'erc-mode)
1330 target 1363 target
1331 (not (memq (aref target 0) '(?# ?& ?+ ?!))))))) 1364 (not (memq (aref target 0) '(?# ?& ?+ ?!)))))))
1332 1365
1333(defun erc-ison-p (nick) 1366(defun erc-ison-p (nick)
1334 "Return non-nil if NICK is online." 1367 "Return non-nil if NICK is online."
@@ -1338,39 +1371,39 @@ If BUFFER is nil, the current buffer is used."
1338 (erc-once-with-server-event 1371 (erc-once-with-server-event
1339 303 1372 303
1340 (lambda (_proc parsed) 1373 (lambda (_proc parsed)
1341 (let ((ison (split-string (aref parsed 3)))) 1374 (let ((ison (split-string (aref parsed 3))))
1342 (setq erc-online-p (car (erc-member-ignore-case nick ison))) 1375 (setq erc-online-p (car (erc-member-ignore-case nick ison)))
1343 t))) 1376 t)))
1344 (erc-server-send (format "ISON %s" nick)) 1377 (erc-server-send (format "ISON %s" nick))
1345 (while (eq erc-online-p 'unknown) (accept-process-output)) 1378 (while (eq erc-online-p 'unknown) (accept-process-output))
1346 (if (called-interactively-p 'interactive) 1379 (if (called-interactively-p 'interactive)
1347 (message "%s is %sonline" 1380 (message "%s is %sonline"
1348 (or erc-online-p nick) 1381 (or erc-online-p nick)
1349 (if erc-online-p "" "not ")) 1382 (if erc-online-p "" "not "))
1350 erc-online-p)))) 1383 erc-online-p))))
1351 1384
1352(defun erc-log-aux (string) 1385(defun erc-log-aux (string)
1353 "Do the debug logging of STRING." 1386 "Do the debug logging of STRING."
1354 (let ((cb (current-buffer)) 1387 (let ((cb (current-buffer))
1355 (point 1) 1388 (point 1)
1356 (was-eob nil) 1389 (was-eob nil)
1357 (session-buffer (erc-server-buffer))) 1390 (session-buffer (erc-server-buffer)))
1358 (if session-buffer 1391 (if session-buffer
1359 (progn 1392 (progn
1360 (set-buffer session-buffer) 1393 (set-buffer session-buffer)
1361 (if (not (and erc-dbuf (bufferp erc-dbuf) (buffer-live-p erc-dbuf))) 1394 (if (not (and erc-dbuf (bufferp erc-dbuf) (buffer-live-p erc-dbuf)))
1362 (progn 1395 (progn
1363 (setq erc-dbuf (get-buffer-create 1396 (setq erc-dbuf (get-buffer-create
1364 (concat "*ERC-DEBUG: " 1397 (concat "*ERC-DEBUG: "
1365 erc-session-server "*"))))) 1398 erc-session-server "*")))))
1366 (set-buffer erc-dbuf) 1399 (set-buffer erc-dbuf)
1367 (setq point (point)) 1400 (setq point (point))
1368 (setq was-eob (eobp)) 1401 (setq was-eob (eobp))
1369 (goto-char (point-max)) 1402 (goto-char (point-max))
1370 (insert (concat "** " string "\n")) 1403 (insert (concat "** " string "\n"))
1371 (if was-eob (goto-char (point-max)) 1404 (if was-eob (goto-char (point-max))
1372 (goto-char point)) 1405 (goto-char point))
1373 (set-buffer cb)) 1406 (set-buffer cb))
1374 (message "ERC: ** %s" string)))) 1407 (message "ERC: ** %s" string))))
1375 1408
1376;; Last active buffer, to print server messages in the right place 1409;; Last active buffer, to print server messages in the right place
@@ -1386,15 +1419,15 @@ server buffer.")
1386Defaults to the server buffer." 1419Defaults to the server buffer."
1387 (erc-with-server-buffer 1420 (erc-with-server-buffer
1388 (if (buffer-live-p erc-active-buffer) 1421 (if (buffer-live-p erc-active-buffer)
1389 erc-active-buffer 1422 erc-active-buffer
1390 (setq erc-active-buffer (current-buffer))))) 1423 (setq erc-active-buffer (current-buffer)))))
1391 1424
1392(defun erc-set-active-buffer (buffer) 1425(defun erc-set-active-buffer (buffer)
1393 "Set the value of `erc-active-buffer' to BUFFER." 1426 "Set the value of `erc-active-buffer' to BUFFER."
1394 (cond ((erc-server-buffer) 1427 (cond ((erc-server-buffer)
1395 (with-current-buffer (erc-server-buffer) 1428 (with-current-buffer (erc-server-buffer)
1396 (setq erc-active-buffer buffer))) 1429 (setq erc-active-buffer buffer)))
1397 (t (setq erc-active-buffer buffer)))) 1430 (t (setq erc-active-buffer buffer))))
1398 1431
1399;; Mode activation routines 1432;; Mode activation routines
1400 1433
@@ -1431,19 +1464,19 @@ The available choices are:
1431 any other value - in place of the current buffer." 1464 any other value - in place of the current buffer."
1432 :group 'erc-buffers 1465 :group 'erc-buffers
1433 :type '(choice (const :tag "Split window and select" window) 1466 :type '(choice (const :tag "Split window and select" window)
1434 (const :tag "Split window, don't select" window-noselect) 1467 (const :tag "Split window, don't select" window-noselect)
1435 (const :tag "New frame" frame) 1468 (const :tag "New frame" frame)
1436 (const :tag "Bury in new buffer" bury) 1469 (const :tag "Bury in new buffer" bury)
1437 (const :tag "Use current buffer" buffer) 1470 (const :tag "Use current buffer" buffer)
1438 (const :tag "Use current buffer" t))) 1471 (const :tag "Use current buffer" t)))
1439 1472
1440(defcustom erc-frame-alist nil 1473(defcustom erc-frame-alist nil
1441 "Alist of frame parameters for creating erc frames. 1474 "Alist of frame parameters for creating erc frames.
1442A value of nil means to use `default-frame-alist'." 1475A value of nil means to use `default-frame-alist'."
1443 :group 'erc-buffers 1476 :group 'erc-buffers
1444 :type '(repeat (cons :format "%v" 1477 :type '(repeat (cons :format "%v"
1445 (symbol :tag "Parameter") 1478 (symbol :tag "Parameter")
1446 (sexp :tag "Value")))) 1479 (sexp :tag "Value"))))
1447 1480
1448(defcustom erc-frame-dedicated-flag nil 1481(defcustom erc-frame-dedicated-flag nil
1449 "Non-nil means the erc frames are dedicated to that buffer. 1482 "Non-nil means the erc frames are dedicated to that buffer.
@@ -1462,11 +1495,11 @@ effect when `erc-join-buffer' is set to `frame'."
1462(defun erc-channel-p (channel) 1495(defun erc-channel-p (channel)
1463 "Return non-nil if CHANNEL seems to be an IRC channel name." 1496 "Return non-nil if CHANNEL seems to be an IRC channel name."
1464 (cond ((stringp channel) 1497 (cond ((stringp channel)
1465 (memq (aref channel 0) '(?# ?& ?+ ?!))) 1498 (memq (aref channel 0) '(?# ?& ?+ ?!)))
1466 ((and (bufferp channel) (buffer-live-p channel)) 1499 ((and (bufferp channel) (buffer-live-p channel))
1467 (with-current-buffer channel 1500 (with-current-buffer channel
1468 (erc-channel-p (erc-default-target)))) 1501 (erc-channel-p (erc-default-target))))
1469 (t nil))) 1502 (t nil)))
1470 1503
1471(defcustom erc-reuse-buffers t 1504(defcustom erc-reuse-buffers t
1472 "If nil, create new buffers on joining a channel/query. 1505 "If nil, create new buffers on joining a channel/query.
@@ -1492,17 +1525,17 @@ symbol, it may have these values:
1492 (let ((port-nr (string-to-number port))) 1525 (let ((port-nr (string-to-number port)))
1493 (cond 1526 (cond
1494 ((> port-nr 0) 1527 ((> port-nr 0)
1495 port-nr) 1528 port-nr)
1496 ((string-equal port "irc") 1529 ((string-equal port "irc")
1497 194) 1530 194)
1498 ((string-equal port "ircs") 1531 ((string-equal port "ircs")
1499 994) 1532 994)
1500 ((string-equal port "ircd") 1533 ((string-equal port "ircd")
1501 6667) 1534 6667)
1502 ((string-equal port "ircd-dalnet") 1535 ((string-equal port "ircd-dalnet")
1503 7000) 1536 7000)
1504 (t 1537 (t
1505 nil)))) 1538 nil))))
1506 ((numberp port) 1539 ((numberp port)
1507 port) 1540 port)
1508 (t 1541 (t
@@ -1557,8 +1590,8 @@ All strings are compared according to IRC protocol case rules, see
1557 (catch 'result 1590 (catch 'result
1558 (while list 1591 (while list
1559 (if (string= string (erc-downcase (car list))) 1592 (if (string= string (erc-downcase (car list)))
1560 (throw 'result list) 1593 (throw 'result list)
1561 (setq list (cdr list)))))) 1594 (setq list (cdr list))))))
1562 1595
1563(defmacro erc-with-buffer (spec &rest body) 1596(defmacro erc-with-buffer (spec &rest body)
1564 "Execute BODY in the buffer associated with SPEC. 1597 "Execute BODY in the buffer associated with SPEC.
@@ -1578,21 +1611,21 @@ See also `with-current-buffer'.
1578\(fn (TARGET [PROCESS]) BODY...)" 1611\(fn (TARGET [PROCESS]) BODY...)"
1579 (declare (indent 1) (debug ((form &optional form) body))) 1612 (declare (indent 1) (debug ((form &optional form) body)))
1580 (let ((buf (make-symbol "buf")) 1613 (let ((buf (make-symbol "buf"))
1581 (proc (make-symbol "proc")) 1614 (proc (make-symbol "proc"))
1582 (target (make-symbol "target")) 1615 (target (make-symbol "target"))
1583 (process (make-symbol "process"))) 1616 (process (make-symbol "process")))
1584 `(let* ((,target ,(car spec)) 1617 `(let* ((,target ,(car spec))
1585 (,process ,(cadr spec)) 1618 (,process ,(cadr spec))
1586 (,buf (if (bufferp ,target) 1619 (,buf (if (bufferp ,target)
1587 ,target 1620 ,target
1588 (let ((,proc (or ,process 1621 (let ((,proc (or ,process
1589 (and (processp erc-server-process) 1622 (and (processp erc-server-process)
1590 erc-server-process)))) 1623 erc-server-process))))
1591 (if (and ,target ,proc) 1624 (if (and ,target ,proc)
1592 (erc-get-buffer ,target ,proc)))))) 1625 (erc-get-buffer ,target ,proc))))))
1593 (when (buffer-live-p ,buf) 1626 (when (buffer-live-p ,buf)
1594 (with-current-buffer ,buf 1627 (with-current-buffer ,buf
1595 ,@body))))) 1628 ,@body)))))
1596 1629
1597(defun erc-get-buffer (target &optional proc) 1630(defun erc-get-buffer (target &optional proc)
1598 "Return the buffer matching TARGET in the process PROC. 1631 "Return the buffer matching TARGET in the process PROC.
@@ -1601,10 +1634,10 @@ If PROC is not supplied, all processes are searched."
1601 (catch 'buffer 1634 (catch 'buffer
1602 (erc-buffer-filter 1635 (erc-buffer-filter
1603 (lambda () 1636 (lambda ()
1604 (let ((current (erc-default-target))) 1637 (let ((current (erc-default-target)))
1605 (and (stringp current) 1638 (and (stringp current)
1606 (string-equal downcased-target (erc-downcase current)) 1639 (string-equal downcased-target (erc-downcase current))
1607 (throw 'buffer (current-buffer))))) 1640 (throw 'buffer (current-buffer)))))
1608 proc)))) 1641 proc))))
1609 1642
1610(defun erc-buffer-filter (predicate &optional proc) 1643(defun erc-buffer-filter (predicate &optional proc)
@@ -1618,14 +1651,14 @@ server connection, or nil which means all open connections."
1618 (delq 1651 (delq
1619 nil 1652 nil
1620 (mapcar (lambda (buf) 1653 (mapcar (lambda (buf)
1621 (when (buffer-live-p buf) 1654 (when (buffer-live-p buf)
1622 (with-current-buffer buf 1655 (with-current-buffer buf
1623 (and (eq major-mode 'erc-mode) 1656 (and (eq major-mode 'erc-mode)
1624 (or (not proc) 1657 (or (not proc)
1625 (eq proc erc-server-process)) 1658 (eq proc erc-server-process))
1626 (funcall predicate) 1659 (funcall predicate)
1627 buf)))) 1660 buf))))
1628 (buffer-list))))) 1661 (buffer-list)))))
1629 1662
1630(defun erc-buffer-list (&optional predicate proc) 1663(defun erc-buffer-list (&optional predicate proc)
1631 "Return a list of ERC buffers. 1664 "Return a list of ERC buffers.
@@ -1645,14 +1678,14 @@ nil."
1645 (declare (indent 1) (debug (form form body))) 1678 (declare (indent 1) (debug (form form body)))
1646 ;; Make the evaluation have the correct order 1679 ;; Make the evaluation have the correct order
1647 (let ((pre (make-symbol "pre")) 1680 (let ((pre (make-symbol "pre"))
1648 (pro (make-symbol "pro"))) 1681 (pro (make-symbol "pro")))
1649 `(let* ((,pro ,process) 1682 `(let* ((,pro ,process)
1650 (,pre ,pred) 1683 (,pre ,pred)
1651 (res (mapcar (lambda (buffer) 1684 (res (mapcar (lambda (buffer)
1652 (with-current-buffer buffer 1685 (with-current-buffer buffer
1653 ,@forms)) 1686 ,@forms))
1654 (erc-buffer-list ,pre 1687 (erc-buffer-list ,pre
1655 ,pro)))) 1688 ,pro))))
1656 ;; Silence the byte-compiler by binding the result of mapcar to 1689 ;; Silence the byte-compiler by binding the result of mapcar to
1657 ;; a variable. 1690 ;; a variable.
1658 res))) 1691 res)))
@@ -1660,7 +1693,7 @@ nil."
1660;; (iswitchb-mode) will autoload iswitchb.el 1693;; (iswitchb-mode) will autoload iswitchb.el
1661(defvar iswitchb-temp-buflist) 1694(defvar iswitchb-temp-buflist)
1662(declare-function iswitchb-read-buffer "iswitchb" 1695(declare-function iswitchb-read-buffer "iswitchb"
1663 (prompt &optional default require-match start matches-set)) 1696 (prompt &optional default require-match start matches-set))
1664(defvar iswitchb-make-buflist-hook) 1697(defvar iswitchb-make-buflist-hook)
1665 1698
1666(defun erc-iswitchb (&optional arg) 1699(defun erc-iswitchb (&optional arg)
@@ -1676,20 +1709,20 @@ needs to be active for this function to work."
1676 (let ((enabled (bound-and-true-p iswitchb-mode))) 1709 (let ((enabled (bound-and-true-p iswitchb-mode)))
1677 (or enabled (iswitchb-mode 1)) 1710 (or enabled (iswitchb-mode 1))
1678 (unwind-protect 1711 (unwind-protect
1679 (let ((iswitchb-make-buflist-hook 1712 (let ((iswitchb-make-buflist-hook
1680 (lambda () 1713 (lambda ()
1681 (setq iswitchb-temp-buflist 1714 (setq iswitchb-temp-buflist
1682 (mapcar 'buffer-name 1715 (mapcar 'buffer-name
1683 (erc-buffer-list 1716 (erc-buffer-list
1684 nil 1717 nil
1685 (when arg erc-server-process))))))) 1718 (when arg erc-server-process)))))))
1686 (switch-to-buffer 1719 (switch-to-buffer
1687 (iswitchb-read-buffer 1720 (iswitchb-read-buffer
1688 "Switch-to: " 1721 "Switch-to: "
1689 (if (boundp 'erc-modified-channels-alist) 1722 (if (boundp 'erc-modified-channels-alist)
1690 (buffer-name (caar (last erc-modified-channels-alist))) 1723 (buffer-name (caar (last erc-modified-channels-alist)))
1691 nil) 1724 nil)
1692 t))) 1725 t)))
1693 (or enabled (iswitchb-mode -1))))) 1726 (or enabled (iswitchb-mode -1)))))
1694 1727
1695(defun erc-channel-list (proc) 1728(defun erc-channel-list (proc)
@@ -1699,7 +1732,7 @@ all channel buffers on all servers."
1699 (erc-buffer-filter 1732 (erc-buffer-filter
1700 (lambda () 1733 (lambda ()
1701 (and (erc-default-target) 1734 (and (erc-default-target)
1702 (erc-channel-p (erc-default-target)))) 1735 (erc-channel-p (erc-default-target))))
1703 proc)) 1736 proc))
1704 1737
1705(defun erc-buffer-list-with-nick (nick proc) 1738(defun erc-buffer-list-with-nick (nick proc)
@@ -1707,8 +1740,8 @@ all channel buffers on all servers."
1707 (with-current-buffer (process-buffer proc) 1740 (with-current-buffer (process-buffer proc)
1708 (let ((user (gethash (erc-downcase nick) erc-server-users))) 1741 (let ((user (gethash (erc-downcase nick) erc-server-users)))
1709 (if user 1742 (if user
1710 (erc-server-user-buffers user) 1743 (erc-server-user-buffers user)
1711 nil)))) 1744 nil))))
1712 1745
1713;; Some local variables 1746;; Some local variables
1714 1747
@@ -1766,31 +1799,31 @@ buffer rather than a server buffer.")
1766 (let ((transforms '((pcomplete . completion)))) 1799 (let ((transforms '((pcomplete . completion))))
1767 (erc-delete-dups 1800 (erc-delete-dups
1768 (mapcar (lambda (m) (or (cdr (assoc m transforms)) m)) 1801 (mapcar (lambda (m) (or (cdr (assoc m transforms)) m))
1769 mods)))) 1802 mods))))
1770 1803
1771(defcustom erc-modules '(netsplit fill button match track completion readonly 1804(defcustom erc-modules '(netsplit fill button match track completion readonly
1772 networks ring autojoin noncommands irccontrols 1805 networks ring autojoin noncommands irccontrols
1773 move-to-prompt stamp menu list) 1806 move-to-prompt stamp menu list)
1774 "A list of modules which ERC should enable. 1807 "A list of modules which ERC should enable.
1775If you set the value of this without using `customize' remember to call 1808If you set the value of this without using `customize' remember to call
1776\(erc-update-modules) after you change it. When using `customize', modules 1809\(erc-update-modules) after you change it. When using `customize', modules
1777removed from the list will be disabled." 1810removed from the list will be disabled."
1778 :get (lambda (sym) 1811 :get (lambda (sym)
1779 ;; replace outdated names with their newer equivalents 1812 ;; replace outdated names with their newer equivalents
1780 (erc-migrate-modules (symbol-value sym))) 1813 (erc-migrate-modules (symbol-value sym)))
1781 :set (lambda (sym val) 1814 :set (lambda (sym val)
1782 ;; disable modules which have just been removed 1815 ;; disable modules which have just been removed
1783 (when (and (boundp 'erc-modules) erc-modules val) 1816 (when (and (boundp 'erc-modules) erc-modules val)
1784 (dolist (module erc-modules) 1817 (dolist (module erc-modules)
1785 (unless (member module val) 1818 (unless (member module val)
1786 (let ((f (intern-soft (format "erc-%s-mode" module)))) 1819 (let ((f (intern-soft (format "erc-%s-mode" module))))
1787 (when (and (fboundp f) (boundp f) (symbol-value f)) 1820 (when (and (fboundp f) (boundp f) (symbol-value f))
1788 (message "Disabling `erc-%s'" module) 1821 (message "Disabling `erc-%s'" module)
1789 (funcall f 0)))))) 1822 (funcall f 0))))))
1790 (set sym val) 1823 (set sym val)
1791 ;; this test is for the case where erc hasn't been loaded yet 1824 ;; this test is for the case where erc hasn't been loaded yet
1792 (when (fboundp 'erc-update-modules) 1825 (when (fboundp 'erc-update-modules)
1793 (erc-update-modules))) 1826 (erc-update-modules)))
1794 :type 1827 :type
1795 '(set 1828 '(set
1796 :greedy t 1829 :greedy t
@@ -1798,42 +1831,42 @@ removed from the list will be disabled."
1798 (const :tag "autojoin: Join channels automatically" autojoin) 1831 (const :tag "autojoin: Join channels automatically" autojoin)
1799 (const :tag "button: Buttonize URLs, nicknames, and other text" button) 1832 (const :tag "button: Buttonize URLs, nicknames, and other text" button)
1800 (const :tag "capab: Mark unidentified users on servers supporting CAPAB" 1833 (const :tag "capab: Mark unidentified users on servers supporting CAPAB"
1801 capab-identify) 1834 capab-identify)
1802 (const :tag "completion: Complete nicknames and commands (programmable)" 1835 (const :tag "completion: Complete nicknames and commands (programmable)"
1803 completion) 1836 completion)
1804 (const :tag "hecomplete: Complete nicknames and commands (obsolete, use \"completion\")" hecomplete) 1837 (const :tag "hecomplete: Complete nicknames and commands (obsolete, use \"completion\")" hecomplete)
1805 (const :tag "dcc: Provide Direct Client-to-Client support" dcc) 1838 (const :tag "dcc: Provide Direct Client-to-Client support" dcc)
1806 (const :tag "fill: Wrap long lines" fill) 1839 (const :tag "fill: Wrap long lines" fill)
1807 (const :tag "identd: Launch an identd server on port 8113" identd) 1840 (const :tag "identd: Launch an identd server on port 8113" identd)
1808 (const :tag "irccontrols: Highlight or remove IRC control characters" 1841 (const :tag "irccontrols: Highlight or remove IRC control characters"
1809 irccontrols) 1842 irccontrols)
1810 (const :tag "keep-place: Leave point above un-viewed text" keep-place) 1843 (const :tag "keep-place: Leave point above un-viewed text" keep-place)
1811 (const :tag "list: List channels in a separate buffer" list) 1844 (const :tag "list: List channels in a separate buffer" list)
1812 (const :tag "log: Save buffers in logs" log) 1845 (const :tag "log: Save buffers in logs" log)
1813 (const :tag "match: Highlight pals, fools, and other keywords" match) 1846 (const :tag "match: Highlight pals, fools, and other keywords" match)
1814 (const :tag "menu: Display a menu in ERC buffers" menu) 1847 (const :tag "menu: Display a menu in ERC buffers" menu)
1815 (const :tag "move-to-prompt: Move to the prompt when typing text" 1848 (const :tag "move-to-prompt: Move to the prompt when typing text"
1816 move-to-prompt) 1849 move-to-prompt)
1817 (const :tag "netsplit: Detect netsplits" netsplit) 1850 (const :tag "netsplit: Detect netsplits" netsplit)
1818 (const :tag "networks: Provide data about IRC networks" networks) 1851 (const :tag "networks: Provide data about IRC networks" networks)
1819 (const :tag "noncommands: Don't display non-IRC commands after evaluation" 1852 (const :tag "noncommands: Don't display non-IRC commands after evaluation"
1820 noncommands) 1853 noncommands)
1821 (const :tag 1854 (const :tag
1822 "notify: Notify when the online status of certain users changes" 1855 "notify: Notify when the online status of certain users changes"
1823 notify) 1856 notify)
1824 (const :tag "notifications: Send notifications on PRIVMSG or nickname mentions" 1857 (const :tag "notifications: Send notifications on PRIVMSG or nickname mentions"
1825 notifications) 1858 notifications)
1826 (const :tag "page: Process CTCP PAGE requests from IRC" page) 1859 (const :tag "page: Process CTCP PAGE requests from IRC" page)
1827 (const :tag "readonly: Make displayed lines read-only" readonly) 1860 (const :tag "readonly: Make displayed lines read-only" readonly)
1828 (const :tag "replace: Replace text in messages" replace) 1861 (const :tag "replace: Replace text in messages" replace)
1829 (const :tag "ring: Enable an input history" ring) 1862 (const :tag "ring: Enable an input history" ring)
1830 (const :tag "scrolltobottom: Scroll to the bottom of the buffer" 1863 (const :tag "scrolltobottom: Scroll to the bottom of the buffer"
1831 scrolltobottom) 1864 scrolltobottom)
1832 (const :tag "services: Identify to Nickserv (IRC Services) automatically" 1865 (const :tag "services: Identify to Nickserv (IRC Services) automatically"
1833 services) 1866 services)
1834 (const :tag "smiley: Convert smileys to pretty icons" smiley) 1867 (const :tag "smiley: Convert smileys to pretty icons" smiley)
1835 (const :tag "sound: Play sounds when you receive CTCP SOUND requests" 1868 (const :tag "sound: Play sounds when you receive CTCP SOUND requests"
1836 sound) 1869 sound)
1837 (const :tag "stamp: Add timestamps to messages" stamp) 1870 (const :tag "stamp: Add timestamps to messages" stamp)
1838 (const :tag "spelling: Check spelling" spelling) 1871 (const :tag "spelling: Check spelling" spelling)
1839 (const :tag "track: Track channel activity in the mode-line" track) 1872 (const :tag "track: Track channel activity in the mode-line" track)
@@ -1851,27 +1884,27 @@ removed from the list will be disabled."
1851 (cond 1884 (cond
1852 ;; yuck. perhaps we should bring the filenames into sync? 1885 ;; yuck. perhaps we should bring the filenames into sync?
1853 ((string= req "erc-capab-identify") 1886 ((string= req "erc-capab-identify")
1854 (setq req "erc-capab")) 1887 (setq req "erc-capab"))
1855 ((string= req "erc-completion") 1888 ((string= req "erc-completion")
1856 (setq req "erc-pcomplete")) 1889 (setq req "erc-pcomplete"))
1857 ((string= req "erc-pcomplete") 1890 ((string= req "erc-pcomplete")
1858 (setq mod 'completion)) 1891 (setq mod 'completion))
1859 ((string= req "erc-autojoin") 1892 ((string= req "erc-autojoin")
1860 (setq req "erc-join"))) 1893 (setq req "erc-join")))
1861 (condition-case nil 1894 (condition-case nil
1862 (require (intern req)) 1895 (require (intern req))
1863 (error nil)) 1896 (error nil))
1864 (let ((sym (intern-soft (concat "erc-" (symbol-name mod) "-mode")))) 1897 (let ((sym (intern-soft (concat "erc-" (symbol-name mod) "-mode"))))
1865 (if (fboundp sym) 1898 (if (fboundp sym)
1866 (funcall sym 1) 1899 (funcall sym 1)
1867 (error "`%s' is not a known ERC module" mod)))))) 1900 (error "`%s' is not a known ERC module" mod))))))
1868 1901
1869(defun erc-setup-buffer (buffer) 1902(defun erc-setup-buffer (buffer)
1870 "Consults `erc-join-buffer' to find out how to display `BUFFER'." 1903 "Consults `erc-join-buffer' to find out how to display `BUFFER'."
1871 (pcase erc-join-buffer 1904 (pcase erc-join-buffer
1872 (`window 1905 (`window
1873 (if (active-minibuffer-window) 1906 (if (active-minibuffer-window)
1874 (display-buffer buffer) 1907 (display-buffer buffer)
1875 (switch-to-buffer-other-window buffer))) 1908 (switch-to-buffer-other-window buffer)))
1876 (`window-noselect 1909 (`window-noselect
1877 (display-buffer buffer)) 1910 (display-buffer buffer))
@@ -1879,21 +1912,21 @@ removed from the list will be disabled."
1879 nil) 1912 nil)
1880 (`frame 1913 (`frame
1881 (when (or (not erc-reuse-frames) 1914 (when (or (not erc-reuse-frames)
1882 (not (get-buffer-window buffer t))) 1915 (not (get-buffer-window buffer t)))
1883 (let ((frame (make-frame (or erc-frame-alist 1916 (let ((frame (make-frame (or erc-frame-alist
1884 default-frame-alist)))) 1917 default-frame-alist))))
1885 (raise-frame frame) 1918 (raise-frame frame)
1886 (select-frame frame)) 1919 (select-frame frame))
1887 (switch-to-buffer buffer) 1920 (switch-to-buffer buffer)
1888 (when erc-frame-dedicated-flag 1921 (when erc-frame-dedicated-flag
1889 (set-window-dedicated-p (selected-window) t)))) 1922 (set-window-dedicated-p (selected-window) t))))
1890 (_ 1923 (_
1891 (if (active-minibuffer-window) 1924 (if (active-minibuffer-window)
1892 (display-buffer buffer) 1925 (display-buffer buffer)
1893 (switch-to-buffer buffer))))) 1926 (switch-to-buffer buffer)))))
1894 1927
1895(defun erc-open (&optional server port nick full-name 1928(defun erc-open (&optional server port nick full-name
1896 connect passwd tgt-list channel process) 1929 connect passwd tgt-list channel process)
1897 "Connect to SERVER on PORT as NICK with FULL-NAME. 1930 "Connect to SERVER on PORT as NICK with FULL-NAME.
1898 1931
1899If CONNECT is non-nil, connect to the server. Otherwise assume 1932If CONNECT is non-nil, connect to the server. Otherwise assume
@@ -1905,13 +1938,13 @@ non-nil, use it to initialize `erc-default-recipients'.
1905 1938
1906Returns the buffer for the given server or channel." 1939Returns the buffer for the given server or channel."
1907 (let ((server-announced-name (when (and (boundp 'erc-session-server) 1940 (let ((server-announced-name (when (and (boundp 'erc-session-server)
1908 (string= server erc-session-server)) 1941 (string= server erc-session-server))
1909 erc-server-announced-name)) 1942 erc-server-announced-name))
1910 (connected-p (unless connect erc-server-connected)) 1943 (connected-p (unless connect erc-server-connected))
1911 (buffer (erc-get-buffer-create server port channel)) 1944 (buffer (erc-get-buffer-create server port channel))
1912 (old-buffer (current-buffer)) 1945 (old-buffer (current-buffer))
1913 old-point 1946 old-point
1914 continued-session) 1947 continued-session)
1915 (when connect (run-hook-with-args 'erc-before-connect server port nick)) 1948 (when connect (run-hook-with-args 'erc-before-connect server port nick))
1916 (erc-update-modules) 1949 (erc-update-modules)
1917 (set-buffer buffer) 1950 (set-buffer buffer)
@@ -1930,8 +1963,8 @@ Returns the buffer for the given server or channel."
1930 (when (get-text-property (point) 'erc-prompt) 1963 (when (get-text-property (point) 'erc-prompt)
1931 (setq continued-session t) 1964 (setq continued-session t)
1932 (set-marker erc-input-marker 1965 (set-marker erc-input-marker
1933 (or (next-single-property-change (point) 'erc-prompt) 1966 (or (next-single-property-change (point) 'erc-prompt)
1934 (point-max)))) 1967 (point-max))))
1935 (unless continued-session 1968 (unless continued-session
1936 (goto-char (point-max)) 1969 (goto-char (point-max))
1937 (insert "\n")) 1970 (insert "\n"))
@@ -1941,14 +1974,14 @@ Returns the buffer for the given server or channel."
1941 (setq erc-server-current-nick nil) 1974 (setq erc-server-current-nick nil)
1942 ;; Initialize erc-server-users and erc-channel-users 1975 ;; Initialize erc-server-users and erc-channel-users
1943 (if connect 1976 (if connect
1944 (progn ;; server buffer 1977 (progn ;; server buffer
1945 (setq erc-server-users 1978 (setq erc-server-users
1946 (make-hash-table :test 'equal)) 1979 (make-hash-table :test 'equal))
1947 (setq erc-channel-users nil)) 1980 (setq erc-channel-users nil))
1948 (progn ;; target buffer 1981 (progn ;; target buffer
1949 (setq erc-server-users nil) 1982 (setq erc-server-users nil)
1950 (setq erc-channel-users 1983 (setq erc-channel-users
1951 (make-hash-table :test 'equal)))) 1984 (make-hash-table :test 'equal))))
1952 ;; clear last incomplete line read 1985 ;; clear last incomplete line read
1953 (setq erc-server-filter-data nil) 1986 (setq erc-server-filter-data nil)
1954 (setq erc-channel-topic "") 1987 (setq erc-channel-topic "")
@@ -1969,29 +2002,29 @@ Returns the buffer for the given server or channel."
1969 (setq erc-default-nicks (if (consp erc-nick) erc-nick (list erc-nick))) 2002 (setq erc-default-nicks (if (consp erc-nick) erc-nick (list erc-nick)))
1970 ;; password stuff 2003 ;; password stuff
1971 (setq erc-session-password 2004 (setq erc-session-password
1972 (or passwd 2005 (or passwd
1973 (let ((secret 2006 (let ((secret
1974 (plist-get 2007 (plist-get
1975 (nth 0 2008 (nth 0
1976 (auth-source-search :host server 2009 (auth-source-search :host server
1977 :max 1 2010 :max 1
1978 :user nick 2011 :user nick
1979 :port port 2012 :port port
1980 :require '(:secret))) 2013 :require '(:secret)))
1981 :secret))) 2014 :secret)))
1982 (if (functionp secret) 2015 (if (functionp secret)
1983 (funcall secret) 2016 (funcall secret)
1984 secret)))) 2017 secret))))
1985 ;; debug output buffer 2018 ;; debug output buffer
1986 (setq erc-dbuf 2019 (setq erc-dbuf
1987 (when erc-log-p 2020 (when erc-log-p
1988 (get-buffer-create (concat "*ERC-DEBUG: " server "*")))) 2021 (get-buffer-create (concat "*ERC-DEBUG: " server "*"))))
1989 ;; set up prompt 2022 ;; set up prompt
1990 (unless continued-session 2023 (unless continued-session
1991 (goto-char (point-max)) 2024 (goto-char (point-max))
1992 (insert "\n")) 2025 (insert "\n"))
1993 (if continued-session 2026 (if continued-session
1994 (goto-char old-point) 2027 (goto-char old-point)
1995 (set-marker erc-insert-marker (point)) 2028 (set-marker erc-insert-marker (point))
1996 (erc-display-prompt) 2029 (erc-display-prompt)
1997 (goto-char (point-max))) 2030 (goto-char (point-max)))
@@ -2008,9 +2041,9 @@ Returns the buffer for the given server or channel."
2008 ;; Now display the buffer in a window as per user wishes. 2041 ;; Now display the buffer in a window as per user wishes.
2009 (unless (eq buffer old-buffer) 2042 (unless (eq buffer old-buffer)
2010 (when erc-log-p 2043 (when erc-log-p
2011 ;; we can't log to debug buffer, it may not exist yet 2044 ;; we can't log to debug buffer, it may not exist yet
2012 (message "erc: old buffer %s, switching to %s" 2045 (message "erc: old buffer %s, switching to %s"
2013 old-buffer buffer)) 2046 old-buffer buffer))
2014 (erc-setup-buffer buffer)) 2047 (erc-setup-buffer buffer))
2015 2048
2016 buffer)) 2049 buffer))
@@ -2021,7 +2054,7 @@ BUFFER is the current buffer."
2021 (with-current-buffer buffer 2054 (with-current-buffer buffer
2022 (setq erc-last-saved-position (make-marker)) 2055 (setq erc-last-saved-position (make-marker))
2023 (move-marker erc-last-saved-position 2056 (move-marker erc-last-saved-position
2024 (1- (marker-position erc-insert-marker))))) 2057 (1- (marker-position erc-insert-marker)))))
2025 2058
2026;; interactive startup 2059;; interactive startup
2027 2060
@@ -2039,9 +2072,9 @@ If no buffer matches, return nil."
2039 (erc-buffer-list 2072 (erc-buffer-list
2040 (lambda () 2073 (lambda ()
2041 (and (erc-server-process-alive) 2074 (and (erc-server-process-alive)
2042 (string= erc-session-server server) 2075 (string= erc-session-server server)
2043 (erc-port-equal erc-session-port port) 2076 (erc-port-equal erc-session-port port)
2044 (erc-current-nick-p nick))))) 2077 (erc-current-nick-p nick)))))
2045 2078
2046(defcustom erc-before-connect nil 2079(defcustom erc-before-connect nil
2047 "Hook called before connecting to a server. 2080 "Hook called before connecting to a server.
@@ -2063,38 +2096,38 @@ functions in here get called with the parameters SERVER and NICK."
2063 "Prompt the user for values of nick, server, port, and password." 2096 "Prompt the user for values of nick, server, port, and password."
2064 (let (user-input server port nick passwd) 2097 (let (user-input server port nick passwd)
2065 (setq user-input (read-from-minibuffer 2098 (setq user-input (read-from-minibuffer
2066 "IRC server: " 2099 "IRC server: "
2067 (erc-compute-server) nil nil 'erc-server-history-list)) 2100 (erc-compute-server) nil nil 'erc-server-history-list))
2068 2101
2069 (if (string-match "\\(.*\\):\\(.*\\)\\'" user-input) 2102 (if (string-match "\\(.*\\):\\(.*\\)\\'" user-input)
2070 (setq port (erc-string-to-port (match-string 2 user-input)) 2103 (setq port (erc-string-to-port (match-string 2 user-input))
2071 user-input (match-string 1 user-input)) 2104 user-input (match-string 1 user-input))
2072 (setq port 2105 (setq port
2073 (erc-string-to-port (read-from-minibuffer 2106 (erc-string-to-port (read-from-minibuffer
2074 "IRC port: " (erc-port-to-string 2107 "IRC port: " (erc-port-to-string
2075 (erc-compute-port)))))) 2108 (erc-compute-port))))))
2076 2109
2077 (if (string-match "\\`\\(.*\\)@\\(.*\\)" user-input) 2110 (if (string-match "\\`\\(.*\\)@\\(.*\\)" user-input)
2078 (setq nick (match-string 1 user-input) 2111 (setq nick (match-string 1 user-input)
2079 user-input (match-string 2 user-input)) 2112 user-input (match-string 2 user-input))
2080 (setq nick 2113 (setq nick
2081 (if (erc-already-logged-in server port nick) 2114 (if (erc-already-logged-in server port nick)
2082 (read-from-minibuffer 2115 (read-from-minibuffer
2083 (erc-format-message 'nick-in-use ?n nick) 2116 (erc-format-message 'nick-in-use ?n nick)
2084 nick 2117 nick
2085 nil nil 'erc-nick-history-list) 2118 nil nil 'erc-nick-history-list)
2086 (read-from-minibuffer 2119 (read-from-minibuffer
2087 "Nickname: " (erc-compute-nick nick) 2120 "Nickname: " (erc-compute-nick nick)
2088 nil nil 'erc-nick-history-list)))) 2121 nil nil 'erc-nick-history-list))))
2089 2122
2090 (setq server user-input) 2123 (setq server user-input)
2091 2124
2092 (setq passwd (if erc-prompt-for-password 2125 (setq passwd (if erc-prompt-for-password
2093 (if (and erc-password 2126 (if (and erc-password
2094 (y-or-n-p "Use the default password? ")) 2127 (y-or-n-p "Use the default password? "))
2095 erc-password 2128 erc-password
2096 (read-passwd "Password: ")) 2129 (read-passwd "Password: "))
2097 erc-password)) 2130 erc-password))
2098 (when (and passwd (string= "" passwd)) 2131 (when (and passwd (string= "" passwd))
2099 (setq passwd nil)) 2132 (setq passwd nil))
2100 2133
@@ -2105,17 +2138,17 @@ functions in here get called with the parameters SERVER and NICK."
2105 ;; bncs transparent, so that erc-compute-buffer-name displays 2138 ;; bncs transparent, so that erc-compute-buffer-name displays
2106 ;; the server one is connected to. 2139 ;; the server one is connected to.
2107 (setq nick (read-from-minibuffer 2140 (setq nick (read-from-minibuffer
2108 (erc-format-message 'nick-in-use ?n nick) 2141 (erc-format-message 'nick-in-use ?n nick)
2109 nick 2142 nick
2110 nil nil 'erc-nick-history-list))) 2143 nil nil 'erc-nick-history-list)))
2111 (list :server server :port port :nick nick :password passwd))) 2144 (list :server server :port port :nick nick :password passwd)))
2112 2145
2113;;;###autoload 2146;;;###autoload
2114(cl-defun erc (&key (server (erc-compute-server)) 2147(cl-defun erc (&key (server (erc-compute-server))
2115 (port (erc-compute-port)) 2148 (port (erc-compute-port))
2116 (nick (erc-compute-nick)) 2149 (nick (erc-compute-nick))
2117 password 2150 password
2118 (full-name (erc-compute-full-name))) 2151 (full-name (erc-compute-full-name)))
2119 "ERC is a powerful, modular, and extensible IRC client. 2152 "ERC is a powerful, modular, and extensible IRC client.
2120This function is the main entry point for ERC. 2153This function is the main entry point for ERC.
2121 2154
@@ -2155,7 +2188,7 @@ Arguments are the same as for `erc'."
2155The process will be given the name NAME, its target buffer will be 2188The process will be given the name NAME, its target buffer will be
2156BUFFER. HOST and PORT specify the connection target." 2189BUFFER. HOST and PORT specify the connection target."
2157 (open-network-stream name buffer host port 2190 (open-network-stream name buffer host port
2158 :type 'tls)) 2191 :type 'tls))
2159 2192
2160;;; Displaying error messages 2193;;; Displaying error messages
2161 2194
@@ -2195,36 +2228,36 @@ If OUTBOUND is non-nil, STRING is being sent to the IRC server
2195and appears in face `erc-input-face' in the buffer." 2228and appears in face `erc-input-face' in the buffer."
2196 (when erc-debug-irc-protocol 2229 (when erc-debug-irc-protocol
2197 (let ((network-name (or (ignore-errors (erc-network-name)) 2230 (let ((network-name (or (ignore-errors (erc-network-name))
2198 "???"))) 2231 "???")))
2199 (with-current-buffer (get-buffer-create "*erc-protocol*") 2232 (with-current-buffer (get-buffer-create "*erc-protocol*")
2200 (save-excursion 2233 (save-excursion
2201 (goto-char (point-max)) 2234 (goto-char (point-max))
2202 (let ((inhibit-read-only t)) 2235 (let ((inhibit-read-only t))
2203 (insert (if (not outbound) 2236 (insert (if (not outbound)
2204 ;; Cope with the fact that string might 2237 ;; Cope with the fact that string might
2205 ;; contain multiple lines of text. 2238 ;; contain multiple lines of text.
2206 (let ((lines (delete "" (split-string string 2239 (let ((lines (delete "" (split-string string
2207 "\n\\|\r\n"))) 2240 "\n\\|\r\n")))
2208 (result "")) 2241 (result ""))
2209 (dolist (line lines) 2242 (dolist (line lines)
2210 (setq result (concat result network-name 2243 (setq result (concat result network-name
2211 " << " line "\n"))) 2244 " << " line "\n")))
2212 result) 2245 result)
2213 (erc-propertize 2246 (erc-propertize
2214 (concat network-name " >> " string 2247 (concat network-name " >> " string
2215 (if (/= ?\n 2248 (if (/= ?\n
2216 (aref string 2249 (aref string
2217 (1- (length string)))) 2250 (1- (length string))))
2218 "\n")) 2251 "\n"))
2219 'face 'erc-input-face))))) 2252 'face 'erc-input-face)))))
2220 (let ((orig-win (selected-window)) 2253 (let ((orig-win (selected-window))
2221 (debug-buffer-window (get-buffer-window (current-buffer) t))) 2254 (debug-buffer-window (get-buffer-window (current-buffer) t)))
2222 (when debug-buffer-window 2255 (when debug-buffer-window
2223 (select-window debug-buffer-window) 2256 (select-window debug-buffer-window)
2224 (when (= 1 (count-lines (point) (point-max))) 2257 (when (= 1 (count-lines (point) (point-max)))
2225 (goto-char (point-max)) 2258 (goto-char (point-max))
2226 (recenter -1)) 2259 (recenter -1))
2227 (select-window orig-win))))))) 2260 (select-window orig-win)))))))
2228 2261
2229(defun erc-toggle-debug-irc-protocol (&optional arg) 2262(defun erc-toggle-debug-irc-protocol (&optional arg)
2230 "Toggle the value of `erc-debug-irc-protocol'. 2263 "Toggle the value of `erc-debug-irc-protocol'.
@@ -2235,26 +2268,26 @@ If ARG is non-nil, show the *erc-protocol* buffer."
2235 (with-current-buffer buf 2268 (with-current-buffer buf
2236 (erc-view-mode-enter) 2269 (erc-view-mode-enter)
2237 (when (null (current-local-map)) 2270 (when (null (current-local-map))
2238 (let ((inhibit-read-only t)) 2271 (let ((inhibit-read-only t))
2239 (insert (erc-make-notice "This buffer displays all IRC protocol traffic exchanged with each server.\n")) 2272 (insert (erc-make-notice "This buffer displays all IRC protocol traffic exchanged with each server.\n"))
2240 (insert (erc-make-notice "Kill this buffer to terminate protocol logging.\n\n"))) 2273 (insert (erc-make-notice "Kill this buffer to terminate protocol logging.\n\n")))
2241 (use-local-map (make-sparse-keymap)) 2274 (use-local-map (make-sparse-keymap))
2242 (local-set-key (kbd "t") 'erc-toggle-debug-irc-protocol)) 2275 (local-set-key (kbd "t") 'erc-toggle-debug-irc-protocol))
2243 (add-hook 'kill-buffer-hook 2276 (add-hook 'kill-buffer-hook
2244 #'(lambda () (setq erc-debug-irc-protocol nil)) 2277 #'(lambda () (setq erc-debug-irc-protocol nil))
2245 nil 'local) 2278 nil 'local)
2246 (goto-char (point-max)) 2279 (goto-char (point-max))
2247 (let ((inhibit-read-only t)) 2280 (let ((inhibit-read-only t))
2248 (insert (erc-make-notice 2281 (insert (erc-make-notice
2249 (format "IRC protocol logging %s at %s -- Press `t' to toggle logging.\n" 2282 (format "IRC protocol logging %s at %s -- Press `t' to toggle logging.\n"
2250 (if erc-debug-irc-protocol "disabled" "enabled") 2283 (if erc-debug-irc-protocol "disabled" "enabled")
2251 (current-time-string)))))) 2284 (current-time-string))))))
2252 (setq erc-debug-irc-protocol (not erc-debug-irc-protocol)) 2285 (setq erc-debug-irc-protocol (not erc-debug-irc-protocol))
2253 (if (and arg 2286 (if (and arg
2254 (not (get-buffer-window "*erc-protocol*" t))) 2287 (not (get-buffer-window "*erc-protocol*" t)))
2255 (display-buffer buf t)) 2288 (display-buffer buf t))
2256 (message "IRC protocol traffic logging %s (see buffer *erc-protocol*)." 2289 (message "IRC protocol traffic logging %s (see buffer *erc-protocol*)."
2257 (if erc-debug-irc-protocol "enabled" "disabled")))) 2290 (if erc-debug-irc-protocol "enabled" "disabled"))))
2258 2291
2259;;; I/O interface 2292;;; I/O interface
2260 2293
@@ -2293,69 +2326,69 @@ If STRING is nil, the function does nothing."
2293 (when string 2326 (when string
2294 (with-current-buffer (or buffer (process-buffer erc-server-process)) 2327 (with-current-buffer (or buffer (process-buffer erc-server-process))
2295 (let ((insert-position (or (marker-position erc-insert-marker) 2328 (let ((insert-position (or (marker-position erc-insert-marker)
2296 (point-max)))) 2329 (point-max))))
2297 (let ((string string) ;; FIXME! Can this be removed? 2330 (let ((string string) ;; FIXME! Can this be removed?
2298 (buffer-undo-list t) 2331 (buffer-undo-list t)
2299 (inhibit-read-only t)) 2332 (inhibit-read-only t))
2300 (unless (string-match "\n$" string) 2333 (unless (string-match "\n$" string)
2301 (setq string (concat string "\n")) 2334 (setq string (concat string "\n"))
2302 (when (erc-string-invisible-p string) 2335 (when (erc-string-invisible-p string)
2303 (erc-put-text-properties 0 (length string) 2336 (erc-put-text-properties 0 (length string)
2304 '(invisible intangible) string))) 2337 '(invisible intangible) string)))
2305 (erc-log (concat "erc-display-line: " string 2338 (erc-log (concat "erc-display-line: " string
2306 (format "(%S)" string) " in buffer " 2339 (format "(%S)" string) " in buffer "
2307 (format "%s" buffer))) 2340 (format "%s" buffer)))
2308 (setq erc-insert-this t) 2341 (setq erc-insert-this t)
2309 (run-hook-with-args 'erc-insert-pre-hook string) 2342 (run-hook-with-args 'erc-insert-pre-hook string)
2310 (if (null erc-insert-this) 2343 (if (null erc-insert-this)
2311 ;; Leave erc-insert-this set to t as much as possible. Fran 2344 ;; Leave erc-insert-this set to t as much as possible. Fran
2312 ;; Litterio <franl> has seen erc-insert-this set to nil while 2345 ;; Litterio <franl> has seen erc-insert-this set to nil while
2313 ;; erc-send-pre-hook is running, which should never happen. This 2346 ;; erc-send-pre-hook is running, which should never happen. This
2314 ;; may cure it. 2347 ;; may cure it.
2315 (setq erc-insert-this t) 2348 (setq erc-insert-this t)
2316 (save-excursion ;; to restore point in the new buffer 2349 (save-excursion ;; to restore point in the new buffer
2317 (save-restriction 2350 (save-restriction
2318 (widen) 2351 (widen)
2319 (goto-char insert-position) 2352 (goto-char insert-position)
2320 (insert-before-markers string) 2353 (insert-before-markers string)
2321 ;; run insertion hook, with point at restored location 2354 ;; run insertion hook, with point at restored location
2322 (save-restriction 2355 (save-restriction
2323 (narrow-to-region insert-position (point)) 2356 (narrow-to-region insert-position (point))
2324 (run-hooks 'erc-insert-modify-hook) 2357 (run-hooks 'erc-insert-modify-hook)
2325 (run-hooks 'erc-insert-post-hook) 2358 (run-hooks 'erc-insert-post-hook)
2326 (when erc-remove-parsed-property 2359 (when erc-remove-parsed-property
2327 (remove-text-properties (point-min) (point-max) 2360 (remove-text-properties (point-min) (point-max)
2328 '(erc-parsed nil)))))))) 2361 '(erc-parsed nil))))))))
2329 (erc-update-undo-list (- (or (marker-position erc-insert-marker) 2362 (erc-update-undo-list (- (or (marker-position erc-insert-marker)
2330 (point-max)) 2363 (point-max))
2331 insert-position)))))) 2364 insert-position))))))
2332 2365
2333(defun erc-update-undo-list (shift) 2366(defun erc-update-undo-list (shift)
2334 ;; Translate buffer positions in buffer-undo-list by SHIFT. 2367 ;; Translate buffer positions in buffer-undo-list by SHIFT.
2335 (unless (or (zerop shift) (atom buffer-undo-list)) 2368 (unless (or (zerop shift) (atom buffer-undo-list))
2336 (let ((list buffer-undo-list) elt) 2369 (let ((list buffer-undo-list) elt)
2337 (while list 2370 (while list
2338 (setq elt (car list)) 2371 (setq elt (car list))
2339 (cond ((integerp elt) ; POSITION 2372 (cond ((integerp elt) ; POSITION
2340 (cl-incf (car list) shift)) 2373 (cl-incf (car list) shift))
2341 ((or (atom elt) ; nil, EXTENT 2374 ((or (atom elt) ; nil, EXTENT
2342 ;; (eq t (car elt)) ; (t . TIME) 2375 ;; (eq t (car elt)) ; (t . TIME)
2343 (markerp (car elt))) ; (MARKER . DISTANCE) 2376 (markerp (car elt))) ; (MARKER . DISTANCE)
2344 nil) 2377 nil)
2345 ((integerp (car elt)) ; (BEGIN . END) 2378 ((integerp (car elt)) ; (BEGIN . END)
2346 (cl-incf (car elt) shift) 2379 (cl-incf (car elt) shift)
2347 (cl-incf (cdr elt) shift)) 2380 (cl-incf (cdr elt) shift))
2348 ((stringp (car elt)) ; (TEXT . POSITION) 2381 ((stringp (car elt)) ; (TEXT . POSITION)
2349 (cl-incf (cdr elt) (* (if (natnump (cdr elt)) 1 -1) shift))) 2382 (cl-incf (cdr elt) (* (if (natnump (cdr elt)) 1 -1) shift)))
2350 ((null (car elt)) ; (nil PROPERTY VALUE BEG . END) 2383 ((null (car elt)) ; (nil PROPERTY VALUE BEG . END)
2351 (let ((cons (nthcdr 3 elt))) 2384 (let ((cons (nthcdr 3 elt)))
2352 (cl-incf (car cons) shift) 2385 (cl-incf (car cons) shift)
2353 (cl-incf (cdr cons) shift))) 2386 (cl-incf (cdr cons) shift)))
2354 ((and (featurep 'xemacs) 2387 ((and (featurep 'xemacs)
2355 (extentp (car elt))) ; (EXTENT START END) 2388 (extentp (car elt))) ; (EXTENT START END)
2356 (cl-incf (nth 1 elt) shift) 2389 (cl-incf (nth 1 elt) shift)
2357 (cl-incf (nth 2 elt) shift))) 2390 (cl-incf (nth 2 elt) shift)))
2358 (setq list (cdr list)))))) 2391 (setq list (cdr list))))))
2359 2392
2360(defvar erc-valid-nick-regexp "[]a-zA-Z^[;\\`_{}|][]^[;\\`_{}|a-zA-Z0-9-]*" 2393(defvar erc-valid-nick-regexp "[]a-zA-Z^[;\\`_{}|][]^[;\\`_{}|a-zA-Z0-9-]*"
2361 "Regexp which matches all valid characters in a IRC nickname.") 2394 "Regexp which matches all valid characters in a IRC nickname.")
@@ -2376,41 +2409,41 @@ buffer is used. `erc-display-line-1' is used to display STRING.
2376 2409
2377If STRING is nil, the function does nothing." 2410If STRING is nil, the function does nothing."
2378 (let ((inhibit-point-motion-hooks t) 2411 (let ((inhibit-point-motion-hooks t)
2379 new-bufs) 2412 new-bufs)
2380 (dolist (buf (cond 2413 (dolist (buf (cond
2381 ((bufferp buffer) (list buffer)) 2414 ((bufferp buffer) (list buffer))
2382 ((listp buffer) buffer) 2415 ((listp buffer) buffer)
2383 ((processp buffer) (list (process-buffer buffer))) 2416 ((processp buffer) (list (process-buffer buffer)))
2384 ((eq 'all buffer) 2417 ((eq 'all buffer)
2385 ;; Hmm, or all of the same session server? 2418 ;; Hmm, or all of the same session server?
2386 (erc-buffer-list nil erc-server-process)) 2419 (erc-buffer-list nil erc-server-process))
2387 ((and (eq 'active buffer) (erc-active-buffer)) 2420 ((and (eq 'active buffer) (erc-active-buffer))
2388 (list (erc-active-buffer))) 2421 (list (erc-active-buffer)))
2389 ((erc-server-buffer-live-p) 2422 ((erc-server-buffer-live-p)
2390 (list (process-buffer erc-server-process))) 2423 (list (process-buffer erc-server-process)))
2391 (t (list (current-buffer))))) 2424 (t (list (current-buffer)))))
2392 (when (buffer-live-p buf) 2425 (when (buffer-live-p buf)
2393 (erc-display-line-1 string buf) 2426 (erc-display-line-1 string buf)
2394 (push buf new-bufs))) 2427 (push buf new-bufs)))
2395 (when (null new-bufs) 2428 (when (null new-bufs)
2396 (erc-display-line-1 string (if (erc-server-buffer-live-p) 2429 (erc-display-line-1 string (if (erc-server-buffer-live-p)
2397 (process-buffer erc-server-process) 2430 (process-buffer erc-server-process)
2398 (current-buffer)))))) 2431 (current-buffer))))))
2399 2432
2400(defun erc-display-message-highlight (type string) 2433(defun erc-display-message-highlight (type string)
2401 "Highlight STRING according to TYPE, where erc-TYPE-face is an ERC face. 2434 "Highlight STRING according to TYPE, where erc-TYPE-face is an ERC face.
2402 2435
2403See also `erc-make-notice'." 2436See also `erc-make-notice'."
2404 (cond ((eq type 'notice) 2437 (cond ((eq type 'notice)
2405 (erc-make-notice string)) 2438 (erc-make-notice string))
2406 (t 2439 (t
2407 (erc-put-text-property 2440 (erc-put-text-property
2408 0 (length string) 2441 0 (length string)
2409 'face (or (intern-soft 2442 'face (or (intern-soft
2410 (concat "erc-" (symbol-name type) "-face")) 2443 (concat "erc-" (symbol-name type) "-face"))
2411 "erc-default-face") 2444 "erc-default-face")
2412 string) 2445 string)
2413 string))) 2446 string)))
2414 2447
2415(defvar erc-lurker-state nil 2448(defvar erc-lurker-state nil
2416 "Track the time of the last PRIVMSG for each (server,nick) pair. 2449 "Track the time of the last PRIVMSG for each (server,nick) pair.
@@ -2487,15 +2520,15 @@ consumption for long-lived IRC or Emacs sessions."
2487 (lambda (server hash) 2520 (lambda (server hash)
2488 (maphash 2521 (maphash
2489 (lambda (nick last-PRIVMSG-time) 2522 (lambda (nick last-PRIVMSG-time)
2490 (when 2523 (when
2491 (> (float-time (time-subtract 2524 (> (float-time (time-subtract
2492 (current-time) 2525 (current-time)
2493 last-PRIVMSG-time)) 2526 last-PRIVMSG-time))
2494 erc-lurker-threshold-time) 2527 erc-lurker-threshold-time)
2495 (remhash nick hash))) 2528 (remhash nick hash)))
2496 hash) 2529 hash)
2497 (if (zerop (hash-table-count hash)) 2530 (if (zerop (hash-table-count hash))
2498 (remhash server erc-lurker-state))) 2531 (remhash server erc-lurker-state)))
2499 erc-lurker-state)) 2532 erc-lurker-state))
2500 2533
2501(defvar erc-lurker-cleanup-count 0 2534(defvar erc-lurker-cleanup-count 0
@@ -2535,7 +2568,7 @@ updates of `erc-lurker-state'."
2535 (erc-canonicalize-server-name erc-server-announced-name))) 2568 (erc-canonicalize-server-name erc-server-announced-name)))
2536 (when (equal command "PRIVMSG") 2569 (when (equal command "PRIVMSG")
2537 (when (>= (cl-incf erc-lurker-cleanup-count) 2570 (when (>= (cl-incf erc-lurker-cleanup-count)
2538 erc-lurker-cleanup-interval) 2571 erc-lurker-cleanup-interval)
2539 (setq erc-lurker-cleanup-count 0) 2572 (setq erc-lurker-cleanup-count 0)
2540 (erc-lurker-cleanup)) 2573 (erc-lurker-cleanup))
2541 (unless (gethash server erc-lurker-state) 2574 (unless (gethash server erc-lurker-state)
@@ -2550,14 +2583,14 @@ Lurking is the condition where NICK has issued no PRIVMSG on this
2550server within `erc-lurker-threshold-time'. See also 2583server within `erc-lurker-threshold-time'. See also
2551`erc-lurker-trim-nicks' and `erc-lurker-ignore-chars'." 2584`erc-lurker-trim-nicks' and `erc-lurker-ignore-chars'."
2552 (unless erc-lurker-state (erc-lurker-initialize)) 2585 (unless erc-lurker-state (erc-lurker-initialize))
2553 (let* ((server 2586 (let* ((server
2554 (erc-canonicalize-server-name erc-server-announced-name)) 2587 (erc-canonicalize-server-name erc-server-announced-name))
2555 (last-PRIVMSG-time 2588 (last-PRIVMSG-time
2556 (gethash (erc-lurker-maybe-trim nick) 2589 (gethash (erc-lurker-maybe-trim nick)
2557 (gethash server erc-lurker-state (make-hash-table))))) 2590 (gethash server erc-lurker-state (make-hash-table)))))
2558 (or (null last-PRIVMSG-time) 2591 (or (null last-PRIVMSG-time)
2559 (> (float-time 2592 (> (float-time
2560 (time-subtract (current-time) last-PRIVMSG-time)) 2593 (time-subtract (current-time) last-PRIVMSG-time))
2561 erc-lurker-threshold-time)))) 2594 erc-lurker-threshold-time))))
2562 2595
2563(defcustom erc-common-server-suffixes 2596(defcustom erc-common-server-suffixes
@@ -2577,8 +2610,8 @@ otherwise `erc-server-announced-name'. SERVER is matched against
2577`erc-common-server-suffixes'." 2610`erc-common-server-suffixes'."
2578 (when server 2611 (when server
2579 (or (cdar (erc-remove-if-not 2612 (or (cdar (erc-remove-if-not
2580 (lambda (net) (string-match (car net) server)) 2613 (lambda (net) (string-match (car net) server))
2581 erc-common-server-suffixes)) 2614 erc-common-server-suffixes))
2582 erc-server-announced-name))) 2615 erc-server-announced-name)))
2583 2616
2584(defun erc-hide-current-message-p (parsed) 2617(defun erc-hide-current-message-p (parsed)
@@ -2599,27 +2632,27 @@ ARGS, PARSED, and TYPE are used to format MSG sensibly.
2599 2632
2600See also `erc-format-message' and `erc-display-line'." 2633See also `erc-format-message' and `erc-display-line'."
2601 (let ((string (if (symbolp msg) 2634 (let ((string (if (symbolp msg)
2602 (apply 'erc-format-message msg args) 2635 (apply 'erc-format-message msg args)
2603 msg))) 2636 msg)))
2604 (setq string 2637 (setq string
2605 (cond 2638 (cond
2606 ((null type) 2639 ((null type)
2607 string) 2640 string)
2608 ((listp type) 2641 ((listp type)
2609 (mapc (lambda (type) 2642 (mapc (lambda (type)
2610 (setq string 2643 (setq string
2611 (erc-display-message-highlight type string))) 2644 (erc-display-message-highlight type string)))
2612 type) 2645 type)
2613 string) 2646 string)
2614 ((symbolp type) 2647 ((symbolp type)
2615 (erc-display-message-highlight type string)))) 2648 (erc-display-message-highlight type string))))
2616 2649
2617 (if (not (erc-response-p parsed)) 2650 (if (not (erc-response-p parsed))
2618 (erc-display-line string buffer) 2651 (erc-display-line string buffer)
2619 (unless (erc-hide-current-message-p parsed) 2652 (unless (erc-hide-current-message-p parsed)
2620 (erc-put-text-property 0 (length string) 'erc-parsed parsed string) 2653 (erc-put-text-property 0 (length string) 'erc-parsed parsed string)
2621 (erc-put-text-property 0 (length string) 'rear-sticky t string) 2654 (erc-put-text-property 0 (length string) 'rear-sticky t string)
2622 (erc-display-line string buffer))))) 2655 (erc-display-line string buffer)))))
2623 2656
2624(defun erc-message-type-member (position list) 2657(defun erc-message-type-member (position list)
2625 "Return non-nil if the erc-parsed text-property at POSITION is in LIST. 2658 "Return non-nil if the erc-parsed text-property at POSITION is in LIST.
@@ -2637,19 +2670,19 @@ present."
2637 2670
2638See also `erc-server-send'." 2671See also `erc-server-send'."
2639 (setq line (format "PRIVMSG %s :%s" 2672 (setq line (format "PRIVMSG %s :%s"
2640 target 2673 target
2641 ;; If the line is empty, we still want to 2674 ;; If the line is empty, we still want to
2642 ;; send it - i.e. an empty pasted line. 2675 ;; send it - i.e. an empty pasted line.
2643 (if (string= line "\n") 2676 (if (string= line "\n")
2644 " \n" 2677 " \n"
2645 line))) 2678 line)))
2646 (erc-server-send line force target)) 2679 (erc-server-send line force target))
2647 2680
2648(defun erc-get-arglist (fun) 2681(defun erc-get-arglist (fun)
2649 "Return the argument list of a function without the parens." 2682 "Return the argument list of a function without the parens."
2650 (let ((arglist (format "%S" (erc-function-arglist fun)))) 2683 (let ((arglist (format "%S" (erc-function-arglist fun))))
2651 (if (string-match "^(\\(.*\\))$" arglist) 2684 (if (string-match "^(\\(.*\\))$" arglist)
2652 (match-string 1 arglist) 2685 (match-string 1 arglist)
2653 arglist))) 2686 arglist)))
2654 2687
2655(defun erc-command-no-process-p (str) 2688(defun erc-command-no-process-p (str)
@@ -2657,15 +2690,15 @@ See also `erc-server-send'."
2657is not alive, nil otherwise." 2690is not alive, nil otherwise."
2658 (let ((fun (erc-extract-command-from-line str))) 2691 (let ((fun (erc-extract-command-from-line str)))
2659 (and fun 2692 (and fun
2660 (symbolp (car fun)) 2693 (symbolp (car fun))
2661 (get (car fun) 'process-not-needed)))) 2694 (get (car fun) 'process-not-needed))))
2662 2695
2663(defun erc-command-name (cmd) 2696(defun erc-command-name (cmd)
2664 "For CMD being the function name of a ERC command, something like 2697 "For CMD being the function name of a ERC command, something like
2665erc-cmd-FOO, this returns a string /FOO." 2698erc-cmd-FOO, this returns a string /FOO."
2666 (let ((command-name (symbol-name cmd))) 2699 (let ((command-name (symbol-name cmd)))
2667 (if (string-match "^erc-cmd-\\(.*\\)$" command-name) 2700 (if (string-match "^erc-cmd-\\(.*\\)$" command-name)
2668 (concat "/" (match-string 1 command-name)) 2701 (concat "/" (match-string 1 command-name))
2669 command-name))) 2702 command-name)))
2670 2703
2671(defun erc-process-input-line (line &optional force no-command) 2704(defun erc-process-input-line (line &optional force no-command)
@@ -2681,30 +2714,30 @@ An optional FORCE argument forces sending the line when flood
2681protection is in effect. The optional NO-COMMAND argument prohibits 2714protection is in effect. The optional NO-COMMAND argument prohibits
2682this function from interpreting the line as a command." 2715this function from interpreting the line as a command."
2683 (let ((command-list (erc-extract-command-from-line line))) 2716 (let ((command-list (erc-extract-command-from-line line)))
2684 (if (and command-list 2717 (if (and command-list
2685 (not no-command)) 2718 (not no-command))
2686 (let* ((cmd (nth 0 command-list)) 2719 (let* ((cmd (nth 0 command-list))
2687 (args (nth 1 command-list))) 2720 (args (nth 1 command-list)))
2688 (condition-case nil 2721 (condition-case nil
2689 (if (listp args) 2722 (if (listp args)
2690 (apply cmd args) 2723 (apply cmd args)
2691 (funcall cmd args)) 2724 (funcall cmd args))
2692 (wrong-number-of-arguments 2725 (wrong-number-of-arguments
2693 (erc-display-message nil 'error (current-buffer) 'incorrect-args 2726 (erc-display-message nil 'error (current-buffer) 'incorrect-args
2694 ?c (erc-command-name cmd) 2727 ?c (erc-command-name cmd)
2695 ?u (or (erc-get-arglist cmd) 2728 ?u (or (erc-get-arglist cmd)
2696 "") 2729 "")
2697 ?d (format "%s\n" 2730 ?d (format "%s\n"
2698 (or (documentation cmd) ""))) 2731 (or (documentation cmd) "")))
2699 nil))) 2732 nil)))
2700 (let ((r (erc-default-target))) 2733 (let ((r (erc-default-target)))
2701 (if r 2734 (if r
2702 (funcall erc-send-input-line-function r line force) 2735 (funcall erc-send-input-line-function r line force)
2703 (erc-display-message nil 'error (current-buffer) 'no-target) 2736 (erc-display-message nil 'error (current-buffer) 'no-target)
2704 nil))))) 2737 nil)))))
2705 2738
2706;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2739;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2707;; Input commands handlers 2740;; Input commands handlers
2708;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2741;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2709 2742
2710(defun erc-cmd-AMSG (line) 2743(defun erc-cmd-AMSG (line)
@@ -2712,9 +2745,9 @@ this function from interpreting the line as a command."
2712 (interactive "sSend to all channels you're on: ") 2745 (interactive "sSend to all channels you're on: ")
2713 (setq line (erc-trim-string line)) 2746 (setq line (erc-trim-string line))
2714 (erc-with-all-buffers-of-server nil 2747 (erc-with-all-buffers-of-server nil
2715 (lambda () 2748 (lambda ()
2716 (erc-channel-p (erc-default-target))) 2749 (erc-channel-p (erc-default-target)))
2717 (erc-send-message line))) 2750 (erc-send-message line)))
2718(put 'erc-cmd-AMSG 'do-not-parse-args t) 2751(put 'erc-cmd-AMSG 'do-not-parse-args t)
2719 2752
2720(defun erc-cmd-SAY (line) 2753(defun erc-cmd-SAY (line)
@@ -2735,35 +2768,35 @@ VALUE is computed by evaluating the rest of LINE in Lisp."
2735 (cond 2768 (cond
2736 ((string-match "^\\s-*\\(\\S-+\\)\\s-+\\(.*\\)$" line) 2769 ((string-match "^\\s-*\\(\\S-+\\)\\s-+\\(.*\\)$" line)
2737 (let ((var (read (concat "erc-" (match-string 1 line)))) 2770 (let ((var (read (concat "erc-" (match-string 1 line))))
2738 (val (read (match-string 2 line)))) 2771 (val (read (match-string 2 line))))
2739 (if (boundp var) 2772 (if (boundp var)
2740 (progn 2773 (progn
2741 (set var (eval val)) 2774 (set var (eval val))
2742 (erc-display-message 2775 (erc-display-message
2743 nil nil 'active (format "Set %S to %S" var val)) 2776 nil nil 'active (format "Set %S to %S" var val))
2744 t) 2777 t)
2745 (setq var (read (match-string 1 line))) 2778 (setq var (read (match-string 1 line)))
2746 (if (boundp var) 2779 (if (boundp var)
2747 (progn 2780 (progn
2748 (set var (eval val)) 2781 (set var (eval val))
2749 (erc-display-message 2782 (erc-display-message
2750 nil nil 'active (format "Set %S to %S" var val)) 2783 nil nil 'active (format "Set %S to %S" var val))
2751 t) 2784 t)
2752 (erc-display-message nil 'error 'active 'variable-not-bound) 2785 (erc-display-message nil 'error 'active 'variable-not-bound)
2753 nil)))) 2786 nil))))
2754 ((string-match "^\\s-*$" line) 2787 ((string-match "^\\s-*$" line)
2755 (erc-display-line 2788 (erc-display-line
2756 (concat "Available user variables:\n" 2789 (concat "Available user variables:\n"
2757 (apply 2790 (apply
2758 'concat 2791 'concat
2759 (mapcar 2792 (mapcar
2760 (lambda (var) 2793 (lambda (var)
2761 (let ((val (symbol-value var))) 2794 (let ((val (symbol-value var)))
2762 (concat (format "%S:" var) 2795 (concat (format "%S:" var)
2763 (if (consp val) 2796 (if (consp val)
2764 (concat "\n" (pp-to-string val)) 2797 (concat "\n" (pp-to-string val))
2765 (format " %S\n" val))))) 2798 (format " %S\n" val)))))
2766 (apropos-internal "^erc-" 'custom-variable-p)))) 2799 (apropos-internal "^erc-" 'custom-variable-p))))
2767 (current-buffer)) t) 2800 (current-buffer)) t)
2768 (t nil))) 2801 (t nil)))
2769(defalias 'erc-cmd-VAR 'erc-cmd-SET) 2802(defalias 'erc-cmd-VAR 'erc-cmd-SET)
@@ -2786,42 +2819,42 @@ therefore has to contain the command itself as well."
2786If no USER argument is specified, list the contents of `erc-ignore-list'." 2819If no USER argument is specified, list the contents of `erc-ignore-list'."
2787 (if user 2820 (if user
2788 (let ((quoted (regexp-quote user))) 2821 (let ((quoted (regexp-quote user)))
2789 (when (and (not (string= user quoted)) 2822 (when (and (not (string= user quoted))
2790 (y-or-n-p (format "Use regexp-quoted form (%s) instead? " 2823 (y-or-n-p (format "Use regexp-quoted form (%s) instead? "
2791 quoted))) 2824 quoted)))
2792 (setq user quoted)) 2825 (setq user quoted))
2793 (erc-display-line 2826 (erc-display-line
2794 (erc-make-notice (format "Now ignoring %s" user)) 2827 (erc-make-notice (format "Now ignoring %s" user))
2795 'active) 2828 'active)
2796 (erc-with-server-buffer (add-to-list 'erc-ignore-list user))) 2829 (erc-with-server-buffer (add-to-list 'erc-ignore-list user)))
2797 (if (null (erc-with-server-buffer erc-ignore-list)) 2830 (if (null (erc-with-server-buffer erc-ignore-list))
2798 (erc-display-line (erc-make-notice "Ignore list is empty") 'active) 2831 (erc-display-line (erc-make-notice "Ignore list is empty") 'active)
2799 (erc-display-line (erc-make-notice "Ignore list:") 'active) 2832 (erc-display-line (erc-make-notice "Ignore list:") 'active)
2800 (mapc #'(lambda (item) 2833 (mapc #'(lambda (item)
2801 (erc-display-line (erc-make-notice item) 2834 (erc-display-line (erc-make-notice item)
2802 'active)) 2835 'active))
2803 (erc-with-server-buffer erc-ignore-list)))) 2836 (erc-with-server-buffer erc-ignore-list))))
2804 t) 2837 t)
2805 2838
2806(defun erc-cmd-UNIGNORE (user) 2839(defun erc-cmd-UNIGNORE (user)
2807 "Remove the user specified in USER from the ignore list." 2840 "Remove the user specified in USER from the ignore list."
2808 (let ((ignored-nick (car (erc-with-server-buffer 2841 (let ((ignored-nick (car (erc-with-server-buffer
2809 (erc-member-ignore-case (regexp-quote user) 2842 (erc-member-ignore-case (regexp-quote user)
2810 erc-ignore-list))))) 2843 erc-ignore-list)))))
2811 (unless ignored-nick 2844 (unless ignored-nick
2812 (if (setq ignored-nick (erc-ignored-user-p user)) 2845 (if (setq ignored-nick (erc-ignored-user-p user))
2813 (unless (y-or-n-p (format "Remove this regexp (%s)? " 2846 (unless (y-or-n-p (format "Remove this regexp (%s)? "
2814 ignored-nick)) 2847 ignored-nick))
2815 (setq ignored-nick nil)) 2848 (setq ignored-nick nil))
2816 (erc-display-line 2849 (erc-display-line
2817 (erc-make-notice (format "%s is not currently ignored!" user)) 2850 (erc-make-notice (format "%s is not currently ignored!" user))
2818 'active))) 2851 'active)))
2819 (when ignored-nick 2852 (when ignored-nick
2820 (erc-display-line 2853 (erc-display-line
2821 (erc-make-notice (format "No longer ignoring %s" user)) 2854 (erc-make-notice (format "No longer ignoring %s" user))
2822 'active) 2855 'active)
2823 (erc-with-server-buffer 2856 (erc-with-server-buffer
2824 (setq erc-ignore-list (delete ignored-nick erc-ignore-list))))) 2857 (setq erc-ignore-list (delete ignored-nick erc-ignore-list)))))
2825 t) 2858 t)
2826 2859
2827(defun erc-cmd-CLEAR () 2860(defun erc-cmd-CLEAR ()
@@ -2835,20 +2868,20 @@ If no USER argument is specified, list the contents of `erc-ignore-list'."
2835 (interactive) 2868 (interactive)
2836 (let ((ops nil)) 2869 (let ((ops nil))
2837 (if erc-channel-users 2870 (if erc-channel-users
2838 (maphash (lambda (_nick user-data) 2871 (maphash (lambda (_nick user-data)
2839 (let ((cuser (cdr user-data))) 2872 (let ((cuser (cdr user-data)))
2840 (if (and cuser 2873 (if (and cuser
2841 (erc-channel-user-op cuser)) 2874 (erc-channel-user-op cuser))
2842 (setq ops (cons (erc-server-user-nickname 2875 (setq ops (cons (erc-server-user-nickname
2843 (car user-data)) 2876 (car user-data))
2844 ops))))) 2877 ops)))))
2845 erc-channel-users)) 2878 erc-channel-users))
2846 (setq ops (sort ops 'string-lessp)) 2879 (setq ops (sort ops 'string-lessp))
2847 (if ops 2880 (if ops
2848 (erc-display-message 2881 (erc-display-message
2849 nil 'notice (current-buffer) 'ops 2882 nil 'notice (current-buffer) 'ops
2850 ?i (length ops) ?s (if (> (length ops) 1) "s" "") 2883 ?i (length ops) ?s (if (> (length ops) 1) "s" "")
2851 ?o (mapconcat 'identity ops " ")) 2884 ?o (mapconcat 'identity ops " "))
2852 (erc-display-message nil 'notice (current-buffer) 'ops-none))) 2885 (erc-display-message nil 'notice (current-buffer) 'ops-none)))
2853 t) 2886 t)
2854 2887
@@ -2857,11 +2890,11 @@ If no USER argument is specified, list the contents of `erc-ignore-list'."
2857 (require 'mail-extr) 2890 (require 'mail-extr)
2858 (let ((co (ignore-errors (what-domain tld)))) 2891 (let ((co (ignore-errors (what-domain tld))))
2859 (if co 2892 (if co
2860 (erc-display-message 2893 (erc-display-message
2861 nil 'notice 'active 'country ?c co ?d tld) 2894 nil 'notice 'active 'country ?c co ?d tld)
2862 (erc-display-message 2895 (erc-display-message
2863 nil 'notice 'active 'country-unknown ?d tld)) 2896 nil 'notice 'active 'country-unknown ?d tld))
2864 t)) 2897 t))
2865(put 'erc-cmd-COUNTRY 'process-not-needed t) 2898(put 'erc-cmd-COUNTRY 'process-not-needed t)
2866 2899
2867(defun erc-cmd-AWAY (line) 2900(defun erc-cmd-AWAY (line)
@@ -2872,8 +2905,8 @@ If no reason is given, unset away status."
2872 (erc-log (format "cmd: AWAY: %s" reason)) 2905 (erc-log (format "cmd: AWAY: %s" reason))
2873 (erc-server-send 2906 (erc-server-send
2874 (if (string= reason "") 2907 (if (string= reason "")
2875 "AWAY" 2908 "AWAY"
2876 (concat "AWAY :" reason)))) 2909 (concat "AWAY :" reason))))
2877 t)) 2910 t))
2878(put 'erc-cmd-AWAY 'do-not-parse-args t) 2911(put 'erc-cmd-AWAY 'do-not-parse-args t)
2879 2912
@@ -2891,8 +2924,8 @@ If no reason is given, unset away status."
2891CMD is the CTCP command, possible values being ECHO, FINGER, CLIENTINFO, TIME, 2924CMD is the CTCP command, possible values being ECHO, FINGER, CLIENTINFO, TIME,
2892VERSION and so on. It is called with ARGS." 2925VERSION and so on. It is called with ARGS."
2893 (let ((str (concat cmd 2926 (let ((str (concat cmd
2894 (when args 2927 (when args
2895 (concat " " (mapconcat #'identity args " ")))))) 2928 (concat " " (mapconcat #'identity args " "))))))
2896 (erc-log (format "cmd: CTCP [%s]: [%s]" nick str)) 2929 (erc-log (format "cmd: CTCP [%s]: [%s]" nick str))
2897 (erc-send-ctcp-message nick str) 2930 (erc-send-ctcp-message nick str)
2898 t)) 2931 t))
@@ -2915,29 +2948,29 @@ For help about the WHOIS command, do:
2915For a list of user commands (/join /part, ...): 2948For a list of user commands (/join /part, ...):
2916 /help." 2949 /help."
2917 (if func 2950 (if func
2918 (let* ((sym (or (let ((sym (intern-soft 2951 (let* ((sym (or (let ((sym (intern-soft
2919 (concat "erc-cmd-" (upcase func))))) 2952 (concat "erc-cmd-" (upcase func)))))
2920 (if (and sym (or (boundp sym) (fboundp sym))) 2953 (if (and sym (or (boundp sym) (fboundp sym)))
2921 sym 2954 sym
2922 nil)) 2955 nil))
2923 (let ((sym (intern-soft func))) 2956 (let ((sym (intern-soft func)))
2924 (if (and sym (or (boundp sym) (fboundp sym))) 2957 (if (and sym (or (boundp sym) (fboundp sym)))
2925 sym 2958 sym
2926 nil)) 2959 nil))
2927 (let ((sym (intern-soft (concat "erc-" func)))) 2960 (let ((sym (intern-soft (concat "erc-" func))))
2928 (if (and sym (or (boundp sym) (fboundp sym))) 2961 (if (and sym (or (boundp sym) (fboundp sym)))
2929 sym 2962 sym
2930 nil))))) 2963 nil)))))
2931 (if sym 2964 (if sym
2932 (cond 2965 (cond
2933 ((boundp sym) (describe-variable sym)) 2966 ((boundp sym) (describe-variable sym))
2934 ((fboundp sym) (describe-function sym)) 2967 ((fboundp sym) (describe-function sym))
2935 (t nil)) 2968 (t nil))
2936 (apropos-command (concat "erc-.*" func) nil 2969 (apropos-command (concat "erc-.*" func) nil
2937 (lambda (x) 2970 (lambda (x)
2938 (or (commandp x) 2971 (or (commandp x)
2939 (get x 'custom-type)))) 2972 (get x 'custom-type))))
2940 t)) 2973 t))
2941 (apropos "erc-cmd-") 2974 (apropos "erc-cmd-")
2942 (message "Type C-h m to get additional information about keybindings.") 2975 (message "Type C-h m to get additional information about keybindings.")
2943 t)) 2976 t))
@@ -2951,23 +2984,23 @@ If CHANNEL is specified as \"-invite\", join the channel to which you
2951were most recently invited. See also `invitation'." 2984were most recently invited. See also `invitation'."
2952 (let (chnl) 2985 (let (chnl)
2953 (if (string= (upcase channel) "-INVITE") 2986 (if (string= (upcase channel) "-INVITE")
2954 (if erc-invitation 2987 (if erc-invitation
2955 (setq chnl erc-invitation) 2988 (setq chnl erc-invitation)
2956 (erc-display-message nil 'error (current-buffer) 'no-invitation)) 2989 (erc-display-message nil 'error (current-buffer) 'no-invitation))
2957 (setq chnl (erc-ensure-channel-name channel))) 2990 (setq chnl (erc-ensure-channel-name channel)))
2958 (when chnl 2991 (when chnl
2959 ;; Prevent double joining of same channel on same server. 2992 ;; Prevent double joining of same channel on same server.
2960 (let ((joined-channels 2993 (let ((joined-channels
2961 (mapcar #'(lambda (chanbuf) 2994 (mapcar #'(lambda (chanbuf)
2962 (with-current-buffer chanbuf (erc-default-target))) 2995 (with-current-buffer chanbuf (erc-default-target)))
2963 (erc-channel-list erc-server-process)))) 2996 (erc-channel-list erc-server-process))))
2964 (if (erc-member-ignore-case chnl joined-channels) 2997 (if (erc-member-ignore-case chnl joined-channels)
2965 (switch-to-buffer (car (erc-member-ignore-case chnl 2998 (switch-to-buffer (car (erc-member-ignore-case chnl
2966 joined-channels))) 2999 joined-channels)))
2967 (erc-log (format "cmd: JOIN: %s" chnl)) 3000 (erc-log (format "cmd: JOIN: %s" chnl))
2968 (erc-server-send (if (and chnl key) 3001 (erc-server-send (if (and chnl key)
2969 (format "JOIN %s %s" chnl key) 3002 (format "JOIN %s %s" chnl key)
2970 (format "JOIN %s" chnl))))))) 3003 (format "JOIN %s" chnl)))))))
2971 t) 3004 t)
2972 3005
2973(defalias 'erc-cmd-CHANNEL 'erc-cmd-JOIN) 3006(defalias 'erc-cmd-CHANNEL 'erc-cmd-JOIN)
@@ -2986,14 +3019,14 @@ If CHANNEL is not specified, display the users in the current channel.
2986This function clears the channel name list first, then sends the 3019This function clears the channel name list first, then sends the
2987command." 3020command."
2988 (let ((tgt (or (and (erc-channel-p channel) channel) 3021 (let ((tgt (or (and (erc-channel-p channel) channel)
2989 (erc-default-target)))) 3022 (erc-default-target))))
2990 (if (and tgt (erc-channel-p tgt)) 3023 (if (and tgt (erc-channel-p tgt))
2991 (progn 3024 (progn
2992 (erc-log (format "cmd: DEFAULT: NAMES %s" tgt)) 3025 (erc-log (format "cmd: DEFAULT: NAMES %s" tgt))
2993 (erc-with-buffer 3026 (erc-with-buffer
2994 (tgt) 3027 (tgt)
2995 (erc-channel-begin-receiving-names)) 3028 (erc-channel-begin-receiving-names))
2996 (erc-server-send (concat "NAMES " tgt))) 3029 (erc-server-send (concat "NAMES " tgt)))
2997 (erc-display-message nil 'error (current-buffer) 'no-default-channel))) 3030 (erc-display-message nil 'error (current-buffer) 'no-default-channel)))
2998 t) 3031 t)
2999(defalias 'erc-cmd-N 'erc-cmd-NAMES) 3032(defalias 'erc-cmd-N 'erc-cmd-NAMES)
@@ -3003,27 +3036,27 @@ command."
3003LINE has the format: \"#CHANNEL NICK REASON\" or \"NICK REASON\"." 3036LINE has the format: \"#CHANNEL NICK REASON\" or \"NICK REASON\"."
3004 (let ((reasonstring (mapconcat 'identity reasonwords " "))) 3037 (let ((reasonstring (mapconcat 'identity reasonwords " ")))
3005 (if (string= "" reasonstring) 3038 (if (string= "" reasonstring)
3006 (setq reasonstring (format "Kicked by %s" (erc-current-nick)))) 3039 (setq reasonstring (format "Kicked by %s" (erc-current-nick))))
3007 (if (erc-channel-p target) 3040 (if (erc-channel-p target)
3008 (let ((nick reason-or-nick)) 3041 (let ((nick reason-or-nick))
3009 (erc-log (format "cmd: KICK: %s/%s: %s" nick target reasonstring)) 3042 (erc-log (format "cmd: KICK: %s/%s: %s" nick target reasonstring))
3010 (erc-server-send (format "KICK %s %s :%s" target nick reasonstring) 3043 (erc-server-send (format "KICK %s %s :%s" target nick reasonstring)
3011 nil target) 3044 nil target)
3012 t) 3045 t)
3013 (when target 3046 (when target
3014 (let ((ch (erc-default-target))) 3047 (let ((ch (erc-default-target)))
3015 (setq reasonstring (concat 3048 (setq reasonstring (concat
3016 (if reason-or-nick (concat reason-or-nick " ")) 3049 (if reason-or-nick (concat reason-or-nick " "))
3017 reasonstring)) 3050 reasonstring))
3018 (if ch 3051 (if ch
3019 (progn 3052 (progn
3020 (erc-log 3053 (erc-log
3021 (format "cmd: KICK: %s/%s: %s" target ch reasonstring)) 3054 (format "cmd: KICK: %s/%s: %s" target ch reasonstring))
3022 (erc-server-send 3055 (erc-server-send
3023 (format "KICK %s %s :%s" ch target reasonstring) nil ch)) 3056 (format "KICK %s %s :%s" ch target reasonstring) nil ch))
3024 (erc-display-message nil 'error (current-buffer) 3057 (erc-display-message nil 'error (current-buffer)
3025 'no-default-channel)) 3058 'no-default-channel))
3026 t))))) 3059 t)))))
3027 3060
3028(defvar erc-script-args nil) 3061(defvar erc-script-args nil)
3029 3062
@@ -3038,20 +3071,20 @@ a script after exceeding the flood threshold."
3038 (cond 3071 (cond
3039 ((string-match "^\\s-*\\(\\S-+\\)\\(.*\\)$" line) 3072 ((string-match "^\\s-*\\(\\S-+\\)\\(.*\\)$" line)
3040 (let* ((file-to-find (match-string 1 line)) 3073 (let* ((file-to-find (match-string 1 line))
3041 (erc-script-args (match-string 2 line)) 3074 (erc-script-args (match-string 2 line))
3042 (file (erc-find-file file-to-find erc-script-path))) 3075 (file (erc-find-file file-to-find erc-script-path)))
3043 (erc-log (format "cmd: LOAD: %s" file-to-find)) 3076 (erc-log (format "cmd: LOAD: %s" file-to-find))
3044 (cond 3077 (cond
3045 ((not file) 3078 ((not file)
3046 (erc-display-message nil 'error (current-buffer) 3079 (erc-display-message nil 'error (current-buffer)
3047 'cannot-find-file ?f file-to-find)) 3080 'cannot-find-file ?f file-to-find))
3048 ((not (file-readable-p file)) 3081 ((not (file-readable-p file))
3049 (erc-display-message nil 'error (current-buffer) 3082 (erc-display-message nil 'error (current-buffer)
3050 'cannot-read-file ?f file)) 3083 'cannot-read-file ?f file))
3051 (t 3084 (t
3052 (message "Loading \'%s\'..." file) 3085 (message "Loading \'%s\'..." file)
3053 (erc-load-script file) 3086 (erc-load-script file)
3054 (message "Loading \'%s\'...done" file)))) 3087 (message "Loading \'%s\'...done" file))))
3055 t) 3088 t)
3056 (t nil))) 3089 (t nil)))
3057 3090
@@ -3061,11 +3094,11 @@ a script after exceeding the flood threshold."
3061If SERVER is non-nil, use that, rather than the current server." 3094If SERVER is non-nil, use that, rather than the current server."
3062 ;; FIXME: is the above docstring correct? -- Lawrence 2004-01-08 3095 ;; FIXME: is the above docstring correct? -- Lawrence 2004-01-08
3063 (let ((send (if server 3096 (let ((send (if server
3064 (format "WHOIS %s %s" user server) 3097 (format "WHOIS %s %s" user server)
3065 (format "WHOIS %s" user)))) 3098 (format "WHOIS %s" user))))
3066 (erc-log (format "cmd: %s" send)) 3099 (erc-log (format "cmd: %s" send))
3067 (erc-server-send send) 3100 (erc-server-send send)
3068 t)) 3101 t))
3069(defalias 'erc-cmd-WI 'erc-cmd-WHOIS) 3102(defalias 'erc-cmd-WI 'erc-cmd-WHOIS)
3070 3103
3071(defun erc-cmd-WHOAMI () 3104(defun erc-cmd-WHOAMI ()
@@ -3076,78 +3109,78 @@ If SERVER is non-nil, use that, rather than the current server."
3076(defun erc-cmd-IDLE (nick) 3109(defun erc-cmd-IDLE (nick)
3077 "Show the length of time NICK has been idle." 3110 "Show the length of time NICK has been idle."
3078 (let ((origbuf (current-buffer)) 3111 (let ((origbuf (current-buffer))
3079 symlist) 3112 symlist)
3080 (erc-with-server-buffer 3113 (erc-with-server-buffer
3081 (push (cons (erc-once-with-server-event 3114 (push (cons (erc-once-with-server-event
3082 311 (lambda (_proc parsed) 3115 311 (lambda (_proc parsed)
3083 (string= nick 3116 (string= nick
3084 (nth 1 (erc-response.command-args 3117 (nth 1 (erc-response.command-args
3085 parsed))))) 3118 parsed)))))
3086 'erc-server-311-functions) 3119 'erc-server-311-functions)
3087 symlist) 3120 symlist)
3088 (push (cons (erc-once-with-server-event 3121 (push (cons (erc-once-with-server-event
3089 312 (lambda (_proc parsed) 3122 312 (lambda (_proc parsed)
3090 (string= nick 3123 (string= nick
3091 (nth 1 (erc-response.command-args 3124 (nth 1 (erc-response.command-args
3092 parsed))))) 3125 parsed)))))
3093 'erc-server-312-functions) 3126 'erc-server-312-functions)
3094 symlist) 3127 symlist)
3095 (push (cons (erc-once-with-server-event 3128 (push (cons (erc-once-with-server-event
3096 318 (lambda (_proc parsed) 3129 318 (lambda (_proc parsed)
3097 (string= nick 3130 (string= nick
3098 (nth 1 (erc-response.command-args 3131 (nth 1 (erc-response.command-args
3099 parsed))))) 3132 parsed)))))
3100 'erc-server-318-functions) 3133 'erc-server-318-functions)
3101 symlist) 3134 symlist)
3102 (push (cons (erc-once-with-server-event 3135 (push (cons (erc-once-with-server-event
3103 319 (lambda (_proc parsed) 3136 319 (lambda (_proc parsed)
3104 (string= nick 3137 (string= nick
3105 (nth 1 (erc-response.command-args 3138 (nth 1 (erc-response.command-args
3106 parsed))))) 3139 parsed)))))
3107 'erc-server-319-functions) 3140 'erc-server-319-functions)
3108 symlist) 3141 symlist)
3109 (push (cons (erc-once-with-server-event 3142 (push (cons (erc-once-with-server-event
3110 320 (lambda (_proc parsed) 3143 320 (lambda (_proc parsed)
3111 (string= nick 3144 (string= nick
3112 (nth 1 (erc-response.command-args 3145 (nth 1 (erc-response.command-args
3113 parsed))))) 3146 parsed)))))
3114 'erc-server-320-functions) 3147 'erc-server-320-functions)
3115 symlist) 3148 symlist)
3116 (push (cons (erc-once-with-server-event 3149 (push (cons (erc-once-with-server-event
3117 330 (lambda (_proc parsed) 3150 330 (lambda (_proc parsed)
3118 (string= nick 3151 (string= nick
3119 (nth 1 (erc-response.command-args 3152 (nth 1 (erc-response.command-args
3120 parsed))))) 3153 parsed)))))
3121 'erc-server-330-functions) 3154 'erc-server-330-functions)
3122 symlist) 3155 symlist)
3123 (push (cons (erc-once-with-server-event 3156 (push (cons (erc-once-with-server-event
3124 317 3157 317
3125 (lambda (_proc parsed) 3158 (lambda (_proc parsed)
3126 (let ((idleseconds 3159 (let ((idleseconds
3127 (string-to-number 3160 (string-to-number
3128 (cl-third 3161 (cl-third
3129 (erc-response.command-args parsed))))) 3162 (erc-response.command-args parsed)))))
3130 (erc-display-line 3163 (erc-display-line
3131 (erc-make-notice 3164 (erc-make-notice
3132 (format "%s has been idle for %s." 3165 (format "%s has been idle for %s."
3133 (erc-string-no-properties nick) 3166 (erc-string-no-properties nick)
3134 (erc-seconds-to-string idleseconds))) 3167 (erc-seconds-to-string idleseconds)))
3135 origbuf) 3168 origbuf)
3136 t))) 3169 t)))
3137 'erc-server-317-functions) 3170 'erc-server-317-functions)
3138 symlist) 3171 symlist)
3139 3172
3140 ;; Send the WHOIS command. 3173 ;; Send the WHOIS command.
3141 (erc-cmd-WHOIS nick) 3174 (erc-cmd-WHOIS nick)
3142 3175
3143 ;; Remove the uninterned symbols from the server hooks that did not run. 3176 ;; Remove the uninterned symbols from the server hooks that did not run.
3144 (run-at-time 20 nil (lambda (buf symlist) 3177 (run-at-time 20 nil (lambda (buf symlist)
3145 (with-current-buffer buf 3178 (with-current-buffer buf
3146 (dolist (sym symlist) 3179 (dolist (sym symlist)
3147 (let ((hooksym (cdr sym)) 3180 (let ((hooksym (cdr sym))
3148 (funcsym (car sym))) 3181 (funcsym (car sym)))
3149 (remove-hook hooksym funcsym t))))) 3182 (remove-hook hooksym funcsym t)))))
3150 (current-buffer) symlist))) 3183 (current-buffer) symlist)))
3151 t) 3184 t)
3152 3185
3153(defun erc-cmd-DESCRIBE (line) 3186(defun erc-cmd-DESCRIBE (line)
@@ -3157,7 +3190,7 @@ LINE has the format \"USER ACTION\"."
3157 ((string-match 3190 ((string-match
3158 "^\\s-*\\(\\S-+\\)\\s-\\(.*\\)$" line) 3191 "^\\s-*\\(\\S-+\\)\\s-\\(.*\\)$" line)
3159 (let ((dst (match-string 1 line)) 3192 (let ((dst (match-string 1 line))
3160 (s (match-string 2 line))) 3193 (s (match-string 2 line)))
3161 (erc-log (format "cmd: DESCRIBE: [%s] %s" dst s)) 3194 (erc-log (format "cmd: DESCRIBE: [%s] %s" dst s))
3162 (erc-send-action dst s)) 3195 (erc-send-action dst s))
3163 t) 3196 t)
@@ -3203,7 +3236,7 @@ See also `erc-message' and `erc-display-line'."
3203 (erc-message "PRIVMSG" (concat (erc-default-target) " " line) force) 3236 (erc-message "PRIVMSG" (concat (erc-default-target) " " line) force)
3204 (erc-display-line 3237 (erc-display-line
3205 (concat (erc-format-my-nick) line) 3238 (concat (erc-format-my-nick) line)
3206 (current-buffer)) 3239 (current-buffer))
3207 ;; FIXME - treat multiline, run hooks, or remove me? 3240 ;; FIXME - treat multiline, run hooks, or remove me?
3208 t) 3241 t)
3209 3242
@@ -3229,7 +3262,7 @@ URL `http://freenode.net/using_the_network.shtml'."
3229 "Send a notice to the channel or user given as the first word. 3262 "Send a notice to the channel or user given as the first word.
3230The rest is the message to send." 3263The rest is the message to send."
3231 (erc-message "NOTICE" (concat channel-or-user " " 3264 (erc-message "NOTICE" (concat channel-or-user " "
3232 (mapconcat #'identity message " ")))) 3265 (mapconcat #'identity message " "))))
3233 3266
3234(defun erc-cmd-MSG (line) 3267(defun erc-cmd-MSG (line)
3235 "Send a message to the channel or user given as the first word in LINE. 3268 "Send a message to the channel or user given as the first word in LINE.
@@ -3250,16 +3283,16 @@ The rest of LINE is the message to send."
3250 "Change current nickname to NICK." 3283 "Change current nickname to NICK."
3251 (erc-log (format "cmd: NICK: %s (erc-bad-nick: %S)" nick erc-bad-nick)) 3284 (erc-log (format "cmd: NICK: %s (erc-bad-nick: %S)" nick erc-bad-nick))
3252 (let ((nicklen (cdr (assoc "NICKLEN" (erc-with-server-buffer 3285 (let ((nicklen (cdr (assoc "NICKLEN" (erc-with-server-buffer
3253 erc-server-parameters))))) 3286 erc-server-parameters)))))
3254 (and nicklen (> (length nick) (string-to-number nicklen)) 3287 (and nicklen (> (length nick) (string-to-number nicklen))
3255 (erc-display-message 3288 (erc-display-message
3256 nil 'notice 'active 'nick-too-long 3289 nil 'notice 'active 'nick-too-long
3257 ?i (length nick) ?l nicklen))) 3290 ?i (length nick) ?l nicklen)))
3258 (erc-server-send (format "NICK %s" nick)) 3291 (erc-server-send (format "NICK %s" nick))
3259 (cond (erc-bad-nick 3292 (cond (erc-bad-nick
3260 (erc-set-current-nick nick) 3293 (erc-set-current-nick nick)
3261 (erc-update-mode-line) 3294 (erc-update-mode-line)
3262 (setq erc-bad-nick nil))) 3295 (setq erc-bad-nick nil)))
3263 t) 3296 t)
3264 3297
3265(defun erc-cmd-PART (line) 3298(defun erc-cmd-PART (line)
@@ -3268,26 +3301,26 @@ Otherwise leave the channel indicated by LINE."
3268 (cond 3301 (cond
3269 ((string-match "^\\s-*\\([&#+!]\\S-+\\)\\s-?\\(.*\\)$" line) 3302 ((string-match "^\\s-*\\([&#+!]\\S-+\\)\\s-?\\(.*\\)$" line)
3270 (let* ((ch (match-string 1 line)) 3303 (let* ((ch (match-string 1 line))
3271 (msg (match-string 2 line)) 3304 (msg (match-string 2 line))
3272 (reason (funcall erc-part-reason (if (equal msg "") nil msg)))) 3305 (reason (funcall erc-part-reason (if (equal msg "") nil msg))))
3273 (erc-log (format "cmd: PART: %s: %s" ch reason)) 3306 (erc-log (format "cmd: PART: %s: %s" ch reason))
3274 (erc-server-send (if (string= reason "") 3307 (erc-server-send (if (string= reason "")
3275 (format "PART %s" ch) 3308 (format "PART %s" ch)
3276 (format "PART %s :%s" ch reason)) 3309 (format "PART %s :%s" ch reason))
3277 nil ch)) 3310 nil ch))
3278 t) 3311 t)
3279 ((string-match "^\\s-*\\(.*\\)$" line) 3312 ((string-match "^\\s-*\\(.*\\)$" line)
3280 (let* ((ch (erc-default-target)) 3313 (let* ((ch (erc-default-target))
3281 (msg (match-string 1 line)) 3314 (msg (match-string 1 line))
3282 (reason (funcall erc-part-reason (if (equal msg "") nil msg)))) 3315 (reason (funcall erc-part-reason (if (equal msg "") nil msg))))
3283 (if (and ch (erc-channel-p ch)) 3316 (if (and ch (erc-channel-p ch))
3284 (progn 3317 (progn
3285 (erc-log (format "cmd: PART: %s: %s" ch reason)) 3318 (erc-log (format "cmd: PART: %s: %s" ch reason))
3286 (erc-server-send (if (string= reason "") 3319 (erc-server-send (if (string= reason "")
3287 (format "PART %s" ch) 3320 (format "PART %s" ch)
3288 (format "PART %s :%s" ch reason)) 3321 (format "PART %s :%s" ch reason))
3289 nil ch)) 3322 nil ch))
3290 (erc-display-message nil 'error (current-buffer) 'no-target))) 3323 (erc-display-message nil 'error (current-buffer) 'no-target)))
3291 t) 3324 t)
3292 (t nil))) 3325 (t nil)))
3293(put 'erc-cmd-PART 'do-not-parse-args t) 3326(put 'erc-cmd-PART 'do-not-parse-args t)
@@ -3322,11 +3355,11 @@ See also `erc-auto-query' to decide how private messages from
3322other people should be displayed." 3355other people should be displayed."
3323 :group 'erc-query 3356 :group 'erc-query
3324 :type '(choice (const :tag "Split window and select" window) 3357 :type '(choice (const :tag "Split window and select" window)
3325 (const :tag "Split window, don't select" window-noselect) 3358 (const :tag "Split window, don't select" window-noselect)
3326 (const :tag "New frame" frame) 3359 (const :tag "New frame" frame)
3327 (const :tag "Bury in new buffer" bury) 3360 (const :tag "Bury in new buffer" bury)
3328 (const :tag "Use current buffer" buffer) 3361 (const :tag "Use current buffer" buffer)
3329 (const :tag "Use current buffer" t))) 3362 (const :tag "Use current buffer" t)))
3330 3363
3331(defun erc-cmd-QUERY (&optional user) 3364(defun erc-cmd-QUERY (&optional user)
3332 "Open a query with USER. 3365 "Open a query with USER.
@@ -3338,11 +3371,11 @@ If USER is omitted, close the current query buffer if one exists
3338 (interactive 3371 (interactive
3339 (list (read-from-minibuffer "Start a query with: " nil))) 3372 (list (read-from-minibuffer "Start a query with: " nil)))
3340 (let ((session-buffer (erc-server-buffer)) 3373 (let ((session-buffer (erc-server-buffer))
3341 (erc-join-buffer erc-query-display)) 3374 (erc-join-buffer erc-query-display))
3342 (if user 3375 (if user
3343 (erc-query user session-buffer) 3376 (erc-query user session-buffer)
3344 ;; currently broken, evil hack to display help anyway 3377 ;; currently broken, evil hack to display help anyway
3345 ;(erc-delete-query)))) 3378 ;(erc-delete-query))))
3346 (signal 'wrong-number-of-arguments "")))) 3379 (signal 'wrong-number-of-arguments ""))))
3347(defalias 'erc-cmd-Q 'erc-cmd-QUERY) 3380(defalias 'erc-cmd-Q 'erc-cmd-QUERY)
3348 3381
@@ -3352,8 +3385,8 @@ If USER is omitted, close the current query buffer if one exists
3352If S is non-nil, it will be used as the quit reason." 3385If S is non-nil, it will be used as the quit reason."
3353 (or s 3386 (or s
3354 (format "\C-bERC\C-b %s (IRC client for Emacs)"; - \C-b%s\C-b" 3387 (format "\C-bERC\C-b %s (IRC client for Emacs)"; - \C-b%s\C-b"
3355 erc-version-string) ; erc-official-location) 3388 erc-version-string) ; erc-official-location)
3356 )) 3389 ))
3357 3390
3358(defun erc-quit-reason-zippy (&optional s) 3391(defun erc-quit-reason-zippy (&optional s)
3359 "Zippy quit message. 3392 "Zippy quit message.
@@ -3361,8 +3394,8 @@ If S is non-nil, it will be used as the quit reason."
3361If S is non-nil, it will be used as the quit reason." 3394If S is non-nil, it will be used as the quit reason."
3362 (or s 3395 (or s
3363 (if (fboundp 'yow) 3396 (if (fboundp 'yow)
3364 (erc-replace-regexp-in-string "\n" "" (yow)) 3397 (erc-replace-regexp-in-string "\n" "" (yow))
3365 (erc-quit-reason-normal)))) 3398 (erc-quit-reason-normal))))
3366 3399
3367(make-obsolete 'erc-quit-reason-zippy "it will be removed." "24.4") 3400(make-obsolete 'erc-quit-reason-zippy "it will be removed." "24.4")
3368 3401
@@ -3370,7 +3403,7 @@ If S is non-nil, it will be used as the quit reason."
3370 "Choose a quit reason based on S (a string)." 3403 "Choose a quit reason based on S (a string)."
3371 (when (featurep 'xemacs) (require 'poe)) 3404 (when (featurep 'xemacs) (require 'poe))
3372 (let ((res (car (assoc-default (or s "") 3405 (let ((res (car (assoc-default (or s "")
3373 erc-quit-reason-various-alist 'string-match)))) 3406 erc-quit-reason-various-alist 'string-match))))
3374 (cond 3407 (cond
3375 ((functionp res) (funcall res)) 3408 ((functionp res) (funcall res))
3376 ((stringp res) res) 3409 ((stringp res) res)
@@ -3383,8 +3416,8 @@ If S is non-nil, it will be used as the quit reason."
3383If S is non-nil, it will be used as the quit reason." 3416If S is non-nil, it will be used as the quit reason."
3384 (or s 3417 (or s
3385 (format "\C-bERC\C-b %s (IRC client for Emacs)"; - \C-b%s\C-b" 3418 (format "\C-bERC\C-b %s (IRC client for Emacs)"; - \C-b%s\C-b"
3386 erc-version-string) ; erc-official-location) 3419 erc-version-string) ; erc-official-location)
3387 )) 3420 ))
3388 3421
3389(defun erc-part-reason-zippy (&optional s) 3422(defun erc-part-reason-zippy (&optional s)
3390 "Zippy part message. 3423 "Zippy part message.
@@ -3392,8 +3425,8 @@ If S is non-nil, it will be used as the quit reason."
3392If S is non-nil, it will be used as the quit reason." 3425If S is non-nil, it will be used as the quit reason."
3393 (or s 3426 (or s
3394 (if (fboundp 'yow) 3427 (if (fboundp 'yow)
3395 (erc-replace-regexp-in-string "\n" "" (yow)) 3428 (erc-replace-regexp-in-string "\n" "" (yow))
3396 (erc-part-reason-normal)))) 3429 (erc-part-reason-normal))))
3397 3430
3398(make-obsolete 'erc-part-reason-zippy "it will be removed." "24.4") 3431(make-obsolete 'erc-part-reason-zippy "it will be removed." "24.4")
3399 3432
@@ -3401,7 +3434,7 @@ If S is non-nil, it will be used as the quit reason."
3401 "Choose a part reason based on S (a string)." 3434 "Choose a part reason based on S (a string)."
3402 (when (featurep 'xemacs) (require 'poe)) 3435 (when (featurep 'xemacs) (require 'poe))
3403 (let ((res (car (assoc-default (or s "") 3436 (let ((res (car (assoc-default (or s "")
3404 erc-part-reason-various-alist 'string-match)))) 3437 erc-part-reason-various-alist 'string-match))))
3405 (cond 3438 (cond
3406 ((functionp res) (funcall res)) 3439 ((functionp res) (funcall res))
3407 ((stringp res) res) 3440 ((stringp res) res)
@@ -3417,28 +3450,28 @@ the message given by REASON."
3417 (cond 3450 (cond
3418 ((string-match "^\\s-*\\(.*\\)$" reason) 3451 ((string-match "^\\s-*\\(.*\\)$" reason)
3419 (let* ((s (match-string 1 reason)) 3452 (let* ((s (match-string 1 reason))
3420 (buffer (erc-server-buffer)) 3453 (buffer (erc-server-buffer))
3421 (reason (funcall erc-quit-reason (if (equal s "") nil s))) 3454 (reason (funcall erc-quit-reason (if (equal s "") nil s)))
3422 server-proc) 3455 server-proc)
3423 (with-current-buffer (if (and buffer 3456 (with-current-buffer (if (and buffer
3424 (bufferp buffer)) 3457 (bufferp buffer))
3425 buffer 3458 buffer
3426 (current-buffer)) 3459 (current-buffer))
3427 (erc-log (format "cmd: QUIT: %s" reason)) 3460 (erc-log (format "cmd: QUIT: %s" reason))
3428 (setq erc-server-quitting t) 3461 (setq erc-server-quitting t)
3429 (erc-set-active-buffer (erc-server-buffer)) 3462 (erc-set-active-buffer (erc-server-buffer))
3430 (setq server-proc erc-server-process) 3463 (setq server-proc erc-server-process)
3431 (erc-server-send (format "QUIT :%s" reason))) 3464 (erc-server-send (format "QUIT :%s" reason)))
3432 (run-hook-with-args 'erc-quit-hook server-proc) 3465 (run-hook-with-args 'erc-quit-hook server-proc)
3433 (when erc-kill-queries-on-quit 3466 (when erc-kill-queries-on-quit
3434 (erc-kill-query-buffers server-proc)) 3467 (erc-kill-query-buffers server-proc))
3435 ;; if the process has not been killed within 4 seconds, kill it 3468 ;; if the process has not been killed within 4 seconds, kill it
3436 (run-at-time 4 nil 3469 (run-at-time 4 nil
3437 (lambda (proc) 3470 (lambda (proc)
3438 (when (and (processp proc) 3471 (when (and (processp proc)
3439 (memq (process-status proc) '(run open))) 3472 (memq (process-status proc) '(run open)))
3440 (delete-process proc))) 3473 (delete-process proc)))
3441 server-proc)) 3474 server-proc))
3442 t) 3475 t)
3443 (t nil))) 3476 (t nil)))
3444 3477
@@ -3451,7 +3484,7 @@ the message given by REASON."
3451(defun erc-cmd-GQUIT (reason) 3484(defun erc-cmd-GQUIT (reason)
3452 "Disconnect from all servers at once with the same quit REASON." 3485 "Disconnect from all servers at once with the same quit REASON."
3453 (erc-with-all-buffers-of-server nil #'erc-open-server-buffer-p 3486 (erc-with-all-buffers-of-server nil #'erc-open-server-buffer-p
3454 (erc-cmd-QUIT reason)) 3487 (erc-cmd-QUIT reason))
3455 (when erc-kill-queries-on-quit 3488 (when erc-kill-queries-on-quit
3456 ;; if the query buffers have not been killed within 4 seconds, 3489 ;; if the query buffers have not been killed within 4 seconds,
3457 ;; kill them 3490 ;; kill them
@@ -3459,8 +3492,8 @@ the message given by REASON."
3459 4 nil 3492 4 nil
3460 (lambda () 3493 (lambda ()
3461 (dolist (buffer (erc-buffer-list (lambda (buf) 3494 (dolist (buffer (erc-buffer-list (lambda (buf)
3462 (not (erc-server-buffer-p buf))))) 3495 (not (erc-server-buffer-p buf)))))
3463 (kill-buffer buffer))))) 3496 (kill-buffer buffer)))))
3464 t) 3497 t)
3465 3498
3466(defalias 'erc-cmd-GQ 'erc-cmd-GQUIT) 3499(defalias 'erc-cmd-GQ 'erc-cmd-GQUIT)
@@ -3470,7 +3503,7 @@ the message given by REASON."
3470(defun erc-cmd-RECONNECT () 3503(defun erc-cmd-RECONNECT ()
3471 "Try to reconnect to the current IRC server." 3504 "Try to reconnect to the current IRC server."
3472 (let ((buffer (erc-server-buffer)) 3505 (let ((buffer (erc-server-buffer))
3473 (process nil)) 3506 (process nil))
3474 (unless (buffer-live-p buffer) 3507 (unless (buffer-live-p buffer)
3475 (setq buffer (current-buffer))) 3508 (setq buffer (current-buffer)))
3476 (with-current-buffer buffer 3509 (with-current-buffer buffer
@@ -3479,8 +3512,8 @@ the message given by REASON."
3479 (setq erc-server-reconnect-count 0) 3512 (setq erc-server-reconnect-count 0)
3480 (setq process (get-buffer-process (erc-server-buffer))) 3513 (setq process (get-buffer-process (erc-server-buffer)))
3481 (if process 3514 (if process
3482 (delete-process process) 3515 (delete-process process)
3483 (erc-server-reconnect)) 3516 (erc-server-reconnect))
3484 (setq erc-server-reconnecting nil))) 3517 (setq erc-server-reconnecting nil)))
3485 t) 3518 t)
3486(put 'erc-cmd-RECONNECT 'process-not-needed t) 3519(put 'erc-cmd-RECONNECT 'process-not-needed t)
@@ -3501,54 +3534,54 @@ the message given by REASON."
3501(defun erc-cmd-SV () 3534(defun erc-cmd-SV ()
3502 "Say the current ERC and Emacs version into channel." 3535 "Say the current ERC and Emacs version into channel."
3503 (erc-send-message (format "I'm using ERC %s with %s %s (%s%s) of %s." 3536 (erc-send-message (format "I'm using ERC %s with %s %s (%s%s) of %s."
3504 erc-version-string 3537 erc-version-string
3505 (if (featurep 'xemacs) "XEmacs" "GNU Emacs") 3538 (if (featurep 'xemacs) "XEmacs" "GNU Emacs")
3506 emacs-version 3539 emacs-version
3507 system-configuration 3540 system-configuration
3508 (concat 3541 (concat
3509 (cond ((featurep 'motif) 3542 (cond ((featurep 'motif)
3510 (concat ", " (substring 3543 (concat ", " (substring
3511 motif-version-string 4))) 3544 motif-version-string 4)))
3512 ((featurep 'gtk) 3545 ((featurep 'gtk)
3513 (concat ", GTK+ Version " 3546 (concat ", GTK+ Version "
3514 gtk-version-string)) 3547 gtk-version-string))
3515 ((featurep 'x-toolkit) ", X toolkit") 3548 ((featurep 'x-toolkit) ", X toolkit")
3516 (t "")) 3549 (t ""))
3517 (if (and (boundp 'x-toolkit-scroll-bars) 3550 (if (and (boundp 'x-toolkit-scroll-bars)
3518 (memq x-toolkit-scroll-bars 3551 (memq x-toolkit-scroll-bars
3519 '(xaw xaw3d))) 3552 '(xaw xaw3d)))
3520 (format ", %s scroll bars" 3553 (format ", %s scroll bars"
3521 (capitalize (symbol-name 3554 (capitalize (symbol-name
3522 x-toolkit-scroll-bars))) 3555 x-toolkit-scroll-bars)))
3523 "") 3556 "")
3524 (if (featurep 'multi-tty) ", multi-tty" "")) 3557 (if (featurep 'multi-tty) ", multi-tty" ""))
3525 erc-emacs-build-time)) 3558 erc-emacs-build-time))
3526 t) 3559 t)
3527 3560
3528(defun erc-cmd-SM () 3561(defun erc-cmd-SM ()
3529 "Say the current ERC modes into channel." 3562 "Say the current ERC modes into channel."
3530 (erc-send-message (format "I'm using the following modules: %s!" 3563 (erc-send-message (format "I'm using the following modules: %s!"
3531 (erc-modes))) 3564 (erc-modes)))
3532 t) 3565 t)
3533 3566
3534(defun erc-cmd-DEOP (&rest people) 3567(defun erc-cmd-DEOP (&rest people)
3535 "Remove the operator setting from user(s) given in PEOPLE." 3568 "Remove the operator setting from user(s) given in PEOPLE."
3536 (when (> (length people) 0) 3569 (when (> (length people) 0)
3537 (erc-server-send (concat "MODE " (erc-default-target) 3570 (erc-server-send (concat "MODE " (erc-default-target)
3538 " -" 3571 " -"
3539 (make-string (length people) ?o) 3572 (make-string (length people) ?o)
3540 " " 3573 " "
3541 (mapconcat 'identity people " "))) 3574 (mapconcat 'identity people " ")))
3542 t)) 3575 t))
3543 3576
3544(defun erc-cmd-OP (&rest people) 3577(defun erc-cmd-OP (&rest people)
3545 "Add the operator setting to users(s) given in PEOPLE." 3578 "Add the operator setting to users(s) given in PEOPLE."
3546 (when (> (length people) 0) 3579 (when (> (length people) 0)
3547 (erc-server-send (concat "MODE " (erc-default-target) 3580 (erc-server-send (concat "MODE " (erc-default-target)
3548 " +" 3581 " +"
3549 (make-string (length people) ?o) 3582 (make-string (length people) ?o)
3550 " " 3583 " "
3551 (mapconcat 'identity people " "))) 3584 (mapconcat 'identity people " ")))
3552 t)) 3585 t))
3553 3586
3554(defun erc-cmd-TIME (&optional line) 3587(defun erc-cmd-TIME (&optional line)
@@ -3574,7 +3607,7 @@ be displayed."
3574 ;; /topic #channel TOPIC 3607 ;; /topic #channel TOPIC
3575 ((string-match "^\\s-*\\([&#+!]\\S-+\\)\\s-\\(.*\\)$" topic) 3608 ((string-match "^\\s-*\\([&#+!]\\S-+\\)\\s-\\(.*\\)$" topic)
3576 (let ((ch (match-string 1 topic)) 3609 (let ((ch (match-string 1 topic))
3577 (topic (match-string 2 topic))) 3610 (topic (match-string 2 topic)))
3578 (erc-log (format "cmd: TOPIC [%s]: %s" ch topic)) 3611 (erc-log (format "cmd: TOPIC [%s]: %s" ch topic))
3579 (erc-server-send (format "TOPIC %s :%s" ch topic) nil ch)) 3612 (erc-server-send (format "TOPIC %s :%s" ch topic) nil ch))
3580 t) 3613 t)
@@ -3591,12 +3624,12 @@ be displayed."
3591 ;; /topic TOPIC 3624 ;; /topic TOPIC
3592 ((string-match "^\\s-*\\(.*\\)$" topic) 3625 ((string-match "^\\s-*\\(.*\\)$" topic)
3593 (let ((ch (erc-default-target)) 3626 (let ((ch (erc-default-target))
3594 (topic (match-string 1 topic))) 3627 (topic (match-string 1 topic)))
3595 (if (and ch (erc-channel-p ch)) 3628 (if (and ch (erc-channel-p ch))
3596 (progn 3629 (progn
3597 (erc-log (format "cmd: TOPIC [%s]: %s" ch topic)) 3630 (erc-log (format "cmd: TOPIC [%s]: %s" ch topic))
3598 (erc-server-send (format "TOPIC %s :%s" ch topic) nil ch)) 3631 (erc-server-send (format "TOPIC %s :%s" ch topic) nil ch))
3599 (erc-display-message nil 'error (current-buffer) 'no-target))) 3632 (erc-display-message nil 'error (current-buffer) 'no-target)))
3600 t) 3633 t)
3601 (t nil))) 3634 (t nil)))
3602(defalias 'erc-cmd-T 'erc-cmd-TOPIC) 3635(defalias 'erc-cmd-T 'erc-cmd-TOPIC)
@@ -3641,69 +3674,69 @@ or not the ban list has been requested from the server.")
3641 3674
3642The ban list is fetched from the server if necessary." 3675The ban list is fetched from the server if necessary."
3643 (let ((chnl (erc-default-target)) 3676 (let ((chnl (erc-default-target))
3644 (chnl-name (buffer-name))) 3677 (chnl-name (buffer-name)))
3645 3678
3646 (cond 3679 (cond
3647 ((not (erc-channel-p chnl)) 3680 ((not (erc-channel-p chnl))
3648 (erc-display-line (erc-make-notice "You're not on a channel\n") 3681 (erc-display-line (erc-make-notice "You're not on a channel\n")
3649 'active)) 3682 'active))
3650 3683
3651 ((not (get 'erc-channel-banlist 'received-from-server)) 3684 ((not (get 'erc-channel-banlist 'received-from-server))
3652 (let ((old-367-hook erc-server-367-functions)) 3685 (let ((old-367-hook erc-server-367-functions))
3653 (setq erc-server-367-functions 'erc-banlist-store 3686 (setq erc-server-367-functions 'erc-banlist-store
3654 erc-channel-banlist nil) 3687 erc-channel-banlist nil)
3655 ;; fetch the ban list then callback 3688 ;; fetch the ban list then callback
3656 (erc-with-server-buffer 3689 (erc-with-server-buffer
3657 (erc-once-with-server-event 3690 (erc-once-with-server-event
3658 368 3691 368
3659 (lambda (_proc _parsed) 3692 (lambda (_proc _parsed)
3660 (with-current-buffer chnl-name 3693 (with-current-buffer chnl-name
3661 (put 'erc-channel-banlist 'received-from-server t) 3694 (put 'erc-channel-banlist 'received-from-server t)
3662 (setq erc-server-367-functions old-367-hook) 3695 (setq erc-server-367-functions old-367-hook)
3663 (erc-cmd-BANLIST) 3696 (erc-cmd-BANLIST)
3664 t))) 3697 t)))
3665 (erc-server-send (format "MODE %s b" chnl))))) 3698 (erc-server-send (format "MODE %s b" chnl)))))
3666 3699
3667 ((null erc-channel-banlist) 3700 ((null erc-channel-banlist)
3668 (erc-display-line (erc-make-notice 3701 (erc-display-line (erc-make-notice
3669 (format "No bans for channel: %s\n" chnl)) 3702 (format "No bans for channel: %s\n" chnl))
3670 'active) 3703 'active)
3671 (put 'erc-channel-banlist 'received-from-server nil)) 3704 (put 'erc-channel-banlist 'received-from-server nil))
3672 3705
3673 (t 3706 (t
3674 (let* ((erc-fill-column (or (and (boundp 'erc-fill-column) 3707 (let* ((erc-fill-column (or (and (boundp 'erc-fill-column)
3675 erc-fill-column) 3708 erc-fill-column)
3676 (and (boundp 'fill-column) 3709 (and (boundp 'fill-column)
3677 fill-column) 3710 fill-column)
3678 (1- (window-width)))) 3711 (1- (window-width))))
3679 (separator (make-string erc-fill-column ?=)) 3712 (separator (make-string erc-fill-column ?=))
3680 (fmt (concat 3713 (fmt (concat
3681 "%-" (number-to-string (/ erc-fill-column 2)) "s" 3714 "%-" (number-to-string (/ erc-fill-column 2)) "s"
3682 "%" (number-to-string (/ erc-fill-column 2)) "s"))) 3715 "%" (number-to-string (/ erc-fill-column 2)) "s")))
3683 3716
3684 (erc-display-line 3717 (erc-display-line
3685 (erc-make-notice (format "Ban list for channel: %s\n" 3718 (erc-make-notice (format "Ban list for channel: %s\n"
3686 (erc-default-target))) 3719 (erc-default-target)))
3687 'active) 3720 'active)
3688 3721
3689 (erc-display-line separator 'active) 3722 (erc-display-line separator 'active)
3690 (erc-display-line (format fmt "Ban Mask" "Banned By") 'active) 3723 (erc-display-line (format fmt "Ban Mask" "Banned By") 'active)
3691 (erc-display-line separator 'active) 3724 (erc-display-line separator 'active)
3692 3725
3693 (mapc 3726 (mapc
3694 (lambda (x) 3727 (lambda (x)
3695 (erc-display-line 3728 (erc-display-line
3696 (format fmt 3729 (format fmt
3697 (truncate-string-to-width (cdr x) (/ erc-fill-column 2)) 3730 (truncate-string-to-width (cdr x) (/ erc-fill-column 2))
3698 (if (car x) 3731 (if (car x)
3699 (truncate-string-to-width (car x) (/ erc-fill-column 2)) 3732 (truncate-string-to-width (car x) (/ erc-fill-column 2))
3700 "")) 3733 ""))
3701 'active)) 3734 'active))
3702 erc-channel-banlist) 3735 erc-channel-banlist)
3703 3736
3704 (erc-display-line (erc-make-notice "End of Ban list") 3737 (erc-display-line (erc-make-notice "End of Ban list")
3705 'active) 3738 'active)
3706 (put 'erc-channel-banlist 'received-from-server nil))))) 3739 (put 'erc-channel-banlist 'received-from-server nil)))))
3707 t) 3740 t)
3708 3741
3709(defalias 'erc-cmd-BL 'erc-cmd-BANLIST) 3742(defalias 'erc-cmd-BL 'erc-cmd-BANLIST)
@@ -3722,31 +3755,31 @@ Unban all currently banned users in the current channel."
3722 3755
3723 ((not (get 'erc-channel-banlist 'received-from-server)) 3756 ((not (get 'erc-channel-banlist 'received-from-server))
3724 (let ((old-367-hook erc-server-367-functions)) 3757 (let ((old-367-hook erc-server-367-functions))
3725 (setq erc-server-367-functions 'erc-banlist-store) 3758 (setq erc-server-367-functions 'erc-banlist-store)
3726 ;; fetch the ban list then callback 3759 ;; fetch the ban list then callback
3727 (erc-with-server-buffer 3760 (erc-with-server-buffer
3728 (erc-once-with-server-event 3761 (erc-once-with-server-event
3729 368 3762 368
3730 (lambda (_proc _parsed) 3763 (lambda (_proc _parsed)
3731 (with-current-buffer chnl 3764 (with-current-buffer chnl
3732 (put 'erc-channel-banlist 'received-from-server t) 3765 (put 'erc-channel-banlist 'received-from-server t)
3733 (setq erc-server-367-functions old-367-hook) 3766 (setq erc-server-367-functions old-367-hook)
3734 (erc-cmd-MASSUNBAN) 3767 (erc-cmd-MASSUNBAN)
3735 t))) 3768 t)))
3736 (erc-server-send (format "MODE %s b" chnl))))) 3769 (erc-server-send (format "MODE %s b" chnl)))))
3737 3770
3738 (t (let ((bans (mapcar 'cdr erc-channel-banlist))) 3771 (t (let ((bans (mapcar 'cdr erc-channel-banlist)))
3739 (when bans 3772 (when bans
3740 ;; Glob the bans into groups of three, and carry out the unban. 3773 ;; Glob the bans into groups of three, and carry out the unban.
3741 ;; eg. /mode #foo -bbb a*!*@* b*!*@* c*!*@* 3774 ;; eg. /mode #foo -bbb a*!*@* b*!*@* c*!*@*
3742 (mapc 3775 (mapc
3743 (lambda (x) 3776 (lambda (x)
3744 (erc-server-send 3777 (erc-server-send
3745 (format "MODE %s -%s %s" (erc-default-target) 3778 (format "MODE %s -%s %s" (erc-default-target)
3746 (make-string (length x) ?b) 3779 (make-string (length x) ?b)
3747 (mapconcat 'identity x " ")))) 3780 (mapconcat 'identity x " "))))
3748 (erc-group-list bans 3)))) 3781 (erc-group-list bans 3))))
3749 t)))) 3782 t))))
3750 3783
3751(defalias 'erc-cmd-MUB 'erc-cmd-MASSUNBAN) 3784(defalias 'erc-cmd-MUB 'erc-cmd-MASSUNBAN)
3752 3785
@@ -3770,12 +3803,12 @@ text again."
3770 (erc-set-active-buffer (current-buffer)) 3803 (erc-set-active-buffer (current-buffer))
3771 (save-excursion 3804 (save-excursion
3772 (let* ((cb (current-buffer)) 3805 (let* ((cb (current-buffer))
3773 (buf (generate-new-buffer erc-grab-buffer-name)) 3806 (buf (generate-new-buffer erc-grab-buffer-name))
3774 (region (buffer-substring start end)) 3807 (region (buffer-substring start end))
3775 (lines (erc-split-multiline-safe region))) 3808 (lines (erc-split-multiline-safe region)))
3776 (set-buffer buf) 3809 (set-buffer buf)
3777 (dolist (line lines) 3810 (dolist (line lines)
3778 (insert (concat line "\n"))) 3811 (insert (concat line "\n")))
3779 (set-buffer cb) 3812 (set-buffer cb)
3780 (switch-to-buffer-other-window buf))) 3813 (switch-to-buffer-other-window buf)))
3781 (message "erc-grab-region doesn't grab colors etc. anymore. If you use this, please tell the maintainers.") 3814 (message "erc-grab-region doesn't grab colors etc. anymore. If you use this, please tell the maintainers.")
@@ -3791,8 +3824,8 @@ If POS is nil, PROMPT will be displayed at `point'.
3791If FACE is non-nil, it will be used to propertize the prompt. If it is nil, 3824If FACE is non-nil, it will be used to propertize the prompt. If it is nil,
3792`erc-prompt-face' will be used." 3825`erc-prompt-face' will be used."
3793 (let* ((prompt (or prompt (erc-prompt))) 3826 (let* ((prompt (or prompt (erc-prompt)))
3794 (l (length prompt)) 3827 (l (length prompt))
3795 (ob (current-buffer))) 3828 (ob (current-buffer)))
3796 ;; We cannot use save-excursion because we move point, therefore 3829 ;; We cannot use save-excursion because we move point, therefore
3797 ;; we resort to the ol' ob trick to restore this. 3830 ;; we resort to the ol' ob trick to restore this.
3798 (when (and buffer (bufferp buffer)) 3831 (when (and buffer (bufferp buffer))
@@ -3804,20 +3837,20 @@ If FACE is non-nil, it will be used to propertize the prompt. If it is nil,
3804 (setq pos (or pos (point))) 3837 (setq pos (or pos (point)))
3805 (goto-char pos) 3838 (goto-char pos)
3806 (when (> l 0) 3839 (when (> l 0)
3807 ;; Do not extend the text properties when typing at the end 3840 ;; Do not extend the text properties when typing at the end
3808 ;; of the prompt, but stuff typed in front of the prompt 3841 ;; of the prompt, but stuff typed in front of the prompt
3809 ;; shall remain part of the prompt. 3842 ;; shall remain part of the prompt.
3810 (setq prompt (erc-propertize prompt 3843 (setq prompt (erc-propertize prompt
3811 'start-open t ; XEmacs 3844 'start-open t ; XEmacs
3812 'rear-nonsticky t ; Emacs 3845 'rear-nonsticky t ; Emacs
3813 'erc-prompt t 3846 'erc-prompt t
3814 'field t 3847 'field t
3815 'front-sticky t 3848 'front-sticky t
3816 'read-only t)) 3849 'read-only t))
3817 (erc-put-text-property 0 (1- (length prompt)) 3850 (erc-put-text-property 0 (1- (length prompt))
3818 'face (or face 'erc-prompt-face) 3851 'face (or face 'erc-prompt-face)
3819 prompt) 3852 prompt)
3820 (insert prompt)) 3853 (insert prompt))
3821 ;; Set the input marker 3854 ;; Set the input marker
3822 (set-marker erc-input-marker (point))) 3855 (set-marker erc-input-marker (point)))
3823 3856
@@ -3837,11 +3870,11 @@ If FACE is non-nil, it will be used to propertize the prompt. If it is nil,
3837 "Read input from the minibuffer." 3870 "Read input from the minibuffer."
3838 (interactive) 3871 (interactive)
3839 (let ((minibuffer-allow-text-properties t) 3872 (let ((minibuffer-allow-text-properties t)
3840 (read-map minibuffer-local-map)) 3873 (read-map minibuffer-local-map))
3841 (insert (read-from-minibuffer "Message: " 3874 (insert (read-from-minibuffer "Message: "
3842 (string (if (featurep 'xemacs) 3875 (string (if (featurep 'xemacs)
3843 last-command-char 3876 last-command-char
3844 last-command-event)) read-map)) 3877 last-command-event)) read-map))
3845 (erc-send-current-line))) 3878 (erc-send-current-line)))
3846 3879
3847(defvar erc-action-history-list () 3880(defvar erc-action-history-list ()
@@ -3852,9 +3885,9 @@ If FACE is non-nil, it will be used to propertize the prompt. If it is nil,
3852 (interactive "") 3885 (interactive "")
3853 (erc-set-active-buffer (current-buffer)) 3886 (erc-set-active-buffer (current-buffer))
3854 (let ((action (read-from-minibuffer 3887 (let ((action (read-from-minibuffer
3855 "Action: " nil nil nil 'erc-action-history-list))) 3888 "Action: " nil nil nil 'erc-action-history-list)))
3856 (if (not (string-match "^\\s-*$" action)) 3889 (if (not (string-match "^\\s-*$" action))
3857 (erc-send-action (erc-default-target) action)))) 3890 (erc-send-action (erc-default-target) action))))
3858 3891
3859(defun erc-join-channel (channel &optional key) 3892(defun erc-join-channel (channel &optional key)
3860 "Join CHANNEL. 3893 "Join CHANNEL.
@@ -3863,9 +3896,9 @@ If `point' is at the beginning of a channel name, use that as default."
3863 (interactive 3896 (interactive
3864 (list 3897 (list
3865 (let ((chnl (if (looking-at "\\([&#+!][^ \n]+\\)") (match-string 1) "")) 3898 (let ((chnl (if (looking-at "\\([&#+!][^ \n]+\\)") (match-string 1) ""))
3866 (table (when (erc-server-buffer-live-p) 3899 (table (when (erc-server-buffer-live-p)
3867 (set-buffer (process-buffer erc-server-process)) 3900 (set-buffer (process-buffer erc-server-process))
3868 erc-channel-list))) 3901 erc-channel-list)))
3869 (completing-read "Join channel: " table nil nil nil nil chnl)) 3902 (completing-read "Join channel: " table nil nil nil nil chnl))
3870 (when (or current-prefix-arg erc-prompt-for-channel-key) 3903 (when (or current-prefix-arg erc-prompt-for-channel-key)
3871 (read-from-minibuffer "Channel key (RET for none): " nil)))) 3904 (read-from-minibuffer "Channel key (RET for none): " nil))))
@@ -3876,9 +3909,9 @@ If `point' is at the beginning of a channel name, use that as default."
3876 (interactive 3909 (interactive
3877 (list 3910 (list
3878 (if (and (boundp 'reason) (stringp reason) (not (string= reason ""))) 3911 (if (and (boundp 'reason) (stringp reason) (not (string= reason "")))
3879 reason 3912 reason
3880 (read-from-minibuffer (concat "Reason for leaving " (erc-default-target) 3913 (read-from-minibuffer (concat "Reason for leaving " (erc-default-target)
3881 ": "))))) 3914 ": ")))))
3882 (erc-cmd-PART (concat (erc-default-target)" " reason))) 3915 (erc-cmd-PART (concat (erc-default-target)" " reason)))
3883 3916
3884(defun erc-set-topic (topic) 3917(defun erc-set-topic (topic)
@@ -3889,8 +3922,8 @@ If `point' is at the beginning of a channel name, use that as default."
3889 (concat "Set topic of " (erc-default-target) ": ") 3922 (concat "Set topic of " (erc-default-target) ": ")
3890 (when erc-channel-topic 3923 (when erc-channel-topic
3891 (let ((ss (split-string erc-channel-topic "\C-o"))) 3924 (let ((ss (split-string erc-channel-topic "\C-o")))
3892 (cons (apply 'concat (if (cdr ss) (butlast ss) ss)) 3925 (cons (apply 'concat (if (cdr ss) (butlast ss) ss))
3893 0)))))) 3926 0))))))
3894 (let ((topic-list (split-string topic "\C-o"))) ; strip off the topic setter 3927 (let ((topic-list (split-string topic "\C-o"))) ; strip off the topic setter
3895 (erc-cmd-TOPIC (concat (erc-default-target) " " (car topic-list))))) 3928 (erc-cmd-TOPIC (concat (erc-default-target) " " (car topic-list)))))
3896 3929
@@ -3898,31 +3931,31 @@ If `point' is at the beginning of a channel name, use that as default."
3898 "Set a LIMIT for the current channel. Remove limit if nil. 3931 "Set a LIMIT for the current channel. Remove limit if nil.
3899Prompt for one if called interactively." 3932Prompt for one if called interactively."
3900 (interactive (list (read-from-minibuffer 3933 (interactive (list (read-from-minibuffer
3901 (format "Limit for %s (RET to remove limit): " 3934 (format "Limit for %s (RET to remove limit): "
3902 (erc-default-target))))) 3935 (erc-default-target)))))
3903 (let ((tgt (erc-default-target))) 3936 (let ((tgt (erc-default-target)))
3904 (erc-server-send (if (and limit (>= (length limit) 1)) 3937 (erc-server-send (if (and limit (>= (length limit) 1))
3905 (format "MODE %s +l %s" tgt limit) 3938 (format "MODE %s +l %s" tgt limit)
3906 (format "MODE %s -l" tgt))))) 3939 (format "MODE %s -l" tgt)))))
3907 3940
3908(defun erc-set-channel-key (&optional key) 3941(defun erc-set-channel-key (&optional key)
3909 "Set a KEY for the current channel. Remove key if nil. 3942 "Set a KEY for the current channel. Remove key if nil.
3910Prompt for one if called interactively." 3943Prompt for one if called interactively."
3911 (interactive (list (read-from-minibuffer 3944 (interactive (list (read-from-minibuffer
3912 (format "Key for %s (RET to remove key): " 3945 (format "Key for %s (RET to remove key): "
3913 (erc-default-target))))) 3946 (erc-default-target)))))
3914 (let ((tgt (erc-default-target))) 3947 (let ((tgt (erc-default-target)))
3915 (erc-server-send (if (and key (>= (length key) 1)) 3948 (erc-server-send (if (and key (>= (length key) 1))
3916 (format "MODE %s +k %s" tgt key) 3949 (format "MODE %s +k %s" tgt key)
3917 (format "MODE %s -k" tgt))))) 3950 (format "MODE %s -k" tgt)))))
3918 3951
3919(defun erc-quit-server (reason) 3952(defun erc-quit-server (reason)
3920 "Disconnect from current server after prompting for REASON. 3953 "Disconnect from current server after prompting for REASON.
3921`erc-quit-reason' works with this just like with `erc-cmd-QUIT'." 3954`erc-quit-reason' works with this just like with `erc-cmd-QUIT'."
3922 (interactive (list (read-from-minibuffer 3955 (interactive (list (read-from-minibuffer
3923 (format "Reason for quitting %s: " 3956 (format "Reason for quitting %s: "
3924 (or erc-server-announced-name 3957 (or erc-server-announced-name
3925 erc-session-server))))) 3958 erc-session-server)))))
3926 (erc-cmd-QUIT reason)) 3959 (erc-cmd-QUIT reason))
3927 3960
3928;; Movement of point 3961;; Movement of point
@@ -3941,10 +3974,10 @@ This places `point' just after the prompt, or at the beginning of the line."
3941 "Kill current input line using `erc-bol' followed by `kill-line'." 3974 "Kill current input line using `erc-bol' followed by `kill-line'."
3942 (interactive) 3975 (interactive)
3943 (when (and (erc-bol) 3976 (when (and (erc-bol)
3944 (/= (point) (point-max))) ;; Prevent a (ding) and an error when 3977 (/= (point) (point-max))) ;; Prevent a (ding) and an error when
3945 ;; there's nothing to kill 3978 ;; there's nothing to kill
3946 (if (boundp 'erc-input-ring-index) 3979 (if (boundp 'erc-input-ring-index)
3947 (setq erc-input-ring-index nil)) 3980 (setq erc-input-ring-index nil))
3948 (kill-line))) 3981 (kill-line)))
3949 3982
3950(defun erc-complete-word-at-point () 3983(defun erc-complete-word-at-point ()
@@ -3954,7 +3987,7 @@ This places `point' just after the prompt, or at the beginning of the line."
3954 3987
3955;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3988;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3956;; 3989;;
3957;; IRC SERVER INPUT HANDLING 3990;; IRC SERVER INPUT HANDLING
3958;; 3991;;
3959;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3992;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3960 3993
@@ -3964,7 +3997,7 @@ This places `point' just after the prompt, or at the beginning of the line."
3964; experiment area. 3997; experiment area.
3965 3998
3966(defcustom erc-default-server-hook '(erc-debug-missing-hooks 3999(defcustom erc-default-server-hook '(erc-debug-missing-hooks
3967 erc-default-server-handler) 4000 erc-default-server-handler)
3968 "Default for server messages which aren't covered by `erc-server-hooks'." 4001 "Default for server messages which aren't covered by `erc-server-hooks'."
3969 :group 'erc-server-hooks 4002 :group 'erc-server-hooks
3970 :type 'hook) 4003 :type 'hook)
@@ -3979,9 +4012,9 @@ Displays PROC and PARSED appropriately using `erc-display-message'."
3979 'identity 4012 'identity
3980 (let (res) 4013 (let (res)
3981 (mapc #'(lambda (x) 4014 (mapc #'(lambda (x)
3982 (if (stringp x) 4015 (if (stringp x)
3983 (setq res (append res (list x))))) 4016 (setq res (append res (list x)))))
3984 parsed) 4017 parsed)
3985 res) 4018 res)
3986 " "))) 4019 " ")))
3987 4020
@@ -4003,18 +4036,18 @@ See `erc-default-server-hook'."
4003To change how this query window is displayed, use `let' to bind 4036To change how this query window is displayed, use `let' to bind
4004`erc-join-buffer' before calling this." 4037`erc-join-buffer' before calling this."
4005 (unless (and server 4038 (unless (and server
4006 (buffer-live-p server) 4039 (buffer-live-p server)
4007 (set-buffer server)) 4040 (set-buffer server))
4008 (error "Couldn't switch to server buffer")) 4041 (error "Couldn't switch to server buffer"))
4009 (let ((buf (erc-open erc-session-server 4042 (let ((buf (erc-open erc-session-server
4010 erc-session-port 4043 erc-session-port
4011 (erc-current-nick) 4044 (erc-current-nick)
4012 erc-session-user-full-name 4045 erc-session-user-full-name
4013 nil 4046 nil
4014 nil 4047 nil
4015 (list target) 4048 (list target)
4016 target 4049 target
4017 erc-server-process))) 4050 erc-server-process)))
4018 (unless buf 4051 (unless buf
4019 (error "Couldn't open query window")) 4052 (error "Couldn't open query window"))
4020 (erc-update-mode-line) 4053 (erc-update-mode-line)
@@ -4030,12 +4063,12 @@ a new window, but not to select it. See the documentation for
4030`erc-join-buffer' for a description of the available choices." 4063`erc-join-buffer' for a description of the available choices."
4031 :group 'erc-query 4064 :group 'erc-query
4032 :type '(choice (const :tag "Don't create query window" nil) 4065 :type '(choice (const :tag "Don't create query window" nil)
4033 (const :tag "Split window and select" window) 4066 (const :tag "Split window and select" window)
4034 (const :tag "Split window, don't select" window-noselect) 4067 (const :tag "Split window, don't select" window-noselect)
4035 (const :tag "New frame" frame) 4068 (const :tag "New frame" frame)
4036 (const :tag "Bury in new buffer" bury) 4069 (const :tag "Bury in new buffer" bury)
4037 (const :tag "Use current buffer" buffer) 4070 (const :tag "Use current buffer" buffer)
4038 (const :tag "Use current buffer" t))) 4071 (const :tag "Use current buffer" t)))
4039 4072
4040(defcustom erc-query-on-unjoined-chan-privmsg t 4073(defcustom erc-query-on-unjoined-chan-privmsg t
4041 "If non-nil create query buffer on receiving any PRIVMSG at all. 4074 "If non-nil create query buffer on receiving any PRIVMSG at all.
@@ -4069,15 +4102,15 @@ unmodified if nothing can be removed.
4069E.g. \"Read error to Nick [user@some.host]: 110\" would be shortened to 4102E.g. \"Read error to Nick [user@some.host]: 110\" would be shortened to
4070\"Read error: 110\". The same applies for \"Ping Timeout\"." 4103\"Read error: 110\". The same applies for \"Ping Timeout\"."
4071 (setq nick (regexp-quote nick) 4104 (setq nick (regexp-quote nick)
4072 login (regexp-quote login) 4105 login (regexp-quote login)
4073 host (regexp-quote host)) 4106 host (regexp-quote host))
4074 (or (when (string-match (concat "^\\(Read error\\) to " 4107 (or (when (string-match (concat "^\\(Read error\\) to "
4075 nick "\\[" host "\\]: " 4108 nick "\\[" host "\\]: "
4076 "\\(.+\\)$") reason) 4109 "\\(.+\\)$") reason)
4077 (concat (match-string 1 reason) ": " (match-string 2 reason))) 4110 (concat (match-string 1 reason) ": " (match-string 2 reason)))
4078 (when (string-match (concat "^\\(Ping timeout\\) for " 4111 (when (string-match (concat "^\\(Ping timeout\\) for "
4079 nick "\\[" host "\\]$") reason) 4112 nick "\\[" host "\\]$") reason)
4080 (match-string 1 reason)) 4113 (match-string 1 reason))
4081 reason)) 4114 reason))
4082 4115
4083(defun erc-nickname-in-use (nick reason) 4116(defun erc-nickname-in-use (nick reason)
@@ -4085,40 +4118,40 @@ E.g. \"Read error to Nick [user@some.host]: 110\" would be shortened to
4085 4118
4086See also `erc-display-error-notice'." 4119See also `erc-display-error-notice'."
4087 (if (or (not erc-try-new-nick-p) 4120 (if (or (not erc-try-new-nick-p)
4088 ;; how many default-nicks are left + one more try... 4121 ;; how many default-nicks are left + one more try...
4089 (eq erc-nick-change-attempt-count 4122 (eq erc-nick-change-attempt-count
4090 (if (consp erc-nick) 4123 (if (consp erc-nick)
4091 (+ (length erc-nick) 1) 4124 (+ (length erc-nick) 1)
4092 1))) 4125 1)))
4093 (erc-display-error-notice 4126 (erc-display-error-notice
4094 nil 4127 nil
4095 (format "Nickname %s is %s, try another." nick reason)) 4128 (format "Nickname %s is %s, try another." nick reason))
4096 (setq erc-nick-change-attempt-count (+ erc-nick-change-attempt-count 1)) 4129 (setq erc-nick-change-attempt-count (+ erc-nick-change-attempt-count 1))
4097 (let ((newnick (nth 1 erc-default-nicks)) 4130 (let ((newnick (nth 1 erc-default-nicks))
4098 (nicklen (cdr (assoc "NICKLEN" 4131 (nicklen (cdr (assoc "NICKLEN"
4099 (erc-with-server-buffer 4132 (erc-with-server-buffer
4100 erc-server-parameters))))) 4133 erc-server-parameters)))))
4101 (setq erc-bad-nick t) 4134 (setq erc-bad-nick t)
4102 ;; try to use a different nick 4135 ;; try to use a different nick
4103 (if erc-default-nicks 4136 (if erc-default-nicks
4104 (setq erc-default-nicks (cdr erc-default-nicks))) 4137 (setq erc-default-nicks (cdr erc-default-nicks)))
4105 (if (not newnick) 4138 (if (not newnick)
4106 (setq newnick (concat (truncate-string-to-width 4139 (setq newnick (concat (truncate-string-to-width
4107 nick 4140 nick
4108 (if (and erc-server-connected nicklen) 4141 (if (and erc-server-connected nicklen)
4109 (- (string-to-number nicklen) 4142 (- (string-to-number nicklen)
4110 (length erc-nick-uniquifier)) 4143 (length erc-nick-uniquifier))
4111 ;; rfc2812 max nick length = 9 4144 ;; rfc2812 max nick length = 9
4112 ;; we must assume this is the 4145 ;; we must assume this is the
4113 ;; server's setting if we haven't 4146 ;; server's setting if we haven't
4114 ;; established a connection yet 4147 ;; established a connection yet
4115 (- 9 (length erc-nick-uniquifier)))) 4148 (- 9 (length erc-nick-uniquifier))))
4116 erc-nick-uniquifier))) 4149 erc-nick-uniquifier)))
4117 (erc-cmd-NICK newnick) 4150 (erc-cmd-NICK newnick)
4118 (erc-display-error-notice 4151 (erc-display-error-notice
4119 nil 4152 nil
4120 (format "Nickname %s is %s, trying %s" 4153 (format "Nickname %s is %s, trying %s"
4121 nick reason newnick))))) 4154 nick reason newnick)))))
4122 4155
4123;;; Server messages 4156;;; Server messages
4124 4157
@@ -4142,21 +4175,21 @@ and as second argument the event parsed as a vector."
4142 "Put this on `erc-server-PRIVMSG-functions'." 4175 "Put this on `erc-server-PRIVMSG-functions'."
4143 (when erc-auto-query 4176 (when erc-auto-query
4144 (let* ((nick (car (erc-parse-user (erc-response.sender parsed)))) 4177 (let* ((nick (car (erc-parse-user (erc-response.sender parsed))))
4145 (target (car (erc-response.command-args parsed))) 4178 (target (car (erc-response.command-args parsed)))
4146 (msg (erc-response.contents parsed)) 4179 (msg (erc-response.contents parsed))
4147 (query (if (not erc-query-on-unjoined-chan-privmsg) 4180 (query (if (not erc-query-on-unjoined-chan-privmsg)
4148 nick 4181 nick
4149 (if (erc-current-nick-p target) 4182 (if (erc-current-nick-p target)
4150 nick 4183 nick
4151 target)))) 4184 target))))
4152 (and (not (erc-ignored-user-p (erc-response.sender parsed))) 4185 (and (not (erc-ignored-user-p (erc-response.sender parsed)))
4153 (or erc-query-on-unjoined-chan-privmsg 4186 (or erc-query-on-unjoined-chan-privmsg
4154 (string= target (erc-current-nick))) 4187 (string= target (erc-current-nick)))
4155 (not (erc-get-buffer query proc)) 4188 (not (erc-get-buffer query proc))
4156 (not (erc-is-message-ctcp-and-not-action-p msg)) 4189 (not (erc-is-message-ctcp-and-not-action-p msg))
4157 (let ((erc-query-display erc-auto-query)) 4190 (let ((erc-query-display erc-auto-query))
4158 (erc-cmd-QUERY query)) 4191 (erc-cmd-QUERY query))
4159 nil)))) 4192 nil))))
4160 4193
4161(defun erc-is-message-ctcp-p (message) 4194(defun erc-is-message-ctcp-p (message)
4162 "Check if MESSAGE is a CTCP message or not." 4195 "Check if MESSAGE is a CTCP message or not."
@@ -4170,16 +4203,16 @@ and as second argument the event parsed as a vector."
4170(defun erc-format-privmessage (nick msg privp msgp) 4203(defun erc-format-privmessage (nick msg privp msgp)
4171 "Format a PRIVMSG in an insertable fashion." 4204 "Format a PRIVMSG in an insertable fashion."
4172 (let* ((mark-s (if msgp (if privp "*" "<") "-")) 4205 (let* ((mark-s (if msgp (if privp "*" "<") "-"))
4173 (mark-e (if msgp (if privp "*" ">") "-")) 4206 (mark-e (if msgp (if privp "*" ">") "-"))
4174 (str (format "%s%s%s %s" mark-s nick mark-e msg)) 4207 (str (format "%s%s%s %s" mark-s nick mark-e msg))
4175 (nick-face (if privp 'erc-nick-msg-face 'erc-nick-default-face)) 4208 (nick-face (if privp 'erc-nick-msg-face 'erc-nick-default-face))
4176 (msg-face (if privp 'erc-direct-msg-face 'erc-default-face))) 4209 (msg-face (if privp 'erc-direct-msg-face 'erc-default-face)))
4177 ;; add text properties to text before the nick, the nick and after the nick 4210 ;; add text properties to text before the nick, the nick and after the nick
4178 (erc-put-text-property 0 (length mark-s) 'face msg-face str) 4211 (erc-put-text-property 0 (length mark-s) 'face msg-face str)
4179 (erc-put-text-property (length mark-s) (+ (length mark-s) (length nick)) 4212 (erc-put-text-property (length mark-s) (+ (length mark-s) (length nick))
4180 'face nick-face str) 4213 'face nick-face str)
4181 (erc-put-text-property (+ (length mark-s) (length nick)) (length str) 4214 (erc-put-text-property (+ (length mark-s) (length nick)) (length str)
4182 'face msg-face str) 4215 'face msg-face str)
4183 str)) 4216 str))
4184 4217
4185(defcustom erc-format-nick-function 'erc-format-nick 4218(defcustom erc-format-nick-function 'erc-format-nick
@@ -4190,7 +4223,24 @@ and as second argument the event parsed as a vector."
4190(defun erc-format-nick (&optional user _channel-data) 4223(defun erc-format-nick (&optional user _channel-data)
4191 "Return the nickname of USER. 4224 "Return the nickname of USER.
4192See also `erc-format-nick-function'." 4225See also `erc-format-nick-function'."
4193 (when user (erc-server-user-nickname user))) 4226 (let ((nick (erc-server-user-nickname user)))
4227 (concat (erc-propertize
4228 (erc-get-user-mode-prefix nick)
4229 'face 'erc-nick-prefix-face) nick)))
4230
4231(defun erc-get-user-mode-prefix (user)
4232 (when user
4233 (cond ((erc-channel-user-owner-p user)
4234 (erc-propertize "~" 'help-echo "owner"))
4235 ((erc-channel-user-admin-p user)
4236 (erc-propertize "&" 'help-echo "admin"))
4237 ((erc-channel-user-op-p user)
4238 (erc-propertize "@" 'help-echo "operator"))
4239 ((erc-channel-user-halfop-p user)
4240 (erc-propertize "%" 'help-echo "half-op"))
4241 ((erc-channel-user-voice-p user)
4242 (erc-propertize "+" 'help-echo "voice"))
4243 (t ""))))
4194 4244
4195(defun erc-format-@nick (&optional user channel-data) 4245(defun erc-format-@nick (&optional user channel-data)
4196 "Format the nickname of USER showing if USER is an operator or has voice. 4246 "Format the nickname of USER showing if USER is an operator or has voice.
@@ -4198,20 +4248,23 @@ Operators have \"@\" and users with voice have \"+\" as a prefix.
4198Use CHANNEL-DATA to determine op and voice status. 4248Use CHANNEL-DATA to determine op and voice status.
4199See also `erc-format-nick-function'." 4249See also `erc-format-nick-function'."
4200 (when user 4250 (when user
4201 (let ((op (and channel-data (erc-channel-user-op channel-data) "@")) 4251 (let ((nick (erc-server-user-nickname user)))
4202 (voice (and channel-data (erc-channel-user-voice channel-data) "+"))) 4252 (concat (erc-propertize
4203 (concat voice op (erc-server-user-nickname user))))) 4253 (erc-get-user-mode-prefix nick)
4254 'face 'erc-nick-prefix-face) nick nick))))
4204 4255
4205(defun erc-format-my-nick () 4256(defun erc-format-my-nick ()
4206 "Return the beginning of this user's message, correctly propertized." 4257 "Return the beginning of this user's message, correctly propertized."
4207 (if erc-show-my-nick 4258 (if erc-show-my-nick
4208 (let ((open "<") 4259 (let* ((open "<")
4209 (close "> ") 4260 (close "> ")
4210 (nick (erc-current-nick))) 4261 (nick (erc-current-nick))
4211 (concat 4262 (mode (erc-get-user-mode-prefix nick)))
4212 (erc-propertize open 'face 'erc-default-face) 4263 (concat
4213 (erc-propertize nick 'face 'erc-my-nick-face) 4264 (erc-propertize open 'face 'erc-default-face)
4214 (erc-propertize close 'face 'erc-default-face))) 4265 (erc-propertize mode 'face 'erc-my-nick-prefix-face)
4266 (erc-propertize nick 'face 'erc-my-nick-face)
4267 (erc-propertize close 'face 'erc-default-face)))
4215 (let ((prefix "> ")) 4268 (let ((prefix "> "))
4216 (erc-propertize prefix 'face 'erc-default-face)))) 4269 (erc-propertize prefix 'face 'erc-default-face))))
4217 4270
@@ -4275,7 +4328,7 @@ See also: `erc-echo-notice-in-first-user-buffer',
4275`erc-buffer-list-with-nick'." 4328`erc-buffer-list-with-nick'."
4276 (let ((buffers (erc-buffer-list-with-nick sender erc-server-process))) 4329 (let ((buffers (erc-buffer-list-with-nick sender erc-server-process)))
4277 (if buffers 4330 (if buffers
4278 (progn (erc-display-message parsed nil buffers s) t) 4331 (progn (erc-display-message parsed nil buffers s) t)
4279 nil))) 4332 nil)))
4280 4333
4281(defun erc-echo-notice-in-user-and-target-buffers (s parsed buffer sender) 4334(defun erc-echo-notice-in-user-and-target-buffers (s parsed buffer sender)
@@ -4290,8 +4343,8 @@ See also: `erc-echo-notice-in-user-buffers',
4290`erc-buffer-list-with-nick'." 4343`erc-buffer-list-with-nick'."
4291 (let ((buffers (erc-buffer-list-with-nick sender erc-server-process))) 4344 (let ((buffers (erc-buffer-list-with-nick sender erc-server-process)))
4292 (unless (memq buffer buffers) (push buffer buffers)) 4345 (unless (memq buffer buffers) (push buffer buffers))
4293 (if buffers ;FIXME: How could it be nil? 4346 (if buffers ;FIXME: How could it be nil?
4294 (progn (erc-display-message parsed nil buffers s) t) 4347 (progn (erc-display-message parsed nil buffers s) t)
4295 nil))) 4348 nil)))
4296 4349
4297(defun erc-echo-notice-in-first-user-buffer (s parsed _buffer sender) 4350(defun erc-echo-notice-in-first-user-buffer (s parsed _buffer sender)
@@ -4305,7 +4358,7 @@ See also: `erc-echo-notice-in-user-buffers',
4305`erc-buffer-list-with-nick'." 4358`erc-buffer-list-with-nick'."
4306 (let ((buffers (erc-buffer-list-with-nick sender erc-server-process))) 4359 (let ((buffers (erc-buffer-list-with-nick sender erc-server-process)))
4307 (if buffers 4360 (if buffers
4308 (progn (erc-display-message parsed nil (car buffers) s) t) 4361 (progn (erc-display-message parsed nil (car buffers) s) t)
4309 nil))) 4362 nil)))
4310 4363
4311;;; Ban manipulation 4364;;; Ban manipulation
@@ -4313,61 +4366,61 @@ See also: `erc-echo-notice-in-user-buffers',
4313(defun erc-banlist-store (proc parsed) 4366(defun erc-banlist-store (proc parsed)
4314 "Record ban entries for a channel." 4367 "Record ban entries for a channel."
4315 (pcase-let ((`(,channel ,mask ,whoset) 4368 (pcase-let ((`(,channel ,mask ,whoset)
4316 (cdr (erc-response.command-args parsed)))) 4369 (cdr (erc-response.command-args parsed))))
4317 ;; Determine to which buffer the message corresponds 4370 ;; Determine to which buffer the message corresponds
4318 (let ((buffer (erc-get-buffer channel proc))) 4371 (let ((buffer (erc-get-buffer channel proc)))
4319 (with-current-buffer buffer 4372 (with-current-buffer buffer
4320 (unless (member (cons whoset mask) erc-channel-banlist) 4373 (unless (member (cons whoset mask) erc-channel-banlist)
4321 (setq erc-channel-banlist (cons (cons whoset mask) 4374 (setq erc-channel-banlist (cons (cons whoset mask)
4322 erc-channel-banlist)))))) 4375 erc-channel-banlist))))))
4323 nil) 4376 nil)
4324 4377
4325(defun erc-banlist-finished (proc parsed) 4378(defun erc-banlist-finished (proc parsed)
4326 "Record that we have received the banlist." 4379 "Record that we have received the banlist."
4327 (let* ((channel (nth 1 (erc-response.command-args parsed))) 4380 (let* ((channel (nth 1 (erc-response.command-args parsed)))
4328 (buffer (erc-get-buffer channel proc))) 4381 (buffer (erc-get-buffer channel proc)))
4329 (with-current-buffer buffer 4382 (with-current-buffer buffer
4330 (put 'erc-channel-banlist 'received-from-server t))) 4383 (put 'erc-channel-banlist 'received-from-server t)))
4331 t) ; suppress the 'end of banlist' message 4384 t) ; suppress the 'end of banlist' message
4332 4385
4333(defun erc-banlist-update (proc parsed) 4386(defun erc-banlist-update (proc parsed)
4334 "Check MODE commands for bans and update the banlist appropriately." 4387 "Check MODE commands for bans and update the banlist appropriately."
4335 ;; FIXME: Possibly incorrect. -- Lawrence 2004-05-11 4388 ;; FIXME: Possibly incorrect. -- Lawrence 2004-05-11
4336 (let* ((tgt (car (erc-response.command-args parsed))) 4389 (let* ((tgt (car (erc-response.command-args parsed)))
4337 (mode (erc-response.contents parsed)) 4390 (mode (erc-response.contents parsed))
4338 (whoset (erc-response.sender parsed)) 4391 (whoset (erc-response.sender parsed))
4339 (buffer (erc-get-buffer tgt proc))) 4392 (buffer (erc-get-buffer tgt proc)))
4340 (when buffer 4393 (when buffer
4341 (with-current-buffer buffer 4394 (with-current-buffer buffer
4342 (cond ((not (get 'erc-channel-banlist 'received-from-server)) nil) 4395 (cond ((not (get 'erc-channel-banlist 'received-from-server)) nil)
4343 ((string-match "^\\([+-]\\)b" mode) 4396 ((string-match "^\\([+-]\\)b" mode)
4344 ;; This is a ban 4397 ;; This is a ban
4345 (cond 4398 (cond
4346 ((string-match "^-" mode) 4399 ((string-match "^-" mode)
4347 ;; Remove the unbanned masks from the ban list 4400 ;; Remove the unbanned masks from the ban list
4348 (setq erc-channel-banlist 4401 (setq erc-channel-banlist
4349 (erc-delete-if 4402 (erc-delete-if
4350 #'(lambda (y) 4403 #'(lambda (y)
4351 (member (upcase (cdr y)) 4404 (member (upcase (cdr y))
4352 (mapcar #'upcase 4405 (mapcar #'upcase
4353 (cdr (split-string mode))))) 4406 (cdr (split-string mode)))))
4354 erc-channel-banlist))) 4407 erc-channel-banlist)))
4355 ((string-match "^+" mode) 4408 ((string-match "^+" mode)
4356 ;; Add the banned mask(s) to the ban list 4409 ;; Add the banned mask(s) to the ban list
4357 (mapc 4410 (mapc
4358 (lambda (mask) 4411 (lambda (mask)
4359 (unless (member (cons whoset mask) erc-channel-banlist) 4412 (unless (member (cons whoset mask) erc-channel-banlist)
4360 (setq erc-channel-banlist 4413 (setq erc-channel-banlist
4361 (cons (cons whoset mask) erc-channel-banlist)))) 4414 (cons (cons whoset mask) erc-channel-banlist))))
4362 (cdr (split-string mode)))))))))) 4415 (cdr (split-string mode))))))))))
4363 nil) 4416 nil)
4364 4417
4365;; used for the banlist cmds 4418;; used for the banlist cmds
4366(defun erc-group-list (list n) 4419(defun erc-group-list (list n)
4367 "Group LIST into sublists of length N." 4420 "Group LIST into sublists of length N."
4368 (cond ((null list) nil) 4421 (cond ((null list) nil)
4369 ((null (nthcdr n list)) (list list)) 4422 ((null (nthcdr n list)) (list list))
4370 (t (cons (erc-subseq list 0 n) (erc-group-list (nthcdr n list) n))))) 4423 (t (cons (erc-subseq list 0 n) (erc-group-list (nthcdr n list) n)))))
4371 4424
4372 4425
4373;;; MOTD numreplies 4426;;; MOTD numreplies
@@ -4380,7 +4433,7 @@ See also: `erc-echo-notice-in-user-buffers',
4380 ;; execute a startup script 4433 ;; execute a startup script
4381 (let ((f (erc-select-startup-file))) 4434 (let ((f (erc-select-startup-file)))
4382 (when f 4435 (when f
4383 (erc-load-script f))))) 4436 (erc-load-script f)))))
4384 4437
4385(defun erc-connection-established (proc parsed) 4438(defun erc-connection-established (proc parsed)
4386 "Run just after connection. 4439 "Run just after connection.
@@ -4389,14 +4442,14 @@ Set user modes and run `erc-after-connect' hook."
4389 (with-current-buffer (process-buffer proc) 4442 (with-current-buffer (process-buffer proc)
4390 (unless erc-server-connected ; only once per session 4443 (unless erc-server-connected ; only once per session
4391 (let ((server (or erc-server-announced-name 4444 (let ((server (or erc-server-announced-name
4392 (erc-response.sender parsed))) 4445 (erc-response.sender parsed)))
4393 (nick (car (erc-response.command-args parsed))) 4446 (nick (car (erc-response.command-args parsed)))
4394 (buffer (process-buffer proc))) 4447 (buffer (process-buffer proc)))
4395 (setq erc-server-connected t) 4448 (setq erc-server-connected t)
4396 (erc-update-mode-line) 4449 (erc-update-mode-line)
4397 (erc-set-initial-user-mode nick buffer) 4450 (erc-set-initial-user-mode nick buffer)
4398 (erc-server-setup-periodical-ping buffer) 4451 (erc-server-setup-periodical-ping buffer)
4399 (run-hook-with-args 'erc-after-connect server nick))))) 4452 (run-hook-with-args 'erc-after-connect server nick)))))
4400 4453
4401(defun erc-set-initial-user-mode (nick buffer) 4454(defun erc-set-initial-user-mode (nick buffer)
4402 "If `erc-user-mode' is non-nil for NICK, set the user modes. 4455 "If `erc-user-mode' is non-nil for NICK, set the user modes.
@@ -4404,11 +4457,11 @@ The server buffer is given by BUFFER."
4404 (with-current-buffer buffer 4457 (with-current-buffer buffer
4405 (when erc-user-mode 4458 (when erc-user-mode
4406 (let ((mode (if (functionp erc-user-mode) 4459 (let ((mode (if (functionp erc-user-mode)
4407 (funcall erc-user-mode) 4460 (funcall erc-user-mode)
4408 erc-user-mode))) 4461 erc-user-mode)))
4409 (when (stringp mode) 4462 (when (stringp mode)
4410 (erc-log (format "changing mode for %s to %s" nick mode)) 4463 (erc-log (format "changing mode for %s to %s" nick mode))
4411 (erc-server-send (format "MODE %s %s" nick mode))))))) 4464 (erc-server-send (format "MODE %s %s" nick mode)))))))
4412 4465
4413(defun erc-display-error-notice (parsed string) 4466(defun erc-display-error-notice (parsed string)
4414 "Display STRING as an error notice. 4467 "Display STRING as an error notice.
@@ -4421,41 +4474,41 @@ See also `erc-display-message'."
4421 ;; FIXME: This needs a proper docstring -- Lawrence 2004-01-08 4474 ;; FIXME: This needs a proper docstring -- Lawrence 2004-01-08
4422 "Process a CTCP query." 4475 "Process a CTCP query."
4423 (let ((queries (delete "" (split-string (erc-response.contents parsed) 4476 (let ((queries (delete "" (split-string (erc-response.contents parsed)
4424 "\C-a")))) 4477 "\C-a"))))
4425 (if (> (length queries) 4) 4478 (if (> (length queries) 4)
4426 (erc-display-message 4479 (erc-display-message
4427 parsed (list 'notice 'error) proc 'ctcp-too-many) 4480 parsed (list 'notice 'error) proc 'ctcp-too-many)
4428 (if (= 0 (length queries)) 4481 (if (= 0 (length queries))
4429 (erc-display-message 4482 (erc-display-message
4430 parsed (list 'notice 'error) proc 4483 parsed (list 'notice 'error) proc
4431 'ctcp-empty ?n nick) 4484 'ctcp-empty ?n nick)
4432 (while queries 4485 (while queries
4433 (let* ((type (upcase (car (split-string (car queries))))) 4486 (let* ((type (upcase (car (split-string (car queries)))))
4434 (hook (intern-soft (concat "erc-ctcp-query-" type "-hook")))) 4487 (hook (intern-soft (concat "erc-ctcp-query-" type "-hook"))))
4435 (if (and hook (boundp hook)) 4488 (if (and hook (boundp hook))
4436 (if (string-equal type "ACTION") 4489 (if (string-equal type "ACTION")
4437 (run-hook-with-args-until-success 4490 (run-hook-with-args-until-success
4438 hook proc parsed nick login host 4491 hook proc parsed nick login host
4439 (car (erc-response.command-args parsed)) 4492 (car (erc-response.command-args parsed))
4440 (car queries)) 4493 (car queries))
4441 (when erc-paranoid 4494 (when erc-paranoid
4442 (if (erc-current-nick-p 4495 (if (erc-current-nick-p
4443 (car (erc-response.command-args parsed))) 4496 (car (erc-response.command-args parsed)))
4444 (erc-display-message 4497 (erc-display-message
4445 parsed 'error 'active 'ctcp-request 4498 parsed 'error 'active 'ctcp-request
4446 ?n nick ?u login ?h host ?r (car queries)) 4499 ?n nick ?u login ?h host ?r (car queries))
4447 (erc-display-message 4500 (erc-display-message
4448 parsed 'error 'active 'ctcp-request-to 4501 parsed 'error 'active 'ctcp-request-to
4449 ?n nick ?u login ?h host ?r (car queries) 4502 ?n nick ?u login ?h host ?r (car queries)
4450 ?t (car (erc-response.command-args parsed))))) 4503 ?t (car (erc-response.command-args parsed)))))
4451 (run-hook-with-args-until-success 4504 (run-hook-with-args-until-success
4452 hook proc nick login host 4505 hook proc nick login host
4453 (car (erc-response.command-args parsed)) 4506 (car (erc-response.command-args parsed))
4454 (car queries))) 4507 (car queries)))
4455 (erc-display-message 4508 (erc-display-message
4456 parsed (list 'notice 'error) proc 4509 parsed (list 'notice 'error) proc
4457 'undefined-ctcp))) 4510 'undefined-ctcp)))
4458 (setq queries (cdr queries))))))) 4511 (setq queries (cdr queries)))))))
4459 4512
4460(defvar erc-ctcp-query-ACTION-hook '(erc-ctcp-query-ACTION)) 4513(defvar erc-ctcp-query-ACTION-hook '(erc-ctcp-query-ACTION))
4461 4514
@@ -4463,9 +4516,9 @@ See also `erc-display-message'."
4463 "Respond to a CTCP ACTION query." 4516 "Respond to a CTCP ACTION query."
4464 (when (string-match "^ACTION\\s-\\(.*\\)\\s-*$" msg) 4517 (when (string-match "^ACTION\\s-\\(.*\\)\\s-*$" msg)
4465 (let ((s (match-string 1 msg)) 4518 (let ((s (match-string 1 msg))
4466 (buf (or (erc-get-buffer to proc) 4519 (buf (or (erc-get-buffer to proc)
4467 (erc-get-buffer nick proc) 4520 (erc-get-buffer nick proc)
4468 (process-buffer proc)))) 4521 (process-buffer proc))))
4469 (erc-display-message 4522 (erc-display-message
4470 parsed 'action buf 4523 parsed 'action buf
4471 'ACTION ?n nick ?u login ?h host ?a s)))) 4524 'ACTION ?n nick ?u login ?h host ?a s))))
@@ -4477,7 +4530,7 @@ See also `erc-display-message'."
4477 (when (string-match "^CLIENTINFO\\(\\s-*\\|\\s-+.*\\)$" msg) 4530 (when (string-match "^CLIENTINFO\\(\\s-*\\|\\s-+.*\\)$" msg)
4478 (let ((s (erc-client-info (erc-trim-string (match-string 1 msg))))) 4531 (let ((s (erc-client-info (erc-trim-string (match-string 1 msg)))))
4479 (unless erc-disable-ctcp-replies 4532 (unless erc-disable-ctcp-replies
4480 (erc-send-ctcp-notice nick (format "CLIENTINFO %s" s))))) 4533 (erc-send-ctcp-notice nick (format "CLIENTINFO %s" s)))))
4481 nil) 4534 nil)
4482 4535
4483(defvar erc-ctcp-query-ECHO-hook '(erc-ctcp-query-ECHO)) 4536(defvar erc-ctcp-query-ECHO-hook '(erc-ctcp-query-ECHO))
@@ -4486,7 +4539,7 @@ See also `erc-display-message'."
4486 (when (string-match "^ECHO\\s-+\\(.*\\)\\s-*$" msg) 4539 (when (string-match "^ECHO\\s-+\\(.*\\)\\s-*$" msg)
4487 (let ((s (match-string 1 msg))) 4540 (let ((s (match-string 1 msg)))
4488 (unless erc-disable-ctcp-replies 4541 (unless erc-disable-ctcp-replies
4489 (erc-send-ctcp-notice nick (format "ECHO %s" s))))) 4542 (erc-send-ctcp-notice nick (format "ECHO %s" s)))))
4490 nil) 4543 nil)
4491 4544
4492(defvar erc-ctcp-query-FINGER-hook '(erc-ctcp-query-FINGER)) 4545(defvar erc-ctcp-query-FINGER-hook '(erc-ctcp-query-FINGER))
@@ -4494,15 +4547,15 @@ See also `erc-display-message'."
4494 "Respond to a CTCP FINGER query." 4547 "Respond to a CTCP FINGER query."
4495 (unless erc-disable-ctcp-replies 4548 (unless erc-disable-ctcp-replies
4496 (let ((s (if erc-anonymous-login 4549 (let ((s (if erc-anonymous-login
4497 (format "FINGER I'm %s." (erc-current-nick)) 4550 (format "FINGER I'm %s." (erc-current-nick))
4498 (format "FINGER %s (%s@%s)." 4551 (format "FINGER %s (%s@%s)."
4499 (user-full-name) 4552 (user-full-name)
4500 (user-login-name) 4553 (user-login-name)
4501 (system-name)))) 4554 (system-name))))
4502 (ns (erc-time-diff erc-server-last-sent-time (erc-current-time)))) 4555 (ns (erc-time-diff erc-server-last-sent-time (erc-current-time))))
4503 (when (> ns 0) 4556 (when (> ns 0)
4504 (setq s (concat s " Idle for " (erc-sec-to-time ns)))) 4557 (setq s (concat s " Idle for " (erc-sec-to-time ns))))
4505 (erc-send-ctcp-notice nick s))) 4558 (erc-send-ctcp-notice nick s)))
4506 nil) 4559 nil)
4507 4560
4508(defvar erc-ctcp-query-PING-hook '(erc-ctcp-query-PING)) 4561(defvar erc-ctcp-query-PING-hook '(erc-ctcp-query-PING))
@@ -4511,7 +4564,7 @@ See also `erc-display-message'."
4511 (when (string-match "^PING\\s-+\\(.*\\)" msg) 4564 (when (string-match "^PING\\s-+\\(.*\\)" msg)
4512 (unless erc-disable-ctcp-replies 4565 (unless erc-disable-ctcp-replies
4513 (let ((arg (match-string 1 msg))) 4566 (let ((arg (match-string 1 msg)))
4514 (erc-send-ctcp-notice nick (format "PING %s" arg))))) 4567 (erc-send-ctcp-notice nick (format "PING %s" arg)))))
4515 nil) 4568 nil)
4516 4569
4517(defvar erc-ctcp-query-TIME-hook '(erc-ctcp-query-TIME)) 4570(defvar erc-ctcp-query-TIME-hook '(erc-ctcp-query-TIME))
@@ -4534,19 +4587,19 @@ See also `erc-display-message'."
4534 (unless erc-disable-ctcp-replies 4587 (unless erc-disable-ctcp-replies
4535 (erc-send-ctcp-notice 4588 (erc-send-ctcp-notice
4536 nick (format 4589 nick (format
4537 "VERSION \C-bERC\C-b %s - an IRC client for emacs (\C-b%s\C-b)" 4590 "VERSION \C-bERC\C-b %s - an IRC client for emacs (\C-b%s\C-b)"
4538 erc-version-string 4591 erc-version-string
4539 erc-official-location))) 4592 erc-official-location)))
4540 nil) 4593 nil)
4541 4594
4542(defun erc-process-ctcp-reply (proc parsed nick login host msg) 4595(defun erc-process-ctcp-reply (proc parsed nick login host msg)
4543 "Process MSG as a CTCP reply." 4596 "Process MSG as a CTCP reply."
4544 (let* ((type (car (split-string msg))) 4597 (let* ((type (car (split-string msg)))
4545 (hook (intern (concat "erc-ctcp-reply-" type "-hook")))) 4598 (hook (intern (concat "erc-ctcp-reply-" type "-hook"))))
4546 (if (boundp hook) 4599 (if (boundp hook)
4547 (run-hook-with-args-until-success 4600 (run-hook-with-args-until-success
4548 hook proc nick login host 4601 hook proc nick login host
4549 (car (erc-response.command-args parsed)) msg) 4602 (car (erc-response.command-args parsed)) msg)
4550 (erc-display-message 4603 (erc-display-message
4551 parsed 'notice 'active 4604 parsed 'notice 'active
4552 'CTCP-UNKNOWN ?n nick ?u login ?h host ?m msg)))) 4605 'CTCP-UNKNOWN ?n nick ?u login ?h host ?m msg))))
@@ -4588,16 +4641,16 @@ See also `erc-display-message'."
4588 nil 4641 nil
4589 (let ((time (match-string 1 msg))) 4642 (let ((time (match-string 1 msg)))
4590 (condition-case nil 4643 (condition-case nil
4591 (let ((delta (erc-time-diff (string-to-number time) 4644 (let ((delta (erc-time-diff (string-to-number time)
4592 (erc-current-time)))) 4645 (erc-current-time))))
4593 (erc-display-message 4646 (erc-display-message
4594 nil 'notice 'active 4647 nil 'notice 'active
4595 'CTCP-PING ?n nick 4648 'CTCP-PING ?n nick
4596 ?t (erc-sec-to-time delta))) 4649 ?t (erc-sec-to-time delta)))
4597 (range-error 4650 (range-error
4598 (erc-display-message 4651 (erc-display-message
4599 nil 'error 'active 4652 nil 'error 'active
4600 'bad-ping-response ?n nick ?t time)))))) 4653 'bad-ping-response ?n nick ?t time))))))
4601 4654
4602(defvar erc-ctcp-reply-TIME-hook '(erc-ctcp-reply-TIME)) 4655(defvar erc-ctcp-reply-TIME-hook '(erc-ctcp-reply-TIME))
4603(defun erc-ctcp-reply-TIME (_proc nick _login _host _to msg) 4656(defun erc-ctcp-reply-TIME (_proc nick _login _host _to msg)
@@ -4627,31 +4680,31 @@ If non-nil, return from being away."
4627 (let ((sessionbuf (process-buffer proc))) 4680 (let ((sessionbuf (process-buffer proc)))
4628 (when sessionbuf 4681 (when sessionbuf
4629 (with-current-buffer sessionbuf 4682 (with-current-buffer sessionbuf
4630 (when erc-away-nickname 4683 (when erc-away-nickname
4631 (erc-log (format "erc-process-away: away-nick: %s, away-p: %s" 4684 (erc-log (format "erc-process-away: away-nick: %s, away-p: %s"
4632 erc-away-nickname away-p)) 4685 erc-away-nickname away-p))
4633 (erc-cmd-NICK (if away-p 4686 (erc-cmd-NICK (if away-p
4634 erc-away-nickname 4687 erc-away-nickname
4635 erc-nick))) 4688 erc-nick)))
4636 (cond 4689 (cond
4637 (away-p 4690 (away-p
4638 (setq erc-away (current-time))) 4691 (setq erc-away (current-time)))
4639 (t 4692 (t
4640 (let ((away-time erc-away)) 4693 (let ((away-time erc-away))
4641 ;; away must be set to NIL BEFORE sending anything to prevent 4694 ;; away must be set to NIL BEFORE sending anything to prevent
4642 ;; an infinite recursion 4695 ;; an infinite recursion
4643 (setq erc-away nil) 4696 (setq erc-away nil)
4644 (with-current-buffer (erc-active-buffer) 4697 (with-current-buffer (erc-active-buffer)
4645 (when erc-public-away-p 4698 (when erc-public-away-p
4646 (erc-send-action 4699 (erc-send-action
4647 (erc-default-target) 4700 (erc-default-target)
4648 (if away-time 4701 (if away-time
4649 (format "is back (gone for %s)" 4702 (format "is back (gone for %s)"
4650 (erc-sec-to-time 4703 (erc-sec-to-time
4651 (erc-time-diff 4704 (erc-time-diff
4652 (erc-emacs-time-to-erc-time away-time) 4705 (erc-emacs-time-to-erc-time away-time)
4653 (erc-current-time)))) 4706 (erc-current-time))))
4654 "is back"))))))))) 4707 "is back")))))))))
4655 (erc-update-mode-line))) 4708 (erc-update-mode-line)))
4656 4709
4657;;;; List of channel members handling 4710;;;; List of channel members handling
@@ -4674,30 +4727,30 @@ channel buffer.
4674 4727
4675See also `erc-channel-begin-receiving-names'." 4728See also `erc-channel-begin-receiving-names'."
4676 (maphash (lambda (nick _user) 4729 (maphash (lambda (nick _user)
4677 (if (null (gethash nick erc-channel-new-member-names)) 4730 (if (null (gethash nick erc-channel-new-member-names))
4678 (erc-remove-channel-user nick))) 4731 (erc-remove-channel-user nick)))
4679 erc-channel-users) 4732 erc-channel-users)
4680 (setq erc-channel-new-member-names nil)) 4733 (setq erc-channel-new-member-names nil))
4681 4734
4682(defun erc-parse-prefix () 4735(defun erc-parse-prefix ()
4683 "Return an alist of valid prefix character types and their representations. 4736 "Return an alist of valid prefix character types and their representations.
4684Example: (operator) o => @, (voiced) v => +." 4737Example: (operator) o => @, (voiced) v => +."
4685 (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer 4738 (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer
4686 erc-server-parameters))) 4739 erc-server-parameters)))
4687 ;; provide a sane default 4740 ;; provide a sane default
4688 "(ov)@+")) 4741 "(qaohv)~&@%+"))
4689 types chars) 4742 types chars)
4690 (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str) 4743 (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str)
4691 (setq types (match-string 1 str) 4744 (setq types (match-string 1 str)
4692 chars (match-string 2 str)) 4745 chars (match-string 2 str))
4693 (let ((len (min (length types) (length chars))) 4746 (let ((len (min (length types) (length chars)))
4694 (i 0) 4747 (i 0)
4695 (alist nil)) 4748 (alist nil))
4696 (while (< i len) 4749 (while (< i len)
4697 (setq alist (cons (cons (elt types i) (elt chars i)) 4750 (setq alist (cons (cons (elt types i) (elt chars i))
4698 alist)) 4751 alist))
4699 (setq i (1+ i))) 4752 (setq i (1+ i)))
4700 alist)))) 4753 alist))))
4701 4754
4702(defun erc-channel-receive-names (names-string) 4755(defun erc-channel-receive-names (names-string)
4703 "This function is for internal use only. 4756 "This function is for internal use only.
@@ -4705,40 +4758,45 @@ Example: (operator) o => @, (voiced) v => +."
4705Update `erc-channel-users' according to NAMES-STRING. 4758Update `erc-channel-users' according to NAMES-STRING.
4706NAMES-STRING is a string listing some of the names on the 4759NAMES-STRING is a string listing some of the names on the
4707channel." 4760channel."
4708 (let (prefix op-ch voice-ch names name op voice) 4761 (let* ((prefix (erc-parse-prefix))
4709 (setq prefix (erc-parse-prefix)) 4762 (voice-ch (cdr (assq ?v prefix)))
4710 (setq op-ch (cdr (assq ?o prefix)) 4763 (op-ch (cdr (assq ?o prefix)))
4711 voice-ch (cdr (assq ?v prefix))) 4764 (hop-ch (cdr (assq ?h prefix)))
4712 ;; We need to delete "" because in XEmacs, (split-string "a ") 4765 (adm-ch (cdr (assq ?a prefix)))
4713 ;; returns ("a" ""). 4766 (own-ch (cdr (assq ?q prefix)))
4767 names name op voice halfop admin owner)
4714 (setq names (delete "" (split-string names-string))) 4768 (setq names (delete "" (split-string names-string)))
4715 (let ((erc-channel-members-changed-hook nil)) 4769 (let ((erc-channel-members-changed-hook nil))
4716 (dolist (item names) 4770 (dolist (item names)
4717 (let ((updatep t)) 4771 (let ((updatep t))
4718 (if (rassq (elt item 0) prefix) 4772 (setq name item op 'off voice 'off halfop 'off admin 'off owner 'off)
4719 (cond ((= (length item) 1) 4773 (if (rassq (elt item 0) prefix)
4720 (setq updatep nil)) 4774 (cond ((= (length item) 1)
4721 ((eq (elt item 0) op-ch) 4775 (setq updatep nil))
4722 (setq name (substring item 1) 4776 ((eq (elt item 0) voice-ch)
4723 op 'on 4777 (setq name (substring item 1)
4724 voice 'off)) 4778 voice 'on))
4725 ((eq (elt item 0) voice-ch) 4779 ((eq (elt item 0) hop-ch)
4726 (setq name (substring item 1) 4780 (setq name (substring item 1)
4727 op 'off 4781 halfop 'on))
4728 voice 'on)) 4782 ((eq (elt item 0) op-ch)
4729 (t (setq name (substring item 1) 4783 (setq name (substring item 1)
4730 op 'off 4784 op 'on))
4731 voice 'off))) 4785 ((eq (elt item 0) adm-ch)
4732 (setq name item 4786 (setq name (substring item 1)
4733 op 'off 4787 admin 'on))
4734 voice 'off)) 4788 ((eq (elt item 0) own-ch)
4735 (when updatep 4789 (setq name (substring item 1)
4736 (puthash (erc-downcase name) t 4790 owner 'on))
4737 erc-channel-new-member-names) 4791 (t (setq name (substring item 1)))))
4738 (erc-update-current-channel-member 4792 (when updatep
4739 name name t op voice))))) 4793 (puthash (erc-downcase name) t
4794 erc-channel-new-member-names)
4795 (erc-update-current-channel-member
4796 name name t voice halfop op admin owner)))))
4740 (run-hooks 'erc-channel-members-changed-hook))) 4797 (run-hooks 'erc-channel-members-changed-hook)))
4741 4798
4799
4742(defcustom erc-channel-members-changed-hook nil 4800(defcustom erc-channel-members-changed-hook nil
4743 "This hook is called every time the variable `channel-members' changes. 4801 "This hook is called every time the variable `channel-members' changes.
4744The buffer where the change happened is current while this hook is called." 4802The buffer where the change happened is current while this hook is called."
@@ -4746,15 +4804,15 @@ The buffer where the change happened is current while this hook is called."
4746 :type 'hook) 4804 :type 'hook)
4747 4805
4748(defun erc-update-user-nick (nick &optional new-nick 4806(defun erc-update-user-nick (nick &optional new-nick
4749 host login full-name info) 4807 host login full-name info)
4750 "Update the stored user information for the user with nickname NICK. 4808 "Update the stored user information for the user with nickname NICK.
4751 4809
4752See also: `erc-update-user'." 4810See also: `erc-update-user'."
4753 (erc-update-user (erc-get-server-user nick) new-nick 4811 (erc-update-user (erc-get-server-user nick) new-nick
4754 host login full-name info)) 4812 host login full-name info))
4755 4813
4756(defun erc-update-user (user &optional new-nick 4814(defun erc-update-user (user &optional new-nick
4757 host login full-name info) 4815 host login full-name info)
4758 "Update user info for USER. USER must be an erc-server-user 4816 "Update user info for USER. USER must be an erc-server-user
4759struct. Any of NEW-NICK, HOST, LOGIN, FULL-NAME, INFO which are 4817struct. Any of NEW-NICK, HOST, LOGIN, FULL-NAME, INFO which are
4760non-nil and not equal to the existing values for USER are used to 4818non-nil and not equal to the existing values for USER are used to
@@ -4766,45 +4824,44 @@ which USER is a member, and t is returned."
4766 (let (changed) 4824 (let (changed)
4767 (when user 4825 (when user
4768 (when (and new-nick 4826 (when (and new-nick
4769 (not (equal (erc-server-user-nickname user) 4827 (not (equal (erc-server-user-nickname user)
4770 new-nick))) 4828 new-nick)))
4771 (setq changed t) 4829 (setq changed t)
4772 (erc-change-user-nickname user new-nick)) 4830 (erc-change-user-nickname user new-nick))
4773 (when (and host 4831 (when (and host
4774 (not (equal (erc-server-user-host user) host))) 4832 (not (equal (erc-server-user-host user) host)))
4775 (setq changed t) 4833 (setq changed t)
4776 (setf (erc-server-user-host user) host)) 4834 (setf (erc-server-user-host user) host))
4777 (when (and login 4835 (when (and login
4778 (not (equal (erc-server-user-login user) login))) 4836 (not (equal (erc-server-user-login user) login)))
4779 (setq changed t) 4837 (setq changed t)
4780 (setf (erc-server-user-login user) login)) 4838 (setf (erc-server-user-login user) login))
4781 (when (and full-name 4839 (when (and full-name
4782 (not (equal (erc-server-user-full-name user) 4840 (not (equal (erc-server-user-full-name user)
4783 full-name))) 4841 full-name)))
4784 (setq changed t) 4842 (setq changed t)
4785 (setf (erc-server-user-full-name user) full-name)) 4843 (setf (erc-server-user-full-name user) full-name))
4786 (when (and info 4844 (when (and info
4787 (not (equal (erc-server-user-info user) info))) 4845 (not (equal (erc-server-user-info user) info)))
4788 (setq changed t) 4846 (setq changed t)
4789 (setf (erc-server-user-info user) info)) 4847 (setf (erc-server-user-info user) info))
4790 (if changed 4848 (if changed
4791 (dolist (buf (erc-server-user-buffers user)) 4849 (dolist (buf (erc-server-user-buffers user))
4792 (if (buffer-live-p buf) 4850 (if (buffer-live-p buf)
4793 (with-current-buffer buf 4851 (with-current-buffer buf
4794 (run-hooks 'erc-channel-members-changed-hook)))))) 4852 (run-hooks 'erc-channel-members-changed-hook))))))
4795 changed)) 4853 changed))
4796 4854
4797(defun erc-update-current-channel-member 4855(defun erc-update-current-channel-member
4798 (nick new-nick &optional add op voice host login full-name info 4856 (nick new-nick &optional add voice halfop op admin owner host login full-name info
4799 update-message-time) 4857 update-message-time)
4800 "Update the stored user information for the user with nickname NICK. 4858 "Update the stored user information for the user with nickname NICK.
4801`erc-update-user' is called to handle changes to nickname, 4859`erc-update-user' is called to handle changes to nickname,
4802HOST, LOGIN, FULL-NAME, and INFO. If OP or VOICE are non-nil, 4860HOST, LOGIN, FULL-NAME, and INFO. If VOICE HALFOP OP ADMIN or OWNER
4803they must be equal to either `on' or `off', in which case the 4861are non-nil, they must be equal to either `on' or `off', in which
4804operator or voice status of the user in the current channel is 4862case the status of the user in the current channel is changed accordingly.
4805changed accordingly. If UPDATE-MESSAGE-TIME is non-nil, the 4863If UPDATE-MESSAGE-TIME is non-nil, the last-message-time of the user
4806last-message-time of the user in the current channel is set 4864 in the current channel is set to (current-time).
4807to (current-time).
4808 4865
4809If ADD is non-nil, the user will be added with the specified 4866If ADD is non-nil, the user will be added with the specified
4810information if it is not already present in the user or channel 4867information if it is not already present in the user or channel
@@ -4815,74 +4872,104 @@ If, and only if, changes are made, or the user is added,
4815 4872
4816See also: `erc-update-user' and `erc-update-channel-member'." 4873See also: `erc-update-user' and `erc-update-channel-member'."
4817 (let* (changed user-changed 4874 (let* (changed user-changed
4818 (channel-data (erc-get-channel-user nick)) 4875 (channel-data (erc-get-channel-user nick))
4819 (cuser (cdr channel-data)) 4876 (cuser (cdr channel-data))
4820 (user (if channel-data (car channel-data) 4877 (user (if channel-data (car channel-data)
4821 (erc-get-server-user nick)))) 4878 (erc-get-server-user nick))))
4822 (if cuser 4879 (if cuser
4823 (progn 4880 (progn
4824 (erc-log (format "update-member: user = %S, cuser = %S" user cuser)) 4881 (erc-log (format "update-member: user = %S, cuser = %S" user cuser))
4825 (when (and op 4882 (when (and voice
4826 (not (eq (erc-channel-user-op cuser) op))) 4883 (not (eq (erc-channel-user-voice cuser) voice)))
4827 (setq changed t) 4884 (setq changed t)
4828 (setf (erc-channel-user-op cuser) 4885 (setf (erc-channel-user-voice cuser)
4829 (cond ((eq op 'on) t) 4886 (cond ((eq voice 'on) t)
4830 ((eq op 'off) nil) 4887 ((eq voice 'off) nil)
4831 (t op)))) 4888 (t voice))))
4832 (when (and voice 4889 (when (and halfop
4833 (not (eq (erc-channel-user-voice cuser) voice))) 4890 (not (eq (erc-channel-user-halfop cuser) halfop)))
4834 (setq changed t) 4891 (setq changed t)
4835 (setf (erc-channel-user-voice cuser) 4892 (setf (erc-channel-user-halfop cuser)
4836 (cond ((eq voice 'on) t) 4893 (cond ((eq halfop 'on) t)
4837 ((eq voice 'off) nil) 4894 ((eq halfop 'off) nil)
4838 (t voice)))) 4895 (t halfop))))
4839 (when update-message-time 4896 (when (and op
4840 (setf (erc-channel-user-last-message-time cuser) (current-time))) 4897 (not (eq (erc-channel-user-op cuser) op)))
4841 (setq user-changed 4898 (setq changed t)
4842 (erc-update-user user new-nick 4899 (setf (erc-channel-user-op cuser)
4843 host login full-name info))) 4900 (cond ((eq op 'on) t)
4901 ((eq op 'off) nil)
4902 (t op))))
4903 (when (and admin
4904 (not (eq (erc-channel-user-admin cuser) admin)))
4905 (setq changed t)
4906 (setf (erc-channel-user-admin cuser)
4907 (cond ((eq admin 'on) t)
4908 ((eq admin 'off) nil)
4909 (t admin))))
4910 (when (and owner
4911 (not (eq (erc-channel-user-owner cuser) owner)))
4912 (setq changed t)
4913 (setf (erc-channel-user-owner cuser)
4914 (cond ((eq owner 'on) t)
4915 ((eq owner 'off) nil)
4916 (t owner))))
4917 (when update-message-time
4918 (setf (erc-channel-user-last-message-time cuser) (current-time)))
4919 (setq user-changed
4920 (erc-update-user user new-nick
4921 host login full-name info)))
4844 (when add 4922 (when add
4845 (if (null user) 4923 (if (null user)
4846 (progn 4924 (progn
4847 (setq user (make-erc-server-user 4925 (setq user (make-erc-server-user
4848 :nickname nick 4926 :nickname nick
4849 :host host 4927 :host host
4850 :full-name full-name 4928 :full-name full-name
4851 :login login 4929 :login login
4852 :info info 4930 :info info
4853 :buffers (list (current-buffer)))) 4931 :buffers (list (current-buffer))))
4854 (erc-add-server-user nick user)) 4932 (erc-add-server-user nick user))
4855 (setf (erc-server-user-buffers user) 4933 (setf (erc-server-user-buffers user)
4856 (cons (current-buffer) 4934 (cons (current-buffer)
4857 (erc-server-user-buffers user)))) 4935 (erc-server-user-buffers user))))
4858 (setq cuser (make-erc-channel-user 4936 (setq cuser (make-erc-channel-user
4859 :op (cond ((eq op 'on) t) 4937 :voice (cond ((eq voice 'on) t)
4860 ((eq op 'off) nil) 4938 ((eq voice 'off) nil)
4861 (t op)) 4939 (t voice))
4862 :voice (cond ((eq voice 'on) t) 4940 :halfop (cond ((eq halfop 'on) t)
4863 ((eq voice 'off) nil) 4941 ((eq halfop 'off) nil)
4864 (t voice)) 4942 (t halfop))
4865 :last-message-time 4943 :op (cond ((eq op 'on) t)
4866 (if update-message-time (current-time)))) 4944 ((eq op 'off) nil)
4867 (puthash (erc-downcase nick) (cons user cuser) 4945 (t op))
4868 erc-channel-users) 4946 :admin (cond ((eq admin 'on) t)
4869 (setq changed t))) 4947 ((eq admin 'off) nil)
4948 (t admin))
4949 :owner (cond ((eq owner 'on) t)
4950 ((eq owner 'off) nil)
4951 (t owner))
4952 :last-message-time
4953 (if update-message-time (current-time))))
4954 (puthash (erc-downcase nick) (cons user cuser)
4955 erc-channel-users)
4956 (setq changed t)))
4870 (when (and changed (null user-changed)) 4957 (when (and changed (null user-changed))
4871 (run-hooks 'erc-channel-members-changed-hook)) 4958 (run-hooks 'erc-channel-members-changed-hook))
4872 (or changed user-changed add))) 4959 (or changed user-changed add)))
4873 4960
4874(defun erc-update-channel-member (channel nick new-nick 4961(defun erc-update-channel-member (channel nick new-nick
4875 &optional add op voice host login 4962 &optional add voice halfop op admin owner host login
4876 full-name info update-message-time) 4963 full-name info update-message-time)
4877 "Update user and channel information for the user with 4964 "Update user and channel information for the user with
4878nickname NICK in channel CHANNEL. 4965nickname NICK in channel CHANNEL.
4879 4966
4880See also: `erc-update-current-channel-member'." 4967See also: `erc-update-current-channel-member'."
4881 (erc-with-buffer 4968 (erc-with-buffer
4882 (channel) 4969 (channel)
4883 (erc-update-current-channel-member nick new-nick add op voice host 4970 (erc-update-current-channel-member nick new-nick add voice halfop op admin owner host
4884 login full-name info 4971 login full-name info
4885 update-message-time))) 4972 update-message-time)))
4886 4973
4887(defun erc-remove-current-channel-member (nick) 4974(defun erc-remove-current-channel-member (nick)
4888 "Remove NICK from current channel membership list. 4975 "Remove NICK from current channel membership list.
@@ -4897,8 +4984,8 @@ Runs `erc-channel-members-changed-hook'."
4897 4984
4898See also `erc-remove-current-channel-member'." 4985See also `erc-remove-current-channel-member'."
4899 (erc-with-buffer 4986 (erc-with-buffer
4900 (channel) 4987 (channel)
4901 (erc-remove-current-channel-member nick))) 4988 (erc-remove-current-channel-member nick)))
4902 4989
4903(defun erc-update-channel-topic (channel topic &optional modify) 4990(defun erc-update-channel-topic (channel topic &optional modify)
4904 "Find a buffer for CHANNEL and set the TOPIC for it. 4991 "Find a buffer for CHANNEL and set the TOPIC for it.
@@ -4907,40 +4994,40 @@ If optional MODIFY is 'append or 'prepend, then append or prepend the
4907TOPIC string to the current topic." 4994TOPIC string to the current topic."
4908 (erc-with-buffer (channel) 4995 (erc-with-buffer (channel)
4909 (cond ((eq modify 'append) 4996 (cond ((eq modify 'append)
4910 (setq erc-channel-topic (concat erc-channel-topic topic))) 4997 (setq erc-channel-topic (concat erc-channel-topic topic)))
4911 ((eq modify 'prepend) 4998 ((eq modify 'prepend)
4912 (setq erc-channel-topic (concat topic erc-channel-topic))) 4999 (setq erc-channel-topic (concat topic erc-channel-topic)))
4913 (t (setq erc-channel-topic topic))) 5000 (t (setq erc-channel-topic topic)))
4914 (erc-update-mode-line-buffer (current-buffer)))) 5001 (erc-update-mode-line-buffer (current-buffer))))
4915 5002
4916(defun erc-set-modes (tgt mode-string) 5003(defun erc-set-modes (tgt mode-string)
4917 "Set the modes for the TGT provided as MODE-STRING." 5004 "Set the modes for the TGT provided as MODE-STRING."
4918 (let* ((modes (erc-parse-modes mode-string)) 5005 (let* ((modes (erc-parse-modes mode-string))
4919 (add-modes (nth 0 modes)) 5006 (add-modes (nth 0 modes))
4920 ;; list of triples: (mode-char 'on/'off argument) 5007 ;; list of triples: (mode-char 'on/'off argument)
4921 (arg-modes (nth 2 modes))) 5008 (arg-modes (nth 2 modes)))
4922 (cond ((erc-channel-p tgt); channel modes 5009 (cond ((erc-channel-p tgt); channel modes
4923 (let ((buf (and erc-server-process 5010 (let ((buf (and erc-server-process
4924 (erc-get-buffer tgt erc-server-process)))) 5011 (erc-get-buffer tgt erc-server-process))))
4925 (when buf 5012 (when buf
4926 (with-current-buffer buf 5013 (with-current-buffer buf
4927 (setq erc-channel-modes add-modes) 5014 (setq erc-channel-modes add-modes)
4928 (setq erc-channel-user-limit nil) 5015 (setq erc-channel-user-limit nil)
4929 (setq erc-channel-key nil) 5016 (setq erc-channel-key nil)
4930 (while arg-modes 5017 (while arg-modes
4931 (let ((mode (nth 0 (car arg-modes))) 5018 (let ((mode (nth 0 (car arg-modes)))
4932 (onoff (nth 1 (car arg-modes))) 5019 (onoff (nth 1 (car arg-modes)))
4933 (arg (nth 2 (car arg-modes)))) 5020 (arg (nth 2 (car arg-modes))))
4934 (cond ((string-match "^[Ll]" mode) 5021 (cond ((string-match "^[Ll]" mode)
4935 (erc-update-channel-limit tgt onoff arg)) 5022 (erc-update-channel-limit tgt onoff arg))
4936 ((string-match "^[Kk]" mode) 5023 ((string-match "^[Kk]" mode)
4937 (erc-update-channel-key tgt onoff arg)) 5024 (erc-update-channel-key tgt onoff arg))
4938 (t nil))) 5025 (t nil)))
4939 (setq arg-modes (cdr arg-modes))) 5026 (setq arg-modes (cdr arg-modes)))
4940 (erc-update-mode-line-buffer buf))))) 5027 (erc-update-mode-line-buffer buf)))))
4941 ;; we do not keep our nick's modes yet 5028 ;; we do not keep our nick's modes yet
4942 ;;(t (setq erc-user-modes add-modes)) 5029 ;;(t (setq erc-user-modes add-modes))
4943 ) 5030 )
4944 )) 5031 ))
4945 5032
4946(defun erc-sort-strings (list-of-strings) 5033(defun erc-sort-strings (list-of-strings)
@@ -4963,42 +5050,42 @@ arg-modes is a list of triples of the form:
4963 (MODE-CHAR ON/OFF ARGUMENT)." 5050 (MODE-CHAR ON/OFF ARGUMENT)."
4964 (if (string-match "^\\s-*\\(\\S-+\\)\\(\\s-.*$\\|$\\)" mode-string) 5051 (if (string-match "^\\s-*\\(\\S-+\\)\\(\\s-.*$\\|$\\)" mode-string)
4965 (let ((chars (mapcar 'char-to-string (match-string 1 mode-string))) 5052 (let ((chars (mapcar 'char-to-string (match-string 1 mode-string)))
4966 ;; arguments in channel modes 5053 ;; arguments in channel modes
4967 (args-str (match-string 2 mode-string)) 5054 (args-str (match-string 2 mode-string))
4968 (args nil) 5055 (args nil)
4969 (add-modes nil) 5056 (add-modes nil)
4970 (remove-modes nil) 5057 (remove-modes nil)
4971 (arg-modes nil); list of triples: (mode-char 'on/'off argument) 5058 (arg-modes nil); list of triples: (mode-char 'on/'off argument)
4972 (add-p t)) 5059 (add-p t))
4973 ;; make the argument list 5060 ;; make the argument list
4974 (while (string-match "^\\s-*\\(\\S-+\\)\\(\\s-+.*$\\|$\\)" args-str) 5061 (while (string-match "^\\s-*\\(\\S-+\\)\\(\\s-+.*$\\|$\\)" args-str)
4975 (setq args (cons (match-string 1 args-str) args)) 5062 (setq args (cons (match-string 1 args-str) args))
4976 (setq args-str (match-string 2 args-str))) 5063 (setq args-str (match-string 2 args-str)))
4977 (setq args (nreverse args)) 5064 (setq args (nreverse args))
4978 ;; collect what modes changed, and match them with arguments 5065 ;; collect what modes changed, and match them with arguments
4979 (while chars 5066 (while chars
4980 (cond ((string= (car chars) "+") (setq add-p t)) 5067 (cond ((string= (car chars) "+") (setq add-p t))
4981 ((string= (car chars) "-") (setq add-p nil)) 5068 ((string= (car chars) "-") (setq add-p nil))
4982 ((string-match "^[ovbOVB]" (car chars)) 5069 ((string-match "^[qaovhbQAOVHB]" (car chars))
4983 (setq arg-modes (cons (list (car chars) 5070 (setq arg-modes (cons (list (car chars)
4984 (if add-p 'on 'off) 5071 (if add-p 'on 'off)
4985 (if args (car args) nil)) 5072 (if args (car args) nil))
4986 arg-modes)) 5073 arg-modes))
4987 (if args (setq args (cdr args)))) 5074 (if args (setq args (cdr args))))
4988 ((string-match "^[LlKk]" (car chars)) 5075 ((string-match "^[LlKk]" (car chars))
4989 (setq arg-modes (cons (list (car chars) 5076 (setq arg-modes (cons (list (car chars)
4990 (if add-p 'on 'off) 5077 (if add-p 'on 'off)
4991 (if (and add-p args) 5078 (if (and add-p args)
4992 (car args) nil)) 5079 (car args) nil))
4993 arg-modes)) 5080 arg-modes))
4994 (if (and add-p args) (setq args (cdr args)))) 5081 (if (and add-p args) (setq args (cdr args))))
4995 (add-p (setq add-modes (cons (car chars) add-modes))) 5082 (add-p (setq add-modes (cons (car chars) add-modes)))
4996 (t (setq remove-modes (cons (car chars) remove-modes)))) 5083 (t (setq remove-modes (cons (car chars) remove-modes))))
4997 (setq chars (cdr chars))) 5084 (setq chars (cdr chars)))
4998 (setq add-modes (nreverse add-modes)) 5085 (setq add-modes (nreverse add-modes))
4999 (setq remove-modes (nreverse remove-modes)) 5086 (setq remove-modes (nreverse remove-modes))
5000 (setq arg-modes (nreverse arg-modes)) 5087 (setq arg-modes (nreverse arg-modes))
5001 (list add-modes remove-modes arg-modes)) 5088 (list add-modes remove-modes arg-modes))
5002 nil)) 5089 nil))
5003 5090
5004(defun erc-update-modes (tgt mode-string &optional nick host login) 5091(defun erc-update-modes (tgt mode-string &optional nick host login)
@@ -5007,65 +5094,70 @@ Optional arguments: NICK, HOST and LOGIN - the attributes of the
5007person who changed the modes." 5094person who changed the modes."
5008 ;; FIXME: neither of nick, host, and login are used! 5095 ;; FIXME: neither of nick, host, and login are used!
5009 (let* ((modes (erc-parse-modes mode-string)) 5096 (let* ((modes (erc-parse-modes mode-string))
5010 (add-modes (nth 0 modes)) 5097 (add-modes (nth 0 modes))
5011 (remove-modes (nth 1 modes)) 5098 (remove-modes (nth 1 modes))
5012 ;; list of triples: (mode-char 'on/'off argument) 5099 ;; list of triples: (mode-char 'on/'off argument)
5013 (arg-modes (nth 2 modes))) 5100 (arg-modes (nth 2 modes)))
5014 ;; now parse the modes changes and do the updates 5101 ;; now parse the modes changes and do the updates
5015 (cond ((erc-channel-p tgt); channel modes 5102 (cond ((erc-channel-p tgt); channel modes
5016 (let ((buf (and erc-server-process 5103 (let ((buf (and erc-server-process
5017 (erc-get-buffer tgt erc-server-process)))) 5104 (erc-get-buffer tgt erc-server-process))))
5018 (when buf 5105 (when buf
5019 ;; FIXME! This used to have an original buffer 5106 ;; FIXME! This used to have an original buffer
5020 ;; variable, but it never switched back to the original 5107 ;; variable, but it never switched back to the original
5021 ;; buffer. Is this wanted behavior? 5108 ;; buffer. Is this wanted behavior?
5022 (set-buffer buf) 5109 (set-buffer buf)
5023 (if (not (boundp 'erc-channel-modes)) 5110 (if (not (boundp 'erc-channel-modes))
5024 (setq erc-channel-modes nil)) 5111 (setq erc-channel-modes nil))
5025 (while remove-modes 5112 (while remove-modes
5026 (setq erc-channel-modes (delete (car remove-modes) 5113 (setq erc-channel-modes (delete (car remove-modes)
5027 erc-channel-modes) 5114 erc-channel-modes)
5028 remove-modes (cdr remove-modes))) 5115 remove-modes (cdr remove-modes)))
5029 (while add-modes 5116 (while add-modes
5030 (setq erc-channel-modes (cons (car add-modes) 5117 (setq erc-channel-modes (cons (car add-modes)
5031 erc-channel-modes) 5118 erc-channel-modes)
5032 add-modes (cdr add-modes))) 5119 add-modes (cdr add-modes)))
5033 (setq erc-channel-modes (erc-sort-strings erc-channel-modes)) 5120 (setq erc-channel-modes (erc-sort-strings erc-channel-modes))
5034 (while arg-modes 5121 (while arg-modes
5035 (let ((mode (nth 0 (car arg-modes))) 5122 (let ((mode (nth 0 (car arg-modes)))
5036 (onoff (nth 1 (car arg-modes))) 5123 (onoff (nth 1 (car arg-modes)))
5037 (arg (nth 2 (car arg-modes)))) 5124 (arg (nth 2 (car arg-modes))))
5038 (cond ((string-match "^[oO]" mode) 5125 (cond ((string-match "^[Vv]" mode)
5039 (erc-update-channel-member tgt arg arg nil onoff)) 5126 (erc-update-channel-member tgt arg arg nil onoff))
5040 ((string-match "^[Vv]" mode) 5127 ((string-match "^[hH]" mode)
5041 (erc-update-channel-member tgt arg arg nil nil 5128 (erc-update-channel-member tgt arg arg nil nil onoff))
5042 onoff)) 5129 ((string-match "^[oO]" mode)
5043 ((string-match "^[Ll]" mode) 5130 (erc-update-channel-member tgt arg arg nil nil nil onoff))
5044 (erc-update-channel-limit tgt onoff arg)) 5131 ((string-match "^[aA]" mode)
5045 ((string-match "^[Kk]" mode) 5132 (erc-update-channel-member tgt arg arg nil nil nil nil onoff))
5046 (erc-update-channel-key tgt onoff arg)) 5133 ((string-match "^[qQ]" mode)
5047 (t nil)); only ops are tracked now 5134 (erc-update-channel-member tgt arg arg nil nil nil nil nil onoff))
5048 (setq arg-modes (cdr arg-modes)))) 5135 ((string-match "^[Ll]" mode)
5049 (erc-update-mode-line buf)))) 5136 (erc-update-channel-limit tgt onoff arg))
5050 ;; nick modes - ignored at this point 5137 ((string-match "^[Kk]" mode)
5051 (t nil)))) 5138 (erc-update-channel-key tgt onoff arg))
5139 (t nil)); only ops are tracked now
5140 (setq arg-modes (cdr arg-modes))))
5141 (erc-update-mode-line buf))))
5142 ;; nick modes - ignored at this point
5143 (t nil))))
5052 5144
5053(defun erc-update-channel-limit (channel onoff n) 5145(defun erc-update-channel-limit (channel onoff n)
5054 ;; FIXME: what does ONOFF actually do? -- Lawrence 2004-01-08 5146 ;; FIXME: what does ONOFF actually do? -- Lawrence 2004-01-08
5055 "Update CHANNEL's user limit to N." 5147 "Update CHANNEL's user limit to N."
5056 (if (or (not (eq onoff 'on)) 5148 (if (or (not (eq onoff 'on))
5057 (and (stringp n) (string-match "^[0-9]+$" n))) 5149 (and (stringp n) (string-match "^[0-9]+$" n)))
5058 (erc-with-buffer 5150 (erc-with-buffer
5059 (channel) 5151 (channel)
5060 (cond ((eq onoff 'on) (setq erc-channel-user-limit (string-to-number n))) 5152 (cond ((eq onoff 'on) (setq erc-channel-user-limit (string-to-number n)))
5061 (t (setq erc-channel-user-limit nil)))))) 5153 (t (setq erc-channel-user-limit nil))))))
5062 5154
5063(defun erc-update-channel-key (channel onoff key) 5155(defun erc-update-channel-key (channel onoff key)
5064 "Update CHANNEL's key to KEY if ONOFF is 'on or to nil if it's 'off." 5156 "Update CHANNEL's key to KEY if ONOFF is 'on or to nil if it's 'off."
5065 (erc-with-buffer 5157 (erc-with-buffer
5066 (channel) 5158 (channel)
5067 (cond ((eq onoff 'on) (setq erc-channel-key key)) 5159 (cond ((eq onoff 'on) (setq erc-channel-key key))
5068 (t (setq erc-channel-key nil))))) 5160 (t (setq erc-channel-key nil)))))
5069 5161
5070(defun erc-handle-user-status-change (type nlh &optional l) 5162(defun erc-handle-user-status-change (type nlh &optional l)
5071 "Handle changes in any user's status. 5163 "Handle changes in any user's status.
@@ -5078,9 +5170,9 @@ and L is a list containing additional TYPE-specific arguments.
5078 5170
5079So far the following TYPE/L pairs are supported: 5171So far the following TYPE/L pairs are supported:
5080 5172
5081 Event TYPE L 5173 Event TYPE L
5082 5174
5083 nickname change 'nick (NEW-NICK)" 5175 nickname change 'nick (NEW-NICK)"
5084 (erc-log (format "user-change: type: %S nlh: %S l: %S" type nlh l)) 5176 (erc-log (format "user-change: type: %S nlh: %S l: %S" type nlh l))
5085 (cond 5177 (cond
5086 ;; nickname change 5178 ;; nickname change
@@ -5095,7 +5187,7 @@ See also variable `erc-notice-highlight-type'."
5095 (cond 5187 (cond
5096 ((eq erc-notice-highlight-type 'prefix) 5188 ((eq erc-notice-highlight-type 'prefix)
5097 (erc-put-text-property 0 (length erc-notice-prefix) 5189 (erc-put-text-property 0 (length erc-notice-prefix)
5098 'face 'erc-notice-face s) 5190 'face 'erc-notice-face s)
5099 s) 5191 s)
5100 ((eq erc-notice-highlight-type 'all) 5192 ((eq erc-notice-highlight-type 'all)
5101 (erc-put-text-property 0 (length s) 'face 'erc-notice-face s) 5193 (erc-put-text-property 0 (length s) 'face 'erc-notice-face s)
@@ -5139,13 +5231,13 @@ Return a list of the three separate tokens."
5139 (cond 5231 (cond
5140 ((string-match "^\\([^!\n]*\\)!\\([^@\n]*\\)@\\(.*\\)$" string) 5232 ((string-match "^\\([^!\n]*\\)!\\([^@\n]*\\)@\\(.*\\)$" string)
5141 (list (match-string 1 string) 5233 (list (match-string 1 string)
5142 (match-string 2 string) 5234 (match-string 2 string)
5143 (match-string 3 string))) 5235 (match-string 3 string)))
5144 ;; Some bogus bouncers send Nick!(null), try to live with that. 5236 ;; Some bogus bouncers send Nick!(null), try to live with that.
5145 ((string-match "^\\([^!\n]*\\)!\\(.*\\)$" string) 5237 ((string-match "^\\([^!\n]*\\)!\\(.*\\)$" string)
5146 (list (match-string 1 string) 5238 (list (match-string 1 string)
5147 "" 5239 ""
5148 (match-string 2 string))) 5240 (match-string 2 string)))
5149 (t 5241 (t
5150 (list string "" "")))) 5242 (list string "" ""))))
5151 5243
@@ -5156,7 +5248,7 @@ See also `erc-parse-user'."
5156 (car (erc-parse-user string))) 5248 (car (erc-parse-user string)))
5157 5249
5158(defun erc-put-text-properties (start end properties 5250(defun erc-put-text-properties (start end properties
5159 &optional object value-list) 5251 &optional object value-list)
5160 "Set text-properties for OBJECT. 5252 "Set text-properties for OBJECT.
5161 5253
5162START and END describe positions in OBJECT. 5254START and END describe positions in OBJECT.
@@ -5164,7 +5256,7 @@ If VALUE-LIST is nil, set each property in PROPERTIES to t, else set
5164each property to the corresponding value in VALUE-LIST." 5256each property to the corresponding value in VALUE-LIST."
5165 (unless value-list 5257 (unless value-list
5166 (setq value-list (mapcar (lambda (_x) t) 5258 (setq value-list (mapcar (lambda (_x) t)
5167 properties))) 5259 properties)))
5168 (while (and properties value-list) 5260 (while (and properties value-list)
5169 (erc-put-text-property 5261 (erc-put-text-property
5170 start end (pop properties) (pop value-list) object))) 5262 start end (pop properties) (pop value-list) object)))
@@ -5176,7 +5268,7 @@ each property to the corresponding value in VALUE-LIST."
5176 5268
5177Specifically, return the position of `erc-insert-marker'." 5269Specifically, return the position of `erc-insert-marker'."
5178 (or (and (boundp 'erc-insert-marker) 5270 (or (and (boundp 'erc-insert-marker)
5179 (markerp erc-insert-marker)) 5271 (markerp erc-insert-marker))
5180 (error "erc-insert-marker has no value, please report a bug")) 5272 (error "erc-insert-marker has no value, please report a bug"))
5181 (marker-position erc-insert-marker)) 5273 (marker-position erc-insert-marker))
5182 5274
@@ -5206,43 +5298,43 @@ submitted line to be intentional."
5206 (interactive) 5298 (interactive)
5207 (let ((now (float-time))) 5299 (let ((now (float-time)))
5208 (if (or (not erc-accidental-paste-threshold-seconds) 5300 (if (or (not erc-accidental-paste-threshold-seconds)
5209 (< erc-accidental-paste-threshold-seconds 5301 (< erc-accidental-paste-threshold-seconds
5210 (- now erc-last-input-time))) 5302 (- now erc-last-input-time)))
5211 (save-restriction 5303 (save-restriction
5212 (widen) 5304 (widen)
5213 (if (< (point) (erc-beg-of-input-line)) 5305 (if (< (point) (erc-beg-of-input-line))
5214 (erc-error "Point is not in the input area") 5306 (erc-error "Point is not in the input area")
5215 (let ((inhibit-read-only t) 5307 (let ((inhibit-read-only t)
5216 (str (erc-user-input)) 5308 (str (erc-user-input))
5217 (old-buf (current-buffer))) 5309 (old-buf (current-buffer)))
5218 (if (and (not (erc-server-buffer-live-p)) 5310 (if (and (not (erc-server-buffer-live-p))
5219 (not (erc-command-no-process-p str))) 5311 (not (erc-command-no-process-p str)))
5220 (erc-error "ERC: No process running") 5312 (erc-error "ERC: No process running")
5221 (erc-set-active-buffer (current-buffer)) 5313 (erc-set-active-buffer (current-buffer))
5222 ;; Kill the input and the prompt 5314 ;; Kill the input and the prompt
5223 (delete-region (erc-beg-of-input-line) 5315 (delete-region (erc-beg-of-input-line)
5224 (erc-end-of-input-line)) 5316 (erc-end-of-input-line))
5225 (unwind-protect 5317 (unwind-protect
5226 (erc-send-input str) 5318 (erc-send-input str)
5227 ;; Fix the buffer if the command didn't kill it 5319 ;; Fix the buffer if the command didn't kill it
5228 (when (buffer-live-p old-buf) 5320 (when (buffer-live-p old-buf)
5229 (with-current-buffer old-buf 5321 (with-current-buffer old-buf
5230 (save-restriction 5322 (save-restriction
5231 (widen) 5323 (widen)
5232 (goto-char (point-max)) 5324 (goto-char (point-max))
5233 (when (processp erc-server-process) 5325 (when (processp erc-server-process)
5234 (set-marker (process-mark erc-server-process) (point))) 5326 (set-marker (process-mark erc-server-process) (point)))
5235 (set-marker erc-insert-marker (point)) 5327 (set-marker erc-insert-marker (point))
5236 (let ((buffer-modified (buffer-modified-p))) 5328 (let ((buffer-modified (buffer-modified-p)))
5237 (erc-display-prompt) 5329 (erc-display-prompt)
5238 (set-buffer-modified-p buffer-modified)))))) 5330 (set-buffer-modified-p buffer-modified))))))
5239 5331
5240 ;; Only when last hook has been run... 5332 ;; Only when last hook has been run...
5241 (run-hook-with-args 'erc-send-completed-hook str)))) 5333 (run-hook-with-args 'erc-send-completed-hook str))))
5242 (setq erc-last-input-time now)) 5334 (setq erc-last-input-time now))
5243 (switch-to-buffer "*ERC Accidental Paste Overflow*") 5335 (switch-to-buffer "*ERC Accidental Paste Overflow*")
5244 (lwarn 'erc :warning 5336 (lwarn 'erc :warning
5245 "You seem to have accidentally pasted some text!")))) 5337 "You seem to have accidentally pasted some text!"))))
5246 5338
5247(defun erc-user-input () 5339(defun erc-user-input ()
5248 "Return the input of the user in the current buffer." 5340 "Return the input of the user in the current buffer."
@@ -5261,7 +5353,7 @@ This returns non-nil only if we actually send anything."
5261 (cond 5353 (cond
5262 ;; Ignore empty input 5354 ;; Ignore empty input
5263 ((if erc-send-whitespace-lines 5355 ((if erc-send-whitespace-lines
5264 (string= input "") 5356 (string= input "")
5265 (string-match "\\`[ \t\r\f\n]*\\'" input)) 5357 (string-match "\\`[ \t\r\f\n]*\\'" input))
5266 (when erc-warn-about-blank-lines 5358 (when erc-warn-about-blank-lines
5267 (message "Blank line - ignoring...") 5359 (message "Blank line - ignoring...")
@@ -5269,48 +5361,48 @@ This returns non-nil only if we actually send anything."
5269 nil) 5361 nil)
5270 (t 5362 (t
5271 (let ((str input) 5363 (let ((str input)
5272 (erc-insert-this t)) 5364 (erc-insert-this t))
5273 (setq erc-send-this t) 5365 (setq erc-send-this t)
5274 (run-hook-with-args 'erc-send-pre-hook input) 5366 (run-hook-with-args 'erc-send-pre-hook input)
5275 (when erc-send-this 5367 (when erc-send-this
5276 (if (or (string-match "\n" str) 5368 (if (or (string-match "\n" str)
5277 (not (string-match erc-command-regexp str))) 5369 (not (string-match erc-command-regexp str)))
5278 (mapc 5370 (mapc
5279 (lambda (line) 5371 (lambda (line)
5280 (mapc 5372 (mapc
5281 (lambda (line) 5373 (lambda (line)
5282 ;; Insert what has to be inserted for this. 5374 ;; Insert what has to be inserted for this.
5283 (erc-display-msg line) 5375 (erc-display-msg line)
5284 (erc-process-input-line (concat line "\n") 5376 (erc-process-input-line (concat line "\n")
5285 (null erc-flood-protect) t)) 5377 (null erc-flood-protect) t))
5286 (or (and erc-flood-protect (erc-split-line line)) 5378 (or (and erc-flood-protect (erc-split-line line))
5287 (list line)))) 5379 (list line))))
5288 (split-string str "\n")) 5380 (split-string str "\n"))
5289 ;; Insert the prompt along with the command. 5381 ;; Insert the prompt along with the command.
5290 (erc-display-command str) 5382 (erc-display-command str)
5291 (erc-process-input-line (concat str "\n") t nil)) 5383 (erc-process-input-line (concat str "\n") t nil))
5292 t))))) 5384 t)))))
5293 5385
5294(defun erc-display-command (line) 5386(defun erc-display-command (line)
5295 (when erc-insert-this 5387 (when erc-insert-this
5296 (let ((insert-position (point))) 5388 (let ((insert-position (point)))
5297 (unless erc-hide-prompt 5389 (unless erc-hide-prompt
5298 (erc-display-prompt nil nil (erc-command-indicator) 5390 (erc-display-prompt nil nil (erc-command-indicator)
5299 (and (erc-command-indicator) 5391 (and (erc-command-indicator)
5300 'erc-command-indicator-face))) 5392 'erc-command-indicator-face)))
5301 (let ((beg (point))) 5393 (let ((beg (point)))
5302 (insert line) 5394 (insert line)
5303 (erc-put-text-property beg (point) 5395 (erc-put-text-property beg (point)
5304 'face 'erc-command-indicator-face) 5396 'face 'erc-command-indicator-face)
5305 (insert "\n")) 5397 (insert "\n"))
5306 (when (processp erc-server-process) 5398 (when (processp erc-server-process)
5307 (set-marker (process-mark erc-server-process) (point))) 5399 (set-marker (process-mark erc-server-process) (point)))
5308 (set-marker erc-insert-marker (point)) 5400 (set-marker erc-insert-marker (point))
5309 (save-excursion 5401 (save-excursion
5310 (save-restriction 5402 (save-restriction
5311 (narrow-to-region insert-position (point)) 5403 (narrow-to-region insert-position (point))
5312 (run-hooks 'erc-send-modify-hook) 5404 (run-hooks 'erc-send-modify-hook)
5313 (run-hooks 'erc-send-post-hook)))))) 5405 (run-hooks 'erc-send-post-hook))))))
5314 5406
5315(defun erc-display-msg (line) 5407(defun erc-display-msg (line)
5316 "Display LINE as a message of the user to the current target at the 5408 "Display LINE as a message of the user to the current target at the
@@ -5319,18 +5411,18 @@ current position."
5319 (let ((insert-position (point))) 5411 (let ((insert-position (point)))
5320 (insert (erc-format-my-nick)) 5412 (insert (erc-format-my-nick))
5321 (let ((beg (point))) 5413 (let ((beg (point)))
5322 (insert line) 5414 (insert line)
5323 (erc-put-text-property beg (point) 5415 (erc-put-text-property beg (point)
5324 'face 'erc-input-face)) 5416 'face 'erc-input-face))
5325 (insert "\n") 5417 (insert "\n")
5326 (when (processp erc-server-process) 5418 (when (processp erc-server-process)
5327 (set-marker (process-mark erc-server-process) (point))) 5419 (set-marker (process-mark erc-server-process) (point)))
5328 (set-marker erc-insert-marker (point)) 5420 (set-marker erc-insert-marker (point))
5329 (save-excursion 5421 (save-excursion
5330 (save-restriction 5422 (save-restriction
5331 (narrow-to-region insert-position (point)) 5423 (narrow-to-region insert-position (point))
5332 (run-hooks 'erc-send-modify-hook) 5424 (run-hooks 'erc-send-modify-hook)
5333 (run-hooks 'erc-send-post-hook)))))) 5425 (run-hooks 'erc-send-post-hook))))))
5334 5426
5335(defun erc-command-symbol (command) 5427(defun erc-command-symbol (command)
5336 "Return the ERC command symbol for COMMAND if it exists and is bound." 5428 "Return the ERC command symbol for COMMAND if it exists and is bound."
@@ -5343,16 +5435,16 @@ If no command was given, return nil. If command matches, return a
5343list of the form: (command args) where both elements are strings." 5435list of the form: (command args) where both elements are strings."
5344 (when (string-match erc-command-regexp line) 5436 (when (string-match erc-command-regexp line)
5345 (let* ((cmd (erc-command-symbol (match-string 1 line))) 5437 (let* ((cmd (erc-command-symbol (match-string 1 line)))
5346 ;; note: return is nil, we apply this simply for side effects 5438 ;; note: return is nil, we apply this simply for side effects
5347 (_canon-defun (while (and cmd (symbolp (symbol-function cmd))) 5439 (_canon-defun (while (and cmd (symbolp (symbol-function cmd)))
5348 (setq cmd (symbol-function cmd)))) 5440 (setq cmd (symbol-function cmd))))
5349 (cmd-fun (or cmd #'erc-cmd-default)) 5441 (cmd-fun (or cmd #'erc-cmd-default))
5350 (arg (if cmd 5442 (arg (if cmd
5351 (if (get cmd-fun 'do-not-parse-args) 5443 (if (get cmd-fun 'do-not-parse-args)
5352 (format "%s" (match-string 2 line)) 5444 (format "%s" (match-string 2 line))
5353 (delete "" (split-string (erc-trim-string 5445 (delete "" (split-string (erc-trim-string
5354 (match-string 2 line)) " "))) 5446 (match-string 2 line)) " ")))
5355 line))) 5447 line)))
5356 (list cmd-fun arg)))) 5448 (list cmd-fun arg))))
5357 5449
5358(defun erc-split-multiline-safe (string) 5450(defun erc-split-multiline-safe (string)
@@ -5360,16 +5452,16 @@ list of the form: (command args) where both elements are strings."
5360Do it only for STRING as the complete input, do not carry unfinished 5452Do it only for STRING as the complete input, do not carry unfinished
5361strings over to the next call." 5453strings over to the next call."
5362 (let ((l ()) 5454 (let ((l ())
5363 (i0 0) 5455 (i0 0)
5364 (doit t)) 5456 (doit t))
5365 (while doit 5457 (while doit
5366 (let ((i (string-match "\r?\n" string i0)) 5458 (let ((i (string-match "\r?\n" string i0))
5367 (s (substring string i0))) 5459 (s (substring string i0)))
5368 (cond (i (setq l (cons (substring string i0 i) l)) 5460 (cond (i (setq l (cons (substring string i0 i) l))
5369 (setq i0 (match-end 0))) 5461 (setq i0 (match-end 0)))
5370 ((> (length s) 0) 5462 ((> (length s) 0)
5371 (setq l (cons s l))(setq doit nil)) 5463 (setq l (cons s l))(setq doit nil))
5372 (t (setq doit nil))))) 5464 (t (setq doit nil)))))
5373 (nreverse l))) 5465 (nreverse l)))
5374 5466
5375;; nick handling 5467;; nick handling
@@ -5377,15 +5469,15 @@ strings over to the next call."
5377(defun erc-set-current-nick (nick) 5469(defun erc-set-current-nick (nick)
5378 "Set the current nickname to NICK." 5470 "Set the current nickname to NICK."
5379 (with-current-buffer (if (buffer-live-p (erc-server-buffer)) 5471 (with-current-buffer (if (buffer-live-p (erc-server-buffer))
5380 (erc-server-buffer) 5472 (erc-server-buffer)
5381 (current-buffer)) 5473 (current-buffer))
5382 (setq erc-server-current-nick nick))) 5474 (setq erc-server-current-nick nick)))
5383 5475
5384(defun erc-current-nick () 5476(defun erc-current-nick ()
5385 "Return the current nickname." 5477 "Return the current nickname."
5386 (with-current-buffer (if (buffer-live-p (erc-server-buffer)) 5478 (with-current-buffer (if (buffer-live-p (erc-server-buffer))
5387 (erc-server-buffer) 5479 (erc-server-buffer)
5388 (current-buffer)) 5480 (current-buffer))
5389 erc-server-current-nick)) 5481 erc-server-current-nick))
5390 5482
5391(defun erc-current-nick-p (nick) 5483(defun erc-current-nick-p (nick)
@@ -5399,7 +5491,7 @@ This matches strings according to the IRC protocol's case convention.
5399 5491
5400See also `erc-downcase'." 5492See also `erc-downcase'."
5401 (string= (erc-downcase nick1) 5493 (string= (erc-downcase nick1)
5402 (erc-downcase nick2))) 5494 (erc-downcase nick2)))
5403 5495
5404;; default target handling 5496;; default target handling
5405 5497
@@ -5414,38 +5506,38 @@ See also `erc-downcase'."
5414(defun erc-add-default-channel (channel) 5506(defun erc-add-default-channel (channel)
5415 "Add CHANNEL to the default channel list." 5507 "Add CHANNEL to the default channel list."
5416 (let ((chl (downcase channel))) 5508 (let ((chl (downcase channel)))
5417 (setq erc-default-recipients 5509 (setq erc-default-recipients
5418 (cons chl erc-default-recipients)))) 5510 (cons chl erc-default-recipients))))
5419 5511
5420(defun erc-delete-default-channel (channel &optional buffer) 5512(defun erc-delete-default-channel (channel &optional buffer)
5421 "Delete CHANNEL from the default channel list." 5513 "Delete CHANNEL from the default channel list."
5422 (with-current-buffer (if (and buffer 5514 (with-current-buffer (if (and buffer
5423 (bufferp buffer)) 5515 (bufferp buffer))
5424 buffer 5516 buffer
5425 (current-buffer)) 5517 (current-buffer))
5426 (setq erc-default-recipients (delete (downcase channel) 5518 (setq erc-default-recipients (delete (downcase channel)
5427 erc-default-recipients)))) 5519 erc-default-recipients))))
5428 5520
5429(defun erc-add-query (nickname) 5521(defun erc-add-query (nickname)
5430 "Add QUERY'd NICKNAME to the default channel list. 5522 "Add QUERY'd NICKNAME to the default channel list.
5431 5523
5432The previous default target of QUERY type gets removed." 5524The previous default target of QUERY type gets removed."
5433 (let ((d1 (car erc-default-recipients)) 5525 (let ((d1 (car erc-default-recipients))
5434 (d2 (cdr erc-default-recipients)) 5526 (d2 (cdr erc-default-recipients))
5435 (qt (cons 'QUERY (downcase nickname)))) 5527 (qt (cons 'QUERY (downcase nickname))))
5436 (setq erc-default-recipients (cons qt (if (and (listp d1) 5528 (setq erc-default-recipients (cons qt (if (and (listp d1)
5437 (eq (car d1) 'QUERY)) 5529 (eq (car d1) 'QUERY))
5438 d2 5530 d2
5439 erc-default-recipients))))) 5531 erc-default-recipients)))))
5440 5532
5441(defun erc-delete-query () 5533(defun erc-delete-query ()
5442 "Delete the topmost target if it is a QUERY." 5534 "Delete the topmost target if it is a QUERY."
5443 5535
5444 (let ((d1 (car erc-default-recipients)) 5536 (let ((d1 (car erc-default-recipients))
5445 (d2 (cdr erc-default-recipients))) 5537 (d2 (cdr erc-default-recipients)))
5446 (if (and (listp d1) 5538 (if (and (listp d1)
5447 (eq (car d1) 'QUERY)) 5539 (eq (car d1) 'QUERY))
5448 (setq erc-default-recipients d2) 5540 (setq erc-default-recipients d2)
5449 (error "Current target is not a QUERY")))) 5541 (error "Current target is not a QUERY"))))
5450 5542
5451(defun erc-ignored-user-p (spec) 5543(defun erc-ignored-user-p (spec)
@@ -5457,7 +5549,7 @@ match, returns that regexp."
5457 (catch 'found 5549 (catch 'found
5458 (dolist (ignored (erc-with-server-buffer erc-ignore-list)) 5550 (dolist (ignored (erc-with-server-buffer erc-ignore-list))
5459 (if (string-match ignored spec) 5551 (if (string-match ignored spec)
5460 (throw 'found ignored))))) 5552 (throw 'found ignored)))))
5461 5553
5462(defun erc-ignored-reply-p (msg tgt proc) 5554(defun erc-ignored-reply-p (msg tgt proc)
5463 ;; FIXME: this docstring needs fixing -- Lawrence 2004-01-08 5555 ;; FIXME: this docstring needs fixing -- Lawrence 2004-01-08
@@ -5467,12 +5559,12 @@ Takes a message MSG to a channel and returns non-nil if the addressed
5467user matches any regexp in `erc-ignore-reply-list'." 5559user matches any regexp in `erc-ignore-reply-list'."
5468 (let ((target-nick (erc-message-target msg))) 5560 (let ((target-nick (erc-message-target msg)))
5469 (if (not target-nick) 5561 (if (not target-nick)
5470 nil 5562 nil
5471 (erc-with-buffer (tgt proc) 5563 (erc-with-buffer (tgt proc)
5472 (let ((user (erc-get-server-user target-nick))) 5564 (let ((user (erc-get-server-user target-nick)))
5473 (when user 5565 (when user
5474 (erc-list-match erc-ignore-reply-list 5566 (erc-list-match erc-ignore-reply-list
5475 (erc-user-spec user)))))))) 5567 (erc-user-spec user))))))))
5476 5568
5477(defun erc-message-target (msg) 5569(defun erc-message-target (msg)
5478 "Return the addressed target in MSG. 5570 "Return the addressed target in MSG.
@@ -5485,19 +5577,19 @@ The addressed target is the string before the first colon in MSG."
5485(defun erc-user-spec (user) 5577(defun erc-user-spec (user)
5486 "Create a nick!user@host spec from a user struct." 5578 "Create a nick!user@host spec from a user struct."
5487 (let ((nick (erc-server-user-nickname user)) 5579 (let ((nick (erc-server-user-nickname user))
5488 (host (erc-server-user-host user)) 5580 (host (erc-server-user-host user))
5489 (login (erc-server-user-login user))) 5581 (login (erc-server-user-login user)))
5490 (concat (or nick "") 5582 (concat (or nick "")
5491 "!" 5583 "!"
5492 (or login "") 5584 (or login "")
5493 "@" 5585 "@"
5494 (or host "")))) 5586 (or host ""))))
5495 5587
5496(defun erc-list-match (lst str) 5588(defun erc-list-match (lst str)
5497 "Return non-nil if any regexp in LST matches STR." 5589 "Return non-nil if any regexp in LST matches STR."
5498 (memq nil (mapcar (lambda (regexp) 5590 (memq nil (mapcar (lambda (regexp)
5499 (not (string-match regexp str))) 5591 (not (string-match regexp str)))
5500 lst))) 5592 lst)))
5501 5593
5502;; other "toggles" 5594;; other "toggles"
5503 5595
@@ -5509,9 +5601,9 @@ If ARG is positive, turns CTCP replies on.
5509If ARG is non-nil and not positive, turns CTCP replies off." 5601If ARG is non-nil and not positive, turns CTCP replies off."
5510 (interactive "P") 5602 (interactive "P")
5511 (cond ((and (numberp arg) (> arg 0)) 5603 (cond ((and (numberp arg) (> arg 0))
5512 (setq erc-disable-ctcp-replies t)) 5604 (setq erc-disable-ctcp-replies t))
5513 (arg (setq erc-disable-ctcp-replies nil)) 5605 (arg (setq erc-disable-ctcp-replies nil))
5514 (t (setq erc-disable-ctcp-replies (not erc-disable-ctcp-replies)))) 5606 (t (setq erc-disable-ctcp-replies (not erc-disable-ctcp-replies))))
5515 (message "ERC CTCP replies are %s" (if erc-disable-ctcp-replies "OFF" "ON"))) 5607 (message "ERC CTCP replies are %s" (if erc-disable-ctcp-replies "OFF" "ON")))
5516 5608
5517(defun erc-toggle-flood-control (&optional arg) 5609(defun erc-toggle-flood-control (&optional arg)
@@ -5524,12 +5616,12 @@ See `erc-server-flood-margin' for an explanation of the available
5524flood control parameters." 5616flood control parameters."
5525 (interactive "P") 5617 (interactive "P")
5526 (cond ((and (numberp arg) (> arg 0)) 5618 (cond ((and (numberp arg) (> arg 0))
5527 (setq erc-flood-protect t)) 5619 (setq erc-flood-protect t))
5528 (arg (setq erc-flood-protect nil)) 5620 (arg (setq erc-flood-protect nil))
5529 (t (setq erc-flood-protect (not erc-flood-protect)))) 5621 (t (setq erc-flood-protect (not erc-flood-protect))))
5530 (message "ERC flood control is %s" 5622 (message "ERC flood control is %s"
5531 (cond (erc-flood-protect "ON") 5623 (cond (erc-flood-protect "ON")
5532 (t "OFF")))) 5624 (t "OFF"))))
5533 5625
5534;; Some useful channel and nick commands for fast key bindings 5626;; Some useful channel and nick commands for fast key bindings
5535 5627
@@ -5543,7 +5635,7 @@ This command is sent even if excess flood is detected."
5543 (erc-set-active-buffer (current-buffer)) 5635 (erc-set-active-buffer (current-buffer))
5544 (let ((tgt (erc-default-target))) 5636 (let ((tgt (erc-default-target)))
5545 (if (or (not tgt) (not (erc-channel-p tgt))) 5637 (if (or (not tgt) (not (erc-channel-p tgt)))
5546 (erc-display-message nil 'error (current-buffer) 'no-target) 5638 (erc-display-message nil 'error (current-buffer) 'no-target)
5547 (erc-load-irc-script-lines 5639 (erc-load-irc-script-lines
5548 (list (concat "/mode " tgt (if arg " -i" " +i"))) 5640 (list (concat "/mode " tgt (if arg " -i" " +i")))
5549 t)))) 5641 t))))
@@ -5561,14 +5653,14 @@ Anything else will be sent to `erc-toggle-channel-mode'."
5561 (when (featurep 'xemacs) 5653 (when (featurep 'xemacs)
5562 (setq key (char-to-string (event-to-character (aref key 0))))) 5654 (setq key (char-to-string (event-to-character (aref key 0)))))
5563 (cond ((equal key "\C-g") 5655 (cond ((equal key "\C-g")
5564 (keyboard-quit)) 5656 (keyboard-quit))
5565 ((equal key "\C-m") 5657 ((equal key "\C-m")
5566 (erc-insert-mode-command)) 5658 (erc-insert-mode-command))
5567 ((equal key "l") 5659 ((equal key "l")
5568 (call-interactively 'erc-set-channel-limit)) 5660 (call-interactively 'erc-set-channel-limit))
5569 ((equal key "k") 5661 ((equal key "k")
5570 (call-interactively 'erc-set-channel-key)) 5662 (call-interactively 'erc-set-channel-key))
5571 (t (erc-toggle-channel-mode key)))) 5663 (t (erc-toggle-channel-mode key))))
5572 5664
5573(defun erc-toggle-channel-mode (mode &optional channel) 5665(defun erc-toggle-channel-mode (mode &optional channel)
5574 "Toggle channel MODE. 5666 "Toggle channel MODE.
@@ -5579,13 +5671,13 @@ If CHANNEL is non-nil, toggle MODE for that channel, otherwise use
5579 (erc-set-active-buffer (current-buffer)) 5671 (erc-set-active-buffer (current-buffer))
5580 (let ((tgt (or channel (erc-default-target)))) 5672 (let ((tgt (or channel (erc-default-target))))
5581 (if (or (null tgt) (null (erc-channel-p tgt))) 5673 (if (or (null tgt) (null (erc-channel-p tgt)))
5582 (erc-display-message nil 'error 'active 'no-target) 5674 (erc-display-message nil 'error 'active 'no-target)
5583 (let* ((active (member mode erc-channel-modes)) 5675 (let* ((active (member mode erc-channel-modes))
5584 (newstate (if active "OFF" "ON"))) 5676 (newstate (if active "OFF" "ON")))
5585 (erc-log (format "%s: Toggle mode %s %s" tgt mode newstate)) 5677 (erc-log (format "%s: Toggle mode %s %s" tgt mode newstate))
5586 (message "Toggle channel mode %s %s" mode newstate) 5678 (message "Toggle channel mode %s %s" mode newstate)
5587 (erc-server-send (format "MODE %s %s%s" 5679 (erc-server-send (format "MODE %s %s%s"
5588 tgt (if active "-" "+") mode)))))) 5680 tgt (if active "-" "+") mode))))))
5589 5681
5590(defun erc-insert-mode-command () 5682(defun erc-insert-mode-command ()
5591 "Insert the line \"/mode <current target> \" at `point'." 5683 "Insert the line \"/mode <current target> \" at `point'."
@@ -5621,9 +5713,9 @@ If FILE is found, return the path to it."
5621 (let ((filepath file)) 5713 (let ((filepath file))
5622 (if (file-readable-p filepath) filepath 5714 (if (file-readable-p filepath) filepath
5623 (while (and path 5715 (while (and path
5624 (progn (setq filepath (expand-file-name file (car path))) 5716 (progn (setq filepath (expand-file-name file (car path)))
5625 (not (file-readable-p filepath)))) 5717 (not (file-readable-p filepath))))
5626 (setq path (cdr path))) 5718 (setq path (cdr path)))
5627 (if path filepath nil)))) 5719 (if path filepath nil))))
5628 5720
5629(defun erc-select-startup-file () 5721(defun erc-select-startup-file ()
@@ -5633,7 +5725,7 @@ See also `erc-startup-file-list'."
5633 (dolist (f erc-startup-file-list) 5725 (dolist (f erc-startup-file-list)
5634 (setq f (convert-standard-filename f)) 5726 (setq f (convert-standard-filename f))
5635 (when (file-readable-p f) 5727 (when (file-readable-p f)
5636 (throw 'found f))))) 5728 (throw 'found f)))))
5637 5729
5638(defun erc-find-script-file (file) 5730(defun erc-find-script-file (file)
5639 "Search for FILE in `default-directory', and any in `erc-script-path'." 5731 "Search for FILE in `default-directory', and any in `erc-script-path'."
@@ -5666,15 +5758,15 @@ $* = the entire argument string, $1 = the first argument, $2 = the second,
5666and so on." 5758and so on."
5667 (if (not args) (setq args "")) 5759 (if (not args) (setq args ""))
5668 (let* ((arg-esc-regexp "\\(\\$\\(\\*\\|[1-9][0-9]*\\)\\)\\([^0-9]\\|$\\)") 5760 (let* ((arg-esc-regexp "\\(\\$\\(\\*\\|[1-9][0-9]*\\)\\)\\([^0-9]\\|$\\)")
5669 (percent-regexp "\\(%.\\)") 5761 (percent-regexp "\\(%.\\)")
5670 (esc-regexp (concat arg-esc-regexp "\\|" percent-regexp)) 5762 (esc-regexp (concat arg-esc-regexp "\\|" percent-regexp))
5671 (tgt (erc-default-target)) 5763 (tgt (erc-default-target))
5672 (server (and (boundp 'erc-session-server) erc-session-server)) 5764 (server (and (boundp 'erc-session-server) erc-session-server))
5673 (nick (erc-current-nick)) 5765 (nick (erc-current-nick))
5674 (res "") 5766 (res "")
5675 (tmp nil) 5767 (tmp nil)
5676 (arg-list nil) 5768 (arg-list nil)
5677 (arg-num 0)) 5769 (arg-num 0))
5678 (if (not tgt) (setq tgt "")) 5770 (if (not tgt) (setq tgt ""))
5679 (if (not server) (setq server "")) 5771 (if (not server) (setq server ""))
5680 (if (not nick) (setq nick "")) 5772 (if (not nick) (setq nick ""))
@@ -5690,36 +5782,36 @@ and so on."
5690 (while tmp 5782 (while tmp
5691 ;;(message "beginning of while: tmp=%S" tmp) 5783 ;;(message "beginning of while: tmp=%S" tmp)
5692 (let* ((hd (substring line 0 tmp)) 5784 (let* ((hd (substring line 0 tmp))
5693 (esc "") 5785 (esc "")
5694 (subst "") 5786 (subst "")
5695 (tail (substring line tmp))) 5787 (tail (substring line tmp)))
5696 (cond ((string-match (concat "^" arg-esc-regexp) tail) 5788 (cond ((string-match (concat "^" arg-esc-regexp) tail)
5697 (setq esc (match-string 1 tail)) 5789 (setq esc (match-string 1 tail))
5698 (setq tail (substring tail (match-end 1)))) 5790 (setq tail (substring tail (match-end 1))))
5699 ((string-match (concat "^" percent-regexp) tail) 5791 ((string-match (concat "^" percent-regexp) tail)
5700 (setq esc (match-string 1 tail)) 5792 (setq esc (match-string 1 tail))
5701 (setq tail (substring tail (match-end 1))))) 5793 (setq tail (substring tail (match-end 1)))))
5702 ;;(message "hd=%S, esc=%S, tail=%S, arg-num=%S" hd esc tail arg-num) 5794 ;;(message "hd=%S, esc=%S, tail=%S, arg-num=%S" hd esc tail arg-num)
5703 (setq res (concat res hd)) 5795 (setq res (concat res hd))
5704 (setq subst 5796 (setq subst
5705 (cond ((string= esc "") "") 5797 (cond ((string= esc "") "")
5706 ((string-match "^\\$\\*$" esc) args) 5798 ((string-match "^\\$\\*$" esc) args)
5707 ((string-match "^\\$\\([0-9]+\\)$" esc) 5799 ((string-match "^\\$\\([0-9]+\\)$" esc)
5708 (let ((n (string-to-number (match-string 1 esc)))) 5800 (let ((n (string-to-number (match-string 1 esc))))
5709 (message "n = %S, integerp(n)=%S" n (integerp n)) 5801 (message "n = %S, integerp(n)=%S" n (integerp n))
5710 (if (<= n arg-num) (nth (1- n) arg-list) ""))) 5802 (if (<= n arg-num) (nth (1- n) arg-list) "")))
5711 ((string-match "^%[Cc]$" esc) tgt) 5803 ((string-match "^%[Cc]$" esc) tgt)
5712 ((string-match "^%[Ss]$" esc) server) 5804 ((string-match "^%[Ss]$" esc) server)
5713 ((string-match "^%[Nn]$" esc) nick) 5805 ((string-match "^%[Nn]$" esc) nick)
5714 ((string-match "^%\\(.\\)$" esc) (match-string 1 esc)) 5806 ((string-match "^%\\(.\\)$" esc) (match-string 1 esc))
5715 (t (erc-log (format "BUG in erc-process-script-line: bad escape sequence: %S\n" esc)) 5807 (t (erc-log (format "BUG in erc-process-script-line: bad escape sequence: %S\n" esc))
5716 (message "BUG IN ERC: esc=%S" esc) 5808 (message "BUG IN ERC: esc=%S" esc)
5717 ""))) 5809 "")))
5718 (setq line tail) 5810 (setq line tail)
5719 (setq tmp (string-match esc-regexp line)) 5811 (setq tmp (string-match esc-regexp line))
5720 (setq res (concat res subst)) 5812 (setq res (concat res subst))
5721 ;;(message "end of while: line=%S, res=%S, tmp=%S" line res tmp) 5813 ;;(message "end of while: line=%S, res=%S, tmp=%S" line res tmp)
5722 )) 5814 ))
5723 (setq res (concat res line)) 5815 (setq res (concat res line))
5724 res)) 5816 res))
5725 5817
@@ -5727,8 +5819,8 @@ and so on."
5727 "Load an IRC script from FILE." 5819 "Load an IRC script from FILE."
5728 (erc-log (concat "erc-load-script: " file)) 5820 (erc-log (concat "erc-load-script: " file))
5729 (let ((str (with-temp-buffer 5821 (let ((str (with-temp-buffer
5730 (insert-file-contents file) 5822 (insert-file-contents file)
5731 (buffer-string)))) 5823 (buffer-string))))
5732 (erc-load-irc-script-lines (erc-split-multiline-safe str) force))) 5824 (erc-load-irc-script-lines (erc-split-multiline-safe str) force)))
5733 5825
5734(defun erc-load-irc-script-lines (lines &optional force noexpand) 5826(defun erc-load-irc-script-lines (lines &optional force noexpand)
@@ -5738,25 +5830,25 @@ If optional NOEXPAND is non-nil, do not expand script-specific
5738sequences, process the lines verbatim. Use this for multiline 5830sequences, process the lines verbatim. Use this for multiline
5739user input." 5831user input."
5740 (let* ((cb (current-buffer)) 5832 (let* ((cb (current-buffer))
5741 (s "") 5833 (s "")
5742 (sp (or (erc-command-indicator) (erc-prompt))) 5834 (sp (or (erc-command-indicator) (erc-prompt)))
5743 (args (and (boundp 'erc-script-args) erc-script-args))) 5835 (args (and (boundp 'erc-script-args) erc-script-args)))
5744 (if (and args (string-match "^ " args)) 5836 (if (and args (string-match "^ " args))
5745 (setq args (substring args 1))) 5837 (setq args (substring args 1)))
5746 ;; prepare the prompt string for echo 5838 ;; prepare the prompt string for echo
5747 (erc-put-text-property 0 (length sp) 5839 (erc-put-text-property 0 (length sp)
5748 'face 'erc-command-indicator-face sp) 5840 'face 'erc-command-indicator-face sp)
5749 (while lines 5841 (while lines
5750 (setq s (car lines)) 5842 (setq s (car lines))
5751 (erc-log (concat "erc-load-script: CMD: " s)) 5843 (erc-log (concat "erc-load-script: CMD: " s))
5752 (unless (string-match "^\\s-*$" s) 5844 (unless (string-match "^\\s-*$" s)
5753 (let ((line (if noexpand s (erc-process-script-line s args)))) 5845 (let ((line (if noexpand s (erc-process-script-line s args))))
5754 (if (and (erc-process-input-line line force) 5846 (if (and (erc-process-input-line line force)
5755 erc-script-echo) 5847 erc-script-echo)
5756 (progn 5848 (progn
5757 (erc-put-text-property 0 (length line) 5849 (erc-put-text-property 0 (length line)
5758 'face 'erc-input-face line) 5850 'face 'erc-input-face line)
5759 (erc-display-line (concat sp line) cb))))) 5851 (erc-display-line (concat sp line) cb)))))
5760 (setq lines (cdr lines))))) 5852 (setq lines (cdr lines)))))
5761 5853
5762;; authentication 5854;; authentication
@@ -5764,21 +5856,21 @@ user input."
5764(defun erc-login () 5856(defun erc-login ()
5765 "Perform user authentication at the IRC server." 5857 "Perform user authentication at the IRC server."
5766 (erc-log (format "login: nick: %s, user: %s %s %s :%s" 5858 (erc-log (format "login: nick: %s, user: %s %s %s :%s"
5767 (erc-current-nick) 5859 (erc-current-nick)
5768 (user-login-name) 5860 (user-login-name)
5769 (or erc-system-name (system-name)) 5861 (or erc-system-name (system-name))
5770 erc-session-server 5862 erc-session-server
5771 erc-session-user-full-name)) 5863 erc-session-user-full-name))
5772 (if erc-session-password 5864 (if erc-session-password
5773 (erc-server-send (format "PASS %s" erc-session-password)) 5865 (erc-server-send (format "PASS %s" erc-session-password))
5774 (message "Logging in without password")) 5866 (message "Logging in without password"))
5775 (erc-server-send (format "NICK %s" (erc-current-nick))) 5867 (erc-server-send (format "NICK %s" (erc-current-nick)))
5776 (erc-server-send 5868 (erc-server-send
5777 (format "USER %s %s %s :%s" 5869 (format "USER %s %s %s :%s"
5778 ;; hacked - S.B. 5870 ;; hacked - S.B.
5779 (if erc-anonymous-login erc-email-userid (user-login-name)) 5871 (if erc-anonymous-login erc-email-userid (user-login-name))
5780 "0" "*" 5872 "0" "*"
5781 erc-session-user-full-name)) 5873 erc-session-user-full-name))
5782 (erc-update-mode-line)) 5874 (erc-update-mode-line))
5783 5875
5784;; connection properties' heuristics 5876;; connection properties' heuristics
@@ -5794,8 +5886,8 @@ Sets the buffer local variables:
5794- `erc-server-current-nick'" 5886- `erc-server-current-nick'"
5795 (setq erc-session-connector erc-server-connect-function 5887 (setq erc-session-connector erc-server-connect-function
5796 erc-session-server (erc-compute-server server) 5888 erc-session-server (erc-compute-server server)
5797 erc-session-port (or port erc-default-port) 5889 erc-session-port (or port erc-default-port)
5798 erc-session-user-full-name (erc-compute-full-name name)) 5890 erc-session-user-full-name (erc-compute-full-name name))
5799 (erc-set-current-nick (erc-compute-nick nick))) 5891 (erc-set-current-nick (erc-compute-nick nick)))
5800 5892
5801(defun erc-compute-server (&optional server) 5893(defun erc-compute-server (&optional server)
@@ -5863,7 +5955,7 @@ non-nil value is found.
5863Returns a list of the form (HIGH LOW), compatible with Emacs time format." 5955Returns a list of the form (HIGH LOW), compatible with Emacs time format."
5864 (let* ((n (string-to-number (concat string ".0")))) 5956 (let* ((n (string-to-number (concat string ".0"))))
5865 (list (truncate (/ n 65536)) 5957 (list (truncate (/ n 65536))
5866 (truncate (mod n 65536))))) 5958 (truncate (mod n 65536)))))
5867 5959
5868(defun erc-emacs-time-to-erc-time (time) 5960(defun erc-emacs-time-to-erc-time (time)
5869 "Convert Emacs TIME to a number of seconds since the epoch." 5961 "Convert Emacs TIME to a number of seconds since the epoch."
@@ -5889,33 +5981,33 @@ See also `erc-emacs-time-to-erc-time'."
5889 "Convert NS to a time string HH:MM.SS." 5981 "Convert NS to a time string HH:MM.SS."
5890 (setq ns (truncate ns)) 5982 (setq ns (truncate ns))
5891 (format "%02d:%02d.%02d" 5983 (format "%02d:%02d.%02d"
5892 (/ ns 3600) 5984 (/ ns 3600)
5893 (/ (% ns 3600) 60) 5985 (/ (% ns 3600) 60)
5894 (% ns 60))) 5986 (% ns 60)))
5895 5987
5896(defun erc-seconds-to-string (seconds) 5988(defun erc-seconds-to-string (seconds)
5897 "Convert a number of SECONDS into an English phrase." 5989 "Convert a number of SECONDS into an English phrase."
5898 (let (days hours minutes format-args output) 5990 (let (days hours minutes format-args output)
5899 (setq days (/ seconds 86400) 5991 (setq days (/ seconds 86400)
5900 seconds (% seconds 86400) 5992 seconds (% seconds 86400)
5901 hours (/ seconds 3600) 5993 hours (/ seconds 3600)
5902 seconds (% seconds 3600) 5994 seconds (% seconds 3600)
5903 minutes (/ seconds 60) 5995 minutes (/ seconds 60)
5904 seconds (% seconds 60) 5996 seconds (% seconds 60)
5905 format-args (if (> days 0) 5997 format-args (if (> days 0)
5906 `("%d days, %d hours, %d minutes, %d seconds" 5998 `("%d days, %d hours, %d minutes, %d seconds"
5907 ,days ,hours ,minutes ,seconds) 5999 ,days ,hours ,minutes ,seconds)
5908 (if (> hours 0) 6000 (if (> hours 0)
5909 `("%d hours, %d minutes, %d seconds" 6001 `("%d hours, %d minutes, %d seconds"
5910 ,hours ,minutes ,seconds) 6002 ,hours ,minutes ,seconds)
5911 (if (> minutes 0) 6003 (if (> minutes 0)
5912 `("%d minutes, %d seconds" ,minutes ,seconds) 6004 `("%d minutes, %d seconds" ,minutes ,seconds)
5913 `("%d seconds" ,seconds)))) 6005 `("%d seconds" ,seconds))))
5914 output (apply 'format format-args)) 6006 output (apply 'format format-args))
5915 ;; Change all "1 units" to "1 unit". 6007 ;; Change all "1 units" to "1 unit".
5916 (while (string-match "\\([^0-9]\\|^\\)1 \\S-+\\(s\\)" output) 6008 (while (string-match "\\([^0-9]\\|^\\)1 \\S-+\\(s\\)" output)
5917 (setq output (erc-replace-match-subexpression-in-string 6009 (setq output (erc-replace-match-subexpression-in-string
5918 "" output (match-string 2 output) 2 (match-beginning 2)))) 6010 "" output (match-string 2 output) 2 (match-beginning 2))))
5919 output)) 6011 output))
5920 6012
5921 6013
@@ -5938,14 +6030,14 @@ If S is nil or an empty string then return general CLIENTINFO."
5938 (if (or (not s) (string= s "")) 6030 (if (or (not s) (string= s ""))
5939 (concat 6031 (concat
5940 (apply #'concat 6032 (apply #'concat
5941 (mapcar (lambda (e) 6033 (mapcar (lambda (e)
5942 (concat (car e) " ")) 6034 (concat (car e) " "))
5943 erc-clientinfo-alist)) 6035 erc-clientinfo-alist))
5944 ": use CLIENTINFO <COMMAND> to get more specific information") 6036 ": use CLIENTINFO <COMMAND> to get more specific information")
5945 (let ((h (assoc (upcase s) erc-clientinfo-alist))) 6037 (let ((h (assoc (upcase s) erc-clientinfo-alist)))
5946 (if h 6038 (if h
5947 (concat s " " (cdr h)) 6039 (concat s " " (cdr h))
5948 (concat s ": unknown command"))))) 6040 (concat s ": unknown command")))))
5949 6041
5950;; Hook functions 6042;; Hook functions
5951 6043
@@ -5960,9 +6052,9 @@ If it doesn't exist, create it."
5960 ;; here, we only want to match the channel buffers, to avoid 6052 ;; here, we only want to match the channel buffers, to avoid
5961 ;; "selecting killed buffers" b0rkage. 6053 ;; "selecting killed buffers" b0rkage.
5962 (erc-with-all-buffers-of-server process 6054 (erc-with-all-buffers-of-server process
5963 (lambda () 6055 (lambda ()
5964 (not (erc-server-buffer-p))) 6056 (not (erc-server-buffer-p)))
5965 (kill-buffer (current-buffer)))) 6057 (kill-buffer (current-buffer))))
5966 6058
5967(defun erc-nick-at-point () 6059(defun erc-nick-at-point ()
5968 "Give information about the nickname at `point'. 6060 "Give information about the nickname at `point'.
@@ -5973,31 +6065,37 @@ entry of `channel-members'."
5973 (interactive) 6065 (interactive)
5974 (require 'thingatpt) 6066 (require 'thingatpt)
5975 (let* ((word (word-at-point)) 6067 (let* ((word (word-at-point))
5976 (channel-data (erc-get-channel-user word)) 6068 (channel-data (erc-get-channel-user word))
5977 (cuser (cdr channel-data)) 6069 (cuser (cdr channel-data))
5978 (user (if channel-data 6070 (user (if channel-data
5979 (car channel-data) 6071 (car channel-data)
5980 (erc-get-server-user word))) 6072 (erc-get-server-user word)))
5981 host login full-name nick op voice) 6073 host login full-name nick voice halfop op admin owner)
5982 (when user 6074 (when user
5983 (setq nick (erc-server-user-nickname user) 6075 (setq nick (erc-server-user-nickname user)
5984 host (erc-server-user-host user) 6076 host (erc-server-user-host user)
5985 login (erc-server-user-login user) 6077 login (erc-server-user-login user)
5986 full-name (erc-server-user-full-name user)) 6078 full-name (erc-server-user-full-name user))
5987 (if cuser 6079 (if cuser
5988 (setq op (erc-channel-user-op cuser) 6080 (setq voice (erc-channel-user-voice cuser)
5989 voice (erc-channel-user-voice cuser))) 6081 halfop (erc-channel-user-halfop cuser)
5990 (if (called-interactively-p 'interactive) 6082 op (erc-channel-user-op cuser)
5991 (message "%s is %s@%s%s%s" 6083 admin (erc-channel-user-admin cuser)
5992 nick login host 6084 owner (erc-channel-user-owner cuser))))
5993 (if full-name (format " (%s)" full-name) "") 6085 (if (called-interactively-p 'interactive)
5994 (if (or op voice) 6086 (message "%s is %s@%s%s%s"
5995 (format " and is +%s%s on %s" 6087 nick login host
5996 (if op "o" "") 6088 (if full-name (format " (%s)" full-name) "")
5997 (if voice "v" "") 6089 (if (or voice halfop op admin owner)
5998 (erc-default-target)) 6090 (format " and is +%s%s on %s"
5999 "")) 6091 (if voice "v" "")
6000 user)))) 6092 (if halfop "h" "")
6093 (if op "o" "")
6094 (if admin "a" "")
6095 (if owner "q" "")
6096 (erc-default-target))
6097 ""))
6098 user)))
6001 6099
6002(defun erc-away-time () 6100(defun erc-away-time ()
6003 "Return non-nil if the current ERC process is set away. 6101 "Return non-nil if the current ERC process is set away.
@@ -6042,11 +6140,11 @@ displayed.
6042See `erc-mode-line-format' for which characters are can be used." 6140See `erc-mode-line-format' for which characters are can be used."
6043 :group 'erc-mode-line-and-header 6141 :group 'erc-mode-line-and-header
6044 :set (lambda (sym val) 6142 :set (lambda (sym val)
6045 (set sym val) 6143 (set sym val)
6046 (when (fboundp 'erc-update-mode-line) 6144 (when (fboundp 'erc-update-mode-line)
6047 (erc-update-mode-line nil))) 6145 (erc-update-mode-line nil)))
6048 :type '(choice (const :tag "Disabled" nil) 6146 :type '(choice (const :tag "Disabled" nil)
6049 string)) 6147 string))
6050 6148
6051(defcustom erc-header-line-uses-tabbar-p nil 6149(defcustom erc-header-line-uses-tabbar-p nil
6052 "Use tabbar mode instead of the header line to display the header." 6150 "Use tabbar mode instead of the header line to display the header."
@@ -6067,8 +6165,8 @@ If given a function, call it and use the resulting face name.
6067Otherwise, use the `erc-header-line' face." 6165Otherwise, use the `erc-header-line' face."
6068 :group 'erc-mode-line-and-header 6166 :group 'erc-mode-line-and-header
6069 :type '(choice (const :tag "Don't colorize" nil) 6167 :type '(choice (const :tag "Don't colorize" nil)
6070 (const :tag "Use the erc-header-line face" t) 6168 (const :tag "Use the erc-header-line face" t)
6071 (function :tag "Call a function"))) 6169 (function :tag "Call a function")))
6072 6170
6073(defcustom erc-show-channel-key-p t 6171(defcustom erc-show-channel-key-p t
6074 "Show the channel key in the header line." 6172 "Show the channel key in the header line."
@@ -6087,40 +6185,40 @@ This should be a string with substitution variables recognized by
6087 "Shorten SERVER-NAME according to `erc-common-server-suffixes'." 6185 "Shorten SERVER-NAME according to `erc-common-server-suffixes'."
6088 (if (stringp server-name) 6186 (if (stringp server-name)
6089 (with-temp-buffer 6187 (with-temp-buffer
6090 (insert server-name) 6188 (insert server-name)
6091 (let ((alist erc-common-server-suffixes)) 6189 (let ((alist erc-common-server-suffixes))
6092 (while alist 6190 (while alist
6093 (goto-char (point-min)) 6191 (goto-char (point-min))
6094 (if (re-search-forward (caar alist) nil t) 6192 (if (re-search-forward (caar alist) nil t)
6095 (replace-match (cdar alist))) 6193 (replace-match (cdar alist)))
6096 (setq alist (cdr alist)))) 6194 (setq alist (cdr alist))))
6097 (buffer-string)))) 6195 (buffer-string))))
6098 6196
6099(defun erc-format-target () 6197(defun erc-format-target ()
6100 "Return the name of the target (channel or nickname or servername:port)." 6198 "Return the name of the target (channel or nickname or servername:port)."
6101 (let ((target (erc-default-target))) 6199 (let ((target (erc-default-target)))
6102 (or target 6200 (or target
6103 (concat (erc-shorten-server-name 6201 (concat (erc-shorten-server-name
6104 (or erc-server-announced-name 6202 (or erc-server-announced-name
6105 erc-session-server)) 6203 erc-session-server))
6106 ":" (erc-port-to-string erc-session-port))))) 6204 ":" (erc-port-to-string erc-session-port)))))
6107 6205
6108(defun erc-format-target-and/or-server () 6206(defun erc-format-target-and/or-server ()
6109 "Return the server name or the current target and server name combined." 6207 "Return the server name or the current target and server name combined."
6110 (let ((server-name (erc-shorten-server-name 6208 (let ((server-name (erc-shorten-server-name
6111 (or erc-server-announced-name 6209 (or erc-server-announced-name
6112 erc-session-server)))) 6210 erc-session-server))))
6113 (cond ((erc-default-target) 6211 (cond ((erc-default-target)
6114 (concat (erc-string-no-properties (erc-default-target)) 6212 (concat (erc-string-no-properties (erc-default-target))
6115 "@" server-name)) 6213 "@" server-name))
6116 (server-name server-name) 6214 (server-name server-name)
6117 (t (buffer-name (current-buffer)))))) 6215 (t (buffer-name (current-buffer))))))
6118 6216
6119(defun erc-format-network () 6217(defun erc-format-network ()
6120 "Return the name of the network we are currently on." 6218 "Return the name of the network we are currently on."
6121 (let ((network (and (fboundp 'erc-network-name) (erc-network-name)))) 6219 (let ((network (and (fboundp 'erc-network-name) (erc-network-name))))
6122 (if (and network (symbolp network)) 6220 (if (and network (symbolp network))
6123 (symbol-name network) 6221 (symbol-name network)
6124 ""))) 6222 "")))
6125 6223
6126(defun erc-format-target-and/or-network () 6224(defun erc-format-target-and/or-network ()
@@ -6128,48 +6226,48 @@ This should be a string with substitution variables recognized by
6128If the name of the network is not available, then use the 6226If the name of the network is not available, then use the
6129shortened server name instead." 6227shortened server name instead."
6130 (let ((network-name (or (and (fboundp 'erc-network-name) (erc-network-name)) 6228 (let ((network-name (or (and (fboundp 'erc-network-name) (erc-network-name))
6131 (erc-shorten-server-name 6229 (erc-shorten-server-name
6132 (or erc-server-announced-name 6230 (or erc-server-announced-name
6133 erc-session-server))))) 6231 erc-session-server)))))
6134 (when (and network-name (symbolp network-name)) 6232 (when (and network-name (symbolp network-name))
6135 (setq network-name (symbol-name network-name))) 6233 (setq network-name (symbol-name network-name)))
6136 (cond ((erc-default-target) 6234 (cond ((erc-default-target)
6137 (concat (erc-string-no-properties (erc-default-target)) 6235 (concat (erc-string-no-properties (erc-default-target))
6138 "@" network-name)) 6236 "@" network-name))
6139 (network-name network-name) 6237 (network-name network-name)
6140 (t (buffer-name (current-buffer)))))) 6238 (t (buffer-name (current-buffer))))))
6141 6239
6142(defun erc-format-away-status () 6240(defun erc-format-away-status ()
6143 "Return a formatted `erc-mode-line-away-status-format' 6241 "Return a formatted `erc-mode-line-away-status-format'
6144if `erc-away' is non-nil." 6242if `erc-away' is non-nil."
6145 (let ((a (erc-away-time))) 6243 (let ((a (erc-away-time)))
6146 (if a 6244 (if a
6147 (format-time-string erc-mode-line-away-status-format a) 6245 (format-time-string erc-mode-line-away-status-format a)
6148 ""))) 6246 "")))
6149 6247
6150(defun erc-format-channel-modes () 6248(defun erc-format-channel-modes ()
6151 "Return the current channel's modes." 6249 "Return the current channel's modes."
6152 (concat (apply 'concat 6250 (concat (apply 'concat
6153 "+" erc-channel-modes) 6251 "+" erc-channel-modes)
6154 (cond ((and erc-channel-user-limit erc-channel-key) 6252 (cond ((and erc-channel-user-limit erc-channel-key)
6155 (if erc-show-channel-key-p 6253 (if erc-show-channel-key-p
6156 (format "lk %.0f %s" erc-channel-user-limit 6254 (format "lk %.0f %s" erc-channel-user-limit
6157 erc-channel-key) 6255 erc-channel-key)
6158 (format "kl %.0f" erc-channel-user-limit))) 6256 (format "kl %.0f" erc-channel-user-limit)))
6159 (erc-channel-user-limit 6257 (erc-channel-user-limit
6160 ;; Emacs has no bignums 6258 ;; Emacs has no bignums
6161 (format "l %.0f" erc-channel-user-limit)) 6259 (format "l %.0f" erc-channel-user-limit))
6162 (erc-channel-key 6260 (erc-channel-key
6163 (if erc-show-channel-key-p 6261 (if erc-show-channel-key-p
6164 (format "k %s" erc-channel-key) 6262 (format "k %s" erc-channel-key)
6165 "k")) 6263 "k"))
6166 (t nil)))) 6264 (t nil))))
6167 6265
6168(defun erc-format-lag-time () 6266(defun erc-format-lag-time ()
6169 "Return the estimated lag time to server, `erc-server-lag'." 6267 "Return the estimated lag time to server, `erc-server-lag'."
6170 (let ((lag (erc-with-server-buffer erc-server-lag))) 6268 (let ((lag (erc-with-server-buffer erc-server-lag)))
6171 (cond (lag (format "lag:%.0f" lag)) 6269 (cond (lag (format "lag:%.0f" lag))
6172 (t "")))) 6270 (t ""))))
6173 6271
6174;; erc-goodies is required at end of this file. 6272;; erc-goodies is required at end of this file.
6175(declare-function erc-controls-strip "erc-goodies" (str)) 6273(declare-function erc-controls-strip "erc-goodies" (str))
@@ -6180,66 +6278,66 @@ if `erc-away' is non-nil."
6180 "Update the mode line in a single ERC buffer BUFFER." 6278 "Update the mode line in a single ERC buffer BUFFER."
6181 (with-current-buffer buffer 6279 (with-current-buffer buffer
6182 (let ((spec (format-spec-make 6280 (let ((spec (format-spec-make
6183 ?a (erc-format-away-status) 6281 ?a (erc-format-away-status)
6184 ?l (erc-format-lag-time) 6282 ?l (erc-format-lag-time)
6185 ?m (erc-format-channel-modes) 6283 ?m (erc-format-channel-modes)
6186 ?n (or (erc-current-nick) "") 6284 ?n (or (erc-current-nick) "")
6187 ?N (erc-format-network) 6285 ?N (erc-format-network)
6188 ?o (or (erc-controls-strip erc-channel-topic) "") 6286 ?o (or (erc-controls-strip erc-channel-topic) "")
6189 ?p (erc-port-to-string erc-session-port) 6287 ?p (erc-port-to-string erc-session-port)
6190 ?s (erc-format-target-and/or-server) 6288 ?s (erc-format-target-and/or-server)
6191 ?S (erc-format-target-and/or-network) 6289 ?S (erc-format-target-and/or-network)
6192 ?t (erc-format-target))) 6290 ?t (erc-format-target)))
6193 (process-status (cond ((and (erc-server-process-alive) 6291 (process-status (cond ((and (erc-server-process-alive)
6194 (not erc-server-connected)) 6292 (not erc-server-connected))
6195 ":connecting") 6293 ":connecting")
6196 ((erc-server-process-alive) 6294 ((erc-server-process-alive)
6197 "") 6295 "")
6198 (t 6296 (t
6199 ": CLOSED"))) 6297 ": CLOSED")))
6200 (face (cond ((eq erc-header-line-face-method nil) 6298 (face (cond ((eq erc-header-line-face-method nil)
6201 nil) 6299 nil)
6202 ((functionp erc-header-line-face-method) 6300 ((functionp erc-header-line-face-method)
6203 (funcall erc-header-line-face-method)) 6301 (funcall erc-header-line-face-method))
6204 (t 6302 (t
6205 'erc-header-line)))) 6303 'erc-header-line))))
6206 (cond ((featurep 'xemacs) 6304 (cond ((featurep 'xemacs)
6207 (setq modeline-buffer-identification 6305 (setq modeline-buffer-identification
6208 (list (format-spec erc-mode-line-format spec))) 6306 (list (format-spec erc-mode-line-format spec)))
6209 (setq modeline-process (list process-status))) 6307 (setq modeline-process (list process-status)))
6210 (t 6308 (t
6211 (setq mode-line-buffer-identification 6309 (setq mode-line-buffer-identification
6212 (list (format-spec erc-mode-line-format spec))) 6310 (list (format-spec erc-mode-line-format spec)))
6213 (setq mode-line-process (list process-status)))) 6311 (setq mode-line-process (list process-status))))
6214 (when (boundp 'header-line-format) 6312 (when (boundp 'header-line-format)
6215 (let ((header (if erc-header-line-format 6313 (let ((header (if erc-header-line-format
6216 (format-spec erc-header-line-format spec) 6314 (format-spec erc-header-line-format spec)
6217 nil))) 6315 nil)))
6218 (cond (erc-header-line-uses-tabbar-p 6316 (cond (erc-header-line-uses-tabbar-p
6219 (set (make-local-variable 'tabbar--local-hlf) 6317 (set (make-local-variable 'tabbar--local-hlf)
6220 header-line-format) 6318 header-line-format)
6221 (kill-local-variable 'header-line-format)) 6319 (kill-local-variable 'header-line-format))
6222 ((null header) 6320 ((null header)
6223 (setq header-line-format nil)) 6321 (setq header-line-format nil))
6224 (erc-header-line-uses-help-echo-p 6322 (erc-header-line-uses-help-echo-p
6225 (let ((help-echo (with-temp-buffer 6323 (let ((help-echo (with-temp-buffer
6226 (insert header) 6324 (insert header)
6227 (fill-region (point-min) (point-max)) 6325 (fill-region (point-min) (point-max))
6228 (buffer-string)))) 6326 (buffer-string))))
6229 (setq header-line-format 6327 (setq header-line-format
6230 (erc-replace-regexp-in-string 6328 (erc-replace-regexp-in-string
6231 "%" 6329 "%"
6232 "%%" 6330 "%%"
6233 (if face 6331 (if face
6234 (erc-propertize header 'help-echo help-echo 6332 (erc-propertize header 'help-echo help-echo
6235 'face face) 6333 'face face)
6236 (erc-propertize header 'help-echo help-echo)))))) 6334 (erc-propertize header 'help-echo help-echo))))))
6237 (t (setq header-line-format 6335 (t (setq header-line-format
6238 (if face 6336 (if face
6239 (erc-propertize header 'face face) 6337 (erc-propertize header 'face face)
6240 header))))))) 6338 header)))))))
6241 (if (featurep 'xemacs) 6339 (if (featurep 'xemacs)
6242 (redraw-modeline) 6340 (redraw-modeline)
6243 (force-mode-line-update)))) 6341 (force-mode-line-update))))
6244 6342
6245(defun erc-update-mode-line (&optional buffer) 6343(defun erc-update-mode-line (&optional buffer)
@@ -6250,7 +6348,7 @@ If BUFFER is nil, update the mode line in all ERC buffers."
6250 (erc-update-mode-line-buffer buffer) 6348 (erc-update-mode-line-buffer buffer)
6251 (dolist (buf (erc-buffer-list)) 6349 (dolist (buf (erc-buffer-list))
6252 (when (buffer-live-p buf) 6350 (when (buffer-live-p buf)
6253 (erc-update-mode-line-buffer buf))))) 6351 (erc-update-mode-line-buffer buf)))))
6254 6352
6255;; Miscellaneous 6353;; Miscellaneous
6256 6354
@@ -6267,40 +6365,40 @@ P may be an integer or a service name."
6267 s 6365 s
6268 (let ((n (string-to-number s))) 6366 (let ((n (string-to-number s)))
6269 (if (= n 0) 6367 (if (= n 0)
6270 s 6368 s
6271 n)))) 6369 n))))
6272 6370
6273(defun erc-version (&optional here) 6371(defun erc-version (&optional here)
6274 "Show the version number of ERC in the minibuffer. 6372 "Show the version number of ERC in the minibuffer.
6275If optional argument HERE is non-nil, insert version number at point." 6373If optional argument HERE is non-nil, insert version number at point."
6276 (interactive "P") 6374 (interactive "P")
6277 (let ((version-string 6375 (let ((version-string
6278 (format "ERC %s (GNU Emacs %s)" erc-version-string emacs-version))) 6376 (format "ERC %s (GNU Emacs %s)" erc-version-string emacs-version)))
6279 (if here 6377 (if here
6280 (insert version-string) 6378 (insert version-string)
6281 (if (called-interactively-p 'interactive) 6379 (if (called-interactively-p 'interactive)
6282 (message "%s" version-string) 6380 (message "%s" version-string)
6283 version-string)))) 6381 version-string))))
6284 6382
6285(defun erc-modes (&optional here) 6383(defun erc-modes (&optional here)
6286 "Show the active ERC modes in the minibuffer. 6384 "Show the active ERC modes in the minibuffer.
6287If optional argument HERE is non-nil, insert version number at point." 6385If optional argument HERE is non-nil, insert version number at point."
6288 (interactive "P") 6386 (interactive "P")
6289 (let ((string 6387 (let ((string
6290 (mapconcat 'identity 6388 (mapconcat 'identity
6291 (let (modes (case-fold-search nil)) 6389 (let (modes (case-fold-search nil))
6292 (dolist (var (apropos-internal "^erc-.*mode$")) 6390 (dolist (var (apropos-internal "^erc-.*mode$"))
6293 (when (and (boundp var) 6391 (when (and (boundp var)
6294 (symbol-value var)) 6392 (symbol-value var))
6295 (setq modes (cons (symbol-name var) 6393 (setq modes (cons (symbol-name var)
6296 modes)))) 6394 modes))))
6297 modes) 6395 modes)
6298 ", "))) 6396 ", ")))
6299 (if here 6397 (if here
6300 (insert string) 6398 (insert string)
6301 (if (called-interactively-p 'interactive) 6399 (if (called-interactively-p 'interactive)
6302 (message "%s" string) 6400 (message "%s" string)
6303 string)))) 6401 string))))
6304 6402
6305(defun erc-trim-string (s) 6403(defun erc-trim-string (s)
6306 "Trim leading and trailing spaces off S." 6404 "Trim leading and trailing spaces off S."
@@ -6326,34 +6424,34 @@ All windows are opened in the current frame."
6326 (switch-to-buffer (car bufs)) 6424 (switch-to-buffer (car bufs))
6327 (setq bufs (cdr bufs)) 6425 (setq bufs (cdr bufs))
6328 (while bufs 6426 (while bufs
6329 (split-window) 6427 (split-window)
6330 (other-window 1) 6428 (other-window 1)
6331 (switch-to-buffer (car bufs)) 6429 (switch-to-buffer (car bufs))
6332 (setq bufs (cdr bufs)) 6430 (setq bufs (cdr bufs))
6333 (balance-windows))))) 6431 (balance-windows)))))
6334 6432
6335(defun erc-popup-input-buffer () 6433(defun erc-popup-input-buffer ()
6336 "Provide an input buffer." 6434 "Provide an input buffer."
6337 (interactive) 6435 (interactive)
6338 (let ((buffer-name (generate-new-buffer-name "*ERC input*")) 6436 (let ((buffer-name (generate-new-buffer-name "*ERC input*"))
6339 (mode (intern 6437 (mode (intern
6340 (completing-read 6438 (completing-read
6341 "Mode: " 6439 "Mode: "
6342 (mapcar (lambda (e) 6440 (mapcar (lambda (e)
6343 (list (symbol-name e))) 6441 (list (symbol-name e)))
6344 (apropos-internal "-mode$" 'commandp)) 6442 (apropos-internal "-mode$" 'commandp))
6345 nil t)))) 6443 nil t))))
6346 (pop-to-buffer (make-indirect-buffer (current-buffer) buffer-name)) 6444 (pop-to-buffer (make-indirect-buffer (current-buffer) buffer-name))
6347 (funcall mode) 6445 (funcall mode)
6348 (narrow-to-region (point) (point)) 6446 (narrow-to-region (point) (point))
6349 (shrink-window-if-larger-than-buffer))) 6447 (shrink-window-if-larger-than-buffer)))
6350 6448
6351;;; Message catalog 6449;;; Message catalog
6352 6450
6353(defun erc-make-message-variable-name (catalog entry) 6451(defun erc-make-message-variable-name (catalog entry)
6354 "Create a variable name corresponding to CATALOG's ENTRY." 6452 "Create a variable name corresponding to CATALOG's ENTRY."
6355 (intern (concat "erc-message-" 6453 (intern (concat "erc-message-"
6356 (symbol-name catalog) "-" (symbol-name entry)))) 6454 (symbol-name catalog) "-" (symbol-name entry))))
6357 6455
6358(defun erc-define-catalog-entry (catalog entry format-spec) 6456(defun erc-define-catalog-entry (catalog entry format-spec)
6359 "Set CATALOG's ENTRY to FORMAT-SPEC." 6457 "Set CATALOG's ENTRY to FORMAT-SPEC."
@@ -6495,18 +6593,18 @@ All windows are opened in the current frame."
6495This function is an example on what could be done with formatting 6593This function is an example on what could be done with formatting
6496functions." 6594functions."
6497 (let ((nick (cadr (memq ?n args))) 6595 (let ((nick (cadr (memq ?n args)))
6498 (user (cadr (memq ?u args))) 6596 (user (cadr (memq ?u args)))
6499 (host (cadr (memq ?h args))) 6597 (host (cadr (memq ?h args)))
6500 (channel (cadr (memq ?c args))) 6598 (channel (cadr (memq ?c args)))
6501 (reason (cadr (memq ?r args)))) 6599 (reason (cadr (memq ?r args))))
6502 (if (string= nick (erc-current-nick)) 6600 (if (string= nick (erc-current-nick))
6503 (format "You have left channel %s" channel) 6601 (format "You have left channel %s" channel)
6504 (format "%s (%s@%s) has left channel %s%s" 6602 (format "%s (%s@%s) has left channel %s%s"
6505 nick user host channel 6603 nick user host channel
6506 (if (not (string= reason "")) 6604 (if (not (string= reason ""))
6507 (format ": %s" 6605 (format ": %s"
6508 (erc-replace-regexp-in-string "%" "%%" reason)) 6606 (erc-replace-regexp-in-string "%" "%%" reason))
6509 ""))))) 6607 "")))))
6510 6608
6511 6609
6512(defvar erc-current-message-catalog 'english) 6610(defvar erc-current-message-catalog 'english)
@@ -6522,15 +6620,15 @@ english, catalog."
6522 (unless catalog (setq catalog erc-current-message-catalog)) 6620 (unless catalog (setq catalog erc-current-message-catalog))
6523 (let ((var (erc-make-message-variable-name catalog entry))) 6621 (let ((var (erc-make-message-variable-name catalog entry)))
6524 (if (boundp var) 6622 (if (boundp var)
6525 (symbol-value var) 6623 (symbol-value var)
6526 (when (boundp (erc-make-message-variable-name 'english entry)) 6624 (when (boundp (erc-make-message-variable-name 'english entry))
6527 (symbol-value (erc-make-message-variable-name 'english entry)))))) 6625 (symbol-value (erc-make-message-variable-name 'english entry))))))
6528 6626
6529(defun erc-format-message (msg &rest args) 6627(defun erc-format-message (msg &rest args)
6530 "Format MSG according to ARGS. 6628 "Format MSG according to ARGS.
6531 6629
6532See also `format-spec'." 6630See also `format-spec'."
6533 (when (eq (logand (length args) 1) 1) ; oddp 6631 (when (eq (logand (length args) 1) 1) ; oddp
6534 (error "Obscure usage of this function appeared")) 6632 (error "Obscure usage of this function appeared"))
6535 (let ((entry (erc-retrieve-catalog-entry msg))) 6633 (let ((entry (erc-retrieve-catalog-entry msg)))
6536 (when (not entry) 6634 (when (not entry)
@@ -6591,8 +6689,8 @@ This function should be on `erc-kill-channel-hook'."
6591 (when (erc-server-process-alive) 6689 (when (erc-server-process-alive)
6592 (let ((tgt (erc-default-target))) 6690 (let ((tgt (erc-default-target)))
6593 (erc-server-send (format "PART %s :%s" tgt 6691 (erc-server-send (format "PART %s :%s" tgt
6594 (funcall erc-part-reason nil)) 6692 (funcall erc-part-reason nil))
6595 nil tgt)))) 6693 nil tgt))))
6596 6694
6597;;; Dealing with `erc-parsed' 6695;;; Dealing with `erc-parsed'
6598 6696
@@ -6614,10 +6712,10 @@ This function should be on `erc-kill-channel-hook'."
6614(defun erc-get-parsed-vector-nick (vect) 6712(defun erc-get-parsed-vector-nick (vect)
6615 "Return nickname in the parsed vector VECT." 6713 "Return nickname in the parsed vector VECT."
6616 (let* ((untreated-nick (and vect (erc-response.sender vect))) 6714 (let* ((untreated-nick (and vect (erc-response.sender vect)))
6617 (maybe-nick (when untreated-nick 6715 (maybe-nick (when untreated-nick
6618 (car (split-string untreated-nick "!"))))) 6716 (car (split-string untreated-nick "!")))))
6619 (when (and (not (null maybe-nick)) 6717 (when (and (not (null maybe-nick))
6620 (erc-is-valid-nick-p maybe-nick)) 6718 (erc-is-valid-nick-p maybe-nick))
6621 untreated-nick))) 6719 untreated-nick)))
6622 6720
6623(defun erc-get-parsed-vector-type (vect) 6721(defun erc-get-parsed-vector-type (vect)
@@ -6634,18 +6732,18 @@ This function should be on `erc-kill-channel-hook'."
6634If ERC is already connected to HOST:PORT, simply /join CHANNEL. 6732If ERC is already connected to HOST:PORT, simply /join CHANNEL.
6635Otherwise, connect to HOST:PORT as USER and /join CHANNEL." 6733Otherwise, connect to HOST:PORT as USER and /join CHANNEL."
6636 (let ((server-buffer 6734 (let ((server-buffer
6637 (car (erc-buffer-filter 6735 (car (erc-buffer-filter
6638 (lambda () 6736 (lambda ()
6639 (and (string-equal erc-session-server host) 6737 (and (string-equal erc-session-server host)
6640 (= erc-session-port port) 6738 (= erc-session-port port)
6641 (erc-open-server-buffer-p))))))) 6739 (erc-open-server-buffer-p)))))))
6642 (with-current-buffer (or server-buffer (current-buffer)) 6740 (with-current-buffer (or server-buffer (current-buffer))
6643 (if (and server-buffer channel) 6741 (if (and server-buffer channel)
6644 (erc-cmd-JOIN channel) 6742 (erc-cmd-JOIN channel)
6645 (erc-open host port (or user (erc-compute-nick)) (erc-compute-full-name) 6743 (erc-open host port (or user (erc-compute-nick)) (erc-compute-full-name)
6646 (not server-buffer) password nil channel 6744 (not server-buffer) password nil channel
6647 (when server-buffer 6745 (when server-buffer
6648 (get-buffer-process server-buffer))))))) 6746 (get-buffer-process server-buffer)))))))
6649 6747
6650(provide 'erc) 6748(provide 'erc)
6651 6749