emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: rcirc.el updates


From: Ryan Yeske
Subject: Re: rcirc.el updates
Date: Thu, 03 Nov 2005 21:35:04 -0800

Here is an updated patch, the only change from the last one is the
removal of the complicated detailed face specifications in favour of
directly inheriting from the font-lock-*-faces the rcirc faces were
originally copied from.

===File ~/contrib/emacs/lisp/rcirc-20051103.diff============
Index: ChangeLog
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/ChangeLog,v
retrieving revision 1.8512
diff -c -r1.8512 ChangeLog
*** ChangeLog   3 Nov 2005 15:41:37 -0000       1.8512
--- ChangeLog   4 Nov 2005 05:28:12 -0000
***************
*** 1,3 ****
--- 1,116 ----
+ 2005-11-03  Ryan Yeske  <address@hidden>
+ 
+       * net/rcirc.el:
+ 
+       Use split-string OMIT-NULLS argument in several places.
+       
+       (rcirc-print): Force redisplay before running hooks.  Do long
+       buffer truncation after making new text read-only.  Deal with nil
+       text when decoding strings.  If TARGET is nil, use either the
+       currently selected buffer, if it is an rcirc buffer and of the
+       same process or the process buffer.
+       (rcirc-mode): Remove header-line.  Recompute short buffer names.
+       Initialize rcirc-buffer-alist here instead of
+       rcirc-get-buffer-create.
+       (rcirc-short-buffer-name): Add variable.
+       (rcirc-kill-buffer-hook): Recompute short buffer names.  Remove
+       nick from private channel.
+       (rcirc-send-input): Send command text to current-buffer.  Don't
+       clear overlay arrow here.
+       (rcirc-short-buffer-name): Return a short buffer name.
+       (rcirc-update-short-buffer-names, rcirc-abbreviate)
+       (rcirc-rebuild-tree, rcirc-make-trees): Add functions to generate
+       buffer-name abbreviations.
+       (rcirc-kill-buffer-hook-1): Split to make debugging easier.  Do
+       not touch nick-table when killing a parted channel.
+       (rcirc-window-configuration-change): Rename from
+       rcirc-update-activity.  Clear arrow from current buffer if it is
+       now hidden.
+       (rcirc-current-buffer): Add variable
+       (rcirc-my-nick, rcirc-other-nick, rcirc-server)
+       (rcirc-nick-in-message, rcirc-prompt, rcirc-mode-line-nick):
+       Remove -face from names.  Inherit from various font-lock-*-faces.
+       (rcirc-update-activity-string): Print "DND" when globally ignoring
+       activity.
+       (rcirc-ignore-buffer-activity-flag): Rename from
+       rcirc-ignore-channel-activity.
+       (rcirc-ignore-all-activity-flag): Doc fix.
+       (rcirc-channels): Remove variable.
+       (rcirc-kill-buffer-hook):
+       (rcirc-get-buffer-create): Add nick to private channel.
+       (rcirc-multiline-edit-submit): Remove tabs.
+       (rcirc-put-nick-channel, rcirc-channel-nicks): Look up nicks case
+       folded.
+       (rcirc-remove-nick-channel): Bug fix.
+       (rcirc-toggle-ignore-buffer-activity): Rename from
+       rcirc-toggle-ignore-channel-activity.
+       (rcirc-record-activity): Add buffers to the front of the list.
+       (rcirc-update-activity): Remove killed buffers from list.
+       (rcirc-process-server-response-1): Remove last argument if it is
+       null before calling handler.
+       (rcirc): Add "rcirc" defcustom prefix.
+       (rcirc-prompt): Simplify default prompt.  Use
+       custom-initialize-default.
+       (rcirc-private-chats): Remove variable.
+       (rcirc-prompt): Change initialization.
+       (rcirc-version): Remove function.
+       (rcirc-id-string): Add constant.
+       (rcirc-last-buffer): Remove variable.
+       (rcirc-buffer-alist): Add variable.
+       (rcirc-connect): Update variable setup.
+       (rcirc-sentinel, rcirc-update-prompt): Use `rcirc-buffer-alist'.
+       (rcirc-trap-errors-flag): Rename from `rcirc-trap-errors' change
+       default.
+       (rcirc-handler-generic): Trigger activity.
+       (rcirc-send-message): Create the buffor of the target.
+       (rcirc-generate-new-buffer-name): Rename from
+       `rcirc-get-buffer-name'.
+       (rcirc-get-buffer): Just return nil if there is no matching
+       buffer.
+       (rcirc-multiline-edit-cancel): Remove function.
+       (rcirc-set-last-buffer): Remove function.
+       (rcirc-get-any-buffer): Add function.
+       (rcirc-join-channels): Don't print /join text.
+       (rcirc-toggle-ignore-channel-activity): Add and update echo area
+       messages.
+       (rcirc-cmd-ctcp): Use rcirc-send-string to send request.
+       (rcirc-handler-NOTICE): Recognize CTCP responses.
+       (rcirc-handler-332, rcirc-handler-332): Use a temp buffer for
+       constructing TOPIC string for buffers we are not JOINed.
+       (rcirc-handler-CTCP-response): Add handler.
+       (rcirc-multiline-edit-submit): Restore the window-configuration
+       before adjusting point.
+       (rcirc): Add customization group.
+       (rcirc-server, rcirc-port, rcirc-nick, rcirc-user-name)
+       (rcirc-user-full-name, rcirc-startup-channels-alist)
+       (rcirc-fill-flag, rcirc-fill-column, rcirc-fill-prefix)
+       (rcirc-ignore-all-activity-flag, rcirc-time-format)
+       (rcirc-input-ring-size, rcirc-read-only-flag)
+       (rcirc-buffer-maximum-lines, rcirc-authinfo-file-name)
+       (rcirc-auto-authenticate-flag, rcirc-prompt, rcirc-print-hooks):
+       Change defvar to defcustom.
+       (rcirc-update-prompt): Add optional ALL arg, which will update
+       prompts in all rcirc buffers.  Regexp quote replacement text.
+       (rcirc-fill-column): Accept 'frame-width as a value.
+       (rcirc-set-changed): Add function.
+       (rcirc-next-active-buffer): Write more meaningful messages.
+       (rcirc-faces): Add customization group.
+       (rcirc-my-nick-face, rcirc-other-nick-face, rcirc-server-face)
+       (rcirc-nick-in-message-face, rcirc-prompt-face)
+       (rcirc-mode-line-nick-face): Move into rcirc-faces group.
+       (with-rcirc-process-buffer): Move before first usage.
+       (rcirc-debug-buffer): Rename from `rcirc-log-buffer'.
+       (rcirc-debug-flag): Rename from `rcirc-log-p'.
+       (rcirc-debug): Rename from `rcirc-log'.
+       (rcirc-format-response-string): Do not print '-' chars for a
+       NOTICE with no sender.  Simplify output of server responses.
+       
+ 2005-11-03  Henrik Enberg <address@hidden>
+ 
+       * net/rcirc.el (rcirc-browse-url-map, rcirc-browse-url-at-point)
+       (rcirc-browse-url-at-mouse, rcirc-mangle-text): Make urls mouse
+       and RET clickable.
+ 
  2005-11-03  Romain Francoise  <address@hidden>
  
        * net/eudcb-mab.el: Now part of GNU Emacs.  Update FSF's address.
Index: net/rcirc.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/net/rcirc.el,v
retrieving revision 1.5
diff -c -r1.5 rcirc.el
*** net/rcirc.el        21 Oct 2005 07:56:46 -0000      1.5
--- net/rcirc.el        4 Nov 2005 05:28:13 -0000
***************
*** 25,36 ****
  
  ;;; Commentary:
  
! ;; rcirc is an Internet Relay Chat (IRC) client for Emacs
! 
! ;; IRC is a form of instant communication over the Internet. It is
! ;; mainly designed for group (many-to-many) communication in
! ;; discussion forums called channels, but also allows one-to-one
! ;; communication.
  
  ;; Open a new irc connection with:
  ;; M-x irc RET
--- 25,41 ----
  
  ;;; Commentary:
  
! ;; Internet Relay Chat (IRC) is a form of instant communication over
! ;; the Internet. It is mainly designed for group (many-to-many)
! ;; communication in discussion forums called channels, but also allows
! ;; one-to-one communication.
! 
! ;; Rcirc has simple defaults and clear and consistent behaviour.
! ;; Message arrival timestamps, activity notification on the modeline,
! ;; message filling, nick completion, and keepalive pings are all
! ;; enabled by default, but can easily be adjusted or turned off.  Each
! ;; discussion takes place in its own buffer and there is a single
! ;; server buffer per connection.
  
  ;; Open a new irc connection with:
  ;; M-x irc RET
***************
*** 41,101 ****
  (require 'time-date)
  (eval-when-compile (require 'cl))
  
! (defvar rcirc-server "irc.freenode.net"
!   "The default server to connect to.")
  
! (defvar rcirc-port 6667
!   "The default port to connect to.")
  
! (defvar rcirc-nick (user-login-name)
!   "Your nick.")
  
! (defvar rcirc-user-name (user-login-name)
!   "Your user name sent to the server when connecting.")
  
! (defvar rcirc-user-full-name (if (string= (user-full-name) "")
                                 rcirc-user-name
                               (user-full-name))
!   "The full name sent to the server when connecting.")
  
! (defvar rcirc-startup-channels-alist nil
    "Alist of channels to join at startup.
! Each element looks like (REGEXP . CHANNEL-LIST).")
  
! (defvar rcirc-fill-flag t
!   "*Non-nil means fill messages printed in channel buffers.")
  
! (defvar rcirc-fill-column nil
!   "*If non-nil, fill to this column, otherwise use value of `fill-column'.")
  
! (defvar rcirc-fill-prefix nil
    "*Text to insert before filled lines.
  If nil, calculate the prefix dynamically to line up text
! underneath each nick.")
! 
! (defvar rcirc-ignore-channel-activity nil
!   "If non-nil, ignore activity in this channel.")
! (make-variable-buffer-local 'rcirc-ignore-channel-activity)
  
! (defvar rcirc-ignore-all-activity-flag nil
!   "*Non-nil means track activity, but do not display it in the modeline.")
  
! (defvar rcirc-time-format "%H:%M "
    "*Describes how timestamps are printed.
! Used as the first arg to `format-time-string'.")
  
! (defvar rcirc-input-ring-size 1024
!   "*Size of input history ring.")
  
! (defvar rcirc-read-only-flag t
!   "*Non-nil means make text in irc buffers read-only.")
  
! (defvar rcirc-buffer-maximum-lines nil
    "*The maximum size in lines for rcirc buffers.
  Channel buffers are truncated from the top to be no greater than this
! number.        If zero or nil, no truncating is done.")
  
! (defvar rcirc-authinfo-file-name
    "~/.rcirc-authinfo"
    "File containing rcirc authentication passwords.
  The file consists of a single list, with each element itself a
--- 46,146 ----
  (require 'time-date)
  (eval-when-compile (require 'cl))
  
! (defgroup rcirc nil
!   "Simple IRC client."
!   :version "22.1"
!   :prefix "rcirc"
!   :group 'applications)
! 
! (defcustom rcirc-server "irc.freenode.net"
!   "The default server to connect to."
!   :type 'string
!   :group 'rcirc)
  
! (defcustom rcirc-port 6667
!   "The default port to connect to."
!   :type 'integer
!   :group 'rcirc)
  
! (defcustom rcirc-nick (user-login-name)
!   "Your nick."
!   :type 'string
!   :group 'rcirc)
  
! (defcustom rcirc-user-name (user-login-name)
!   "Your user name sent to the server when connecting."
!   :type 'string
!   :group 'rcirc)
  
! (defcustom rcirc-user-full-name (if (string= (user-full-name) "")
                                 rcirc-user-name
                               (user-full-name))
!   "The full name sent to the server when connecting."
!   :type 'string
!   :group 'rcirc)
  
! (defcustom rcirc-startup-channels-alist nil
    "Alist of channels to join at startup.
! Each element looks like (SERVER-REGEXP . CHANNEL-LIST)."
!   :type '(alist :key-type string :value-type (repeat string))
!   :group 'rcirc)
  
! (defcustom rcirc-fill-flag t
!   "*Non-nil means line-wrap messages printed in channel buffers."
!   :type 'boolean
!   :group 'rcirc)
  
! (defcustom rcirc-fill-column nil
!   "*Column beyond which automatic line-wrapping should happen.
! If nil, use value of `fill-column'.  If frame-width, use the
! maximum frame width."
!   :type '(choice (const :tag "Value of `fill-column'")
!                (const :tag "Full frame width" frame-width)
!                (integer :tag "Number of columns"))
!   :group 'rcirc)
  
! (defcustom rcirc-fill-prefix nil
    "*Text to insert before filled lines.
  If nil, calculate the prefix dynamically to line up text
! underneath each nick."
!   :type '(choice (const :tag "Dynamic" nil)
!                (string :tag "Prefix text"))
!   :group 'rcirc)
  
! (defvar rcirc-ignore-buffer-activity-flag nil
!   "If non-nil, ignore activity in this buffer.")
! (make-variable-buffer-local 'rcirc-ignore-buffer-activity-flag)
! 
! (defcustom rcirc-ignore-all-activity-flag nil
!   "*Non-nil means do not indicate any activity in the modeline."
!   :type 'boolean
!   :group 'rcirc)
  
! (defcustom rcirc-time-format "%H:%M "
    "*Describes how timestamps are printed.
! Used as the first arg to `format-time-string'."
!   :type 'string
!   :group 'rcirc)
  
! (defcustom rcirc-input-ring-size 1024
!   "*Size of input history ring."
!   :type 'integer
!   :group 'rcirc)
  
! (defcustom rcirc-read-only-flag t
!   "*Non-nil means make text in irc buffers read-only."
!   :type 'boolean
!   :group 'rcirc)
  
! (defcustom rcirc-buffer-maximum-lines nil
    "*The maximum size in lines for rcirc buffers.
  Channel buffers are truncated from the top to be no greater than this
! number.        If zero or nil, no truncating is done."
!   :type '(choice (const :tag "No truncation" nil)
!                (integer :tag "Number of lines"))
!   :group 'rcirc)
  
! (defcustom rcirc-authinfo-file-name
    "~/.rcirc-authinfo"
    "File containing rcirc authentication passwords.
  The file consists of a single list, with each element itself a
***************
*** 111,127 ****
  Example:
   ((\"freenode\" \"bob\" nickserv \"p455w0rd\")
    (\"freenode\" \"bob\" chanserv \"#bobland\" \"passwd99\")
!   (\"bitlbee\" \"robert\" bitlbee \"sekrit\"))")
  
! (defvar rcirc-auto-authenticate-flag (file-readable-p 
rcirc-authinfo-file-name)
    "*Non-nil means automatically send authentication string to server.
! See also `rcirc-authinfo-file-name'.")
! 
! (defvar rcirc-print-hooks nil
!   "Hook run after text is printed.
! Called with 5 arguments, PROCESS, SENDER, RESPONSE, TARGET and TEXT.")
  
! (defvar rcirc-prompt "%n> "
    "Prompt string to use in irc buffers.
  
  The following replacements are made:
--- 156,172 ----
  Example:
   ((\"freenode\" \"bob\" nickserv \"p455w0rd\")
    (\"freenode\" \"bob\" chanserv \"#bobland\" \"passwd99\")
!   (\"bitlbee\" \"robert\" bitlbee \"sekrit\"))"
!   :type 'string
!   :group 'rcirc)
  
! (defcustom rcirc-auto-authenticate-flag (file-readable-p 
rcirc-authinfo-file-name)
    "*Non-nil means automatically send authentication string to server.
! See also `rcirc-authinfo-file-name'."
!   :type 'boolean
!   :group 'rcirc)
  
! (defcustom rcirc-prompt "> "
    "Prompt string to use in irc buffers.
  
  The following replacements are made:
***************
*** 129,142 ****
  %s is the server.
  %t is the buffer target, a channel or a user.
  
! Setting this alone will not affect the prompt; 
! use `rcirc-update-prompt' after changing this variable.")
  
  (defvar rcirc-prompt-start-marker nil)
  (defvar rcirc-prompt-end-marker nil)
  
  (defvar rcirc-nick-table nil)
  
  (defvar rcirc-activity nil
    "List of channels with unviewed activity.")
  
--- 174,200 ----
  %s is the server.
  %t is the buffer target, a channel or a user.
  
! Setting this alone will not affect the prompt;
! use either M-x customize or also call `rcirc-update-prompt'."
!   :type 'string
!   :set 'rcirc-set-changed
!   :initialize 'custom-initialize-default
!   :group 'rcirc)
! 
! (defcustom rcirc-print-hooks nil
!   "Hook run after text is printed.
! Called with 5 arguments, PROCESS, SENDER, RESPONSE, TARGET and TEXT."
!   :type 'hook
!   :group 'rcirc)
  
  (defvar rcirc-prompt-start-marker nil)
  (defvar rcirc-prompt-end-marker nil)
  
  (defvar rcirc-nick-table nil)
  
+ ;; each process has an alist of (target . buffer) pairs
+ (defvar rcirc-buffer-alist nil)
+ 
  (defvar rcirc-activity nil
    "List of channels with unviewed activity.")
  
***************
*** 150,179 ****
  (defvar rcirc-target nil
    "The channel or user associated with this buffer.")
  
- (defvar rcirc-channels nil
-   "Joined channels.")
- 
- (defvar rcirc-private-chats nil
-   "Private chats open.")
- 
  (defvar rcirc-urls nil
    "List of urls seen in the current buffer.")
  
  (defvar rcirc-keepalive-seconds 60
    "Number of seconds between keepalive pings.")
  
  
- (defun rcirc-version (&optional here)
-   "Return rcirc version string.
- If optional argument HERE is non-nil, insert string at point."
-   (interactive "P")
-   (let ((version "rcirc.el 0.9 $Revision: 1.5 $"))
-     (if here
-       (insert version)
-       (if (interactive-p)
-         (message "%s" version)
-       version))))
- 
  (defvar rcirc-startup-channels nil)
  ;;;###autoload
  (defun rcirc (&optional server port nick channels)
--- 208,221 ----
  (defvar rcirc-target nil
    "The channel or user associated with this buffer.")
  
  (defvar rcirc-urls nil
    "List of urls seen in the current buffer.")
  
  (defvar rcirc-keepalive-seconds 60
    "Number of seconds between keepalive pings.")
  
+ (defconst rcirc-id-string (concat "rcirc on GNU Emacs " emacs-version))
  
  (defvar rcirc-startup-channels nil)
  ;;;###autoload
  (defun rcirc (&optional server port nick channels)
***************
*** 181,187 ****
  
  If any of the the optional SERVER, PORT, NICK or CHANNELS are not
  supplied, they are taken from the variables `rcirc-server',
! `rcirc-port', `rcirc-nick', and `rcirc-startup-channels',
  respectively."
    (interactive (list (read-string "IRC Server: " rcirc-server)
                     (read-string "IRC Port: " (number-to-string rcirc-port))
--- 223,229 ----
  
  If any of the the optional SERVER, PORT, NICK or CHANNELS are not
  supplied, they are taken from the variables `rcirc-server',
! `rcirc-port', `rcirc-nick', and `rcirc-startup-channels-alist',
  respectively."
    (interactive (list (read-string "IRC Server: " rcirc-server)
                     (read-string "IRC Port: " (number-to-string rcirc-port))
***************
*** 192,210 ****
    (or channels
        (setq channels
            (if (interactive-p)
!               (delete ""
!                       (split-string
!                        (read-string "Channels: "
!                                    (mapconcat 'identity
!                                               (rcirc-startup-channels server)
!                                               " "))
!                        "[, ]+"))
              (rcirc-startup-channels server))))
    (or global-mode-string (setq global-mode-string '("")))
    (and (not (memq 'rcirc-activity-string global-mode-string))
         (setq global-mode-string
             (append global-mode-string '(rcirc-activity-string))))
!   (add-hook 'window-configuration-change-hook 'rcirc-update-activity)
    (rcirc-connect server port nick rcirc-user-name rcirc-user-full-name
                 channels))
  
--- 234,252 ----
    (or channels
        (setq channels
            (if (interactive-p)
!               (split-string
!                (read-string "Channels: "
!                             (mapconcat 'identity
!                                        (rcirc-startup-channels server)
!                                        " "))
!                        "[, ]+" t)
              (rcirc-startup-channels server))))
    (or global-mode-string (setq global-mode-string '("")))
    (and (not (memq 'rcirc-activity-string global-mode-string))
         (setq global-mode-string
             (append global-mode-string '(rcirc-activity-string))))
!   (add-hook 'window-configuration-change-hook
!           'rcirc-window-configuration-change)
    (rcirc-connect server port nick rcirc-user-name rcirc-user-full-name
                 channels))
  
***************
*** 213,219 ****
  
  
  (defvar rcirc-process-output nil)
- (defvar rcirc-last-buffer nil)
  (defvar rcirc-topic nil)
  (defvar rcirc-keepalive-timer nil)
  (make-variable-buffer-local 'rcirc-topic)
--- 255,260 ----
***************
*** 233,242 ****
        ;; set up process
        (set-process-coding-system process 'raw-text 'raw-text)
        (set-process-filter process 'rcirc-filter)
!       (switch-to-buffer (concat "*" (process-name process) "*"))
        (set-process-buffer process (current-buffer))
        (set-process-sentinel process 'rcirc-sentinel)
        (rcirc-mode process nil)
        (make-local-variable 'rcirc-nick-table)
        (setq rcirc-nick-table (make-hash-table :test 'equal))
        (make-local-variable 'rcirc-server)
--- 274,285 ----
        ;; set up process
        (set-process-coding-system process 'raw-text 'raw-text)
        (set-process-filter process 'rcirc-filter)
!       (switch-to-buffer (rcirc-generate-new-buffer-name process nil))
        (set-process-buffer process (current-buffer))
        (set-process-sentinel process 'rcirc-sentinel)
        (rcirc-mode process nil)
+       (make-local-variable 'rcirc-buffer-alist)
+       (setq rcirc-buffer-alist nil)
        (make-local-variable 'rcirc-nick-table)
        (setq rcirc-nick-table (make-hash-table :test 'equal))
        (make-local-variable 'rcirc-server)
***************
*** 245,256 ****
        (setq rcirc-nick nick)
        (make-local-variable 'rcirc-process-output)
        (setq rcirc-process-output nil)
-       (make-local-variable 'rcirc-last-buffer)
-       (setq rcirc-last-buffer (current-buffer))
-       (make-local-variable 'rcirc-channels)
-       (setq rcirc-channels nil)
-       (make-local-variable 'rcirc-private-chats)
-       (setq rcirc-private-chats nil)
        (make-local-variable 'rcirc-startup-channels)
        (setq rcirc-startup-channels startup-channels)
  
--- 288,293 ----
***************
*** 270,303 ****
        ;; return process object
        process)))
  
  (defun rcirc-keepalive ()
    "Send keep alive pings to active rcirc processes."
    (if (rcirc-process-list)
        (mapc (lambda (process)
!               (with-current-buffer (process-buffer process)
                  (rcirc-send-string process (concat "PING " rcirc-server))))
              (rcirc-process-list))
      (cancel-timer rcirc-keepalive-timer)
      (setq rcirc-keepalive-timer nil)))
  
! (defvar rcirc-log-buffer "*rcirc log*")
! (defvar rcirc-log-p nil
!   "If non-nil, write information to `rcirc-log-buffer'.")
! (defun rcirc-log (process text)
    "Add an entry to the debug log including PROCESS and TEXT.
! Debug text is written to `rcirc-log-buffer' if `rcirc-log-p' is
! non-nil."
!   (when rcirc-log-p
      (save-excursion
        (save-window-excursion
!         (set-buffer (get-buffer-create rcirc-log-buffer))
          (goto-char (point-max))
          (insert (concat
                   "["
                   (format-time-string "%Y-%m-%dT%T ") (process-name process)
                   "] "
                   text))))))
!                
  (defvar rcirc-sentinel-hooks nil
    "Hook functions called when the process sentinel is called.
  Functions are called with PROCESS and SENTINEL arguments.")
--- 307,345 ----
        ;; return process object
        process)))
  
+ (defmacro with-rcirc-process-buffer (process &rest body)
+   (declare (indent 1) (debug t))
+   `(with-current-buffer (process-buffer ,process)
+      ,@body))
+ 
  (defun rcirc-keepalive ()
    "Send keep alive pings to active rcirc processes."
    (if (rcirc-process-list)
        (mapc (lambda (process)
!               (with-rcirc-process-buffer process
                  (rcirc-send-string process (concat "PING " rcirc-server))))
              (rcirc-process-list))
      (cancel-timer rcirc-keepalive-timer)
      (setq rcirc-keepalive-timer nil)))
  
! (defvar rcirc-debug-buffer " *rcirc debug*")
! (defvar rcirc-debug-flag nil
!   "If non-nil, write information to `rcirc-debug-buffer'.")
! (defun rcirc-debug (process text)
    "Add an entry to the debug log including PROCESS and TEXT.
! Debug text is written to `rcirc-debug-buffer' if `rcirc-debug-p'
! is non-nil."
!   (when rcirc-debug-flag
      (save-excursion
        (save-window-excursion
!         (set-buffer (get-buffer-create rcirc-debug-buffer))
          (goto-char (point-max))
          (insert (concat
                   "["
                   (format-time-string "%Y-%m-%dT%T ") (process-name process)
                   "] "
                   text))))))
! 
  (defvar rcirc-sentinel-hooks nil
    "Hook functions called when the process sentinel is called.
  Functions are called with PROCESS and SENTINEL arguments.")
***************
*** 305,324 ****
  (defun rcirc-sentinel (process sentinel)
    "Called when PROCESS receives SENTINEL."
    (let ((sentinel (replace-regexp-in-string "\n" "" sentinel)))
!     (rcirc-log process (format "SENTINEL: %S %S\n" process sentinel))
!     (with-current-buffer (process-buffer process)
!       (dolist (target (append rcirc-channels
!                               rcirc-private-chats
!                               (list (current-buffer))))
!         (rcirc-print process "rcirc.el" "ERROR" target
                       (format "%s: %s (%S)"
                               (process-name process)
                               sentinel
                               (process-status process)) t)
        ;; remove the prompt from buffers
!       (with-current-buffer (if (eq target (current-buffer))
!                                (current-buffer)
!                              (rcirc-get-buffer process target))
          (let ((inhibit-read-only t))
            (delete-region rcirc-prompt-start-marker
                           rcirc-prompt-end-marker)))))
--- 347,362 ----
  (defun rcirc-sentinel (process sentinel)
    "Called when PROCESS receives SENTINEL."
    (let ((sentinel (replace-regexp-in-string "\n" "" sentinel)))
!     (rcirc-debug process (format "SENTINEL: %S %S\n" process sentinel))
!     (with-rcirc-process-buffer process
!       (dolist (buffer (cons nil (mapcar 'cdr rcirc-buffer-alist)))
!         (rcirc-print process "rcirc.el" "ERROR" buffer
                       (format "%s: %s (%S)"
                               (process-name process)
                               sentinel
                               (process-status process)) t)
        ;; remove the prompt from buffers
!       (with-current-buffer (or buffer (current-buffer))
          (let ((inhibit-read-only t))
            (delete-region rcirc-prompt-start-marker
                           rcirc-prompt-end-marker)))))
***************
*** 329,335 ****
    (let (ps)
      (mapc (lambda (p)
              (when (process-buffer p)
!               (with-current-buffer (process-buffer p)
                  (when (eq major-mode 'rcirc-mode)
                    (setq ps (cons p ps))))))
            (process-list))
--- 367,373 ----
    (let (ps)
      (mapc (lambda (p)
              (when (process-buffer p)
!               (with-rcirc-process-buffer p
                  (when (eq major-mode 'rcirc-mode)
                    (setq ps (cons p ps))))))
            (process-list))
***************
*** 340,363 ****
  Function is called with PROCESS COMMAND SENDER ARGS and LINE.")
  (defun rcirc-filter (process output)
    "Called when PROCESS receives OUTPUT."
!   (rcirc-log process output)
!   (with-current-buffer (process-buffer process)
      (setq rcirc-process-output (concat rcirc-process-output output))
      (when (= (aref rcirc-process-output
                     (1- (length rcirc-process-output))) ?\n)
        (mapc (lambda (line)
                (rcirc-process-server-response process line))
!             (delete "" (split-string rcirc-process-output "[\n\r]")))
        (setq rcirc-process-output nil))))
  
! (defvar rcirc-trap-errors nil)
  (defun rcirc-process-server-response (process text)
!   (if rcirc-trap-errors
        (condition-case err
            (rcirc-process-server-response-1 process text)
          (error
           (rcirc-print process "RCIRC" "ERROR" nil
!                       (format "rcirc: error processing: \"%s\" %s" text 
err))))
      (rcirc-process-server-response-1 process text)))
  
  (defun rcirc-process-server-response-1 (process text)
--- 378,401 ----
  Function is called with PROCESS COMMAND SENDER ARGS and LINE.")
  (defun rcirc-filter (process output)
    "Called when PROCESS receives OUTPUT."
!   (rcirc-debug process output)
!   (with-rcirc-process-buffer process
      (setq rcirc-process-output (concat rcirc-process-output output))
      (when (= (aref rcirc-process-output
                     (1- (length rcirc-process-output))) ?\n)
        (mapc (lambda (line)
                (rcirc-process-server-response process line))
!             (split-string rcirc-process-output "[\n\r]" t))
        (setq rcirc-process-output nil))))
  
! (defvar rcirc-trap-errors-flag t)
  (defun rcirc-process-server-response (process text)
!   (if rcirc-trap-errors-flag
        (condition-case err
            (rcirc-process-server-response-1 process text)
          (error
           (rcirc-print process "RCIRC" "ERROR" nil
!                       (format "\"%s\" %s" text err) t)))
      (rcirc-process-server-response-1 process text)))
  
  (defun rcirc-process-server-response-1 (process text)
***************
*** 369,376 ****
          (string-match "^\\([^:]*\\):?\\(.+\\)?$" args)
          (let* ((args1 (match-string 1 args))
                 (args2 (match-string 2 args))
!                (args (append (delete "" (split-string args1 " "))
!                              (list args2))))
          (if (not (fboundp handler))
              (rcirc-handler-generic process cmd sender args text)
            (funcall handler process sender args text))
--- 407,414 ----
          (string-match "^\\([^:]*\\):?\\(.+\\)?$" args)
          (let* ((args1 (match-string 1 args))
                 (args2 (match-string 2 args))
!                (args (delq nil (append (split-string args1 " " t)
!                                      (list args2)))))
          (if (not (fboundp handler))
              (rcirc-handler-generic process cmd sender args text)
            (funcall handler process sender args text))
***************
*** 381,404 ****
  (defun rcirc-handler-generic (process command sender args text)
    "Generic server response handler."
    (rcirc-print process sender command nil
!                (mapconcat 'identity (cdr args) " ")))
  
  (defun rcirc-send-string (process string)
    "Send PROCESS a STRING plus a newline."
    (let ((string (concat (encode-coding-string string
                                                buffer-file-coding-system)
                          "\n")))
!     (rcirc-log process string)
      (process-send-string process string)))
  
  (defun rcirc-server (process)
    "Return PROCESS server, given by the 001 response."
!   (with-current-buffer (process-buffer process)
      rcirc-server))
  
  (defun rcirc-nick (process)
    "Return PROCESS nick."
!   (with-current-buffer (process-buffer process)
      rcirc-nick))
  
  (defvar rcirc-max-message-length 450
--- 419,442 ----
  (defun rcirc-handler-generic (process command sender args text)
    "Generic server response handler."
    (rcirc-print process sender command nil
!                (mapconcat 'identity (cdr args) " ") t))
  
  (defun rcirc-send-string (process string)
    "Send PROCESS a STRING plus a newline."
    (let ((string (concat (encode-coding-string string
                                                buffer-file-coding-system)
                          "\n")))
!     (rcirc-debug process string)
      (process-send-string process string)))
  
  (defun rcirc-server (process)
    "Return PROCESS server, given by the 001 response."
!   (with-rcirc-process-buffer process
      rcirc-server))
  
  (defun rcirc-nick (process)
    "Return PROCESS nick."
!   (with-rcirc-process-buffer process
      rcirc-nick))
  
  (defvar rcirc-max-message-length 450
***************
*** 418,424 ****
                   text))
           (more (if oversize
                     (substring message rcirc-max-message-length))))
!     (rcirc-print process (rcirc-nick process) response target text)
      (rcirc-send-string process (concat response " " target " :" text))
      (if more
          (rcirc-send-message process target more noticep))))
--- 456,464 ----
                   text))
           (more (if oversize
                     (substring message rcirc-max-message-length))))
!     (rcirc-print process (rcirc-nick process) response
!                (rcirc-get-buffer-create process target)
!                text)
      (rcirc-send-string process (concat response " " target " :" text))
      (if more
          (rcirc-send-message process target more noticep))))
***************
*** 459,466 ****
               rcirc-prompt-end-marker))
      (setq rcirc-nick-completions
            (let ((completion-ignore-case t))
!             (all-completions 
!            (buffer-substring 
              (+ rcirc-prompt-end-marker
                 rcirc-nick-completion-start-offset)
              (point))
--- 499,506 ----
               rcirc-prompt-end-marker))
      (setq rcirc-nick-completions
            (let ((completion-ignore-case t))
!             (all-completions
!            (buffer-substring
              (+ rcirc-prompt-end-marker
                 rcirc-nick-completion-start-offset)
              (point))
***************
*** 469,479 ****
                                          (rcirc-buffer-target)))))))
    (let ((completion (car rcirc-nick-completions)))
      (when completion
!       (delete-region (+ rcirc-prompt-end-marker 
                          rcirc-nick-completion-start-offset)
                       (point))
        (insert (concat completion
!                       (if (= (+ rcirc-prompt-end-marker 
                                  rcirc-nick-completion-start-offset)
                               rcirc-prompt-end-marker)
                            ": "))))))
--- 509,519 ----
                                          (rcirc-buffer-target)))))))
    (let ((completion (car rcirc-nick-completions)))
      (when completion
!       (delete-region (+ rcirc-prompt-end-marker
                          rcirc-nick-completion-start-offset)
                       (point))
        (insert (concat completion
!                       (if (= (+ rcirc-prompt-end-marker
                                  rcirc-nick-completion-start-offset)
                               rcirc-prompt-end-marker)
                            ": "))))))
***************
*** 507,513 ****
  (define-key rcirc-mode-map (kbd "C-c C-w") 'rcirc-cmd-whois)
  (define-key rcirc-mode-map (kbd "C-c C-x") 'rcirc-cmd-quit)
  (define-key rcirc-mode-map (kbd "C-c TAB") ; C-i
!   'rcirc-toggle-ignore-channel-activity)
  (define-key rcirc-mode-map (kbd "C-c C-s") 'rcirc-switch-to-server-buffer)
  (define-key rcirc-mode-map (kbd "C-c C-a") 'rcirc-jump-to-first-unread-line)
  
--- 547,553 ----
  (define-key rcirc-mode-map (kbd "C-c C-w") 'rcirc-cmd-whois)
  (define-key rcirc-mode-map (kbd "C-c C-x") 'rcirc-cmd-quit)
  (define-key rcirc-mode-map (kbd "C-c TAB") ; C-i
!   'rcirc-toggle-ignore-buffer-activity)
  (define-key rcirc-mode-map (kbd "C-c C-s") 'rcirc-switch-to-server-buffer)
  (define-key rcirc-mode-map (kbd "C-c C-a") 'rcirc-jump-to-first-unread-line)
  
***************
*** 515,520 ****
--- 555,569 ----
  (define-key global-map (kbd "C-c C-@") 'rcirc-next-active-buffer)
  (define-key global-map (kbd "C-c C-SPC") 'rcirc-next-active-buffer)
  
+ (defvar rcirc-browse-url-map (make-sparse-keymap)
+   "Keymap used ror browsing URLs in `rcirc-mode'.")
+ 
+ (define-key rcirc-browse-url-map (kbd "RET") 'rcirc-browse-url-at-point)
+ (define-key rcirc-browse-url-map (kbd "<mouse-2>") 'rcirc-browse-url-at-mouse)
+ 
+ (defvar rcirc-short-buffer-name nil
+   "Generated abbreviation to use to indicate buffer activity.")
+ 
  (defvar rcirc-mode-hook nil
    "Hook run when setting up rcirc buffer.")
  
***************
*** 533,543 ****
    (setq rcirc-process process)
    (make-local-variable 'rcirc-target)
    (setq rcirc-target target)
    (make-local-variable 'rcirc-urls)
    (setq rcirc-urls nil)
    (setq use-hard-newlines t)
-   (when (rcirc-channel-p rcirc-target)
-     (setq header-line-format 'rcirc-topic))
  
    ;; setup the prompt and markers
    (make-local-variable 'rcirc-prompt-start-marker)
--- 582,593 ----
    (setq rcirc-process process)
    (make-local-variable 'rcirc-target)
    (setq rcirc-target target)
+ 
+   (make-local-variable 'rcirc-short-buffer-name)
+   (setq rcirc-short-buffer-name nil)
    (make-local-variable 'rcirc-urls)
    (setq rcirc-urls nil)
    (setq use-hard-newlines t)
  
    ;; setup the prompt and markers
    (make-local-variable 'rcirc-prompt-start-marker)
***************
*** 552,589 ****
    (setq overlay-arrow-position (make-marker))
    (set-marker overlay-arrow-position nil)
  
    (run-hooks 'rcirc-mode-hook))
  
! (defmacro with-rcirc-process-buffer (process &rest body)
!   (declare (indent 1) (debug t))
!   `(with-current-buffer (process-buffer ,process)
!      ,@body))
  
! (defun rcirc-update-prompt ()
!   "Reset the prompt string in the current buffer."
!   (let ((inhibit-read-only t)
!         (prompt (or rcirc-prompt "")))
!     (mapc (lambda (rep)
!             (setq prompt 
!                 (replace-regexp-in-string (car rep) (cdr rep) prompt)))
!           (list (cons "%n" (with-rcirc-process-buffer rcirc-process
!                            rcirc-nick))
!                 (cons "%s" (with-rcirc-process-buffer rcirc-process 
!                            rcirc-server))
!                 (cons "%t" (or rcirc-target ""))))
!     (save-excursion
!       (delete-region rcirc-prompt-start-marker rcirc-prompt-end-marker)
!       (goto-char rcirc-prompt-start-marker)
!       (let ((start (point)))
!         (insert-before-markers prompt)
!         (set-marker rcirc-prompt-start-marker start)
!         (when (not (zerop (- rcirc-prompt-end-marker
!                              rcirc-prompt-start-marker)))
!           (add-text-properties rcirc-prompt-start-marker
!                                rcirc-prompt-end-marker
!                                (list 'face 'rcirc-prompt-face
!                                      'read-only t 'field t
!                                      'front-sticky t 'rear-nonsticky t)))))))
  
  (defun rcirc-channel-p (target)
    "Return t if TARGET is a channel name."
--- 602,660 ----
    (setq overlay-arrow-position (make-marker))
    (set-marker overlay-arrow-position nil)
  
+   ;; add to buffer list, and update buffer abbrevs
+   (when target                                ; skip server buffer
+     (let ((buffer (current-buffer)))
+       (with-rcirc-process-buffer process
+       (setq rcirc-buffer-alist (cons (cons target buffer)
+                                      rcirc-buffer-alist))))
+     (rcirc-update-short-buffer-names))
+ 
    (run-hooks 'rcirc-mode-hook))
  
! (defun rcirc-update-prompt (&optional all)
!   "Reset the prompt string in the current buffer.
  
! If ALL is non-nil, update prompts in all IRC buffers."
!   (if all
!       (mapc (lambda (process)
!             (mapc (lambda (buffer)
!                     (with-current-buffer buffer
!                       (rcirc-update-prompt)))
!                   (with-rcirc-process-buffer process
!                     (mapcar 'cdr rcirc-buffer-alist))))
!           (rcirc-process-list))
!     (let ((inhibit-read-only t)
!         (prompt (or rcirc-prompt "")))
!       (mapc (lambda (rep)
!             (setq prompt
!                   (replace-regexp-in-string (car rep) (regexp-quote (cdr 
rep)) prompt)))
!           (list (cons "%n" (with-rcirc-process-buffer rcirc-process
!                              rcirc-nick))
!                 (cons "%s" (with-rcirc-process-buffer rcirc-process
!                              rcirc-server))
!                 (cons "%t" (or rcirc-target ""))))
!       (save-excursion
!       (delete-region rcirc-prompt-start-marker rcirc-prompt-end-marker)
!       (goto-char rcirc-prompt-start-marker)
!       (let ((start (point)))
!         (insert-before-markers prompt)
!         (set-marker rcirc-prompt-start-marker start)
!         (when (not (zerop (- rcirc-prompt-end-marker
!                              rcirc-prompt-start-marker)))
!           (add-text-properties rcirc-prompt-start-marker
!                                rcirc-prompt-end-marker
!                                (list 'face 'rcirc-prompt
!                                      'read-only t 'field t
!                                      'front-sticky t 'rear-nonsticky t))))))))
! 
! (defun rcirc-set-changed (option value)
!   "Set OPTION to VALUE and do updates after a customization change."
!   (set-default option value)
!   (cond ((eq option 'rcirc-prompt)
!        (rcirc-update-prompt 'all))
!       (t
!        (error "Bad option %s" option))))
  
  (defun rcirc-channel-p (target)
    "Return t if TARGET is a channel name."
***************
*** 595,659 ****
  (defun rcirc-kill-buffer-hook ()
    "Part the channel when killing an rcirc buffer."
    (when (eq major-mode 'rcirc-mode)
!     (rcirc-clear-activity (current-buffer))
      (when (and rcirc-process
!                (eq (process-status rcirc-process) 'open))
        (if (rcirc-channel-p rcirc-target)
!           (rcirc-cmd-part "" rcirc-process rcirc-target)
!         ;; remove target from privchat list
!         (when rcirc-target
!           (let ((target (downcase rcirc-target)))
!             (with-rcirc-process-buffer rcirc-process
!               (setq rcirc-private-chats
!                   (delete target rcirc-private-chats)))))))))
  (add-hook 'kill-buffer-hook 'rcirc-kill-buffer-hook)
  
! (defun rcirc-get-buffer-name (process target)
!   "Return buffer name based on PROCESS and TARGET."
!   (concat (and target (downcase target)) "@" (process-name process)))
  
! (defun rcirc-get-buffer (process target &optional error)
    "Return the buffer associated with the PROCESS and TARGET.
! If TARGET is nil and ERROR is nil, return the process buffer."
!   (let ((buffer (and target 
!                      (get-buffer (rcirc-get-buffer-name process target)))))
!     (if (and buffer (buffer-live-p buffer))
!         buffer
!       (if error
!           (error "Buffer associated with %s does not exist" target)
!         (process-buffer process)))))
  
  (defun rcirc-get-buffer-create (process target)
!   "Return the buffer named associated with the PROCESS and TARGET.
! Create the buffer if it doesn't exist.  If TARGET is nil, return
! the process buffer."
!   (with-current-buffer (process-buffer process)
!     (if (not target)
!         (current-buffer)
!       (let ((target (downcase target)))
!         ;; add private chats to list.  we dont add channels here, they
!         ;; are managed by the join/part/quit handlers
!         (when (and (not (rcirc-channel-p target))
!                    (not (member target rcirc-private-chats)))
!           (with-rcirc-process-buffer process
!             (setq rcirc-private-chats (cons target rcirc-private-chats))))
!         ;; create and setup a buffer, or return the existing one
!         (let ((bufname (rcirc-get-buffer-name process target)))
!           (with-current-buffer (get-buffer-create bufname)
!             (if (or (not rcirc-process)
!                     (not (equal (process-status rcirc-process) 'open)))
!                 (rcirc-mode process target)
!               (setq rcirc-target target))
!             (current-buffer)))))))
  
  (defun rcirc-send-input ()
    "Send input to target associated with the current buffer."
    (interactive)
    (if (not (eq (process-status rcirc-process) 'open))
!       (error "Network connection to %s is not open" 
               (process-name rcirc-process))
-     ;; update last buffer
-     (rcirc-set-last-buffer rcirc-process (current-buffer))
      (if (< (point) rcirc-prompt-end-marker)
          ;; copy the line down to the input area
          (progn
--- 666,732 ----
  (defun rcirc-kill-buffer-hook ()
    "Part the channel when killing an rcirc buffer."
    (when (eq major-mode 'rcirc-mode)
!     (rcirc-kill-buffer-hook-1)))
! (defun rcirc-kill-buffer-hook-1 ()
!   (let ((buffer (current-buffer)))
!     (rcirc-clear-activity buffer)
      (when (and rcirc-process
!              (eq (process-status rcirc-process) 'open))
!       (with-rcirc-process-buffer rcirc-process
!       (setq rcirc-buffer-alist
!             (rassq-delete-all buffer rcirc-buffer-alist)))
!       (rcirc-update-short-buffer-names)
        (if (rcirc-channel-p rcirc-target)
!         (rcirc-send-string rcirc-process
!                            (concat "PART " rcirc-target
!                                    " :Killed buffer"))
!       (when rcirc-target
!         (rcirc-remove-nick-channel rcirc-process
!                                    (rcirc-nick rcirc-process)
!                                    rcirc-target))))))
! 
  (add-hook 'kill-buffer-hook 'rcirc-kill-buffer-hook)
  
! (defun rcirc-generate-new-buffer-name (process target)
!   "Return a buffer name based on PROCESS and TARGET.
! This is used for the initial name given to irc buffers."
!   (if target
!       (concat target "@" (process-name process))
!     (concat "*" (process-name process) "*")))
  
! (defun rcirc-get-buffer (process target &optional server)
    "Return the buffer associated with the PROCESS and TARGET.
! 
! If TARGET is nil, return the server buffer.
! 
! If optional argument SERVER is non-nil, return the server buffer
! if there is no existing buffer for TARGET, otherwise return nil."
!   (with-rcirc-process-buffer process
!     (if (null target)
!       (current-buffer)
!       (let ((buffer (cdr (assoc-string target rcirc-buffer-alist t))))
!       (or buffer (when server (current-buffer)))))))
  
  (defun rcirc-get-buffer-create (process target)
!   "Return the buffer associated with the PROCESS and TARGET.
! Create the buffer if it doesn't exist."
!   (let ((buffer (rcirc-get-buffer process target)))
!     (or buffer
!       ;; create the buffer
!       (with-rcirc-process-buffer process
!         (let ((new-buffer (get-buffer-create
!                            (rcirc-generate-new-buffer-name process target))))
!           (with-current-buffer new-buffer
!             (rcirc-mode process target))
!           (rcirc-put-nick-channel process (rcirc-nick process) target)
!           new-buffer)))))
  
  (defun rcirc-send-input ()
    "Send input to target associated with the current buffer."
    (interactive)
    (if (not (eq (process-status rcirc-process) 'open))
!       (error "Network connection to %s is not open"
               (process-name rcirc-process))
      (if (< (point) rcirc-prompt-end-marker)
          ;; copy the line down to the input area
          (progn
***************
*** 668,676 ****
              (insert (replace-regexp-in-string
                       "\n\\s-+" " "
                       (buffer-substring-no-properties start end)))))
-       ;; assume text has been read
-       (when (marker-position overlay-arrow-position)
-       (set-marker overlay-arrow-position nil))
        ;; process input
        (goto-char (point-max))
        (let ((target (rcirc-buffer-target))
--- 741,746 ----
***************
*** 690,699 ****
                    (with-current-buffer (current-buffer)
                      (delete-region rcirc-prompt-end-marker (point))
                      (if (string= command "me")
!                         (rcirc-print rcirc-process (rcirc-nick rcirc-process) 
!                                      "ACTION" target args)
!                       (rcirc-print rcirc-process (rcirc-nick rcirc-process) 
!                                    "COMMAND" target input))
                      (set-marker rcirc-prompt-end-marker (point))
                      (if (fboundp fun)
                          (funcall fun args rcirc-process target)
--- 760,769 ----
                    (with-current-buffer (current-buffer)
                      (delete-region rcirc-prompt-end-marker (point))
                      (if (string= command "me")
!                         (rcirc-print rcirc-process (rcirc-nick rcirc-process)
!                                      "ACTION" (current-buffer) args)
!                       (rcirc-print rcirc-process (rcirc-nick rcirc-process)
!                                    "COMMAND" (current-buffer) input))
                      (set-marker rcirc-prompt-end-marker (point))
                      (if (fboundp fun)
                          (funcall fun args rcirc-process target)
***************
*** 751,765 ****
    (interactive)
    (assert (and (eq major-mode 'rcirc-multiline-edit-mode)))
    (assert rcirc-parent-buffer)
    (let ((text (buffer-substring (point-min) (point-max)))
          (buffer (current-buffer))
          (pos (point)))
      (set-buffer rcirc-parent-buffer)
      (goto-char (point-max))
      (insert text)
-     (goto-char (+ rcirc-prompt-end-marker (1- pos)))
      (kill-buffer buffer)
!     (set-window-configuration rcirc-window-configuration)))
  
  (defun rcirc-multiline-edit-cancel ()
    "Cancel the multiline edit."
--- 821,836 ----
    (interactive)
    (assert (and (eq major-mode 'rcirc-multiline-edit-mode)))
    (assert rcirc-parent-buffer)
+   (untabify (point-min) (point-max))
    (let ((text (buffer-substring (point-min) (point-max)))
          (buffer (current-buffer))
          (pos (point)))
      (set-buffer rcirc-parent-buffer)
      (goto-char (point-max))
      (insert text)
      (kill-buffer buffer)
!     (set-window-configuration rcirc-window-configuration)
!     (goto-char (+ rcirc-prompt-end-marker (1- pos)))))
  
  (defun rcirc-multiline-edit-cancel ()
    "Cancel the multiline edit."
***************
*** 768,786 ****
    (kill-buffer (current-buffer))
    (set-window-configuration rcirc-window-configuration))
  
! (defun rcirc-last-buffer (process)
!   "Return the last working buffer for PROCESS.
! Used for displaying messages that don't have an explicit destination."
!   (with-current-buffer (process-buffer process)
!     (or (and rcirc-last-buffer
!              (buffer-live-p rcirc-last-buffer)
!              rcirc-last-buffer)
!         (current-buffer))))
! 
! (defun rcirc-set-last-buffer (process buffer)
!   "Set the last working buffer for PROCESS to BUFFER."
!   (with-current-buffer (process-buffer process)
!     (setq rcirc-last-buffer buffer)))
  
  (defun rcirc-format-response-string (process sender response target text)
    (concat (when rcirc-time-format
--- 839,853 ----
    (kill-buffer (current-buffer))
    (set-window-configuration rcirc-window-configuration))
  
! (defun rcirc-get-any-buffer (process)
!   "Return a buffer for PROCESS, either the one selected or the process 
buffer."
!   (let ((buffer (window-buffer (selected-window))))
!     (if (and buffer
!            (with-current-buffer buffer
!              (and (eq major-mode 'rcirc-mode)
!                   (eq rcirc-process process))))
!       buffer
!       (process-buffer process))))
  
  (defun rcirc-format-response-string (process sender response target text)
    (concat (when rcirc-time-format
***************
*** 792,826 ****
                     (cond ((string= response "PRIVMSG")
                            (setq first "<" middle "> "))
                           ((string= response "NOTICE")
!                           (setq first "-" middle "- "))
                           (t
                            (setq first "[" middle " " end "]")))
!                    (concat first 
                             (rcirc-facify (rcirc-user-nick sender)
                                           (if (string= sender
                                                        (rcirc-nick process))
!                                              'rcirc-my-nick-face
!                                            'rcirc-other-nick-face))
                             middle
                             (rcirc-mangle-text process text)
                             end)))
                  ((string= response "COMMAND")
                   text)
                  ((string= response "ERROR")
!                  (propertize text 'face 'font-lock-warning-face))
                  (t
                   (rcirc-mangle-text
                    process
!                   (rcirc-facify
!                    (concat "*** "
!                          (when (not (string= sender (rcirc-server process)))
!                            (concat (rcirc-user-nick sender) " "))
!                          (when (zerop (string-to-number response))
!                            (concat response " "))
!                            (when (and target (not (string= target 
rcirc-target)))
!                              (concat target " "))
!                            text)
!                    'rcirc-server-face))))))
  
  (defvar rcirc-activity-type nil)
  (make-variable-buffer-local 'rcirc-activity-type)
--- 859,894 ----
                     (cond ((string= response "PRIVMSG")
                            (setq first "<" middle "> "))
                           ((string= response "NOTICE")
!                         (when sender
!                           (setq first "-" middle "- ")))
                           (t
                            (setq first "[" middle " " end "]")))
!                    (concat first
                             (rcirc-facify (rcirc-user-nick sender)
                                           (if (string= sender
                                                        (rcirc-nick process))
!                                              'rcirc-my-nick
!                                            'rcirc-other-nick))
                             middle
                             (rcirc-mangle-text process text)
                             end)))
                  ((string= response "COMMAND")
                   text)
                  ((string= response "ERROR")
!                  (propertize (concat "!!! " text)
!                            'face 'font-lock-warning-face))
                  (t
                   (rcirc-mangle-text
                    process
!                 (concat (rcirc-facify "*** " 'rcirc-server-prefix)
!                         (rcirc-facify
!                          (concat
!                           (when (not (string= sender (rcirc-server process)))
!                             (concat (rcirc-user-nick sender) " "))
!                           (when (zerop (string-to-number response))
!                             (concat response " "))
!                           text)
!                          'rcirc-server)))))))
  
  (defvar rcirc-activity-type nil)
  (make-variable-buffer-local 'rcirc-activity-type)
***************
*** 828,841 ****
    "Print TEXT in the buffer associated with TARGET.
  Format based on SENDER and RESPONSE.  If ACTIVITY is non-nil,
  record activity."
!   (let* ((buffer (cond ((bufferp target) 
                          target)
                         ((not target)
!                         (rcirc-last-buffer process))
!                        ((not (rcirc-channel-p target)) 
!                         (rcirc-get-buffer-create process target))
!                        ((rcirc-get-buffer process target))
!                        (t (process-buffer process))))
           (inhibit-read-only t))
      (with-current-buffer buffer
        (let ((moving (= (point) rcirc-prompt-end-marker))
--- 896,910 ----
    "Print TEXT in the buffer associated with TARGET.
  Format based on SENDER and RESPONSE.  If ACTIVITY is non-nil,
  record activity."
!   (let* ((buffer (cond ((bufferp target)
                          target)
                         ((not target)
!                       (rcirc-get-any-buffer process))
!                      ((not (rcirc-channel-p target))
!                       (rcirc-get-buffer-create process
!                                                (rcirc-user-nick sender)))
!                        ((or (rcirc-get-buffer process target)
!                           (rcirc-get-any-buffer process)))))
           (inhibit-read-only t))
      (with-current-buffer buffer
        (let ((moving (= (point) rcirc-prompt-end-marker))
***************
*** 844,854 ****
  
          (unless (string= sender (rcirc-nick process))
          ;; only decode text from other senders, not ours
!         (setq text (decode-coding-string text buffer-file-coding-system))
          ;; mark the line with overlay arrow
          (unless (or (marker-position overlay-arrow-position)
                      (get-buffer-window (current-buffer)))
!           (set-marker overlay-arrow-position 
                        (marker-position rcirc-prompt-start-marker))))
  
          ;; temporarily set the marker insertion-type because
--- 913,924 ----
  
          (unless (string= sender (rcirc-nick process))
          ;; only decode text from other senders, not ours
!         (setq text (decode-coding-string (or text "")
!                                          buffer-file-coding-system))
          ;; mark the line with overlay arrow
          (unless (or (marker-position overlay-arrow-position)
                      (get-buffer-window (current-buffer)))
!           (set-marker overlay-arrow-position
                        (marker-position rcirc-prompt-start-marker))))
  
          ;; temporarily set the marker insertion-type because
***************
*** 869,875 ****
                   (or rcirc-fill-prefix
                       (make-string
                        (+ (if rcirc-time-format
!                              (length (format-time-string 
                                        rcirc-time-format))
                             0)
                           (cond ((or (string= response "PRIVMSG")
--- 939,945 ----
                   (or rcirc-fill-prefix
                       (make-string
                        (+ (if rcirc-time-format
!                              (length (format-time-string
                                        rcirc-time-format))
                             0)
                           (cond ((or (string= response "PRIVMSG")
***************
*** 882,911 ****
                               (t 3))           ; ***
                           1)
                        ? )))
!                 (fill-column (or rcirc-fill-column fill-column)))
              (fill-region fill-start rcirc-prompt-start-marker 'left t)))
  
-         ;; truncate buffer if it is very long
-         (save-excursion
-           (when (and rcirc-buffer-maximum-lines
-                      (> rcirc-buffer-maximum-lines 0)
-                      (= (forward-line (- rcirc-buffer-maximum-lines)) 0))
-             (delete-region (point-min) (point))))
- 
          ;; set inserted text to be read-only
          (when rcirc-read-only-flag
            (put-text-property rcirc-prompt-start-marker fill-start 'read-only 
t)
            (let ((inhibit-read-only t))
!             (put-text-property rcirc-prompt-start-marker fill-start 
                               'front-sticky t)
              (put-text-property (1- (point)) (point) 'rear-nonsticky t)))
  
          ;; set the window point for buffers show in windows
          (walk-windows (lambda (w)
                          (unless (eq (selected-window) w)
!                           (when (and (eq (current-buffer) 
                                         (window-buffer w))
!                                      (>= (window-point w) 
                                         rcirc-prompt-end-marker))
                              (set-window-point w (point-max)))))
                        nil t)
--- 952,985 ----
                               (t 3))           ; ***
                           1)
                        ? )))
!                 (fill-column (cond ((eq rcirc-fill-column 'frame-width)
!                                   (1- (frame-width)))
!                                  (rcirc-fill-column
!                                   rcirc-fill-column)
!                                  (t fill-column))))
              (fill-region fill-start rcirc-prompt-start-marker 'left t)))
  
          ;; set inserted text to be read-only
          (when rcirc-read-only-flag
            (put-text-property rcirc-prompt-start-marker fill-start 'read-only 
t)
            (let ((inhibit-read-only t))
!             (put-text-property rcirc-prompt-start-marker fill-start
                               'front-sticky t)
              (put-text-property (1- (point)) (point) 'rear-nonsticky t)))
  
+         ;; truncate buffer if it is very long
+         (save-excursion
+           (when (and rcirc-buffer-maximum-lines
+                      (> rcirc-buffer-maximum-lines 0)
+                      (= (forward-line (- rcirc-buffer-maximum-lines)) 0))
+             (delete-region (point-min) (point))))
+ 
          ;; set the window point for buffers show in windows
          (walk-windows (lambda (w)
                          (unless (eq (selected-window) w)
!                           (when (and (eq (current-buffer)
                                         (window-buffer w))
!                                      (>= (window-point w)
                                         rcirc-prompt-end-marker))
                              (set-window-point w (point-max)))))
                        nil t)
***************
*** 924,938 ****
                                     (regexp-quote (rcirc-nick process))
                                     "\\b")
                             text)))
!           (when (or (not rcirc-ignore-channel-activity)
                      ;; always notice when our nick is mentioned, even
                      ;; if ignoring channel activity
                      nick-match)
              (rcirc-record-activity
!            (current-buffer) 
             (when (or nick-match (not (rcirc-channel-p rcirc-target)))
               'nick)))))
  
        (run-hook-with-args 'rcirc-print-hooks
                            process sender response target text))))
  
--- 998,1013 ----
                                     (regexp-quote (rcirc-nick process))
                                     "\\b")
                             text)))
!           (when (or (not rcirc-ignore-buffer-activity-flag)
                      ;; always notice when our nick is mentioned, even
                      ;; if ignoring channel activity
                      nick-match)
              (rcirc-record-activity
!            (current-buffer)
             (when (or nick-match (not (rcirc-channel-p rcirc-target)))
               'nick)))))
  
+       (sit-for 0)                     ; displayed text before hook
        (run-hook-with-args 'rcirc-print-hooks
                            process sender response target text))))
  
***************
*** 948,958 ****
    "Join CHANNELS."
    (save-window-excursion
      (mapc (lambda (channel)
!             (with-current-buffer (process-buffer process)
!               (let (rcirc-last-buffer)  ; make sure /join text is
!                                         ; printed in server buffer
!                 (rcirc-print process (rcirc-nick process) "COMMAND"
!                              nil (concat "/join " channel)))
                (rcirc-cmd-join channel process)))
            channels)))
  
--- 1023,1029 ----
    "Join CHANNELS."
    (save-window-excursion
      (mapc (lambda (channel)
!             (with-rcirc-process-buffer process
                (rcirc-cmd-join channel process)))
            channels)))
  
***************
*** 972,987 ****
  (defun rcirc-nick-channels (process nick)
    "Return list of channels for NICK."
    (let ((nick (rcirc-user-nick nick)))
!     (with-current-buffer (process-buffer process)
        (mapcar (lambda (x) (car x))
                (gethash nick rcirc-nick-table)))))
  
  (defun rcirc-put-nick-channel (process nick channel)
    "Add CHANNEL to list associated with NICK."
!   (with-current-buffer (process-buffer process)
      (let* ((nick (rcirc-user-nick nick))
             (chans (gethash nick rcirc-nick-table))
!            (record (assoc channel chans)))
        (if record
            (setcdr record (current-time))
          (puthash nick (cons (cons channel (current-time))
--- 1043,1058 ----
  (defun rcirc-nick-channels (process nick)
    "Return list of channels for NICK."
    (let ((nick (rcirc-user-nick nick)))
!     (with-rcirc-process-buffer process
        (mapcar (lambda (x) (car x))
                (gethash nick rcirc-nick-table)))))
  
  (defun rcirc-put-nick-channel (process nick channel)
    "Add CHANNEL to list associated with NICK."
!   (with-rcirc-process-buffer process
      (let* ((nick (rcirc-user-nick nick))
             (chans (gethash nick rcirc-nick-table))
!            (record (assoc-string channel chans t)))
        (if record
            (setcdr record (current-time))
          (puthash nick (cons (cons channel (current-time))
***************
*** 990,1015 ****
  
  (defun rcirc-nick-remove (process nick)
    "Remove NICK from table."
!   (with-current-buffer (process-buffer process)
      (remhash nick rcirc-nick-table)))
  
  (defun rcirc-remove-nick-channel (process nick channel)
    "Remove the CHANNEL from list associated with NICK."
!   (with-current-buffer (process-buffer process)
      (let* ((nick (rcirc-user-nick nick))
             (chans (gethash nick rcirc-nick-table))
!            (newchans (assq-delete-all channel chans)))
        (if newchans
            (puthash nick newchans rcirc-nick-table)
          (remhash nick rcirc-nick-table)))))
  
  (defun rcirc-channel-nicks (process channel)
    "Return the list of nicks in CHANNEL sorted by last activity."
!   (with-current-buffer (process-buffer process)
      (let (nicks)
        (maphash
         (lambda (k v)
!          (let ((record (assoc channel v)))
             (if record
                 (setq nicks (cons (cons k (cdr record)) nicks)))))
         rcirc-nick-table)
--- 1061,1091 ----
  
  (defun rcirc-nick-remove (process nick)
    "Remove NICK from table."
!   (with-rcirc-process-buffer process
      (remhash nick rcirc-nick-table)))
  
  (defun rcirc-remove-nick-channel (process nick channel)
    "Remove the CHANNEL from list associated with NICK."
!   (with-rcirc-process-buffer process
      (let* ((nick (rcirc-user-nick nick))
             (chans (gethash nick rcirc-nick-table))
!            (newchans
!           ;; instead of assoc-string-delete-all:
!           (let ((record (assoc-string channel chans t)))
!             (when record
!               (setcar record 'delete)
!               (assq-delete-all 'delete chans)))))
        (if newchans
            (puthash nick newchans rcirc-nick-table)
          (remhash nick rcirc-nick-table)))))
  
  (defun rcirc-channel-nicks (process channel)
    "Return the list of nicks in CHANNEL sorted by last activity."
!   (with-rcirc-process-buffer process
      (let (nicks)
        (maphash
         (lambda (k v)
!          (let ((record (assoc-string channel v t)))
             (if record
                 (setq nicks (cons (cons k (cdr record)) nicks)))))
         rcirc-nick-table)
***************
*** 1017,1028 ****
                (sort nicks (lambda (x y) (time-less-p (cdr y) (cdr x))))))))
  
  ;;; activity tracking
! (or (assq 'rcirc-ignore-channel-activity minor-mode-alist)
      (setq minor-mode-alist
!           (cons '(rcirc-ignore-channel-activity " Ignore") minor-mode-alist)))
  
! (defun rcirc-toggle-ignore-channel-activity (&optional all)
!   "Toggle the value of `rcirc-ignore-channel-activity'.
  If ALL is non-nil, instead toggle the value of
  `rcirc-ignore-all-activity-flag'."
    (interactive "P")
--- 1093,1104 ----
                (sort nicks (lambda (x y) (time-less-p (cdr y) (cdr x))))))))
  
  ;;; activity tracking
! (or (assq 'rcirc-ignore-buffer-activity-flag minor-mode-alist)
      (setq minor-mode-alist
!           (cons '(rcirc-ignore-buffer-activity-flag " Ignore") 
minor-mode-alist)))
  
! (defun rcirc-toggle-ignore-buffer-activity (&optional all)
!   "Toggle the value of `rcirc-ignore-buffer-activity-flag'.
  If ALL is non-nil, instead toggle the value of
  `rcirc-ignore-all-activity-flag'."
    (interactive "P")
***************
*** 1030,1042 ****
        (progn
          (setq rcirc-ignore-all-activity-flag
                (not rcirc-ignore-all-activity-flag))
!         (message (concat "Global activity "
!                          (if rcirc-ignore-all-activity-flag
!                              "hidden"
!                            "displayed")))
          (rcirc-update-activity-string))
!     (setq rcirc-ignore-channel-activity
!           (not rcirc-ignore-channel-activity)))
    (force-mode-line-update))
  
  (defvar rcirc-switch-to-buffer-function 'switch-to-buffer
--- 1106,1120 ----
        (progn
          (setq rcirc-ignore-all-activity-flag
                (not rcirc-ignore-all-activity-flag))
!         (message (if rcirc-ignore-all-activity-flag
!                    "Hide all buffer activity"
!                  "Display buffer activity"))
          (rcirc-update-activity-string))
!     (setq rcirc-ignore-buffer-activity-flag
!           (not rcirc-ignore-buffer-activity-flag))
!     (message (if rcirc-ignore-buffer-activity-flag
!                "Ignore activity in this buffer"
!              "Notice activity in this buffer")))
    (force-mode-line-update))
  
  (defvar rcirc-switch-to-buffer-function 'switch-to-buffer
***************
*** 1069,1097 ****
            (setq rcirc-last-non-irc-buffer (current-buffer)))
          (if (and (> arg 0)
                   (<= arg (length rcirc-activity)))
!             (funcall rcirc-switch-to-buffer-function 
                     (nth (1- arg) rcirc-activity))
            (message "Invalid arg: %d" arg)))
      (if (eq major-mode 'rcirc-mode)
          (if (not (and rcirc-last-non-irc-buffer
                        (buffer-live-p rcirc-last-non-irc-buffer)))
!             (message "No last buffer.")
            (funcall rcirc-switch-to-buffer-function rcirc-last-non-irc-buffer)
            (setq rcirc-last-non-irc-buffer nil))
!       (message "No channel activity.  Go start something."))))
  
  (defvar rcirc-activity-hooks nil
    "Hook to be run when there is channel activity.
  
  Functions are called with a single argument, the buffer with the
  activity.  Only run if the buffer is not visible and
! `rcirc-ignore-channel-activity' is non-nil.")
  
  (defun rcirc-record-activity (buffer type)
    "Record BUFFER activity with TYPE."
    (with-current-buffer buffer
      (when (not (get-buffer-window (current-buffer) t))
!       (add-to-list 'rcirc-activity (current-buffer) 'append)
        (if (not rcirc-activity-type)
            (setq rcirc-activity-type type))
        (rcirc-update-activity-string)))
--- 1147,1176 ----
            (setq rcirc-last-non-irc-buffer (current-buffer)))
          (if (and (> arg 0)
                   (<= arg (length rcirc-activity)))
!             (funcall rcirc-switch-to-buffer-function
                     (nth (1- arg) rcirc-activity))
            (message "Invalid arg: %d" arg)))
      (if (eq major-mode 'rcirc-mode)
          (if (not (and rcirc-last-non-irc-buffer
                        (buffer-live-p rcirc-last-non-irc-buffer)))
!             (message "No IRC activity.  Start something.")
!         (message "No more IRC activity.  Go back to work.")
            (funcall rcirc-switch-to-buffer-function rcirc-last-non-irc-buffer)
            (setq rcirc-last-non-irc-buffer nil))
!       (message "No IRC activity."))))
  
  (defvar rcirc-activity-hooks nil
    "Hook to be run when there is channel activity.
  
  Functions are called with a single argument, the buffer with the
  activity.  Only run if the buffer is not visible and
! `rcirc-ignore-buffer-activity-flag' is non-nil.")
  
  (defun rcirc-record-activity (buffer type)
    "Record BUFFER activity with TYPE."
    (with-current-buffer buffer
      (when (not (get-buffer-window (current-buffer) t))
!       (add-to-list 'rcirc-activity (current-buffer))
        (if (not rcirc-activity-type)
            (setq rcirc-activity-type type))
        (rcirc-update-activity-string)))
***************
*** 1103,1140 ****
    (with-current-buffer buffer
      (setq rcirc-activity-type nil)))
  
  (defun rcirc-update-activity-string ()
    "Update mode-line string."
    (setq rcirc-activity-string
!         (if (or rcirc-ignore-all-activity-flag
!                 (not rcirc-activity))
!             ""
!           (concat " [" (mapconcat 
                        (lambda (b)
                          (let ((s (rcirc-short-buffer-name b)))
                            (with-current-buffer b
                              (if (not (eq rcirc-activity-type 'nick))
                                  s
!                               (rcirc-facify s 
!                                             'rcirc-mode-line-nick-face)))))
!                       rcirc-activity ",") "]"))))
  
  (defun rcirc-short-buffer-name (buffer)
    "Return a short name for BUFFER to use in the modeline indicator."
    (with-current-buffer buffer
!     (or rcirc-target (process-name rcirc-process))))
  
! (defun rcirc-update-activity ()
!   "Go through visible windows and remove buffers from activity list."
!   (walk-windows (lambda (w) (rcirc-clear-activity (window-buffer w))))
!   (rcirc-update-activity-string))
  
  
  ;;; /commands these are called with 3 args: PROCESS, TARGET, which is
  ;; the current buffer/channel/user, and ARGS, which is a string
  ;; containing the text following the /cmd.
  
! (defmacro defun-rcirc-command (command argument docstring interactive-form 
                                         &rest body)
    "Define a command."
    `(defun ,(intern (concat "rcirc-cmd-" (symbol-name command)))
--- 1182,1296 ----
    (with-current-buffer buffer
      (setq rcirc-activity-type nil)))
  
+ ;; TODO: add mouse properties
  (defun rcirc-update-activity-string ()
    "Update mode-line string."
    (setq rcirc-activity-string
!       (cond (rcirc-ignore-all-activity-flag
!              " DND")
!             ((not rcirc-activity)
!              "")
!             (t
!              (concat " ["
!                      (mapconcat
                        (lambda (b)
                          (let ((s (rcirc-short-buffer-name b)))
                            (with-current-buffer b
                              (if (not (eq rcirc-activity-type 'nick))
                                  s
!                               (rcirc-facify s 'rcirc-mode-line-nick)))))
!                       rcirc-activity ",")
!                      "]")))))
  
  (defun rcirc-short-buffer-name (buffer)
    "Return a short name for BUFFER to use in the modeline indicator."
    (with-current-buffer buffer
!     (or rcirc-short-buffer-name (buffer-name))))
  
! (defvar rcirc-current-buffer nil)
! (defun rcirc-window-configuration-change ()
!   "Go through visible windows and remove buffers from activity list.
! Also, clear the overlay arrow if the current buffer is now hidden."
!   (let ((current-now-hidden t))
!     (walk-windows (lambda (w)
!                   (let ((buf (window-buffer w)))
!                     (rcirc-clear-activity buf)
!                     (when (eq buf rcirc-current-buffer)
!                       (setq current-now-hidden nil)))))
!     (when (and rcirc-current-buffer current-now-hidden)
!       (with-current-buffer rcirc-current-buffer
!       (when (eq major-mode 'rcirc-mode)
!         (marker-position overlay-arrow-position)
!         (set-marker overlay-arrow-position nil)))))
! 
!   ;; remove any killed buffers from list
!   (setq rcirc-activity
!       (delq nil (mapcar (lambda (buf) (when (buffer-live-p buf) buf))
!                         rcirc-activity)))
!   (rcirc-update-activity-string)
!   (setq rcirc-current-buffer (current-buffer)))
  
  
+ ;;; buffer name abbreviation
+ (defun rcirc-update-short-buffer-names ()
+   (let ((bufalist
+        (apply 'append (mapcar (lambda (process)
+                                 (with-rcirc-process-buffer process
+                                   rcirc-buffer-alist))
+                               (rcirc-process-list)))))
+     (dolist (i (rcirc-abbreviate bufalist))
+       (with-current-buffer (cdr i)
+       (setq rcirc-short-buffer-name (car i))))))
+ 
+ (defun rcirc-abbreviate (pairs)
+   (apply 'append (mapcar 'rcirc-rebuild-tree (rcirc-make-trees pairs))))
+ 
+ (defun rcirc-rebuild-tree (tree &optional acc)
+   (let ((ch (char-to-string (car tree))))
+     (dolist (x (cdr tree))
+       (if (listp x)
+         (setq acc (append acc
+                          (mapcar (lambda (y)
+                                    (cons (concat ch (car y))
+                                          (cdr y)))
+                                  (rcirc-rebuild-tree x))))
+       (setq acc (cons (cons ch x) acc))))
+     acc))
+ 
+ (defun rcirc-make-trees (pairs)
+   (let (alist)
+     (mapc (lambda (pair)
+           (if (consp pair)
+               (let* ((str (car pair))
+                      (data (cdr pair))
+                      (char (unless (zerop (length str))
+                              (aref str 0)))
+                      (rest (unless (zerop (length str))
+                              (substring str 1)))
+                      (part (if char (assq char alist))))
+                 (if part
+                     ;; existing partition
+                     (setcdr part (cons (cons rest data) (cdr part)))
+                   ;; new partition
+                   (setq alist (cons (if char
+                                         (list char (cons rest data))
+                                       data)
+                                     alist))))
+             (setq alist (cons pair alist))))
+         pairs)
+     ;; recurse into cdrs of alist
+     (mapc (lambda (x)
+           (when (and (listp x) (listp (cadr x)))
+             (setcdr x (if (> (length (cdr x)) 1)
+                           (rcirc-make-trees (cdr x))
+                         (setcdr x (list (cdadr x)))))))
+         alist)))
+ 
  ;;; /commands these are called with 3 args: PROCESS, TARGET, which is
  ;; the current buffer/channel/user, and ARGS, which is a string
  ;; containing the text following the /cmd.
  
! (defmacro defun-rcirc-command (command argument docstring interactive-form
                                         &rest body)
    "Define a command."
    `(defun ,(intern (concat "rcirc-cmd-" (symbol-name command)))
***************
*** 1153,1160 ****
    (if (null message)
        (progn
          (setq target (completing-read "Message nick: "
!                                       (with-current-buffer
!                                           (process-buffer rcirc-process)
                                          rcirc-nick-table)))
          (when (> (length target) 0)
            (setq message (read-string (format "Message %s: " target)))
--- 1309,1315 ----
    (if (null message)
        (progn
          (setq target (completing-read "Message nick: "
!                                       (with-rcirc-process-buffer rcirc-process
                                          rcirc-nick-table)))
          (when (> (length target) 0)
            (setq message (read-string (format "Message %s: " target)))
***************
*** 1169,1181 ****
  (defun-rcirc-command query (nick)
    "Open a private chat buffer to NICK."
    (interactive (list (completing-read "Query nick: "
!                                       (with-current-buffer
!                                           (process-buffer rcirc-process)
                                          rcirc-nick-table))))
!   (let ((new-buffer (eq (rcirc-get-buffer rcirc-process nick)
!                         (process-buffer rcirc-process))))
!     (switch-to-buffer (rcirc-get-buffer-create process nick))
!     (when new-buffer
        (rcirc-cmd-whois nick))))
  
  (defun-rcirc-command join (args)
--- 1324,1335 ----
  (defun-rcirc-command query (nick)
    "Open a private chat buffer to NICK."
    (interactive (list (completing-read "Query nick: "
!                                       (with-rcirc-process-buffer rcirc-process
                                          rcirc-nick-table))))
!   (let ((existing-buffer (rcirc-get-buffer process nick)))
!     (switch-to-buffer (or existing-buffer
!                         (rcirc-get-buffer-create process nick)))
!     (when (not existing-buffer)
        (rcirc-cmd-whois nick))))
  
  (defun-rcirc-command join (args)
***************
*** 1185,1203 ****
           (buffer (rcirc-get-buffer-create process channel)))
      (when (not (eq (selected-window) (minibuffer-window)))
        (funcall rcirc-switch-to-buffer-function buffer))
!     (rcirc-send-string process (concat "JOIN " args))
!     (rcirc-set-last-buffer process buffer)))
  
  (defun-rcirc-command part (channel)
    "Part CHANNEL."
    (interactive "sPart channel: ")
    (let ((channel (if (> (length channel) 0) channel target)))
!     (rcirc-send-string process (concat "PART " channel " :" 
(rcirc-version)))))
  
  (defun-rcirc-command quit (reason)
    "Send a quit message to server with REASON."
    (interactive "sQuit reason: ")
!   (rcirc-send-string process (concat "QUIT :" reason)))
  
  (defun-rcirc-command nick (nick)
    "Change nick to NICK."
--- 1339,1359 ----
           (buffer (rcirc-get-buffer-create process channel)))
      (when (not (eq (selected-window) (minibuffer-window)))
        (funcall rcirc-switch-to-buffer-function buffer))
!     (rcirc-send-string process (concat "JOIN " args))))
  
  (defun-rcirc-command part (channel)
    "Part CHANNEL."
    (interactive "sPart channel: ")
    (let ((channel (if (> (length channel) 0) channel target)))
!     (rcirc-send-string process (concat "PART " channel " :" 
rcirc-id-string))))
  
  (defun-rcirc-command quit (reason)
    "Send a quit message to server with REASON."
    (interactive "sQuit reason: ")
!   (rcirc-send-string process (concat "QUIT :"
!                                    (if (not (zerop (length reason)))
!                                        reason
!                                      rcirc-id-string))))
  
  (defun-rcirc-command nick (nick)
    "Change nick to NICK."
***************
*** 1232,1241 ****
    "Request information from server about NICK."
    (interactive (list
                  (completing-read "Whois: "
!                                  (with-current-buffer
!                                      (process-buffer rcirc-process)
                                     rcirc-nick-table))))
-   (rcirc-set-last-buffer rcirc-process (current-buffer))
    (rcirc-send-string process (concat "WHOIS " nick)))
  
  (defun-rcirc-command mode (args)
--- 1388,1395 ----
    "Request information from server about NICK."
    (interactive (list
                  (completing-read "Whois: "
!                                  (with-rcirc-process-buffer rcirc-process
                                     rcirc-nick-table))))
    (rcirc-send-string process (concat "WHOIS " nick)))
  
  (defun-rcirc-command mode (args)
***************
*** 1267,1273 ****
                                                                rcirc-target))
                          (read-from-minibuffer "Kick reason: "))))
    (let* ((arglist (split-string arg))
!          (argstring (concat (car arglist) " :" 
                              (mapconcat 'identity (cdr arglist) " "))))
      (rcirc-send-string process (concat "KICK " target " " argstring))))
  
--- 1421,1427 ----
                                                                rcirc-target))
                          (read-from-minibuffer "Kick reason: "))))
    (let* ((arglist (split-string arg))
!          (argstring (concat (car arglist) " :"
                              (mapconcat 'identity (cdr arglist) " "))))
      (rcirc-send-string process (concat "KICK " target " " argstring))))
  
***************
*** 1275,1283 ****
    (if (string-match "^\\([^ ]+\\)\\s-+\\(.+\\)$" args)
        (let ((target (match-string 1 args))
              (request (match-string 2 args)))
!         (rcirc-send-message process target 
!                             (concat "\C-a" (upcase request) "\C-a")))
!     (rcirc-print process (rcirc-nick process) "ERROR" target
                   "usage: /ctcp NICK REQUEST")))
  
  (defun rcirc-cmd-me (args &optional process target)
--- 1429,1438 ----
    (if (string-match "^\\([^ ]+\\)\\s-+\\(.+\\)$" args)
        (let ((target (match-string 1 args))
              (request (match-string 2 args)))
!         (rcirc-send-string process
!                          (format "PRIVMSG %s \C-a%s\C-a"
!                                  target (upcase request))))
!     (rcirc-print process (rcirc-nick process) "ERROR" nil
                   "usage: /ctcp NICK REQUEST")))
  
  (defun rcirc-cmd-me (args &optional process target)
***************
*** 1287,1293 ****
  (defun rcirc-message-leader (sender face)
    "Return a string with SENDER propertized with FACE."
    (rcirc-facify (concat "<" (rcirc-user-nick sender) "> ") face))
!   
  (defun rcirc-facify (string face)
    "Return a copy of STRING with FACE property added."
    (propertize (or string "") 'face face 'rear-nonsticky t))
--- 1442,1448 ----
  (defun rcirc-message-leader (sender face)
    "Return a string with SENDER propertized with FACE."
    (rcirc-facify (concat "<" (rcirc-user-nick sender) "> ") face))
! 
  (defun rcirc-facify (string face)
    "Return a copy of STRING with FACE property added."
    (propertize (or string "") 'face face 'rear-nonsticky t))
***************
*** 1309,1314 ****
--- 1464,1483 ----
                                   completions nil nil initial-input 'history)
                  arg)))
  
+ (defun rcirc-browse-url-at-point (point)
+   "Send URL at point to `browse-url'."
+   (interactive "d")
+   (let ((beg (previous-single-property-change point 'mouse-face))
+       (end (next-single-property-change point 'mouse-face)))
+     (browse-url (buffer-substring-no-properties beg end))))
+ 
+ (defun rcirc-browse-url-at-mouse (event)
+   "Send URL at mouse click to `browse-url'."
+   (interactive "e")
+   (let ((position (event-end event)))
+     (with-current-buffer (window-buffer (posn-window position))
+       (rcirc-browse-url-at-point (posn-point position)))))
+ 
  (defun rcirc-map-regexp (function regexp string)
    "Return a copy of STRING after calling FUNCTION for each REGEXP match.
  FUNCTION takes 3 arguments, MATCH-START, MATCH-END, and STRING."
***************
*** 1346,1352 ****
            (rcirc-map-regexp (lambda (start end string)
                                (add-text-properties
                                 start end
!                                (list 'face 'rcirc-nick-in-message-face
                                       'rear-nonsticky t)
                                 string))
                              (concat "\\b"
--- 1515,1521 ----
            (rcirc-map-regexp (lambda (start end string)
                                (add-text-properties
                                 start end
!                                (list 'face 'rcirc-nick-in-message
                                       'rear-nonsticky t)
                                 string))
                              (concat "\\b"
***************
*** 1360,1366 ****
           (let ((orig-face (get-text-property start 'face string)))
             (add-text-properties start end
                                  (list 'face (list orig-face 'bold)
!                                       'rear-nonsticky t)
                                  string))
             (push (substring string start end) rcirc-urls))
           rcirc-url-regexp
--- 1529,1537 ----
           (let ((orig-face (get-text-property start 'face string)))
             (add-text-properties start end
                                  (list 'face (list orig-face 'bold)
!                                       'rear-nonsticky t
!                                       'mouse-face 'highlight
!                                       'keymap rcirc-browse-url-map)
                                  string))
             (push (substring string start end) rcirc-urls))
           rcirc-url-regexp
***************
*** 1376,1388 ****
  (defun rcirc-handler-001 (process sender args text)
    (rcirc-handler-generic process "001" sender args text)
    ;; set the real server name
!   (with-current-buffer (process-buffer process)
      (setq rcirc-server sender)
      (setq rcirc-nick (car args))
      (rcirc-update-prompt)
      (when rcirc-auto-authenticate-flag (rcirc-authenticate))
!     (let (rcirc-last-buffer)
!       (rcirc-join-channels process rcirc-startup-channels))))
  
  (defun rcirc-handler-PRIVMSG (process sender args text)
    (let ((target (if (rcirc-channel-p (car args))
--- 1547,1558 ----
  (defun rcirc-handler-001 (process sender args text)
    (rcirc-handler-generic process "001" sender args text)
    ;; set the real server name
!   (with-rcirc-process-buffer process
      (setq rcirc-server sender)
      (setq rcirc-nick (car args))
      (rcirc-update-prompt)
      (when rcirc-auto-authenticate-flag (rcirc-authenticate))
!     (rcirc-join-channels process rcirc-startup-channels)))
  
  (defun rcirc-handler-PRIVMSG (process sender args text)
    (let ((target (if (rcirc-channel-p (car args))
***************
*** 1399,1454 ****
  (defun rcirc-handler-NOTICE (process sender args text)
    (let ((target (car args))
          (message (cadr args)))
!     (rcirc-print process sender "NOTICE"
!                  (cond ((rcirc-channel-p target)
!                         target)
!                        ((string-match "^\\[\\(#[^ ]+\\)\\]" message)
!                         (match-string 1 message))
!                        (sender
!                         (if (string= sender (rcirc-server process))
!                             (process-buffer process)
!                           (rcirc-user-nick sender))))
!                  message t)
!     (and sender (rcirc-put-nick-channel process sender target))))
  
  (defun rcirc-handler-WALLOPS (process sender args text)
    (let ((target (rcirc-user-nick sender)))
      (rcirc-print process sender "WALLOPS" target (car args) t)))
  
  (defun rcirc-handler-JOIN (process sender args text)
!   (let ((channel (downcase (car args)))
          (nick (rcirc-user-nick sender)))
      (rcirc-get-buffer-create process channel)
      (rcirc-print process sender "JOIN" channel "")
  
      ;; print in private chat buffer if it exists
!     (if (not (eq (process-buffer rcirc-process)
!                  (rcirc-get-buffer rcirc-process nick)))
!         (rcirc-print process sender "JOIN" nick channel))
! 
!     (rcirc-put-nick-channel process sender channel)
!     (if (string= nick (rcirc-nick process))
!         (setq rcirc-channels (cons channel rcirc-channels)))))
  
  ;; PART and KICK are handled the same way
  (defun rcirc-handler-PART-or-KICK (process response channel sender nick args)
    (rcirc-print process sender response channel (concat channel " " args))
  
    ;; print in private chat buffer if it exists
!   (when (not (eq (process-buffer rcirc-process)
!                  (rcirc-get-buffer rcirc-process nick)))
      (rcirc-print process sender response nick (concat channel " " args)))
  
    (if (not (string= nick (rcirc-nick process)))
        ;; this is someone else leaving
!   (rcirc-remove-nick-channel process nick channel)
!   ;; this is us leaving
!   (mapc (lambda (n)
!           (rcirc-remove-nick-channel process n channel))
!         (rcirc-channel-nicks process channel))
!   (setq rcirc-channels (delete channel rcirc-channels))
!   (with-current-buffer (rcirc-get-buffer process channel)
!     (setq rcirc-target nil))))
  
  (defun rcirc-handler-PART (process sender args text)
    (rcirc-handler-PART-or-KICK process "PART"
--- 1569,1628 ----
  (defun rcirc-handler-NOTICE (process sender args text)
    (let ((target (car args))
          (message (cadr args)))
!     (if (string-match "^\C-a\\(.*\\)\C-a$" message)
!         (rcirc-handler-CTCP-response process target sender
!                                    (match-string 1 message))
!       (rcirc-print process sender "NOTICE"
!                  (cond ((rcirc-channel-p target)
!                         target)
!                        ;;; -ChanServ- [#gnu] Welcome...
!                        ((string-match "^\\[\\(#[^ ]+\\)\\]" message)
!                         (match-string 1 message))
!                        (sender
!                         (if (string= sender (rcirc-server process))
!                             (process-buffer process)
!                           (rcirc-user-nick sender))))
!                  message t))))
!     ;; do we need this:
!     ;;(and sender (rcirc-put-nick-channel process sender target))))
  
  (defun rcirc-handler-WALLOPS (process sender args text)
    (let ((target (rcirc-user-nick sender)))
      (rcirc-print process sender "WALLOPS" target (car args) t)))
  
  (defun rcirc-handler-JOIN (process sender args text)
!   (let ((channel (car args))
          (nick (rcirc-user-nick sender)))
      (rcirc-get-buffer-create process channel)
      (rcirc-print process sender "JOIN" channel "")
  
      ;; print in private chat buffer if it exists
!     (when (rcirc-get-buffer rcirc-process nick)
!       (rcirc-print process sender "JOIN" nick channel))
! 
!     (rcirc-put-nick-channel process sender channel)))
  
  ;; PART and KICK are handled the same way
  (defun rcirc-handler-PART-or-KICK (process response channel sender nick args)
    (rcirc-print process sender response channel (concat channel " " args))
  
    ;; print in private chat buffer if it exists
!   (when (rcirc-get-buffer rcirc-process nick)
      (rcirc-print process sender response nick (concat channel " " args)))
  
    (if (not (string= nick (rcirc-nick process)))
        ;; this is someone else leaving
!       (rcirc-remove-nick-channel process nick channel)
!     ;; this is us leaving
!     (mapc (lambda (n)
!           (rcirc-remove-nick-channel process n channel))
!         (rcirc-channel-nicks process channel))
! 
!     ;; if the buffer is still around, make it inactive
!     (let ((buffer (rcirc-get-buffer process channel)))
!       (when buffer
!       (with-current-buffer buffer
!         (setq rcirc-target nil))))))
  
  (defun rcirc-handler-PART (process sender args text)
    (rcirc-handler-PART-or-KICK process "PART"
***************
*** 1456,1462 ****
                                (cadr args)))
  
  (defun rcirc-handler-KICK (process sender args text)
!   (rcirc-handler-PART-or-KICK process "KICK" (car args) sender (cadr args) 
                                (caddr args)))
  
  (defun rcirc-handler-QUIT (process sender args text)
--- 1630,1636 ----
                                (cadr args)))
  
  (defun rcirc-handler-KICK (process sender args text)
!   (rcirc-handler-PART-or-KICK process "KICK" (car args) sender (cadr args)
                                (caddr args)))
  
  (defun rcirc-handler-QUIT (process sender args text)
***************
*** 1466,1474 ****
            (rcirc-nick-channels process nick))
  
      ;; print in private chat buffer if it exists
!     (if (not (eq (process-buffer rcirc-process)
!                  (rcirc-get-buffer rcirc-process nick)))
!         (rcirc-print process sender "QUIT" nick (apply 'concat args)))
  
      (rcirc-nick-remove process nick)))
  
--- 1640,1648 ----
            (rcirc-nick-channels process nick))
  
      ;; print in private chat buffer if it exists
!     (let ((buffer (rcirc-get-buffer rcirc-process nick)))
!       (when buffer
!       (rcirc-print process sender "QUIT" buffer (apply 'concat args))))
  
      (rcirc-nick-remove process nick)))
  
***************
*** 1480,1504 ****
      (dolist (target channels)
        (rcirc-print process sender "NICK" target new-nick))
      ;; update private chat buffer, if it exists
!     (with-current-buffer (rcirc-get-buffer process old-nick)
!       (when (not (equal (process-buffer rcirc-process)
!                         (current-buffer)))
!         (rcirc-print process sender "NICK" old-nick new-nick)
!         (setq rcirc-target new-nick)
!         (rename-buffer (rcirc-get-buffer-name process new-nick))))
      ;; remove old nick and add new one
!     (with-current-buffer (process-buffer process)
        (let ((v (gethash old-nick rcirc-nick-table)))
          (remhash old-nick rcirc-nick-table)
          (puthash new-nick v rcirc-nick-table))
        ;; if this is our nick...
        (when (string= old-nick rcirc-nick)
          (setq rcirc-nick new-nick)
!         ;; update prompts
!         (mapc (lambda (target)
!                 (with-current-buffer (rcirc-get-buffer process target)
!                   (rcirc-update-prompt)))
!               (append rcirc-channels rcirc-private-chats))
          ;; reauthenticate
          (when rcirc-auto-authenticate-flag (rcirc-authenticate))))))
  
--- 1654,1674 ----
      (dolist (target channels)
        (rcirc-print process sender "NICK" target new-nick))
      ;; update private chat buffer, if it exists
!     (let ((chat-buffer (rcirc-get-buffer process old-nick)))
!       (when chat-buffer
!       (with-current-buffer chat-buffer
!         (rcirc-print process sender "NICK" old-nick new-nick)
!         (setq rcirc-target new-nick)
!         (rename-buffer (rcirc-generate-new-buffer-name process new-nick)))))
      ;; remove old nick and add new one
!     (with-rcirc-process-buffer process
        (let ((v (gethash old-nick rcirc-nick-table)))
          (remhash old-nick rcirc-nick-table)
          (puthash new-nick v rcirc-nick-table))
        ;; if this is our nick...
        (when (string= old-nick rcirc-nick)
          (setq rcirc-nick new-nick)
!       (rcirc-update-prompt t)
          ;; reauthenticate
          (when rcirc-auto-authenticate-flag (rcirc-authenticate))))))
  
***************
*** 1517,1534 ****
  
  (defun rcirc-handler-332 (process sender args text)
    "RPL_TOPIC"
!   (with-current-buffer (rcirc-get-buffer process (cadr args))
!     (setq rcirc-topic (caddr args))))
  
  (defun rcirc-handler-333 (process sender args text)
    "Not in rfc1459.txt"
!   (with-current-buffer (rcirc-get-buffer process (cadr args))
!     (let ((setter (caddr args))
!           (time (current-time-string
!                  (seconds-to-time
!                   (string-to-number (cadddr args))))))
!       (rcirc-print process sender "TOPIC" (cadr args)
!                    (format "%s (%s on %s)" rcirc-topic setter time)))))
  
  (defun rcirc-handler-477 (process sender args text)
    "ERR_NOCHANMODES"
--- 1687,1708 ----
  
  (defun rcirc-handler-332 (process sender args text)
    "RPL_TOPIC"
!   (let ((buffer (or (rcirc-get-buffer process (cadr args))
!                   (rcirc-get-temp-buffer-create process (cadr args)))))
!     (with-current-buffer buffer
!       (setq rcirc-topic (caddr args)))))
  
  (defun rcirc-handler-333 (process sender args text)
    "Not in rfc1459.txt"
!   (let ((buffer (or (rcirc-get-buffer process (cadr args))
!                   (rcirc-get-temp-buffer-create process (cadr args)))))
!     (with-current-buffer buffer
!       (let ((setter (caddr args))
!           (time (current-time-string
!                  (seconds-to-time
!                   (string-to-number (cadddr args))))))
!       (rcirc-print process sender "TOPIC" (cadr args)
!                    (format "%s (%s on %s)" rcirc-topic setter time))))))
  
  (defun rcirc-handler-477 (process sender args text)
    "ERR_NOCHANMODES"
***************
*** 1545,1554 ****
  
      ;; print in private chat buffers if they exist
      (mapc (lambda (nick)
!             (when (not (eq (process-buffer rcirc-process)
!                            (rcirc-get-buffer rcirc-process nick)))
!               (rcirc-print process sender "MODE" nick msg)))
!           (cddr args))))
  
  (defun rcirc-get-temp-buffer-create (process channel)
    "Return a buffer based on PROCESS and CHANNEL."
--- 1719,1728 ----
  
      ;; print in private chat buffers if they exist
      (mapc (lambda (nick)
!           (let ((existing-buffer (rcirc-get-buffer process nick)))
!             (when existing-buffer
!               (rcirc-print process sender "MODE" existing-buffer msg))))
!         (cddr args))))
  
  (defun rcirc-get-temp-buffer-create (process channel)
    "Return a buffer based on PROCESS and CHANNEL."
***************
*** 1557,1566 ****
  
  (defun rcirc-handler-353 (process sender args text)
    "RPL_NAMREPLY"
!   (let ((channel (downcase (caddr args))))
      (mapc (lambda (nick)
              (rcirc-put-nick-channel process nick channel))
!           (delete "" (split-string (cadddr args) " ")))
      (with-current-buffer (rcirc-get-temp-buffer-create process channel)
        (goto-char (point-max))
        (insert (car (last args)) " "))))
--- 1731,1740 ----
  
  (defun rcirc-handler-353 (process sender args text)
    "RPL_NAMREPLY"
!   (let ((channel (caddr args)))
      (mapc (lambda (nick)
              (rcirc-put-nick-channel process nick channel))
!           (split-string (cadddr args) " " t))
      (with-current-buffer (rcirc-get-temp-buffer-create process channel)
        (goto-char (point-max))
        (insert (car (last args)) " "))))
***************
*** 1578,1584 ****
    "ERR_NICKNAMEINUSE"
    (rcirc-handler-generic process "433" sender args text)
    (let* ((new-nick (concat (cadr args) "`")))
!     (with-current-buffer (process-buffer process)
        (rcirc-cmd-nick new-nick nil process))))
  
  (defun rcirc-authenticate ()
--- 1752,1758 ----
    "ERR_NICKNAMEINUSE"
    (rcirc-handler-generic process "433" sender args text)
    (let* ((new-nick (concat (cadr args) "`")))
!     (with-rcirc-process-buffer process
        (rcirc-cmd-nick new-nick nil process))))
  
  (defun rcirc-authenticate ()
***************
*** 1590,1596 ****
             (insert-file-contents-literally rcirc-authinfo-file-name)
             (goto-char (point-min))
             (read (current-buffer)))))
!     (with-current-buffer (process-buffer rcirc-process)
        (dolist (i password-alist)
          (let ((server (car i))
                (nick (cadr i))
--- 1764,1770 ----
             (insert-file-contents-literally rcirc-authinfo-file-name)
             (goto-char (point-min))
             (read (current-buffer)))))
!     (with-rcirc-process-buffer rcirc-process
        (dolist (i password-alist)
          (let ((server (car i))
                (nick (cadr i))
***************
*** 1602,1623 ****
                     (rcirc-send-string
                      rcirc-process
                      (concat
!                      "PRIVMSG nickserv :identify " 
                     (car args))))
                    ((equal method 'chanserv)
                     (rcirc-send-string
                      rcirc-process
                      (concat
!                      "PRIVMSG chanserv :identify " 
                     (car args) " " (cadr args))))
                    ((equal method 'bitlbee)
                     (rcirc-send-string
                      rcirc-process
                      (concat "PRIVMSG #bitlbee :identify " (car args))))
                    (t
!                    (message "No %S authentication method defined" 
                            method)))))))))
!  
  (defun rcirc-handler-INVITE (process sender args text)
    (rcirc-print process sender "INVITE" nil (mapconcat 'identity args " ") t))
  
--- 1776,1797 ----
                     (rcirc-send-string
                      rcirc-process
                      (concat
!                      "PRIVMSG nickserv :identify "
                     (car args))))
                    ((equal method 'chanserv)
                     (rcirc-send-string
                      rcirc-process
                      (concat
!                      "PRIVMSG chanserv :identify "
                     (car args) " " (cadr args))))
                    ((equal method 'bitlbee)
                     (rcirc-send-string
                      rcirc-process
                      (concat "PRIVMSG #bitlbee :identify " (car args))))
                    (t
!                    (message "No %S authentication method defined"
                            method)))))))))
! 
  (defun rcirc-handler-INVITE (process sender args text)
    (rcirc-print process sender "INVITE" nil (mapconcat 'identity args " ") t))
  
***************
*** 1631,1648 ****
               (nick (rcirc-user-nick sender))
               (handler (intern-soft (concat "rcirc-handler-ctcp-" request))))
          (if (not (fboundp handler))
!             (rcirc-print process sender "ERROR" target 
!                          (format "unhandled ctcp: %s" text))
            (funcall handler process target sender args)
            (if (not (string= request "ACTION"))
!               (rcirc-print process sender "CTCP" target
!                          (format "%s" text)))))))
  
  (defun rcirc-handler-ctcp-VERSION (process target sender args)
    (rcirc-send-string process
                       (concat "NOTICE " (rcirc-user-nick sender)
!                              " :\C-aVERSION " (rcirc-version)
!                              " - http://www.nongnu.org/rcirc";
                               "\C-a")))
  
  (defun rcirc-handler-ctcp-ACTION (process target sender args)
--- 1805,1824 ----
               (nick (rcirc-user-nick sender))
               (handler (intern-soft (concat "rcirc-handler-ctcp-" request))))
          (if (not (fboundp handler))
!             (rcirc-print process sender "ERROR"
!                        (rcirc-get-buffer process target)
!                          (format "%s sent unsupported ctcp: %s" nick text)
!                        t)
            (funcall handler process target sender args)
            (if (not (string= request "ACTION"))
!               (rcirc-print process sender "CTCP"
!                          (rcirc-get-buffer process target)
!                          (format "%s" text) t))))))
  
  (defun rcirc-handler-ctcp-VERSION (process target sender args)
    (rcirc-send-string process
                       (concat "NOTICE " (rcirc-user-nick sender)
!                              " :\C-aVERSION " rcirc-id-string
                               "\C-a")))
  
  (defun rcirc-handler-ctcp-ACTION (process target sender args)
***************
*** 1652,1713 ****
    (rcirc-send-string process
                       (concat "NOTICE " (rcirc-user-nick sender)
                               " :\C-aTIME " (current-time-string) "\C-a")))
- 
- (defface rcirc-my-nick-face
-   '((((type tty) (class color)) (:foreground "blue" :weight bold))
-     (((class color) (background light)) (:foreground "Blue"))
-     (((class color) (background dark)) (:foreground "LightSkyBlue"))
-     (t (:inverse-video t :bold t)))
-   "The rcirc face used to highlight my messages."
-   :group 'rcirc)
- 
- (defface rcirc-other-nick-face
-   '((((type tty) (class color)) (:foreground "yellow" :weight light))
-     (((class grayscale) (background light))
-      (:foreground "Gray90" :bold t :italic t))
-     (((class grayscale) (background dark))
-      (:foreground "DimGray" :bold t :italic t))
-     (((class color) (background light)) (:foreground "DarkGoldenrod"))
-     (((class color) (background dark)) (:foreground "LightGoldenrod"))
-     (t (:bold t :italic t)))
-   "The rcirc face used to highlight other messages."
-   :group 'rcirc)
- 
- (defface rcirc-server-face
-   '((((type tty pc) (class color) (background light)) (:foreground "red"))
-     (((type tty pc) (class color) (background dark)) (:foreground "red1"))
-     (((class grayscale) (background light))
-      (:foreground "DimGray" :bold t :italic t))
-     (((class grayscale) (background dark))
-      (:foreground "LightGray" :bold t :italic t))
-     (((class color) (background light)) (:foreground "gray40"))
-     (((class color) (background dark)) (:foreground "chocolate1"))
-     (t (:bold t :italic t)))
-   "The rcirc face used to highlight server messages."
-   :group 'rcirc)
  
! (defface rcirc-nick-in-message-face
!   '((((type tty) (class color)) (:foreground "cyan" :weight bold))
!     (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
!     (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
!     (((class color) (background light)) (:foreground "Purple"))
!     (((class color) (background dark)) (:foreground "Cyan"))
!     (t (:bold t)))
!   "The rcirc face used to highlight instances of nick within messages."
!   :group 'rcirc)
! 
! (defface rcirc-prompt-face
!   '((((background dark)) (:foreground "cyan"))
      (t (:foreground "dark blue")))
!   "The rcirc face to use to highlight prompts."
!   :group 'rcirc)
  
! (defface rcirc-mode-line-nick-face
    '((t (:bold t)))
!   "The rcirc face used indicate activity directed at you."
!   :group 'rcirc)
  
! ;; When using M-x flyspell-mode, only check words past the input marker
  (put 'rcirc-mode 'flyspell-mode-predicate 'rcirc-looking-at-input)
  (defun rcirc-looking-at-input ()
    "Returns true if point is past the input marker."
--- 1828,1880 ----
    (rcirc-send-string process
                       (concat "NOTICE " (rcirc-user-nick sender)
                               " :\C-aTIME " (current-time-string) "\C-a")))
  
! (defun rcirc-handler-CTCP-response (process target sender message)
!   (rcirc-print process sender "CTCP" nil message t))
! 
! (defgroup rcirc-faces nil
!   "Faces for rcirc."
!   :group 'rcirc
!   :group 'faces)
! 
! (defface rcirc-my-nick
!   '((t (:inherit font-lock-function-name-face)))
!   "The face used to highlight my messages."
!   :group 'rcirc-faces)
! 
! (defface rcirc-other-nick
!   '((t (:inherit font-lock-variable-name-face)))
!   "The face used to highlight other messages."
!   :group 'rcirc-faces)
! 
! (defface rcirc-server
!   '((t (:inherit font-lock-comment-face)))
!   "The face used to highlight server messages."
!   :group 'rcirc-faces)
! 
! (defface rcirc-server-prefix
!   '((t (:inherit font-lock-comment-delimiter-face)))
!   "The face used to highlight server prefixes."
!   :group 'rcirc-faces)
! 
! (defface rcirc-nick-in-message
!   '((t (:inherit font-lock-keyword-face)))
!   "The face used to highlight instances of nick within messages."
!   :group 'rcirc-faces)
! 
! (defface rcirc-prompt
!   '((((min-colors 88) (background dark)) (:foreground "cyan1"))
!     (((background dark)) (:foreground "cyan"))
      (t (:foreground "dark blue")))
!   "The face to use to highlight prompts."
!   :group 'rcirc-faces)
  
! (defface rcirc-mode-line-nick
    '((t (:bold t)))
!   "The face used indicate activity directed at you."
!   :group 'rcirc-faces)
  
! ;; When using M-x flyspell-mode, only check words after the prompt
  (put 'rcirc-mode 'flyspell-mode-predicate 'rcirc-looking-at-input)
  (defun rcirc-looking-at-input ()
    "Returns true if point is past the input marker."
============================================================




reply via email to

[Prev in Thread] Current Thread [Next in Thread]