diff options
Diffstat (limited to 'lisp/erc/erc.el')
-rw-r--r-- | lisp/erc/erc.el | 153 |
1 files changed, 104 insertions, 49 deletions
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 7de2828b86d..927dce02d64 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1,7 +1,7 @@ ;; erc.el --- An Emacs Internet Relay Chat client ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -;; 2006 Free Software Foundation, Inc. +;; 2006, 2007 Free Software Foundation, Inc. ;; Author: Alexander L. Belikoff (alexander@belikoff.net) ;; Contributors: Sergey Berezin (sergey.berezin@cs.cmu.edu), @@ -74,7 +74,6 @@ (require 'pp) (require 'thingatpt) (require 'erc-compat) -(require 'erc-menu) (defvar erc-official-location "http://emacswiki.org/cgi-bin/wiki/ERC (mailing list: erc-discuss@gnu.org)" @@ -356,6 +355,17 @@ nicknames with erc-server-user struct instances.") (cdr (assq (aref s (match-beginning 0)) c))))) s)) +(defmacro erc-with-server-buffer (&rest body) + "Execute BODY in the current ERC server buffer. +If no server buffer exists, return nil." + (let ((buffer (make-symbol "buffer"))) + `(let ((,buffer (erc-server-buffer))) + (when (buffer-live-p ,buffer) + (with-current-buffer ,buffer + ,@body))))) +(put 'erc-with-server-buffer 'lisp-indent-function 0) +(put 'erc-with-server-buffer 'edebug-form-spec '(body)) + (defstruct (erc-server-user (:type vector) :named) ;; User data nickname host login full-name info @@ -782,6 +792,13 @@ set if some hacker is trying to flood you away." :group 'erc :type 'string) +(defcustom erc-system-name nil + "Use this as the name of your system. +If nil, ERC will call `system-name' to get this information." + :group 'erc + :type '(choice (const :tag "Default system name" nil) + string)) + (defcustom erc-ignore-list nil "*List of regexps matching user identifiers to ignore. @@ -1333,6 +1350,14 @@ If BUFFER is nil, the current buffer is used." (and (eq major-mode 'erc-mode) (null (erc-default-target))))) +(defun erc-open-server-buffer-p (&optional buffer) + "Return non-nil if argument BUFFER is an ERC server buffer that +has an open IRC process. + +If BUFFER is nil, the current buffer is used." + (and (erc-server-buffer-p) + (erc-server-process-alive))) + (defun erc-query-buffer-p (&optional buffer) "Return non-nil if BUFFER is an ERC query buffer. If BUFFER is nil, the current buffer is used." @@ -1672,21 +1697,22 @@ needs to be active for this function to work." (require 'iswitchb)) (let ((enabled iswitchb-mode)) (or enabled (iswitchb-mode 1)) - (let ((iswitchb-make-buflist-hook - (lambda () - (setq iswitchb-temp-buflist - (mapcar 'buffer-name - (erc-buffer-list - nil - (when arg erc-server-process))))))) - (switch-to-buffer - (iswitchb-read-buffer - "Switch-to: " - (if (boundp 'erc-modified-channels-alist) - (buffer-name (caar (last erc-modified-channels-alist))) - nil) - t))) - (or enabled (iswitchb-mode -1)))) + (unwind-protect + (let ((iswitchb-make-buflist-hook + (lambda () + (setq iswitchb-temp-buflist + (mapcar 'buffer-name + (erc-buffer-list + nil + (when arg erc-server-process))))))) + (switch-to-buffer + (iswitchb-read-buffer + "Switch-to: " + (if (boundp 'erc-modified-channels-alist) + (buffer-name (caar (last erc-modified-channels-alist))) + nil) + t))) + (or enabled (iswitchb-mode -1))))) (defun erc-channel-list (proc) "Return a list of channel buffers. @@ -1763,7 +1789,7 @@ all channel buffers on all servers." (defcustom erc-modules '(netsplit fill button match track completion readonly ring autojoin noncommands irccontrols - stamp) + stamp menu) "A list of modules which ERC should enable. If you set the value of this without using `customize' remember to call \(erc-update-modules) after you change it. When using `customize', modules @@ -1790,17 +1816,21 @@ removed from the list will be disabled." (const :tag "Set away status automatically" autoaway) (const :tag "Join channels automatically" autojoin) (const :tag "Buttonize URLs, nicknames, and other text" button) + (const + :tag + "Mark unidentified users on freenode and other servers supporting CAPAB" + capab-identify) (const :tag "Wrap long lines" fill) (const :tag "Launch an identd server on port 8113" identd) (const :tag "Highlight or remove IRC control characters" irccontrols) (const :tag "Save buffers in logs" log) (const :tag "Highlight pals, fools, and other keywords" match) + (const :tag "Display a menu in ERC buffers" menu) (const :tag "Detect netsplits" netsplit) (const :tag "Don't display non-IRC commands after evaluation" noncommands) - (const :tag - "Notify when the online status of certain users changes" + (const :tag "Notify when the online status of certain users changes" notify) (const :tag "Complete nicknames and commands (programmable)" completion) @@ -1830,6 +1860,8 @@ removed from the list will be disabled." (setq req (concat "erc-" (symbol-name mod))) (cond ;; yuck. perhaps we should bring the filenames into sync? + ((string= req "erc-capab-identify") + (setq req "erc-capab")) ((string= req "erc-completion") (setq req "erc-pcomplete")) ((string= req "erc-pcomplete") @@ -1888,10 +1920,12 @@ Returns the buffer for the given server or channel." (connected-p (unless connect erc-server-connected)) (buffer (erc-get-buffer-create server port channel)) (old-buffer (current-buffer)) - (old-point (point)) + old-point continued-session) + (when connect (run-hook-with-args 'erc-before-connect server port nick)) (erc-update-modules) (set-buffer buffer) + (setq old-point (point)) (erc-mode) (setq erc-server-announced-name server-announced-name) (setq erc-server-connected connected-p) @@ -2102,8 +2136,6 @@ server and full-name will be set to those values, whereas `erc-compute-port', `erc-compute-nick' and `erc-compute-full-name' will be invoked for the values of the other parameters." (interactive (erc-select-read-args)) - - (run-hook-with-args 'erc-before-connect server port nick) (erc-open server port nick full-name t password)) (defalias 'erc-select 'erc) @@ -3165,6 +3197,12 @@ the message given by REASON." (defalias 'erc-cmd-GQ 'erc-cmd-GQUIT) (put 'erc-cmd-GQUIT 'do-not-parse-args t) +(defun erc-cmd-RECONNECT () + "Try to reconnect to the current IRC server." + (setq erc-server-reconnect-count 0) + (erc-server-reconnect) + t) + (defun erc-cmd-SERVER (server) "Connect to SERVER, leaving existing connection intact." (erc-log (format "cmd: SERVER: %s" server)) @@ -4292,8 +4330,10 @@ See also `erc-display-message'." nil) (defun erc-process-away (proc away-p) - ;; FIXME: This docstring is AWFUL -- Lawrence 2004-01-08 - "Process the user being away, or returning from an away break." + "Toggle the away status of the user depending on the value of AWAY-P. + +If nil, set the user as away. +If non-nil, return from being away." (let ((sessionbuf (process-buffer proc))) (when sessionbuf (with-current-buffer sessionbuf @@ -4873,6 +4913,9 @@ Specifically, return the position of `erc-insert-marker'." erc-input-marker (erc-end-of-input-line))) +(defvar erc-command-regexp "^/\\([A-Za-z]+\\)\\(\\s-+.*\\|\\s-*\\)$" + "Regular expression used for matching commands in ERC.") + (defun erc-send-input (input) "Treat INPUT as typed in by the user. It is assumed that the input and the prompt is already deleted. @@ -4894,7 +4937,7 @@ This returns non-nil only iff we actually send anything." (run-hook-with-args 'erc-send-pre-hook input) (when erc-send-this (if (or (string-match "\n" str) - (not (char-equal (aref str 0) ?/))) + (not (string-match erc-command-regexp str))) (mapc (lambda (line) (mapc @@ -4959,7 +5002,7 @@ current position." "Extract command and args from the input LINE. If no command was given, return nil. If command matches, return a list of the form: (command args) where both elements are strings." - (when (string-match "^/\\([A-Za-z]+\\)\\(\\s-+.*\\|\\s-*\\)$" line) + (when (string-match erc-command-regexp line) (let* ((cmd (erc-command-symbol (match-string 1 line))) ;; note: return is nil, we apply this simply for side effects (canon-defun (while (and cmd (symbolp (symbol-function cmd))) @@ -5398,7 +5441,7 @@ user input." (erc-log (format "login: nick: %s, user: %s %s %s :%s" (erc-current-nick) (user-login-name) - (system-name) + (or erc-system-name (system-name)) erc-session-server erc-session-user-full-name)) (if erc-session-password @@ -5647,6 +5690,7 @@ of `mode-line-buffer-identification'. The following characters are replaced: %a: String indicating away status or \"\" if you are not away +%l: The estimated lag time to the server %m: The modes of the channel %n: The current nick name %o: The topic of the channel @@ -5658,9 +5702,9 @@ The following characters are replaced: :group 'erc-mode-line-and-header :type 'string) -(defcustom erc-header-line-format "[IRC] %n on %t %m %o" +(defcustom erc-header-line-format "%n on %t (%m,%l) %o" "A string to be formatted and shown in the header-line in `erc-mode'. -Only used in Emacs 21. +Only used starting in Emacs 21. See `erc-mode-line-format' for which characters are can be used." :group 'erc-mode-line-and-header @@ -5750,33 +5794,37 @@ if `erc-away' is non-nil." ""))) (defun erc-format-channel-modes () - "Return the current channel's modes and the estimated lag." + "Return the current channel's modes." + (concat (apply 'concat + "+" erc-channel-modes) + (cond ((and erc-channel-user-limit erc-channel-key) + (if erc-show-channel-key-p + (format "lk %.0f %s" erc-channel-user-limit + erc-channel-key) + (format "kl %.0f" erc-channel-user-limit))) + (erc-channel-user-limit + ;; Emacs has no bignums + (format "l %.0f" erc-channel-user-limit)) + (erc-channel-key + (if erc-show-channel-key-p + (format "k %s" erc-channel-key) + "k")) + (t nil)))) + +(defun erc-format-lag-time () + "Return the estimated lag time to server, `erc-server-lag'." (let ((lag (when (erc-server-buffer-live-p) (with-current-buffer (process-buffer erc-server-process) erc-server-lag)))) - (concat (apply 'concat - "(+" erc-channel-modes) - (cond ((and erc-channel-user-limit erc-channel-key) - (if erc-show-channel-key-p - (format "lk %.0f %s" erc-channel-user-limit - erc-channel-key) - (format "kl %.0f" erc-channel-user-limit))) - (erc-channel-user-limit - ;; Emacs has no bignums - (format "l %.0f" erc-channel-user-limit)) - (erc-channel-key - (if erc-show-channel-key-p - (format "k %s" erc-channel-key) - "k")) - (t "")) - (if lag (format ",lag:%.0f" lag) "") - ")"))) + (cond (lag (format "lag:%.0f" lag)) + (t "")))) (defun erc-update-mode-line-buffer (buffer) "Update the mode line in a single ERC buffer BUFFER." (with-current-buffer buffer (let ((spec (format-spec-make ?a (erc-format-away-status) + ?l (erc-format-lag-time) ?m (erc-format-channel-modes) ?n (or (erc-current-nick) "") ?o (erc-controls-strip erc-channel-topic) @@ -5823,7 +5871,10 @@ if `erc-away' is non-nil." (erc-propertize header 'help-echo help-echo 'face face) (erc-propertize header 'help-echo help-echo)))))) - (t (setq header-line-format header)))))) + (t (setq header-line-format + (if face + (erc-propertize header 'face face) + header))))))) (if (featurep 'xemacs) (redraw-modeline) (force-mode-line-update)))) @@ -6177,6 +6228,10 @@ This function should be on `erc-kill-channel-hook'." ;;; Dealing with `erc-parsed' +(defun erc-find-parsed-property () + "Find the next occurrence of the `erc-parsed' text property." + (text-property-not-all (point-min) (point-max) 'erc-parsed nil)) + (defun erc-get-parsed-vector (point) "Return the whole parsed vector on POINT." (get-text-property point 'erc-parsed)) |