;; erc.el --- An Emacs Internet Relay Chat client
;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-;; 2006, 2007, 2008 Free Software Foundation, Inc.
+;; 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
;; Author: Alexander L. Belikoff (alexander@belikoff.net)
;; Contributors: Sergey Berezin (sergey.berezin@cs.cmu.edu),
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
-(defconst erc-version-string "Version 5.3 (devel)"
+(defconst erc-version-string "Version 5.3"
"ERC version. This is used by function `erc-version'.")
(eval-when-compile (require 'cl))
(define-key map "\C-c\C-r" 'erc-remove-text-properties-region)
(define-key map "\C-c\C-t" 'erc-set-topic)
(define-key map "\C-c\C-u" 'erc-kill-input)
+ (define-key map "\C-c\C-x" 'erc-quit-server)
(define-key map "\M-\t" 'ispell-complete-word)
(define-key map "\t" 'erc-complete-word)
See the variable `erc-command-indicator'."
:group 'erc-faces)
-(defface erc-notice-face '((t (:bold t :foreground "SlateBlue")))
+(defface erc-notice-face
+ (if (or (featurep 'xemacs)
+ (< emacs-major-version 22))
+ '((t (:bold t :foreground "blue")))
+ '((((class color) (min-colors 88))
+ (:bold t :foreground "SlateBlue"))
+ (t (:bold t :foreground "blue"))))
"ERC face for notices."
:group 'erc-faces)
"IRC port to use if it cannot be detected otherwise.")
(defcustom erc-join-buffer 'buffer
- "Determines how to display the newly created IRC buffer.
-'window - in another window,
-'window-noselect - in another window, but don't select that one,
-'frame - in another frame,
-'bury - bury it in a new buffer,
-any other value - in place of the current buffer."
+ "Determines how to display a newly created IRC buffer.
+
+The available choices are:
+
+ 'window - in another window,
+ 'window-noselect - in another window, but don't select that one,
+ 'frame - in another frame,
+ 'bury - bury it in a new buffer,
+ 'buffer - in place of the current buffer,
+ any other value - in place of the current buffer."
:group 'erc-buffers
- :type '(choice (const window)
- (const window-noselect)
- (const frame)
- (const bury)
- (const buffer)))
+ :type '(choice (const :tag "Split window and select" window)
+ (const :tag "Split window, don't select" window-noselect)
+ (const :tag "New frame" frame)
+ (const :tag "Bury in new buffer" bury)
+ (const :tag "Use current buffer" buffer)
+ (const :tag "Use current buffer" t)))
(defcustom erc-frame-alist nil
"*Alist of frame parameters for creating erc frames.
mods))))
(defcustom erc-modules '(netsplit fill button match track completion readonly
- ring autojoin noncommands irccontrols
- stamp menu)
+ networks ring autojoin noncommands irccontrols
+ move-to-prompt stamp menu list)
"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
(const :tag "completion: Complete nicknames and commands (programmable)"
completion)
(const :tag "hecomplete: Complete nicknames and commands (old)" hecomplete)
+ (const :tag "dcc: Provide Direct Client-to-Client support" dcc)
(const :tag "fill: Wrap long lines" fill)
(const :tag "identd: Launch an identd server on port 8113" identd)
(const :tag "irccontrols: Highlight or remove IRC control characters"
irccontrols)
+ (const :tag "keep-place: Leave point above un-viewed text" keep-place)
+ (const :tag "list: List channels in a separate buffer" list)
(const :tag "log: Save buffers in logs" log)
(const :tag "match: Highlight pals, fools, and other keywords" match)
(const :tag "menu: Display a menu in ERC buffers" menu)
+ (const :tag "move-to-prompt: Move to the prompt when typing text"
+ move-to-prompt)
(const :tag "netsplit: Detect netsplits" netsplit)
+ (const :tag "networks: Provide data about IRC networks" networks)
(const :tag "noncommands: Don't display non-IRC commands after evaluation"
noncommands)
(const :tag
(const :tag "track: Track channel activity in the mode-line" track)
(const :tag "truncate: Truncate buffers to a certain size" truncate)
(const :tag "unmorse: Translate morse code in messages" unmorse)
+ (const :tag "xdcc: Act as an XDCC file-server" xdcc)
(repeat :tag "Others" :inline t symbol))
:group 'erc)
I.e. any char in it has the `invisible' property set."
(text-property-any 0 (length string) 'invisible t string))
+(defcustom erc-remove-parsed-property t
+ "Whether to remove the erc-parsed text property after displaying a message.
+
+The default is to remove it, since it causes ERC to take up extra
+memory. If you have code that relies on this property, then set
+this option to nil."
+ :type 'boolean
+ :group 'erc)
+
(defun erc-display-line-1 (string buffer)
"Display STRING in `erc-mode' BUFFER.
Auxiliary function used in `erc-display-line'. The line gets filtered to
(unless (string-match "\n$" string)
(setq string (concat string "\n"))
(when (erc-string-invisible-p string)
- (erc-put-text-properties 0 (length string) string
- '(invisible intangible))))
+ (erc-put-text-properties 0 (length string)
+ '(invisible intangible) string)))
(erc-log (concat "erc-display-line: " string
(format "(%S)" string) " in buffer "
(format "%s" buffer)))
(save-restriction
(narrow-to-region insert-position (point))
(run-hooks 'erc-insert-modify-hook)
- (run-hooks 'erc-insert-post-hook))))))
+ (run-hooks 'erc-insert-post-hook)
+ (when erc-remove-parsed-property
+ (remove-text-properties (point-min) (point-max)
+ '(erc-parsed nil))))))))
(erc-update-undo-list (- (or (marker-position erc-insert-marker)
(point-max))
insert-position))))))
(setq list (cdr list))))))
(defvar erc-valid-nick-regexp "[]a-zA-Z^[;\\`_{}|][]^[;\\`_{}|a-zA-Z0-9-]*"
- "Regexp which matches all legal characters in a IRC nickname.")
+ "Regexp which matches all valid characters in a IRC nickname.")
(defun erc-is-valid-nick-p (nick)
"Check if NICK is a valid IRC nickname."
(t nil)))
(put 'erc-cmd-QUOTE 'do-not-parse-args t)
+(defcustom erc-query-display 'window
+ "Indicates how to display query buffers when using the /QUERY
+command to talk to someone.
+
+The default behavior is to display the message in a new window
+and bring it to the front. See the documentation for
+`erc-join-buffer' for a description of the available choices.
+
+See also `erc-auto-query' to decide how private messages from
+other people should be displayed."
+ :group 'erc-query
+ :type '(choice (const :tag "Split window and select" window)
+ (const :tag "Split window, don't select" window-noselect)
+ (const :tag "New frame" frame)
+ (const :tag "Bury in new buffer" bury)
+ (const :tag "Use current buffer" buffer)
+ (const :tag "Use current buffer" t)))
+
(defun erc-cmd-QUERY (&optional user)
"Open a query with USER.
The type of query window/frame/etc will depend on the value of
-`erc-join-buffer'. If USER is omitted, close the current query buffer if one
-exists - except this is broken now ;-)"
+`erc-query-display'.
+
+If USER is omitted, close the current query buffer if one exists
+- except this is broken now ;-)"
(interactive
(list (read-from-minibuffer "Start a query with: " nil)))
- (let ((session-buffer (erc-server-buffer)))
+ (let ((session-buffer (erc-server-buffer))
+ (erc-join-buffer erc-query-display))
(if user
(erc-query user session-buffer)
;; currently broken, evil hack to display help anyway
t)
(put 'erc-cmd-SERVER 'process-not-needed t)
-(eval-when-compile
- (defvar motif-version-string)
- (defvar gtk-version-string))
+(defvar motif-version-string)
+(defvar gtk-version-string)
(defun erc-cmd-SV ()
"Say the current ERC and Emacs version into channel."
((featurep 'gtk)
(concat ", GTK+ Version "
gtk-version-string))
- ((featurep 'mac-carbon) ", Mac Carbon")
((featurep 'x-toolkit) ", X toolkit")
(t ""))
(if (and (boundp 'x-toolkit-scroll-bars)
(let ((minibuffer-allow-text-properties t)
(read-map minibuffer-local-map))
(insert (read-from-minibuffer "Message: "
- (string last-command-char) read-map))
+ (string (if (featurep 'xemacs)
+ last-command-char
+ last-command-event)) read-map))
(erc-send-current-line)))
(defvar erc-action-history-list ()
(read-from-minibuffer
(concat "Set topic of " (erc-default-target) ": ")
(when erc-channel-topic
- (cons (apply 'concat (butlast (split-string erc-channel-topic "\C-o")))
- 0)))))
+ (let ((ss (split-string erc-channel-topic "\C-o")))
+ (cons (apply 'concat (if (cdr ss) (butlast ss) ss))
+ 0))))))
(let ((topic-list (split-string topic "\C-o"))) ; strip off the topic setter
(erc-cmd-TOPIC (concat (erc-default-target) " " (car topic-list)))))
(erc-update-mode-line)
buf))
-(defcustom erc-auto-query 'bury
+(defcustom erc-auto-query 'window-noselect
"If non-nil, create a query buffer each time you receive a private message.
+If the buffer doesn't already exist, it is created.
-If the buffer doesn't already exist it is created. This can be
-set to a symbol, to control how the new query window should
-appear. See the documentation for `erc-join-buffer' for
-available choices."
+This can be set to a symbol, to control how the new query window
+should appear. The default behavior is to display the buffer in
+a new window, but not to select it. See the documentation for
+`erc-join-buffer' for a description of the available choices."
:group 'erc-query
- :type '(choice (const nil)
- (const buffer)
- (const window)
- (const window-noselect)
- (const bury)
- (const frame)))
+ :type '(choice (const :tag "Don't create query window" nil)
+ (const :tag "Split window and select" window)
+ (const :tag "Split window, don't select" window-noselect)
+ (const :tag "New frame" frame)
+ (const :tag "Bury in new buffer" bury)
+ (const :tag "Use current buffer" buffer)
+ (const :tag "Use current buffer" t)))
(defcustom erc-query-on-unjoined-chan-privmsg t
"If non-nil create query buffer on receiving any PRIVMSG at all.
(string= target (erc-current-nick)))
(not (erc-get-buffer query proc))
(not (erc-is-message-ctcp-and-not-action-p msg))
- (let ((erc-join-buffer erc-auto-query))
+ (let ((erc-query-display erc-auto-query))
(erc-cmd-QUERY query))
nil))))
(defun erc-banlist-store (proc parsed)
"Record ban entries for a channel."
(multiple-value-bind (channel mask whoset)
- (cdr (erc-response.command-args parsed))
+ (values-list (cdr (erc-response.command-args parsed)))
;; Determine to which buffer the message corresponds
(let ((buffer (erc-get-buffer channel proc)))
(with-current-buffer buffer
(setq value-list (mapcar (lambda (x)
t)
properties)))
- (mapcar* (lambda (prop value)
- (erc-put-text-property start end prop value object))
- properties value-list))
+ (while (and properties value-list)
+ (erc-put-text-property
+ start end (pop properties) (pop value-list) object)))
;;; Input area handling:
(defun erc-user-input ()
"Return the input of the user in the current buffer."
- (buffer-substring
+ (buffer-substring-no-properties
erc-input-marker
(erc-end-of-input-line)))
(save-excursion
(let ((inhibit-read-only t))
(set-text-properties start end nil object))))
+(put 'erc-remove-text-properties-region 'disabled t)
;; script execution and startup
;; Mode line handling
-(defcustom erc-mode-line-format "%s %a"
+(defcustom erc-mode-line-format "%S %a"
"A string to be formatted and shown in the mode-line in `erc-mode'.
The string is formatted using `format-spec' and the result is set as the value
%l: The estimated lag time to the server
%m: The modes of the channel
%n: The current nick name
+%N: The name of the network
%o: The topic of the channel
%p: The session port
%t: The name of the target (channel, nickname, or servername:port)
%s: In the server-buffer, this gets filled with the value of
`erc-server-announced-name', in a channel, the value of
- (erc-default-target) also get concatenated."
+ (erc-default-target) also get concatenated.
+%S: In the server-buffer, this gets filled with the value of
+ `erc-network', in a channel, the value of (erc-default-target)
+ also get concatenated."
:group 'erc-mode-line-and-header
:type 'string)
:type '(choice (const :tag "Disabled" nil)
string))
+(defcustom erc-header-line-uses-tabbar-p nil
+ "Use tabbar mode instead of the header line to display the header."
+ :group 'erc-mode-line-and-header
+ :type 'boolean)
+
(defcustom erc-header-line-uses-help-echo-p t
"Show the contents of the header line in the echo area or as a tooltip
when you move point into the header line."
(server-name server-name)
(t (buffer-name (current-buffer))))))
+(defun erc-format-network ()
+ "Return the name of the network we are currently on."
+ (let ((network (and (fboundp 'erc-network-name) (erc-network-name))))
+ (if (and network (symbolp network))
+ (symbol-name network)
+ "")))
+
+(defun erc-format-target-and/or-network ()
+ "Return the network or the current target and network combined.
+If the name of the network is not available, then use the
+shortened server name instead."
+ (let ((network-name (or (and (fboundp 'erc-network-name) (erc-network-name))
+ (erc-shorten-server-name
+ (or erc-server-announced-name
+ erc-session-server)))))
+ (when (and network-name (symbolp network-name))
+ (setq network-name (symbol-name network-name)))
+ (cond ((erc-default-target)
+ (concat (erc-string-no-properties (erc-default-target))
+ "@" network-name))
+ (network-name network-name)
+ (t (buffer-name (current-buffer))))))
+
(defun erc-format-away-status ()
"Return a formatted `erc-mode-line-away-status-format'
if `erc-away' is non-nil."
;; erc-goodies is required at end of this file.
(declare-function erc-controls-strip "erc-goodies" (str))
+(defvar tabbar--local-hlf)
+
(defun erc-update-mode-line-buffer (buffer)
"Update the mode line in a single ERC buffer BUFFER."
(with-current-buffer buffer
?l (erc-format-lag-time)
?m (erc-format-channel-modes)
?n (or (erc-current-nick) "")
+ ?N (erc-format-network)
?o (erc-controls-strip erc-channel-topic)
?p (erc-port-to-string erc-session-port)
?s (erc-format-target-and/or-server)
+ ?S (erc-format-target-and/or-network)
?t (erc-format-target)))
(process-status (cond ((and (erc-server-process-alive)
(not erc-server-connected))
(let ((header (if erc-header-line-format
(format-spec erc-header-line-format spec)
nil)))
- (cond ((null header)
+ (cond (erc-header-line-uses-tabbar-p
+ (set (make-local-variable 'tabbar--local-hlf)
+ header-line-format)
+ (kill-local-variable 'header-line-format))
+ ((null header)
(setq header-line-format nil))
(erc-header-line-uses-help-echo-p
(let ((help-echo (with-temp-buffer
(s321 . "Channel Users Topic")
(s322 . "%c [%u] %t")
(s324 . "%c modes: %m")
+ (s328 . "%c URL: %u")
(s329 . "%c was created on %t")
(s330 . "%n %a %i")
(s331 . "No topic is set for %c")