From 2205546269bf5af01d766dc38720f71046b08dfa Mon Sep 17 00:00:00 2001 From: Vibhav Pant Date: Mon, 24 Apr 2017 11:57:46 +0530 Subject: [PATCH] Add support for IRCv3 message tags. * erc-backend.el: erc-response: Add `tags' element. Add (erc-parse-tags). (erc-parse-server-response): Use (erc-parse-tags) to parse message tags (if any), and store them in `erc-resopnse' struct. * erc.el: (erc-display-message): Expose message tags with text properties of the corresponding message line. --- lisp/erc/erc-backend.el | 30 +++++++++++++++++++++++++----- lisp/erc/erc.el | 5 ++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 8eac2e18aee..3368d6701ae 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 @@ (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 @@ See also `erc-server-send'." ;;;; 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 7e19ebbf980..8c65016ed22 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2700,7 +2700,10 @@ See also `erc-format-message' and `erc-display-line'." (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. -- 2.39.5