diff options
Diffstat (limited to 'sx-interaction.el')
-rw-r--r-- | sx-interaction.el | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/sx-interaction.el b/sx-interaction.el index a9203bd..404fb56 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -106,5 +106,85 @@ changes." ;; Display the changes in `data'. (sx--maybe-update-display)))) + +;;; Commenting +(defun sx-comment (data text) + "Post a comment on DATA given by TEXT. +DATA can be a question, an answer, or a comment. Interactively, +it is guessed from context at point. +If DATA is a comment, the comment is posted as a reply to it. + +TEXT is a string. Interactively, it is read from the minibufer." + (interactive + (list (sx--data-here) 'query)) + (sx-assoc-let data + ;; Get the comment text + (when (eq text 'query) + (setq text (read-string + "Comment text: " + (when .comment_id + (sx--user-@name .owner)))) + (while (< (string-width text) 15) + (setq text (read-string "Comment text (at least 15 characters): " text)))) + ;; If non-interactive, `text' could be anything. + (unless (stringp text) + (error "Comment body must be a string")) + ;; And post + (let ((result + (sx-method-call 'posts + :id (or .post_id .answer_id .question_id) + :submethod "comments/add" + :auth 'warn + :url-method "POST" + :filter sx-browse-filter + :site .site + :keywords `((body ,text))))) + ;; The api returns the new DATA. + (when (> (length result) 0) + (sx--add-comment-to-object + (elt result 0) + (if .post_id + (sx--get-post .post_type .site .post_id) + data)) + ;; Display the changes in `data'. + (sx--maybe-update-display))))) + +(defun sx--get-post (type site id) + "Find in the database a post identified by TYPE, SITE and ID. +TYPE is `question' or `answer'. +SITE is a string. +ID is an integer." + (let ((db (cons sx-question-mode--data + sx-question-list--dataset))) + (setq db + (cond + ((string= type "question") db) + ((string= type "answer") + (apply #'cl-map 'list #'identity + (mapcar (lambda (x) (cdr (assoc 'answers x))) db))))) + (car (cl-member-if + (lambda (x) (sx-assoc-let x + (and (equal (or .answer_id .question_id) id) + (equal .site site)))) + db)))) + +(defun sx--add-comment-to-object (comment object) + "Add COMMENT to OBJECT's `comments' property. +OBJECT can be a question or an answer." + (let ((com-cell (assoc 'comments object)) + (count-cell (assoc 'comment_count object))) + (if com-cell + (progn + (setcdr + com-cell + (apply #'vector + (append + (cl-map 'list #'identity + (cdr com-cell)) + (list comment))))) + ;; No previous comments, add it manually. + (setcdr object (cons (car object) (cdr object))) + (setcar object `(comments . [,comment]))))) + (provide 'sx-interaction) ;;; sx-interaction.el ends here |