aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Olson2007-09-08 03:07:09 +0000
committerMichael Olson2007-09-08 03:07:09 +0000
commit526dc846a10978763f1d5c883c0ec61fe43fb9bf (patch)
tree3bbde03d323d54c6fa8065eff28d1a25ca6502c2
parent9a4d5e0c05815ade4cf75523b54686594dcb9dfc (diff)
downloademacs-526dc846a10978763f1d5c883c0ec61fe43fb9bf.tar.gz
emacs-526dc846a10978763f1d5c883c0ec61fe43fb9bf.zip
Sync ERC 5.3 (devel) from upstream
-rw-r--r--doc/misc/ChangeLog5
-rw-r--r--doc/misc/erc.texi27
-rw-r--r--etc/ChangeLog5
-rw-r--r--etc/ERC-NEWS16
-rw-r--r--lisp/erc/erc-backend.el111
-rw-r--r--lisp/erc/erc-button.el2
-rw-r--r--lisp/erc/erc-compat.el13
-rw-r--r--lisp/erc/erc-goodies.el15
-rw-r--r--lisp/erc/erc-identd.el3
-rw-r--r--lisp/erc/erc-log.el67
-rw-r--r--lisp/erc/erc-sound.el10
-rw-r--r--lisp/erc/erc-stamp.el76
-rw-r--r--lisp/erc/erc-track.el97
-rw-r--r--lisp/erc/erc.el255
14 files changed, 512 insertions, 190 deletions
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 3d11858295d..3652fb73655 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,8 @@
12007-09-08 Michael Olson <mwolson@gnu.org>
2
3 * erc.texi (Copying): New section included from gpl.texi. This matches
4 the look of the upstream ERC manual.
5
12007-09-07 Jay Belanger <jay.p.belanger@gmail.com> 62007-09-07 Jay Belanger <jay.p.belanger@gmail.com>
2 7
3 * calc.texi (History and Acknowledgements): Adjust the 8 * calc.texi (History and Acknowledgements): Adjust the
diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index ee1029321d4..3ff8fce9471 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -68,6 +68,10 @@ and modified without restriction.
68* Advanced Usage:: Cool ways of using ERC. 68* Advanced Usage:: Cool ways of using ERC.
69* Getting Help and Reporting Bugs:: 69* Getting Help and Reporting Bugs::
70* History:: The history of ERC. 70* History:: The history of ERC.
71* Copying:: The GNU General Public License gives you
72 permission to redistribute ERC on
73 certain terms; it also explains that
74 there is no warranty.
71* GNU Free Documentation License:: The license for this documentation. 75* GNU Free Documentation License:: The license for this documentation.
72* Concept Index:: Search for terms. 76* Concept Index:: Search for terms.
73 77
@@ -900,7 +904,7 @@ stuff, to the current ERC buffer."
900@c previous chapter) 904@c previous chapter)
901 905
902This section has not yet been written. For now, the easiest way to 906This section has not yet been written. For now, the easiest way to
903check out the available option for ERC is to do 907check out the available options for ERC is to do
904@kbd{M-x customize-group erc RET}. 908@kbd{M-x customize-group erc RET}.
905 909
906 910
@@ -916,7 +920,7 @@ or if you have bugs to report, there are several places you can go.
916@itemize @bullet 920@itemize @bullet
917 921
918@item 922@item
919@uref{http://www.emacswiki.org/cgi-bin/wiki/EmacsIRCClient} is the 923@uref{http://www.emacswiki.org/cgi-bin/wiki/ERC} is the
920emacswiki.org page for ERC. Anyone may add tips, hints, or bug 924emacswiki.org page for ERC. Anyone may add tips, hints, or bug
921descriptions to it. 925descriptions to it.
922 926
@@ -929,14 +933,11 @@ The mailing lists are also available on Gmane.
929accessing the mailing lists, adding content to them, and searching them. 933accessing the mailing lists, adding content to them, and searching them.
930 934
931@enumerate 935@enumerate
932@item gmane.emacs.erc.announce 936@item gmane.emacs.erc.announce: Announcements
933Announcements
934 937
935@item gmane.emacs.erc.discuss 938@item gmane.emacs.erc.discuss: General discussion
936General discussion
937 939
938@item gmane.emacs.erc.cvs 940@item gmane.emacs.erc.cvs: Log messages for changes to the ERC source code
939Log messages for changes to the ERC source code
940 941
941@end enumerate 942@end enumerate
942 943
@@ -948,7 +949,7 @@ questions.
948@end itemize 949@end itemize
949 950
950 951
951@node History, GNU Free Documentation License, Getting Help and Reporting Bugs, Top 952@node History, Copying, Getting Help and Reporting Bugs, Top
952@comment node-name, next, previous, up 953@comment node-name, next, previous, up
953@chapter History 954@chapter History
954@cindex history, of ERC 955@cindex history, of ERC
@@ -1010,8 +1011,12 @@ our revision control system. Our mailing list address changed as well.
1010 1011
1011@end itemize 1012@end itemize
1012 1013
1013@node GNU Free Documentation License, Concept Index, History, Top 1014@node Copying, GNU Free Documentation License, History, Top
1014@appendix GNU Free Documentation License 1015@comment node-name, next, previous, up
1016@include gpl.texi
1017
1018@node GNU Free Documentation License, Concept Index, Copying, Top
1019@comment node-name, next, previous, up
1015@include doclicense.texi 1020@include doclicense.texi
1016 1021
1017@node Concept Index, , GNU Free Documentation License, Top 1022@node Concept Index, , GNU Free Documentation License, Top
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 8760888dcb6..0ec046d506c 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,8 @@
12007-09-08 Michael Olson <mwolson@gnu.org>
2
3 * ERC-NEWS: Update for changes to the development version of ERC
4 5.3.
5
12007-09-06 Glenn Morris <rgm@gnu.org> 62007-09-06 Glenn Morris <rgm@gnu.org>
2 7
3 * ctags.1, emacs.1, emacsclient.1, etags.1: Move from etc/ to 8 * ctags.1, emacs.1, emacsclient.1, etags.1: Move from etc/ to
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index f5bf1e89dde..409dcf03da6 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -3,6 +3,22 @@ ERC NEWS -*- outline -*-
3Copyright (C) 2006, 2007 Free Software Foundation, Inc. 3Copyright (C) 2006, 2007 Free Software Foundation, Inc.
4See the end of the file for license conditions. 4See the end of the file for license conditions.
5 5
6* Changes in ERC 5.3
7
8** New function `erc-tls' is to be used for connecting to a server via TLS.
9The function `erc-ssl' should never be used for that purpose any
10longer, which was the case with the version of ERC that is included
11with Emacs.
12
13** Changes and additions to modules
14
15*** Channel tracking (erc-track.el)
16
17If erc-track-position-in-mode-line is set to nil, the tracking
18information won't be shown in the mode line, which is a change
19from the previous behavior of showing it "After all other
20information".
21
6* Changes in ERC 5.2 22* Changes in ERC 5.2
7 23
8** M-x erc RET now starts ERC. 24** M-x erc RET now starts ERC.
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index 349f9137066..4e250490e9c 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -550,11 +550,12 @@ We will store server variables in the buffer given by BUFFER."
550(defun erc-server-reconnect () 550(defun erc-server-reconnect ()
551"Reestablish the current IRC connection. 551"Reestablish the current IRC connection.
552Make sure you are in an ERC buffer when running this." 552Make sure you are in an ERC buffer when running this."
553 (let ((server (erc-server-buffer))) 553 (let ((buffer (erc-server-buffer)))
554 (unless (and server 554 (unless (buffer-live-p buffer)
555 (buffer-live-p server)) 555 (if (eq major-mode 'erc-mode)
556 (error "Couldn't switch to server buffer")) 556 (setq buffer (current-buffer))
557 (with-current-buffer server 557 (error "Reconnect must be run from an ERC buffer")))
558 (with-current-buffer buffer
558 (erc-update-mode-line) 559 (erc-update-mode-line)
559 (erc-set-active-buffer (current-buffer)) 560 (erc-set-active-buffer (current-buffer))
560 (setq erc-server-last-sent-time 0) 561 (setq erc-server-last-sent-time 0)
@@ -609,39 +610,61 @@ EVENT is the message received from the closed connection process."
609 ;; open-network-stream-nowait error for connection refused 610 ;; open-network-stream-nowait error for connection refused
610 (not (string-match "^failed with code 111" event))))) 611 (not (string-match "^failed with code 111" event)))))
611 612
612(defun erc-process-sentinel-1 (event) 613(defun erc-process-sentinel-2 (event buffer)
614 "Called when `erc-process-sentinel-1' has detected an unexpected disconnect."
615 (if (not (buffer-live-p buffer))
616 (erc-update-mode-line)
617 (with-current-buffer buffer
618 (let ((reconnect-p (erc-server-reconnect-p event)))
619 (erc-display-message nil 'error (current-buffer)
620 (if reconnect-p 'disconnected
621 'disconnected-noreconnect))
622 (if (not reconnect-p)
623 ;; terminate, do not reconnect
624 (progn
625 (erc-display-message nil 'error (current-buffer)
626 'terminated ?e event)
627 ;; Update mode line indicators
628 (erc-update-mode-line)
629 (set-buffer-modified-p nil))
630 ;; reconnect
631 (condition-case err
632 (progn
633 (setq erc-server-reconnecting nil)
634 (erc-server-reconnect)
635 (setq erc-server-reconnect-count 0))
636 (error (when (buffer-live-p buffer)
637 (set-buffer buffer)
638 (if (integerp erc-server-reconnect-attempts)
639 (setq erc-server-reconnect-count
640 (1+ erc-server-reconnect-count))
641 (message "%s ... %s"
642 "Reconnecting until we succeed"
643 "kill the ERC server buffer to stop"))
644 (if (numberp erc-server-reconnect-timeout)
645 (run-at-time erc-server-reconnect-timeout nil
646 #'erc-process-sentinel-2
647 event buffer)
648 (error (concat "`erc-server-reconnect-timeout`"
649 " must be a number")))))))))))
650
651(defun erc-process-sentinel-1 (event buffer)
613 "Called when `erc-process-sentinel' has decided that we're disconnecting. 652 "Called when `erc-process-sentinel' has decided that we're disconnecting.
614Determine whether user has quit or whether erc has been terminated. 653Determine whether user has quit or whether erc has been terminated.
615Conditionally try to reconnect and take appropriate action." 654Conditionally try to reconnect and take appropriate action."
616 (if erc-server-quitting 655 (with-current-buffer buffer
617 ;; normal quit 656 (if erc-server-quitting
618 (progn 657 ;; normal quit
619 (erc-display-message nil 'error (current-buffer) 'finished) 658 (progn
620 (when erc-kill-server-buffer-on-quit 659 (erc-display-message nil 'error (current-buffer) 'finished)
660 ;; Update mode line indicators
661 (erc-update-mode-line)
662 ;; Kill server buffer if user wants it
621 (set-buffer-modified-p nil) 663 (set-buffer-modified-p nil)
622 (kill-buffer (current-buffer)))) 664 (when erc-kill-server-buffer-on-quit
623 ;; unexpected disconnect 665 (kill-buffer (current-buffer))))
624 (let ((again t)) 666 ;; unexpected disconnect
625 (while again 667 (erc-process-sentinel-2 event buffer))))
626 (setq again nil)
627 (erc-display-message nil 'error (current-buffer)
628 (if (erc-server-reconnect-p event)
629 'disconnected
630 'disconnected-noreconnect))
631 (if (erc-server-reconnect-p event)
632 (condition-case err
633 (progn
634 (setq erc-server-reconnecting nil)
635 (erc-server-reconnect)
636 (setq erc-server-reconnect-count 0))
637 (error (when (integerp erc-server-reconnect-attempts)
638 (setq erc-server-reconnect-count
639 (1+ erc-server-reconnect-count))
640 (sit-for erc-server-reconnect-timeout)
641 (setq again t))))
642 ;; terminate, do not reconnect
643 (erc-display-message nil 'error (current-buffer)
644 'terminated ?e event))))))
645 668
646(defun erc-process-sentinel (cproc event) 669(defun erc-process-sentinel (cproc event)
647 "Sentinel function for ERC process." 670 "Sentinel function for ERC process."
@@ -668,12 +691,7 @@ Conditionally try to reconnect and take appropriate action."
668 (delete-region (point) (point-max)) 691 (delete-region (point) (point-max))
669 ;; Decide what to do with the buffer 692 ;; Decide what to do with the buffer
670 ;; Restart if disconnected 693 ;; Restart if disconnected
671 (erc-process-sentinel-1 event) 694 (erc-process-sentinel-1 event buf)))))
672 ;; Make sure we don't write to the buffer if it has been
673 ;; killed
674 (when (buffer-live-p buf)
675 (erc-update-mode-line)
676 (set-buffer-modified-p nil))))))
677 695
678;;;; Sending messages 696;;;; Sending messages
679 697
@@ -1054,8 +1072,11 @@ Would expand to:
1054 \"Some non-generic variable documentation. 1072 \"Some non-generic variable documentation.
1055 1073
1056 Hook called upon receiving a WHOIS server response. 1074 Hook called upon receiving a WHOIS server response.
1075
1057 Each function is called with two arguments, the process associated 1076 Each function is called with two arguments, the process associated
1058 with the response and the parsed response. 1077 with the response and the parsed response. If the function returns
1078 non-nil, stop processing the hook. Otherwise, continue.
1079
1059 See also `erc-server-311'.\") 1080 See also `erc-server-311'.\")
1060 1081
1061 (defalias 'erc-server-WI 'erc-server-311) 1082 (defalias 'erc-server-WI 'erc-server-311)
@@ -1064,7 +1085,9 @@ Would expand to:
1064 1085
1065 Hook called upon receiving a WI server response. 1086 Hook called upon receiving a WI server response.
1066 Each function is called with two arguments, the process associated 1087 Each function is called with two arguments, the process associated
1067 with the response and the parsed response. 1088 with the response and the parsed response. If the function returns
1089 non-nil, stop processing the hook. Otherwise, continue.
1090
1068 See also `erc-server-311'.\")) 1091 See also `erc-server-311'.\"))
1069 1092
1070\(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)" 1093\(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)"
@@ -1078,7 +1101,9 @@ Would expand to:
1078 (fn-name (intern (format "erc-server-%s" name))) 1101 (fn-name (intern (format "erc-server-%s" name)))
1079 (hook-doc (format "%sHook called upon receiving a %%s server response. 1102 (hook-doc (format "%sHook called upon receiving a %%s server response.
1080Each function is called with two arguments, the process associated 1103Each function is called with two arguments, the process associated
1081with the response and the parsed response. 1104with the response and the parsed response. If the function returns
1105non-nil, stop processing the hook. Otherwise, continue.
1106
1082See also `%s'." 1107See also `%s'."
1083 (if extra-var-doc 1108 (if extra-var-doc
1084 (concat extra-var-doc "\n\n") 1109 (concat extra-var-doc "\n\n")
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 35a20d5279f..81c604d0538 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -99,7 +99,7 @@ above them."
99 (concat "\\(www\\.\\|\\(s?https?\\|" 99 (concat "\\(www\\.\\|\\(s?https?\\|"
100 "ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\)" 100 "ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\)"
101 "\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?" 101 "\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?"
102 "[-a-zA-Z0-9_=!?#$@~`%&*+\\/:;.,]+[-a-zA-Z0-9_=#$@~`%&*+\\/]") 102 "[-a-zA-Z0-9_=!?#$@~`%&*+\\/:;.,()]+[-a-zA-Z0-9_=#$@~`%&*+\\/()]")
103 "Regular expression that matches URLs." 103 "Regular expression that matches URLs."
104 :group 'erc-button 104 :group 'erc-button
105 :type 'regexp) 105 :type 'regexp)
diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el
index 8be3bed1a78..47bdd94ade2 100644
--- a/lisp/erc/erc-compat.el
+++ b/lisp/erc/erc-compat.el
@@ -56,6 +56,18 @@ See `erc-encoding-coding-alist'."
56 (format-time-string "%Y-%m-%d" emacs-build-time)) 56 (format-time-string "%Y-%m-%d" emacs-build-time))
57 "Time at which Emacs was dumped out.") 57 "Time at which Emacs was dumped out.")
58 58
59;; Emacs 21 and XEmacs do not have user-emacs-directory, but XEmacs
60;; has user-init-directory.
61(defvar erc-user-emacs-directory
62 (cond ((boundp 'user-emacs-directory)
63 user-emacs-directory)
64 ((boundp 'user-init-directory)
65 user-init-directory)
66 (t "~/.emacs.d/"))
67 "Directory beneath which additional per-user Emacs-specific files
68are placed.
69Note that this should end with a directory separator.")
70
59;; XEmacs' `replace-match' does not replace matching subexpressions in strings. 71;; XEmacs' `replace-match' does not replace matching subexpressions in strings.
60(defun erc-replace-match-subexpression-in-string 72(defun erc-replace-match-subexpression-in-string
61 (newtext string match subexp start &optional fixedcase literal) 73 (newtext string match subexp start &optional fixedcase literal)
@@ -68,6 +80,7 @@ See `replace-match' for explanations of FIXEDCASE and LITERAL."
68 (replace-match newtext fixedcase literal string)) 80 (replace-match newtext fixedcase literal string))
69 (t (replace-match newtext fixedcase literal string subexp)))) 81 (t (replace-match newtext fixedcase literal string subexp))))
70 82
83(defalias 'erc-with-selected-window 'with-selected-window)
71(defalias 'erc-cancel-timer 'cancel-timer) 84(defalias 'erc-cancel-timer 'cancel-timer)
72(defalias 'erc-make-obsolete 'make-obsolete) 85(defalias 'erc-make-obsolete 'make-obsolete)
73(defalias 'erc-make-obsolete-variable 'make-obsolete-variable) 86(defalias 'erc-make-obsolete-variable 'make-obsolete-variable)
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 49a04513733..9131ce68282 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -84,8 +84,7 @@ DISPLAY-START is ignored."
84 ;; works, but it solves the problem, and has no negative side effects. 84 ;; works, but it solves the problem, and has no negative side effects.
85 ;; (Fran Litterio, 2003/01/07) 85 ;; (Fran Litterio, 2003/01/07)
86 (let ((resize-mini-windows nil)) 86 (let ((resize-mini-windows nil))
87 (save-selected-window 87 (erc-with-selected-window window
88 (select-window window)
89 (save-restriction 88 (save-restriction
90 (widen) 89 (widen)
91 (when (and erc-insert-marker 90 (when (and erc-insert-marker
@@ -282,10 +281,8 @@ The value `erc-interpret-controls-p' must also be t for this to work."
282 "Fetches the right face for background color N (0-15)." 281 "Fetches the right face for background color N (0-15)."
283 (if (stringp n) (setq n (string-to-number n))) 282 (if (stringp n) (setq n (string-to-number n)))
284 (if (not (numberp n)) 283 (if (not (numberp n))
285 (progn 284 (prog1 'default
286 (message "erc-get-bg-color-face: n is NaN: %S" n) 285 (erc-error "erc-get-bg-color-face: n is NaN: %S" n))
287 (beep)
288 'default)
289 (when (> n 16) 286 (when (> n 16)
290 (erc-log (format " Wrong color: %s" n)) 287 (erc-log (format " Wrong color: %s" n))
291 (setq n (mod n 16))) 288 (setq n (mod n 16)))
@@ -298,10 +295,8 @@ The value `erc-interpret-controls-p' must also be t for this to work."
298 "Fetches the right face for foreground color N (0-15)." 295 "Fetches the right face for foreground color N (0-15)."
299 (if (stringp n) (setq n (string-to-number n))) 296 (if (stringp n) (setq n (string-to-number n)))
300 (if (not (numberp n)) 297 (if (not (numberp n))
301 (progn 298 (prog1 'default
302 (message "erc-get-fg-color-face: n is NaN: %S" n) 299 (erc-error "erc-get-fg-color-face: n is NaN: %S" n))
303 (beep)
304 'default)
305 (when (> n 16) 300 (when (> n 16)
306 (erc-log (format " Wrong color: %s" n)) 301 (erc-log (format " Wrong color: %s" n))
307 (setq n (mod n 16))) 302 (setq n (mod n 16)))
diff --git a/lisp/erc/erc-identd.el b/lisp/erc/erc-identd.el
index 4b72ee171b3..db933094e19 100644
--- a/lisp/erc/erc-identd.el
+++ b/lisp/erc/erc-identd.el
@@ -74,7 +74,8 @@ This can be either a string or a number."
74 (format "%s, %s : USERID : %s : %s\n" 74 (format "%s, %s : USERID : %s : %s\n"
75 port-on-server port-on-client 75 port-on-server port-on-client
76 system-type (user-login-name))) 76 system-type (user-login-name)))
77 (process-send-eof erc-identd-process))))) 77 (stop-process erc-identd-process)
78 (delete-process proc)))))
78 79
79;;;###autoload 80;;;###autoload
80(defun erc-identd-start (&optional port) 81(defun erc-identd-start (&optional port)
diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el
index 88132afae0c..856f1dca89e 100644
--- a/lisp/erc/erc-log.el
+++ b/lisp/erc/erc-log.el
@@ -31,17 +31,26 @@
31 31
32;; Quick start: 32;; Quick start:
33;; 33;;
34;; (setq erc-enable-logging t) 34;; (require 'erc-log)
35;; (setq erc-log-channels-directory "/path/to/logfiles") ; must be writable 35;; (setq erc-log-channels-directory "/path/to/logfiles") ; must be writable
36;; (erc-log-enable)
36;; 37;;
37;; There are two ways to setup logging. The first will write to the log files 38;; Or:
38;; on each incoming or outgoing line - this may not be optimal on a laptop
39;; HDD. To do this, M-x customize-variable erc-modules, and add "log".
40;; 39;;
41;; The second method will save buffers on /part, /quit, or killing the 40;; M-x customize-variable erc-modules, and add "log".
42;; channel buffer. To do this, add the following to your .emacs:
43;; 41;;
44;; (require 'erc-log) 42;; There are two ways to setup logging. The first (default) method
43;; will save buffers on /part, /quit, or killing the channel
44;; buffer.
45;;
46;; The second will write to the log files on each incoming or outgoing
47;; line - this may not be optimal on a laptop HDD. To use this
48;; method, add the following to the above instructions.
49;;
50;; (setq erc-save-buffer-on-part nil
51;; erc-save-queries-on-quit nil
52;; erc-log-write-after-send t
53;; erc-log-write-after-insert t)
45;; 54;;
46;; If you only want to save logs for some buffers, customise the 55;; If you only want to save logs for some buffers, customise the
47;; variable `erc-enable-logging'. 56;; variable `erc-enable-logging'.
@@ -99,15 +108,19 @@ The function must take five arguments: BUFFER, TARGET, NICK, SERVER and PORT.
99BUFFER is the buffer to be saved, 108BUFFER is the buffer to be saved,
100TARGET is the name of the channel, or the target of the query, 109TARGET is the name of the channel, or the target of the query,
101NICK is the current nick, 110NICK is the current nick,
102SERVER and PORT are the parameters used to connect BUFFERs 111SERVER and PORT are the parameters that were used to connect to BUFFERs
103`erc-server-process'." 112`erc-server-process'.
113
114If you want to write logs into different directories, make a
115custom function which returns the directory part and set
116`erc-log-channels-directory' to its name."
104 :group 'erc-log 117 :group 'erc-log
105 :type '(choice (const :tag "Long style" erc-generate-log-file-name-long) 118 :type '(choice (const :tag "Long style" erc-generate-log-file-name-long)
106 (const :tag "Long, but with network name rather than server" 119 (const :tag "Long, but with network name rather than server"
107 erc-generate-log-file-name-network) 120 erc-generate-log-file-name-network)
108 (const :tag "Short" erc-generate-log-file-name-short) 121 (const :tag "Short" erc-generate-log-file-name-short)
109 (const :tag "With date" erc-generate-log-file-name-with-date) 122 (const :tag "With date" erc-generate-log-file-name-with-date)
110 (symbol :tag "Other function"))) 123 (function :tag "Other function")))
111 124
112(defcustom erc-truncate-buffer-on-save nil 125(defcustom erc-truncate-buffer-on-save nil
113 "Truncate any ERC (channel, query, server) buffer when it is saved." 126 "Truncate any ERC (channel, query, server) buffer when it is saved."
@@ -134,10 +147,16 @@ Log files are stored in `erc-log-channels-directory'."
134 "The directory to place log files for channels. 147 "The directory to place log files for channels.
135Leave blank to disable logging. If not nil, all the channel 148Leave blank to disable logging. If not nil, all the channel
136buffers are logged in separate files in that directory. The 149buffers are logged in separate files in that directory. The
137directory should not end with a trailing slash." 150directory should not end with a trailing slash.
151
152If this is the name of a function, the function will be called
153with the buffer, target, nick, server, and port arguments. See
154`erc-generate-log-file-name-function' for a description of these
155arguments."
138 :group 'erc-log 156 :group 'erc-log
139 :type '(choice directory 157 :type '(choice directory
140 (const nil))) 158 (function "Function")
159 (const :tag "Disable logging" nil)))
141 160
142(defcustom erc-log-insert-log-on-open nil 161(defcustom erc-log-insert-log-on-open nil
143 "*Insert log file contents into the buffer if a log file exists." 162 "*Insert log file contents into the buffer if a log file exists."
@@ -297,7 +316,8 @@ Logging is enabled if `erc-log-channels-directory' is non-nil, the directory
297is writeable (it will be created as necessary) and 316is writeable (it will be created as necessary) and
298`erc-enable-logging' returns a non-nil value." 317`erc-enable-logging' returns a non-nil value."
299 (and erc-log-channels-directory 318 (and erc-log-channels-directory
300 (erc-directory-writable-p erc-log-channels-directory) 319 (or (functionp erc-log-channels-directory)
320 (erc-directory-writable-p erc-log-channels-directory))
301 (if (functionp erc-enable-logging) 321 (if (functionp erc-enable-logging)
302 (funcall erc-enable-logging (or buffer (current-buffer))) 322 (funcall erc-enable-logging (or buffer (current-buffer)))
303 erc-enable-logging))) 323 erc-enable-logging)))
@@ -316,14 +336,19 @@ filename is downcased."
316If BUFFER is nil, the value of `current-buffer' is used. 336If BUFFER is nil, the value of `current-buffer' is used.
317This is determined by `erc-generate-log-file-name-function'. 337This is determined by `erc-generate-log-file-name-function'.
318The result is converted to lowercase, as IRC is case-insensitive" 338The result is converted to lowercase, as IRC is case-insensitive"
319 (expand-file-name 339 (unless buffer (setq buffer (current-buffer)))
320 (erc-log-standardize-name 340 (let ((target (or (buffer-name buffer) (erc-default-target)))
321 (funcall erc-generate-log-file-name-function 341 (nick (erc-current-nick))
322 (or buffer (current-buffer)) 342 (server erc-session-server)
323 (or (buffer-name buffer) (erc-default-target)) 343 (port erc-session-port))
324 (erc-current-nick) 344 (expand-file-name
325 erc-session-server erc-session-port)) 345 (erc-log-standardize-name
326 erc-log-channels-directory)) 346 (funcall erc-generate-log-file-name-function
347 buffer target nick server port))
348 (if (functionp erc-log-channels-directory)
349 (funcall erc-log-channels-directory
350 buffer target nick server port)
351 erc-log-channels-directory))))
327 352
328(defun erc-generate-log-file-name-with-date (buffer &rest ignore) 353(defun erc-generate-log-file-name-with-date (buffer &rest ignore)
329 "This function computes a short log file name. 354 "This function computes a short log file name.
diff --git a/lisp/erc/erc-sound.el b/lisp/erc/erc-sound.el
index 4d3d792b1b8..d02887a69dc 100644
--- a/lisp/erc/erc-sound.el
+++ b/lisp/erc/erc-sound.el
@@ -125,7 +125,7 @@ See also `play-sound-file'."
125 (if (and (not filepath) erc-default-sound) 125 (if (and (not filepath) erc-default-sound)
126 (setq filepath erc-default-sound)) 126 (setq filepath erc-default-sound))
127 (cond ((and filepath (file-exists-p filepath)) 127 (cond ((and filepath (file-exists-p filepath))
128 (play-sound-file filepath)) 128 (play-sound-file filepath))
129 (t (beep))) 129 (t (beep)))
130 (erc-log (format "Playing sound file %S" filepath)))) 130 (erc-log (format "Playing sound file %S" filepath))))
131 131
@@ -142,5 +142,11 @@ See also `play-sound-file'."
142 142
143(provide 'erc-sound) 143(provide 'erc-sound)
144 144
145;; arch-tag: 53657d1d-007f-4a20-91c1-588e71cf0cee
146;;; erc-sound.el ends here 145;;; erc-sound.el ends here
146;;
147;; Local Variables:
148;; indent-tabs-mode: t
149;; tab-width: 8
150;; End:
151
152;; arch-tag: 53657d1d-007f-4a20-91c1-588e71cf0cee
diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el
index d67dffeaede..3b7f5ba18f2 100644
--- a/lisp/erc/erc-stamp.el
+++ b/lisp/erc/erc-stamp.el
@@ -58,16 +58,48 @@ If nil, timestamping is turned off."
58 :type '(choice (const nil) 58 :type '(choice (const nil)
59 (string))) 59 (string)))
60 60
61(defcustom erc-insert-timestamp-function 'erc-insert-timestamp-right 61(defcustom erc-timestamp-format-left "\n[%a %b %e %Y]\n"
62 "*If set to a string, messages will be timestamped.
63This string is processed using `format-time-string'.
64Good examples are \"%T\" and \"%H:%M\".
65
66This timestamp is used for timestamps on the left side of the
67screen when `erc-insert-timestamp-function' is set to
68`erc-insert-timestamp-left-and-right'.
69
70If nil, timestamping is turned off."
71 :group 'erc-stamp
72 :type '(choice (const nil)
73 (string)))
74
75(defcustom erc-timestamp-format-right " [%H:%M]"
76 "*If set to a string, messages will be timestamped.
77This string is processed using `format-time-string'.
78Good examples are \"%T\" and \"%H:%M\".
79
80This timestamp is used for timestamps on the right side of the
81screen when `erc-insert-timestamp-function' is set to
82`erc-insert-timestamp-left-and-right'.
83
84If nil, timestamping is turned off."
85 :group 'erc-stamp
86 :type '(choice (const nil)
87 (string)))
88
89(defcustom erc-insert-timestamp-function 'erc-insert-timestamp-left-and-right
62 "*Function to use to insert timestamps. 90 "*Function to use to insert timestamps.
63 91
64It takes a single argument STRING which is the final string 92It takes a single argument STRING which is the final string
65which all text-properties already appended. This function only cares about 93which all text-properties already appended. This function only cares about
66inserting this string at the right position. Narrowing is in effect 94inserting this string at the right position. Narrowing is in effect
67while it is called, so (point-min) and (point-max) determine the region to 95while it is called, so (point-min) and (point-max) determine the region to
68operate on." 96operate on.
97
98You will probably want to set
99`erc-insert-away-timestamp-function' to the same value."
69 :group 'erc-stamp 100 :group 'erc-stamp
70 :type '(choice (const :tag "Right" erc-insert-timestamp-right) 101 :type '(choice (const :tag "Both sides" erc-insert-timestamp-left-and-right)
102 (const :tag "Right" erc-insert-timestamp-right)
71 (const :tag "Left" erc-insert-timestamp-left) 103 (const :tag "Left" erc-insert-timestamp-left)
72 function)) 104 function))
73 105
@@ -82,12 +114,14 @@ If `erc-timestamp-format' is set, this will not be used."
82 :type '(choice (const nil) 114 :type '(choice (const nil)
83 (string))) 115 (string)))
84 116
85(defcustom erc-insert-away-timestamp-function 'erc-insert-timestamp-right 117(defcustom erc-insert-away-timestamp-function
118 'erc-insert-timestamp-left-and-right
86 "*Function to use to insert the away timestamp. 119 "*Function to use to insert the away timestamp.
87 120
88See `erc-insert-timestamp-function' for details." 121See `erc-insert-timestamp-function' for details."
89 :group 'erc-stamp 122 :group 'erc-stamp
90 :type '(choice (const :tag "Right" erc-insert-timestamp-right) 123 :type '(choice (const :tag "Both sides" erc-insert-timestamp-left-and-right)
124 (const :tag "Right" erc-insert-timestamp-right)
91 (const :tag "Left" erc-insert-timestamp-left) 125 (const :tag "Left" erc-insert-timestamp-left)
92 function)) 126 function))
93 127
@@ -160,6 +194,18 @@ or `erc-send-modify-hook'."
160 "Last timestamp inserted into the buffer.") 194 "Last timestamp inserted into the buffer.")
161(make-variable-buffer-local 'erc-timestamp-last-inserted) 195(make-variable-buffer-local 'erc-timestamp-last-inserted)
162 196
197(defvar erc-timestamp-last-inserted-left nil
198 "Last timestamp inserted into the left side of the buffer.
199This is used when `erc-insert-timestamp-function' is set to
200`erc-timestamp-left-and-right'")
201(make-variable-buffer-local 'erc-timestamp-last-inserted-left)
202
203(defvar erc-timestamp-last-inserted-right nil
204 "Last timestamp inserted into the right side of the buffer.
205This is used when `erc-insert-timestamp-function' is set to
206`erc-timestamp-left-and-right'")
207(make-variable-buffer-local 'erc-timestamp-last-inserted-right)
208
163(defcustom erc-timestamp-only-if-changed-flag t 209(defcustom erc-timestamp-only-if-changed-flag t
164 "*Insert timestamp only if its value changed since last insertion. 210 "*Insert timestamp only if its value changed since last insertion.
165If `erc-insert-timestamp-function' is `erc-insert-timestamp-left', a 211If `erc-insert-timestamp-function' is `erc-insert-timestamp-left', a
@@ -272,6 +318,26 @@ be printed just before the window-width."
272 (when erc-timestamp-intangible 318 (when erc-timestamp-intangible
273 (erc-put-text-property from (1+ (point)) 'intangible t))))) 319 (erc-put-text-property from (1+ (point)) 'intangible t)))))
274 320
321(defun erc-insert-timestamp-left-and-right (string)
322 "This is another function that can be assigned to
323`erc-insert-timestamp-function'. If the date is changed, it will
324print a blank line, the date, and another blank line. If the time is
325changed, it will then print it off to the right."
326 (let* ((ct (current-time))
327 (ts-left (erc-format-timestamp ct erc-timestamp-format-left))
328 (ts-right (erc-format-timestamp ct erc-timestamp-format-right)))
329 ;; insert left timestamp
330 (unless (string-equal ts-left erc-timestamp-last-inserted-left)
331 (goto-char (point-min))
332 (erc-put-text-property 0 (length ts-left) 'field 'erc-timestamp ts-left)
333 (insert ts-left)
334 (setq erc-timestamp-last-inserted-left ts-left))
335 ;; insert right timestamp
336 (let ((erc-timestamp-only-if-changed-flag t)
337 (erc-timestamp-last-inserted erc-timestamp-last-inserted-right))
338 (erc-insert-timestamp-right ts-right)
339 (setq erc-timestamp-last-inserted-right ts-right))))
340
275;; for testing: (setq erc-timestamp-only-if-changed-flag nil) 341;; for testing: (setq erc-timestamp-only-if-changed-flag nil)
276 342
277(defun erc-format-timestamp (time format) 343(defun erc-format-timestamp (time format)
diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el
index f72a5be1de1..5865257434e 100644
--- a/lisp/erc/erc-track.el
+++ b/lisp/erc/erc-track.el
@@ -95,6 +95,12 @@ Activity means that there was no user input in the last 10 seconds."
95 :group 'erc-track 95 :group 'erc-track
96 :type '(repeat string)) 96 :type '(repeat string))
97 97
98(defcustom erc-track-remove-disconnected-buffers nil
99 "*If true, remove buffers associated with a server that is
100disconnected from `erc-modified-channels-alist'."
101 :group 'erc-track
102 :type 'boolean)
103
98(defcustom erc-track-exclude-types '("NICK") 104(defcustom erc-track-exclude-types '("NICK")
99 "*List of message types to be ignored. 105 "*List of message types to be ignored.
100This list could look like '(\"JOIN\" \"PART\")." 106This list could look like '(\"JOIN\" \"PART\")."
@@ -151,6 +157,16 @@ If nil instead of a function, shortening is disabled."
151 :type '(choice (const :tag "Disabled") 157 :type '(choice (const :tag "Disabled")
152 function)) 158 function))
153 159
160(defcustom erc-track-list-changed-hook nil
161 "Hook that is run whenever the contents of
162`erc-modified-channels-alist' changes.
163
164This is useful for people that don't use the default mode-line
165notification but instead use a separate mechanism to provide
166notification of channel activity."
167 :group 'erc-track
168 :type 'hook)
169
154(defcustom erc-track-use-faces t 170(defcustom erc-track-use-faces t
155 "*Use faces in the mode-line. 171 "*Use faces in the mode-line.
156The faces used are the same as used for text in the buffers. 172The faces used are the same as used for text in the buffers.
@@ -192,12 +208,14 @@ Setting this variable only has effects in GNU Emacs versions above 21.3.
192Choices are: 208Choices are:
193'before-modes - add to the beginning of `mode-line-modes' 209'before-modes - add to the beginning of `mode-line-modes'
194'after-modes - add to the end of `mode-line-modes' 210'after-modes - add to the end of `mode-line-modes'
195 211t - add to the end of `global-mode-string'.
196Any other value means add to the end of `global-mode-string'." 212nil - don't add to mode line
213"
197 :group 'erc-track 214 :group 'erc-track
198 :type '(choice (const :tag "Just before mode information" before-modes) 215 :type '(choice (const :tag "Just before mode information" before-modes)
199 (const :tag "Just after mode information" after-modes) 216 (const :tag "Just after mode information" after-modes)
200 (const :tag "After all other information" nil)) 217 (const :tag "After all other information" t)
218 (const :tag "Don't display in mode line" nil))
201 :set (lambda (sym val) 219 :set (lambda (sym val)
202 (set sym val) 220 (set sym val)
203 (when (and (boundp 'erc-track-mode) 221 (when (and (boundp 'erc-track-mode)
@@ -263,12 +281,14 @@ when there are no more active channels."
263(defcustom erc-track-switch-direction 'oldest 281(defcustom erc-track-switch-direction 'oldest
264 "Direction `erc-track-switch-buffer' should switch. 282 "Direction `erc-track-switch-buffer' should switch.
265 283
284 importance - find buffer with the most important message
266 oldest - find oldest active buffer 285 oldest - find oldest active buffer
267 newest - find newest active buffer 286 newest - find newest active buffer
268 leastactive - find buffer with least unseen messages 287 leastactive - find buffer with least unseen messages
269 mostactive - find buffer with most unseen messages." 288 mostactive - find buffer with most unseen messages."
270 :group 'erc-track 289 :group 'erc-track
271 :type '(choice (const oldest) 290 :type '(choice (const importance)
291 (const oldest)
272 (const newest) 292 (const newest)
273 (const leastactive) 293 (const leastactive)
274 (const mostactive))) 294 (const mostactive)))
@@ -296,7 +316,7 @@ See `erc-track-position-in-mode-line' for possible values."
296 (boundp 'mode-line-modes)) 316 (boundp 'mode-line-modes))
297 (add-to-list 'mode-line-modes 317 (add-to-list 'mode-line-modes
298 '(t erc-modified-channels-object) t)) 318 '(t erc-modified-channels-object) t))
299 (t 319 ((eq position t)
300 (when (not global-mode-string) 320 (when (not global-mode-string)
301 (setq global-mode-string '(""))) ; Padding for mode-line wart 321 (setq global-mode-string '(""))) ; Padding for mode-line wart
302 (add-to-list 'global-mode-string 322 (add-to-list 'global-mode-string
@@ -644,14 +664,21 @@ only consider active buffers visible.")
644 (setq erc-buffer-activity (erc-current-time)) 664 (setq erc-buffer-activity (erc-current-time))
645 (erc-track-modified-channels)) 665 (erc-track-modified-channels))
646 666
667(defun erc-track-get-buffer-window (buffer frame-param)
668 (if (eq frame-param 'selected-visible)
669 (if (eq (frame-visible-p (selected-frame)) t)
670 (get-buffer-window buffer nil)
671 nil)
672 (get-buffer-window buffer frame-param)))
673
647(defun erc-buffer-visible (buffer) 674(defun erc-buffer-visible (buffer)
648 "Return non-nil when the buffer is visible." 675 "Return non-nil when the buffer is visible."
649 (if erc-track-when-inactive 676 (if erc-track-when-inactive
650 (when erc-buffer-activity; could be nil 677 (when erc-buffer-activity; could be nil
651 (and (get-buffer-window buffer erc-track-visibility) 678 (and (erc-track-get-buffer-window buffer erc-track-visibility)
652 (<= (erc-time-diff erc-buffer-activity (erc-current-time)) 679 (<= (erc-time-diff erc-buffer-activity (erc-current-time))
653 erc-buffer-activity-timeout))) 680 erc-buffer-activity-timeout)))
654 (get-buffer-window buffer erc-track-visibility))) 681 (erc-track-get-buffer-window buffer erc-track-visibility)))
655 682
656;;; Tracking the channel modifications 683;;; Tracking the channel modifications
657 684
@@ -668,18 +695,22 @@ called via `window-configuration-change-hook'.
668ARGS are ignored." 695ARGS are ignored."
669 (interactive) 696 (interactive)
670 (unless erc-modified-channels-update-inside 697 (unless erc-modified-channels-update-inside
671 (let ((erc-modified-channels-update-inside t)) 698 (let ((erc-modified-channels-update-inside t)
699 (removed-channel nil))
672 (mapcar (lambda (elt) 700 (mapcar (lambda (elt)
673 (let ((buffer (car elt))) 701 (let ((buffer (car elt)))
674 (when (or (not (bufferp buffer)) 702 (when (or (not (bufferp buffer))
675 (not (buffer-live-p buffer)) 703 (not (buffer-live-p buffer))
676 (erc-buffer-visible buffer) 704 (erc-buffer-visible buffer)
705 (and erc-track-remove-disconnected-buffers
677 (not (with-current-buffer buffer 706 (not (with-current-buffer buffer
678 erc-server-connected))) 707 erc-server-connected))))
708 (setq removed-channel t)
679 (erc-modified-channels-remove-buffer buffer)))) 709 (erc-modified-channels-remove-buffer buffer))))
680 erc-modified-channels-alist) 710 erc-modified-channels-alist)
711 (when removed-channel
681 (erc-modified-channels-display) 712 (erc-modified-channels-display)
682 (force-mode-line-update t)))) 713 (force-mode-line-update t)))))
683 714
684(defvar erc-track-mouse-face (if (featurep 'xemacs) 715(defvar erc-track-mouse-face (if (featurep 'xemacs)
685 'modeline-mousable 716 'modeline-mousable
@@ -729,10 +760,13 @@ If FACES are provided, color STRING with them."
729 "Set `erc-modified-channels-object' 760 "Set `erc-modified-channels-object'
730according to `erc-modified-channels-alist'. 761according to `erc-modified-channels-alist'.
731Use `erc-make-mode-line-buffer-name' to create buttons." 762Use `erc-make-mode-line-buffer-name' to create buttons."
732 (if (or 763 (cond ((or (eq 'mostactive erc-track-switch-direction)
733 (eq 'mostactive erc-track-switch-direction) 764 (eq 'leastactive erc-track-switch-direction))
734 (eq 'leastactive erc-track-switch-direction)) 765 (erc-track-sort-by-activest))
735 (erc-track-sort-by-activest)) 766 ((eq 'importance erc-track-switch-direction)
767 (erc-track-sort-by-importance)))
768 (run-hooks 'erc-track-list-changed-hook)
769 (unless (eq erc-track-position-in-mode-line nil)
736 (if (null erc-modified-channels-alist) 770 (if (null erc-modified-channels-alist)
737 (setq erc-modified-channels-object (erc-modified-channels-object nil)) 771 (setq erc-modified-channels-object (erc-modified-channels-object nil))
738 ;; erc-modified-channels-alist contains all the data we need. To 772 ;; erc-modified-channels-alist contains all the data we need. To
@@ -768,7 +802,7 @@ Use `erc-make-mode-line-buffer-name' to create buttons."
768 (when (featurep 'xemacs) 802 (when (featurep 'xemacs)
769 (erc-modified-channels-object nil)) 803 (erc-modified-channels-object nil))
770 (setq erc-modified-channels-object 804 (setq erc-modified-channels-object
771 (erc-modified-channels-object strings))))) 805 (erc-modified-channels-object strings))))))
772 806
773(defun erc-modified-channels-remove-buffer (buffer) 807(defun erc-modified-channels-remove-buffer (buffer)
774 "Remove BUFFER from `erc-modified-channels-alist'." 808 "Remove BUFFER from `erc-modified-channels-alist'."
@@ -802,8 +836,7 @@ is in `erc-mode'."
802 (if (and (not (erc-buffer-visible (current-buffer))) 836 (if (and (not (erc-buffer-visible (current-buffer)))
803 (not (member this-channel erc-track-exclude)) 837 (not (member this-channel erc-track-exclude))
804 (not (and erc-track-exclude-server-buffer 838 (not (and erc-track-exclude-server-buffer
805 (string= this-channel 839 (erc-server-buffer-p)))
806 (buffer-name (erc-server-buffer)))))
807 (not (erc-message-type-member 840 (not (erc-message-type-member
808 (or (erc-find-parsed-property) 841 (or (erc-find-parsed-property)
809 (point-min)) 842 (point-min))
@@ -847,10 +880,10 @@ is in `erc-mode'."
847 (erc-modified-channels-display))) 880 (erc-modified-channels-display)))
848 ;; Else if the active buffer is the current buffer, remove it 881 ;; Else if the active buffer is the current buffer, remove it
849 ;; from our list. 882 ;; from our list.
850 (when (or (erc-buffer-visible (current-buffer)) 883 (when (and (or (erc-buffer-visible (current-buffer))
851 (and this-channel 884 (and this-channel
852 (assq (current-buffer) erc-modified-channels-alist)
853 (member this-channel erc-track-exclude))) 885 (member this-channel erc-track-exclude)))
886 (assq (current-buffer) erc-modified-channels-alist))
854 ;; Remove it from mode-line if buffer is visible or 887 ;; Remove it from mode-line if buffer is visible or
855 ;; channel was added to erc-track-exclude recently. 888 ;; channel was added to erc-track-exclude recently.
856 (erc-modified-channels-remove-buffer (current-buffer)) 889 (erc-modified-channels-remove-buffer (current-buffer))
@@ -887,6 +920,29 @@ That means the number of unseen messages in a channel."
887 (sort erc-modified-channels-alist 920 (sort erc-modified-channels-alist
888 (lambda (a b) (> (nth 1 a) (nth 1 b)))))) 921 (lambda (a b) (> (nth 1 a) (nth 1 b))))))
889 922
923(defun erc-track-face-priority (face)
924 "Return a number indicating the priority of FACE in
925`erc-track-faces-priority-list'. Lower number means higher
926priority.
927
928If face is not in `erc-track-faces-priority-list', it will have a
929higher number than any other face in that list."
930 (let ((count 0))
931 (catch 'done
932 (dolist (item erc-track-faces-priority-list)
933 (if (eq item face)
934 (throw 'done t)
935 (setq count (1+ count)))))
936 count))
937
938(defun erc-track-sort-by-importance ()
939 "Sort erc-modified-channels-alist by importance.
940That means the position of the face in `erc-track-faces-priority-list'."
941 (setq erc-modified-channels-alist
942 (sort erc-modified-channels-alist
943 (lambda (a b) (< (erc-track-face-priority (cddr a))
944 (erc-track-face-priority (cddr b)))))))
945
890(defun erc-track-get-active-buffer (arg) 946(defun erc-track-get-active-buffer (arg)
891 "Return the buffer name of ARG in `erc-modified-channels-alist'. 947 "Return the buffer name of ARG in `erc-modified-channels-alist'.
892Negative arguments index in the opposite direction. This direction is 948Negative arguments index in the opposite direction. This direction is
@@ -898,7 +954,8 @@ relative to `erc-track-switch-direction'"
898 (oldest 'newest) 954 (oldest 'newest)
899 (newest 'oldest) 955 (newest 'oldest)
900 (mostactive 'leastactive) 956 (mostactive 'leastactive)
901 (leastactive 'mostactive))) 957 (leastactive 'mostactive)
958 (importance 'oldest)))
902 (setq arg (- arg))) 959 (setq arg (- arg)))
903 (setq offset (case dir 960 (setq offset (case dir
904 ((oldest leastactive) 961 ((oldest leastactive)
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 2ebadd1a5d6..2c5786adff3 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -66,7 +66,7 @@
66 66
67;;; Code: 67;;; Code:
68 68
69(defconst erc-version-string "Version 5.2" 69(defconst erc-version-string "Version 5.3 (devel)"
70 "ERC version. This is used by function `erc-version'.") 70 "ERC version. This is used by function `erc-version'.")
71 71
72(eval-when-compile (require 'cl)) 72(eval-when-compile (require 'cl))
@@ -836,8 +836,9 @@ See `erc-server-flood-margin' for other flood-related parameters.")
836;; Script parameters 836;; Script parameters
837 837
838(defcustom erc-startup-file-list 838(defcustom erc-startup-file-list
839 '("~/.emacs.d/.ercrc.el" "~/.emacs.d/.ercrc" 839 (list (concat erc-user-emacs-directory ".ercrc.el")
840 "~/.ercrc.el" "~/.ercrc" ".ercrc.el" ".ercrc") 840 (concat erc-user-emacs-directory ".ercrc")
841 "~/.ercrc.el" "~/.ercrc" ".ercrc.el" ".ercrc")
841 "List of files to try for a startup script. 842 "List of files to try for a startup script.
842The first existent and readable one will get executed. 843The first existent and readable one will get executed.
843 844
@@ -1460,7 +1461,7 @@ Turning on `erc-mode' runs the hook `erc-mode-hook'."
1460(defconst erc-default-server "irc.freenode.net" 1461(defconst erc-default-server "irc.freenode.net"
1461 "IRC server to use if it cannot be detected otherwise.") 1462 "IRC server to use if it cannot be detected otherwise.")
1462 1463
1463(defconst erc-default-port "6667" 1464(defconst erc-default-port 6667
1464 "IRC port to use if it cannot be detected otherwise.") 1465 "IRC port to use if it cannot be detected otherwise.")
1465 1466
1466(defcustom erc-join-buffer 'buffer 1467(defcustom erc-join-buffer 'buffer
@@ -1491,6 +1492,14 @@ This only has effect when `erc-join-buffer' is set to `frame'."
1491 :group 'erc-buffers 1492 :group 'erc-buffers
1492 :type 'boolean) 1493 :type 'boolean)
1493 1494
1495(defcustom erc-reuse-frames t
1496 "*Determines whether new frames are always created.
1497Non-nil means that a new frame is not created to display an ERC
1498buffer if there is already a window displaying it. This only has
1499effect when `erc-join-buffer' is set to `frame'."
1500 :group 'erc-buffers
1501 :type 'boolean)
1502
1494(defun erc-channel-p (channel) 1503(defun erc-channel-p (channel)
1495 "Return non-nil if CHANNEL seems to be an IRC channel name." 1504 "Return non-nil if CHANNEL seems to be an IRC channel name."
1496 (cond ((stringp channel) 1505 (cond ((stringp channel)
@@ -1888,14 +1897,16 @@ removed from the list will be disabled."
1888 ((eq erc-join-buffer 'bury) 1897 ((eq erc-join-buffer 'bury)
1889 nil) 1898 nil)
1890 ((eq erc-join-buffer 'frame) 1899 ((eq erc-join-buffer 'frame)
1891 (funcall '(lambda (frame) 1900 (when (or (not erc-reuse-frames)
1901 (not (get-buffer-window buffer t)))
1902 ((lambda (frame)
1892 (raise-frame frame) 1903 (raise-frame frame)
1893 (select-frame frame)) 1904 (select-frame frame))
1894 (make-frame (or erc-frame-alist 1905 (make-frame (or erc-frame-alist
1895 default-frame-alist))) 1906 default-frame-alist)))
1896 (switch-to-buffer buffer) 1907 (switch-to-buffer buffer)
1897 (when erc-frame-dedicated-flag 1908 (when erc-frame-dedicated-flag
1898 (set-window-dedicated-p (selected-window) t))) 1909 (set-window-dedicated-p (selected-window) t))))
1899 (t 1910 (t
1900 (if (active-minibuffer-window) 1911 (if (active-minibuffer-window)
1901 (display-buffer buffer) 1912 (display-buffer buffer)
@@ -2155,16 +2166,48 @@ Arguments are the same as for `erc'."
2155 "Open an SSL stream to an IRC server. 2166 "Open an SSL stream to an IRC server.
2156The process will be given the name NAME, its target buffer will be 2167The process will be given the name NAME, its target buffer will be
2157BUFFER. HOST and PORT specify the connection target." 2168BUFFER. HOST and PORT specify the connection target."
2158 (when (require 'tls) 2169 (when (condition-case nil
2159 (let ((proc (open-tls-stream name buffer host port))) 2170 (require 'ssl)
2171 (error (message "You don't have ssl.el. %s"
2172 "Try using `erc-tls' instead.")
2173 nil))
2174 (let ((proc (open-ssl-stream name buffer host port)))
2160 ;; Ugly hack, but it works for now. Problem is it is 2175 ;; Ugly hack, but it works for now. Problem is it is
2161 ;; very hard to detect when ssl is established, because s_client 2176 ;; very hard to detect when ssl is established, because s_client
2162 ;; doesn't give any CONNECTIONESTABLISHED kind of message, and 2177 ;; doesn't give any CONNECTIONESTABLISHED kind of message, and
2163 ;; most IRC servers send nothing and wait for you to identify. 2178 ;; most IRC servers send nothing and wait for you to identify.
2164 ;; Disabled when switching to tls.el -- jas 2179 (sit-for 5)
2165 ;(sit-for 5)
2166 proc))) 2180 proc)))
2167 2181
2182(defun erc-tls (&rest r)
2183 "Interactively select TLS connection parameters and run ERC.
2184Arguments are the same as for `erc'."
2185 (interactive (erc-select-read-args))
2186 (let ((erc-server-connect-function 'erc-open-tls-stream))
2187 (apply 'erc r)))
2188
2189(defun erc-open-tls-stream (name buffer host port)
2190 "Open an TLS stream to an IRC server.
2191The process will be given the name NAME, its target buffer will be
2192BUFFER. HOST and PORT specify the connection target."
2193 (when (condition-case nil
2194 (require 'tls)
2195 (error (message "You don't have tls.el. %s"
2196 "Try using `erc-ssl' instead.")
2197 nil))
2198 (open-tls-stream name buffer host port)))
2199
2200;;; Displaying error messages
2201
2202(defun erc-error (&rest args)
2203 "Pass ARGS to `format', and display the result as an error message.
2204If `debug-on-error' is set to non-nil, then throw a real error with this
2205message instead, to make debugging easier."
2206 (if debug-on-error
2207 (apply #'error args)
2208 (apply #'message args)
2209 (beep)))
2210
2168;;; Debugging the protocol 2211;;; Debugging the protocol
2169 2212
2170(defvar erc-debug-irc-protocol nil 2213(defvar erc-debug-irc-protocol nil
@@ -2456,6 +2499,14 @@ See also `erc-server-send'."
2456 (match-string 1 arglist) 2499 (match-string 1 arglist)
2457 arglist))) 2500 arglist)))
2458 2501
2502(defun erc-command-no-process-p (str)
2503 "Return non-nil if STR is an ERC command that can be run when the process
2504is not alive, nil otherwise."
2505 (let ((fun (erc-extract-command-from-line str)))
2506 (and fun
2507 (symbolp (car fun))
2508 (get (car fun) 'process-not-needed))))
2509
2459(defun erc-command-name (cmd) 2510(defun erc-command-name (cmd)
2460 "For CMD being the function name of a ERC command, something like 2511 "For CMD being the function name of a ERC command, something like
2461erc-cmd-FOO, this returns a string /FOO." 2512erc-cmd-FOO, this returns a string /FOO."
@@ -2565,6 +2616,7 @@ VALUE is computed by evaluating the rest of LINE in Lisp."
2565(defalias 'erc-cmd-VAR 'erc-cmd-SET) 2616(defalias 'erc-cmd-VAR 'erc-cmd-SET)
2566(defalias 'erc-cmd-VARIABLE 'erc-cmd-SET) 2617(defalias 'erc-cmd-VARIABLE 'erc-cmd-SET)
2567(put 'erc-cmd-SET 'do-not-parse-args t) 2618(put 'erc-cmd-SET 'do-not-parse-args t)
2619(put 'erc-cmd-SET 'process-not-needed t)
2568 2620
2569(defun erc-cmd-default (line) 2621(defun erc-cmd-default (line)
2570 "Fallback command. 2622 "Fallback command.
@@ -2623,6 +2675,7 @@ If no USER argument is specified, list the contents of `erc-ignore-list'."
2623 "Clear the window content." 2675 "Clear the window content."
2624 (recenter 0) 2676 (recenter 0)
2625 t) 2677 t)
2678(put 'erc-cmd-CLEAR 'process-not-needed t)
2626 2679
2627(defun erc-cmd-OPS () 2680(defun erc-cmd-OPS ()
2628 "Show the ops in the current channel." 2681 "Show the ops in the current channel."
@@ -2656,6 +2709,7 @@ If no USER argument is specified, list the contents of `erc-ignore-list'."
2656 (erc-display-message 2709 (erc-display-message
2657 nil 'notice 'active 'country-unknown ?d tld)) 2710 nil 'notice 'active 'country-unknown ?d tld))
2658 t)) 2711 t))
2712(put 'erc-cmd-COUNTRY 'process-not-needed t)
2659 2713
2660(defun erc-cmd-AWAY (line) 2714(defun erc-cmd-AWAY (line)
2661 "Mark the user as being away, the reason being indicated by LINE. 2715 "Mark the user as being away, the reason being indicated by LINE.
@@ -2736,6 +2790,7 @@ For a list of user commands (/join /part, ...):
2736 t)) 2790 t))
2737 2791
2738(defalias 'erc-cmd-H 'erc-cmd-HELP) 2792(defalias 'erc-cmd-H 'erc-cmd-HELP)
2793(put 'erc-cmd-HELP 'process-not-needed t)
2739 2794
2740(defun erc-cmd-JOIN (channel &optional key) 2795(defun erc-cmd-JOIN (channel &optional key)
2741 "Join the channel given in CHANNEL, optionally with KEY. 2796 "Join the channel given in CHANNEL, optionally with KEY.
@@ -2973,6 +3028,7 @@ the matching is case-sensitive."
2973 (occur line) 3028 (occur line)
2974 t) 3029 t)
2975(put 'erc-cmd-LASTLOG 'do-not-parse-args t) 3030(put 'erc-cmd-LASTLOG 'do-not-parse-args t)
3031(put 'erc-cmd-LASTLOG 'process-not-needed t)
2976 3032
2977(defun erc-send-message (line &optional force) 3033(defun erc-send-message (line &optional force)
2978 "Send LINE to the current channel or user and display it. 3034 "Send LINE to the current channel or user and display it.
@@ -3195,20 +3251,34 @@ the message given by REASON."
3195(defalias 'erc-cmd-EXIT 'erc-cmd-QUIT) 3251(defalias 'erc-cmd-EXIT 'erc-cmd-QUIT)
3196(defalias 'erc-cmd-SIGNOFF 'erc-cmd-QUIT) 3252(defalias 'erc-cmd-SIGNOFF 'erc-cmd-QUIT)
3197(put 'erc-cmd-QUIT 'do-not-parse-args t) 3253(put 'erc-cmd-QUIT 'do-not-parse-args t)
3254(put 'erc-cmd-QUIT 'process-not-needed t)
3198 3255
3199(defun erc-cmd-GQUIT (reason) 3256(defun erc-cmd-GQUIT (reason)
3200 "Disconnect from all servers at once with the same quit REASON." 3257 "Disconnect from all servers at once with the same quit REASON."
3201 (erc-with-all-buffers-of-server nil #'erc-open-server-buffer-p 3258 (erc-with-all-buffers-of-server nil #'erc-open-server-buffer-p
3202 (erc-cmd-QUIT reason))) 3259 (erc-cmd-QUIT reason))
3260 (when erc-kill-queries-on-quit
3261 ;; if the query buffers have not been killed within 4 seconds,
3262 ;; kill them
3263 (run-at-time
3264 4 nil
3265 (lambda ()
3266 (dolist (buffer (erc-buffer-list (lambda (buf)
3267 (not (erc-server-buffer-p buf)))))
3268 (kill-buffer buffer)))))
3269 t)
3203 3270
3204(defalias 'erc-cmd-GQ 'erc-cmd-GQUIT) 3271(defalias 'erc-cmd-GQ 'erc-cmd-GQUIT)
3205(put 'erc-cmd-GQUIT 'do-not-parse-args t) 3272(put 'erc-cmd-GQUIT 'do-not-parse-args t)
3273(put 'erc-cmd-GQUIT 'process-not-needed t)
3206 3274
3207(defun erc-cmd-RECONNECT () 3275(defun erc-cmd-RECONNECT ()
3208 "Try to reconnect to the current IRC server." 3276 "Try to reconnect to the current IRC server."
3209 (let ((buffer (or (erc-server-buffer) (current-buffer))) 3277 (let ((buffer (erc-server-buffer))
3210 (process nil)) 3278 (process nil))
3211 (with-current-buffer (if (bufferp buffer) buffer (current-buffer)) 3279 (unless (buffer-live-p buffer)
3280 (setq buffer (current-buffer)))
3281 (with-current-buffer buffer
3212 (setq erc-server-quitting nil) 3282 (setq erc-server-quitting nil)
3213 (setq erc-server-reconnecting t) 3283 (setq erc-server-reconnecting t)
3214 (setq erc-server-reconnect-count 0) 3284 (setq erc-server-reconnect-count 0)
@@ -3218,6 +3288,7 @@ the message given by REASON."
3218 (erc-server-reconnect)) 3288 (erc-server-reconnect))
3219 (setq erc-server-reconnecting nil))) 3289 (setq erc-server-reconnecting nil)))
3220 t) 3290 t)
3291(put 'erc-cmd-RECONNECT 'process-not-needed t)
3221 3292
3222(defun erc-cmd-SERVER (server) 3293(defun erc-cmd-SERVER (server)
3223 "Connect to SERVER, leaving existing connection intact." 3294 "Connect to SERVER, leaving existing connection intact."
@@ -3225,9 +3296,9 @@ the message given by REASON."
3225 (condition-case nil 3296 (condition-case nil
3226 (erc :server server :nick (erc-current-nick)) 3297 (erc :server server :nick (erc-current-nick))
3227 (error 3298 (error
3228 (message "Cannot find host %s." server) 3299 (erc-error "Cannot find host %s." server)))
3229 (beep)))
3230 t) 3300 t)
3301(put 'erc-cmd-SERVER 'process-not-needed t)
3231 3302
3232(eval-when-compile 3303(eval-when-compile
3233 (defvar motif-version-string) 3304 (defvar motif-version-string)
@@ -4411,33 +4482,65 @@ See also `erc-channel-begin-receiving-names'."
4411 erc-channel-users) 4482 erc-channel-users)
4412 (setq erc-channel-new-member-names nil)) 4483 (setq erc-channel-new-member-names nil))
4413 4484
4485(defun erc-parse-prefix ()
4486 "Return an alist of valid prefix character types and their representations.
4487Example: (operator) o => @, (voiced) v => +."
4488 (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer
4489 erc-server-parameters)))
4490 ;; provide a sane default
4491 "(ov)@+"))
4492 types chars)
4493 (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str)
4494 (setq types (match-string 1 str)
4495 chars (match-string 2 str))
4496 (let ((len (min (length types) (length chars)))
4497 (i 0)
4498 (alist nil))
4499 (while (< i len)
4500 (setq alist (cons (cons (elt types i) (elt chars i))
4501 alist))
4502 (setq i (1+ i)))
4503 alist))))
4504
4414(defun erc-channel-receive-names (names-string) 4505(defun erc-channel-receive-names (names-string)
4415 "This function is for internal use only. 4506 "This function is for internal use only.
4416 4507
4417Update `erc-channel-users' according to NAMES-STRING. 4508Update `erc-channel-users' according to NAMES-STRING.
4418NAMES-STRING is a string listing some of the names on the 4509NAMES-STRING is a string listing some of the names on the
4419channel." 4510channel."
4420 (let (names name op voice) 4511 (let (prefix op-ch voice-ch names name op voice)
4421 ;; We need to delete "" because in XEmacs, (split-string "a ") 4512 (setq prefix (erc-parse-prefix))
4422 ;; returns ("a" ""). 4513 (setq op-ch (cdr (assq ?o prefix))
4423 (setq names (delete "" (split-string names-string))) 4514 voice-ch (cdr (assq ?v prefix)))
4424 (let ((erc-channel-members-changed-hook nil)) 4515 ;; We need to delete "" because in XEmacs, (split-string "a ")
4425 (dolist (item names) 4516 ;; returns ("a" "").
4426 (cond ((string-match "^@\\(.*\\)$" item) 4517 (setq names (delete "" (split-string names-string)))
4427 (setq name (match-string 1 item) 4518 (let ((erc-channel-members-changed-hook nil))
4428 op 'on 4519 (dolist (item names)
4429 voice 'off)) 4520 (let ((updatep t)
4430 ((string-match "^+\\(.*\\)$" item) 4521 ch)
4431 (setq name (match-string 1 item) 4522 (if (rassq (elt item 0) prefix)
4432 op 'off 4523 (cond ((= (length item) 1)
4433 voice 'on)) 4524 (setq updatep nil))
4434 (t (setq name item 4525 ((eq (elt item 0) op-ch)
4435 op 'off 4526 (setq name (substring item 1)
4436 voice 'off))) 4527 op 'on
4437 (puthash (erc-downcase name) t 4528 voice 'off))
4438 erc-channel-new-member-names) 4529 ((eq (elt item 0) voice-ch)
4439 (erc-update-current-channel-member 4530 (setq name (substring item 1)
4440 name name t op voice))) 4531 op 'off
4532 voice 'on))
4533 (t (setq name (substring item 1)
4534 op 'off
4535 voice 'off)))
4536 (setq name item
4537 op 'off
4538 voice 'off))
4539 (when updatep
4540 (puthash (erc-downcase name) t
4541 erc-channel-new-member-names)
4542 (erc-update-current-channel-member
4543 name name t op voice)))))
4441 (run-hooks 'erc-channel-members-changed-hook))) 4544 (run-hooks 'erc-channel-members-changed-hook)))
4442 4545
4443(defcustom erc-channel-members-changed-hook nil 4546(defcustom erc-channel-members-changed-hook nil
@@ -4529,15 +4632,15 @@ See also: `erc-update-user' and `erc-update-channel-member'."
4529 (setq changed t) 4632 (setq changed t)
4530 (setf (erc-channel-user-op cuser) 4633 (setf (erc-channel-user-op cuser)
4531 (cond ((eq op 'on) t) 4634 (cond ((eq op 'on) t)
4532 ((eq op 'off) nil) 4635 ((eq op 'off) nil)
4533 (t op)))) 4636 (t op))))
4534 (when (and voice 4637 (when (and voice
4535 (not (eq (erc-channel-user-voice cuser) voice))) 4638 (not (eq (erc-channel-user-voice cuser) voice)))
4536 (setq changed t) 4639 (setq changed t)
4537 (setf (erc-channel-user-voice cuser) 4640 (setf (erc-channel-user-voice cuser)
4538 (cond ((eq voice 'on) t) 4641 (cond ((eq voice 'on) t)
4539 ((eq voice 'off) nil) 4642 ((eq voice 'off) nil)
4540 (t voice)))) 4643 (t voice))))
4541 (when update-message-time 4644 (when update-message-time
4542 (setf (erc-channel-user-last-message-time cuser) (current-time))) 4645 (setf (erc-channel-user-last-message-time cuser) (current-time)))
4543 (setq user-changed 4646 (setq user-changed
@@ -4559,11 +4662,11 @@ See also: `erc-update-user' and `erc-update-channel-member'."
4559 (erc-server-user-buffers user)))) 4662 (erc-server-user-buffers user))))
4560 (setq cuser (make-erc-channel-user 4663 (setq cuser (make-erc-channel-user
4561 :op (cond ((eq op 'on) t) 4664 :op (cond ((eq op 'on) t)
4562 ((eq op 'off) nil) 4665 ((eq op 'off) nil)
4563 (t op)) 4666 (t op))
4564 :voice (cond ((eq voice 'on) t) 4667 :voice (cond ((eq voice 'on) t)
4565 ((eq voice 'off) nil) 4668 ((eq voice 'off) nil)
4566 (t voice)) 4669 (t voice))
4567 :last-message-time 4670 :last-message-time
4568 (if update-message-time (current-time)))) 4671 (if update-message-time (current-time))))
4569 (puthash (erc-downcase nick) (cons user cuser) 4672 (puthash (erc-downcase nick) (cons user cuser)
@@ -4892,39 +4995,37 @@ Specifically, return the position of `erc-insert-marker'."
4892 (interactive) 4995 (interactive)
4893 (save-restriction 4996 (save-restriction
4894 (widen) 4997 (widen)
4895 (cond 4998 (if (< (point) (erc-beg-of-input-line))
4896 ((< (point) (erc-beg-of-input-line)) 4999 (erc-error "Point is not in the input area")
4897 (message "Point is not in the input area")
4898 (beep))
4899 ((not (erc-server-buffer-live-p))
4900 (message "ERC: No process running")
4901 (beep))
4902 (t
4903 (erc-set-active-buffer (current-buffer))
4904 (let ((inhibit-read-only t) 5000 (let ((inhibit-read-only t)
4905 (str (erc-user-input)) 5001 (str (erc-user-input))
4906 (old-buf (current-buffer))) 5002 (old-buf (current-buffer)))
4907 5003 (if (and (not (erc-server-buffer-live-p))
4908 ;; Kill the input and the prompt 5004 (not (erc-command-no-process-p str)))
4909 (delete-region (erc-beg-of-input-line) 5005 (erc-error "ERC: No process running")
4910 (erc-end-of-input-line)) 5006 (erc-set-active-buffer (current-buffer))
4911 5007
4912 (unwind-protect 5008 ;; Kill the input and the prompt
4913 (erc-send-input str) 5009 (delete-region (erc-beg-of-input-line)
4914 ;; Fix the buffer if the command didn't kill it 5010 (erc-end-of-input-line))
4915 (when (buffer-live-p old-buf) 5011
4916 (with-current-buffer old-buf 5012 (unwind-protect
4917 (save-restriction 5013 (erc-send-input str)
4918 (widen) 5014 ;; Fix the buffer if the command didn't kill it
4919 (goto-char (point-max)) 5015 (when (buffer-live-p old-buf)
4920 (set-marker (process-mark erc-server-process) (point)) 5016 (with-current-buffer old-buf
4921 (set-marker erc-insert-marker (point)) 5017 (save-restriction
4922 (let ((buffer-modified (buffer-modified-p))) 5018 (widen)
4923 (erc-display-prompt) 5019 (goto-char (point-max))
4924 (set-buffer-modified-p buffer-modified)))))) 5020 (when (processp erc-server-process)
4925 5021 (set-marker (process-mark erc-server-process) (point)))
4926 ;; Only when last hook has been run... 5022 (set-marker erc-insert-marker (point))
4927 (run-hook-with-args 'erc-send-completed-hook str)))))) 5023 (let ((buffer-modified (buffer-modified-p)))
5024 (erc-display-prompt)
5025 (set-buffer-modified-p buffer-modified))))))
5026
5027 ;; Only when last hook has been run...
5028 (run-hook-with-args 'erc-send-completed-hook str))))))
4928 5029
4929(defun erc-user-input () 5030(defun erc-user-input ()
4930 "Return the input of the user in the current buffer." 5031 "Return the input of the user in the current buffer."
@@ -4985,7 +5086,8 @@ This returns non-nil only if we actually send anything."
4985 (erc-put-text-property beg (point) 5086 (erc-put-text-property beg (point)
4986 'face 'erc-command-indicator-face) 5087 'face 'erc-command-indicator-face)
4987 (insert "\n")) 5088 (insert "\n"))
4988 (set-marker (process-mark erc-server-process) (point)) 5089 (when (processp erc-server-process)
5090 (set-marker (process-mark erc-server-process) (point)))
4989 (set-marker erc-insert-marker (point)) 5091 (set-marker erc-insert-marker (point))
4990 (save-excursion 5092 (save-excursion
4991 (save-restriction 5093 (save-restriction
@@ -5004,7 +5106,8 @@ current position."
5004 (erc-put-text-property beg (point) 5106 (erc-put-text-property beg (point)
5005 'face 'erc-input-face)) 5107 'face 'erc-input-face))
5006 (insert "\n") 5108 (insert "\n")
5007 (set-marker (process-mark erc-server-process) (point)) 5109 (when (processp erc-server-process)
5110 (set-marker (process-mark erc-server-process) (point)))
5008 (set-marker erc-insert-marker (point)) 5111 (set-marker erc-insert-marker (point))
5009 (save-excursion 5112 (save-excursion
5010 (save-restriction 5113 (save-restriction