diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 288e8efe73..eed56174a8 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -53,6 +53,7 @@ ;; CONTENTS --- `erc-response.contents' ;; SENDER --- `erc-response.sender' ;; LINE --- `erc-response.unparsed' +;; TAGS --- `erc-response.tags' ;; ;; WARNING, WARNING!! ;; It's probably not a good idea to destructively modify the list @@ -115,7 +116,8 @@ erc-server-responses (sender "" :type string) (command "" :type string) (command-args '() :type list) - (contents "" :type string)) + (contents "" :type string) + (tags '() :type list)) ;;; User data @@ -955,16 +957,34 @@ erc-send-ctcp-notice ;;;; Handling responses +(defun erc-parse-tags (string) + "Parse IRCv3 tags list in STRING to a (tag . value) alist." + (let ((tags) + (tag-strings (split-string string ";"))) + (dolist (tag-string tag-strings tags) + (let ((pair (split-string tag-string "="))) + (push (if (consp pair) + pair + `(,pair)) + tags))))) + (defun erc-parse-server-response (proc string) "Parse and act upon a complete line from an IRC server. PROC is the process (connection) from which STRING was received. PROCs `process-buffer' is `current-buffer' when this function is called." (unless (string= string "") ;; Ignore empty strings (save-match-data - (let ((posn (if (eq (aref string 0) ?:) - (string-match " " string) - 0)) - (msg (make-erc-response :unparsed string))) + (let* ((tag-list (when (eq (aref string 0) ?@) + (substring string 1 (string-match " " string)))) + (msg (make-erc-response :unparsed string :tags (when tag-list + (erc-parse-tags + tag-list)))) + (string (if tag-list + (substring string (+ 1 (string-match " " string))) + string)) + (posn (if (eq (aref string 0) ?:) + (string-match " " string) + 0))) (setf (erc-response.sender msg) (if (eq posn 0) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 8501e2cba7..c66f9f56ec 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2700,7 +2700,10 @@ erc-display-message (unless (erc-hide-current-message-p parsed) (erc-put-text-property 0 (length string) 'erc-parsed parsed string) (erc-put-text-property 0 (length string) 'rear-sticky t string) - (erc-display-line string buffer))))) + (when (erc-response.tags parsed) + (erc-put-text-property 0 (length string) 'tags (erc-response.tags parsed) + string)) + (erc-display-line string buffer))))) (defun erc-message-type-member (position list) "Return non-nil if the erc-parsed text-property at POSITION is in LIST.