(require 'erc)
(eval-when-compile (require 'cl))
(defgroup erc-capab nil
"Support for dancer-ircd's CAPAB settings."
:group 'erc)
(defcustom erc-capab-identify-prefix "*"
"The prefix used for unidentified users.
If you change this from the default \"*\", be sure to use a
character not found in IRC nicknames to avoid confusion."
:group 'erc-capab
:type '(choice string (const nil)))
(defface erc-capab-identify-unidentified '((t)) "Face to use for `erc-capab-identify-prefix'."
:group 'erc-capab
:group 'erc-faces)
(define-erc-module capab-identify nil
"Handle dancer-ircd's CAPAB IDENTIFY-MSG and IDENTIFY-CTCP."
((add-hook 'erc-server-005-functions 'erc-capab-identify-setup t)
(add-hook 'erc-server-290-functions 'erc-capab-identify-activate)
(add-hook 'erc-server-PRIVMSG-functions
'erc-capab-identify-remove/set-identified-flag)
(add-hook 'erc-server-NOTICE-functions
'erc-capab-identify-remove/set-identified-flag)
(add-hook 'erc-insert-modify-hook 'erc-capab-identify-add-prefix t)
(mapc (lambda (buffer)
(when buffer
(with-current-buffer buffer (erc-capab-identify-setup))))
(erc-buffer-list 'erc-open-server-buffer-p)))
((remove-hook 'erc-server-005-functions 'erc-capab-identify-setup)
(remove-hook 'erc-server-290-functions 'erc-capab-identify-activate)
(remove-hook 'erc-insert-modify-hook 'erc-capab-identify-add-prefix)))
(defvar erc-capab-identify-activated nil
"CAPAB IDENTIFY-MSG has been activated.")
(make-variable-buffer-local 'erc-capab-identify-activated)
(defvar erc-capab-identify-sent nil
"CAPAB IDENTIFY-MSG and IDENTIFY-CTCP messages have been sent.")
(make-variable-buffer-local 'erc-capab-identify-sent)
(defun erc-capab-identify-setup (&optional proc parsed)
"Set up CAPAB IDENTIFY on the current server.
Optional argument PROC is the current server's process.
Optional argument PARSED is the current message, a response struct.
These arguments are sent to this function when called as a hook in
`erc-server-005-functions'."
(unless erc-capab-identify-sent
(erc-capab-identify-send-messages)))
(defun erc-capab-identify-send-messages ()
"Send CAPAB IDENTIFY messages if the server supports it."
(when (and (stringp erc-server-version)
(string-match "^\\(dancer-ircd\\|hyperion\\)" erc-server-version)
(assoc "CAPAB" erc-server-parameters))
(erc-log "Sending CAPAB IDENTIFY-MSG and IDENTIFY-CTCP")
(erc-server-send "CAPAB IDENTIFY-MSG")
(erc-server-send "CAPAB IDENTIFY-CTCP")
(setq erc-capab-identify-sent t)))
(defun erc-capab-identify-activate (proc parsed)
"Set `erc-capab-identify-activated' and display an activation message.
PROC is the current server's process.
PARSED is an `erc-parsed' response struct."
(when (or (string= "IDENTIFY-MSG" (erc-response.contents parsed))
(string= "IDENTIFY-CTCP" (erc-response.contents parsed)))
(setq erc-capab-identify-activated t)
(erc-display-message
parsed 'notice 'active (format "%s activated"
(erc-response.contents parsed)))))
(defun erc-capab-identify-remove/set-identified-flag (proc parsed)
"Remove PARSED message's id flag and add the `erc-identified' text property.
PROC is the current server's process.
PARSED is an `erc-parsed' response struct."
(let ((msg (erc-response.contents parsed)))
(when (and erc-capab-identify-activated
(string-match "^\\([-\\+]\\)\\(.+\\)$" msg))
(setf (erc-response.contents parsed)
(if erc-capab-identify-mode
(erc-propertize (match-string 2 msg)
'erc-identified
(if (string= (match-string 1 msg) "+")
1
0))
(match-string 2 msg)))
nil)))
(defun erc-capab-identify-add-prefix ()
"Add `erc-capab-identify-prefix' to nickname if user is unidentified."
(when (and erc-capab-identify-prefix
(erc-with-server-buffer erc-capab-identify-activated))
(goto-char (or (erc-find-parsed-property) (point-min)))
(let ((nickname (erc-capab-identify-get-unidentified-nickname
(erc-get-parsed-vector (point)))))
(when (and nickname
(goto-char (point-min))
(re-search-forward (regexp-quote nickname) nil t))
(goto-char (match-beginning 0))
(insert (erc-propertize erc-capab-identify-prefix
'face 'erc-capab-identify-unidentified))))))
(defun erc-capab-identify-get-unidentified-nickname (parsed)
"Return the nickname of the user if unidentified.
PARSED is an `erc-parsed' response struct."
(when (and (erc-response-p parsed)
(equal 0 (get-text-property 0 'erc-identified
(erc-response.contents parsed))))
(let ((nickuserhost (erc-get-parsed-vector-nick parsed)))
(when nickuserhost
(nth 0 (erc-parse-user nickuserhost))))))
(provide 'erc-capab)