From ecaf2877f88fbf77202ee5ab30c55831ff27c24d Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 25 Nov 2014 20:55:10 +0000 Subject: Add ids to filter --- sx.el | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sx.el b/sx.el index e5f81a4..ac4758e 100644 --- a/sx.el +++ b/sx.el @@ -56,6 +56,7 @@ question.link question.upvoted question.downvoted + question.question_id user.display_name comment.owner comment.body_markdown @@ -65,6 +66,10 @@ comment.creation_date comment.upvoted comment.score + comment.post_type + comment.post_id + comment.comment_id + answer.answer_id answer.last_editor answer.link answer.owner -- cgit v1.2.3 From fdc0fc501fc347f2e772575695125fb0bb152d15 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 25 Nov 2014 22:49:53 +0000 Subject: Add sx--user-@name function to sx.el --- sx.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sx.el b/sx.el index ac4758e..d4c3ac2 100644 --- a/sx.el +++ b/sx.el @@ -198,6 +198,13 @@ Return the result of BODY." (add-text-properties p (point) ,properties) result)) +(defun sx--user-@name (user) + "Get the `display_name' of USER prepended with @." + (sx-assoc-let user + (when (stringp .display_name) + (concat "@" .display_name)))) + + ;;; Assoc-let (defun sx--site (data) "Get the site in which DATA belongs. -- cgit v1.2.3 From 94046d6f392844a44053afc9e6ad3a71e38f011f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 25 Nov 2014 22:50:03 +0000 Subject: Implement commenting on anything. --- sx-interaction.el | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/sx-interaction.el b/sx-interaction.el index a9203bd..ad65736 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -106,5 +106,78 @@ 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 .author)))) + (while (< (string-width text) 15) + (message "Comments must have more than 15 characters.") + (setq text (read-string "Comment text:" 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 + (cl-case type + (question db) + (answer + (cl-map 'list (lambda (x) (cdr (assoc 'answers x))) + db)))) + (car (cl-member-if + (lambda (x) (sx-assoc-let x + (and (eq .id id) (eq .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-cel (assoc 'comment_count object))) + (setcdr + com-cell + (cl-map 'vector #'identity + (cdr cell) (list comment))) + (cl-incf (cdr count-cell)))) + (provide 'sx-interaction) ;;; sx-interaction.el ends here -- cgit v1.2.3 From e75498fffe766611f6f59deadffd60bff6ccae55 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 25 Nov 2014 23:59:00 +0000 Subject: Old refresh bug --- sx-question.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx-question.el b/sx-question.el index de07c94..a7aadb2 100644 --- a/sx-question.el +++ b/sx-question.el @@ -43,7 +43,7 @@ property. "Query SITE for a QUESTION-ID and return it. If QUESTION-ID doesn't exist on SITE, raise an error." (let ((res (sx-method-call 'questions - :id id + :id question-id :site site :auth t :filter sx-browse-filter))) -- cgit v1.2.3 From cbac35d3cb4d8da99034806e22518f023b4883ff Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 25 Nov 2014 23:59:16 +0000 Subject: new sx--get-post bug --- sx-interaction.el | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sx-interaction.el b/sx-interaction.el index ad65736..a5b25d1 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -156,27 +156,27 @@ 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 - (cl-case type - (question db) - (answer - (cl-map 'list (lambda (x) (cdr (assoc 'answers x))) - db)))) - (car (cl-member-if - (lambda (x) (sx-assoc-let x - (and (eq .id id) (eq .site site)))) - db))) + sx-question-list--dataset))) + (setq db + (cl-case type + (question db) + (answer + (cl-map 'list (lambda (x) (cdr (assoc 'answers x))) + db)))) + (car (cl-member-if + (lambda (x) (sx-assoc-let x + (and (eq .id id) (eq .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-cel (assoc 'comment_count object))) + (count-cell (assoc 'comment_count object))) (setcdr com-cell (cl-map 'vector #'identity - (cdr cell) (list comment))) + (cdr com-cell) (list comment))) (cl-incf (cdr count-cell)))) (provide 'sx-interaction) -- cgit v1.2.3 From c7cb481e1ba3947931d28a4585624ea35fe76721 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 26 Nov 2014 00:04:08 +0000 Subject: Old recentering bug We sometimes get an error because we're recentering a window that's not selected. --- sx-question-mode.el | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sx-question-mode.el b/sx-question-mode.el index 8ccc576..dda65ab 100644 --- a/sx-question-mode.el +++ b/sx-question-mode.el @@ -469,11 +469,12 @@ Prefix argument N moves N sections down or up." (unless (and (overlayp ov) (overlay-get ov 'invisible)) (cl-decf count))))) - (when sx-question-mode-recenter-line - (let ((ov (car-safe (sx-question-mode--section-overlays-at (line-end-position))))) - (when (and (overlayp ov) (> (overlay-end ov) (window-end))) - (recenter sx-question-mode-recenter-line)))) - (sx-message-help-echo)) + (when (equal (selected-window) (get-buffer-window)) + (when sx-question-mode-recenter-line + (let ((ov (car-safe (sx-question-mode--section-overlays-at (line-end-position))))) + (when (and (overlayp ov) (> (overlay-end ov) (window-end))) + (recenter sx-question-mode-recenter-line)))) + (sx-message-help-echo))) (defun sx-question-mode-previous-section (&optional n) "Move down to previous section (question or answer) of this buffer. -- cgit v1.2.3 From 26f140c4a9b4aa4a76586cd9f4531afbbdfb5f42 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 26 Nov 2014 00:47:46 +0000 Subject: Several bug fixes to commenting logic. --- sx-interaction.el | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/sx-interaction.el b/sx-interaction.el index a5b25d1..404fb56 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -121,12 +121,11 @@ TEXT is a string. Interactively, it is read from the minibufer." ;; Get the comment text (when (eq text 'query) (setq text (read-string - "Comment text:" + "Comment text: " (when .comment_id - (sx--user-@name .author)))) + (sx--user-@name .owner)))) (while (< (string-width text) 15) - (message "Comments must have more than 15 characters.") - (setq text (read-string "Comment text:" text)))) + (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")) @@ -158,14 +157,15 @@ ID is an integer." (let ((db (cons sx-question-mode--data sx-question-list--dataset))) (setq db - (cl-case type - (question db) - (answer - (cl-map 'list (lambda (x) (cdr (assoc 'answers x))) - 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 (eq .id id) (eq .site site)))) + (and (equal (or .answer_id .question_id) id) + (equal .site site)))) db)))) (defun sx--add-comment-to-object (comment object) @@ -173,11 +173,18 @@ ID is an integer." OBJECT can be a question or an answer." (let ((com-cell (assoc 'comments object)) (count-cell (assoc 'comment_count object))) - (setcdr - com-cell - (cl-map 'vector #'identity - (cdr com-cell) (list comment))) - (cl-incf (cdr count-cell)))) + (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 -- cgit v1.2.3 From c38dd4d9d23cbf1299e10b8a441855ba22ff567f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 26 Nov 2014 00:47:59 +0000 Subject: A bug fix on the dataset. The question-list--dataset is now a list, not a vector. --- sx-question-list.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sx-question-list.el b/sx-question-list.el index 36a3c51..da2faee 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -427,8 +427,10 @@ This does not update `sx-question-mode--window'." (forward-line -1) (when (functionp sx-question-list--next-page-function) ;; Try to get more questions - (let ((list (funcall sx-question-list--next-page-function - (1+ sx-question-list--pages-so-far)))) + (let ((list + (cl-map 'list #'identity + (funcall sx-question-list--next-page-function + (1+ sx-question-list--pages-so-far))))) (if (null list) (message "No further questions.") ;; If it worked, increment the variable. @@ -436,7 +438,8 @@ This does not update `sx-question-mode--window'." ;; And update the dataset. ;; @TODO: Check for duplicates. (setq sx-question-list--dataset - (append sx-question-list--dataset list)) + (append sx-question-list--dataset + list)) (sx-question-list-refresh 'redisplay 'no-update) (forward-line 1))))) -- cgit v1.2.3 From 977182943de4e3824a9178f3f3c114648b227265 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 26 Nov 2014 00:55:49 +0000 Subject: Add keybind for commenting. --- sx-question-mode.el | 1 + 1 file changed, 1 insertion(+) diff --git a/sx-question-mode.el b/sx-question-mode.el index 06413f2..70b8866 100644 --- a/sx-question-mode.el +++ b/sx-question-mode.el @@ -572,6 +572,7 @@ Letters do not insert themselves; instead, they are commands. `(("n" sx-question-mode-next-section) ("p" sx-question-mode-previous-section) ("g" sx-question-mode-refresh) + ("c" sx-comment) ("v" sx-visit) ("u" sx-toggle-upvote) ("d" sx-toggle-downvote) -- cgit v1.2.3