diff options
-rw-r--r-- | sx-question-list.el | 54 | ||||
-rw-r--r-- | sx.el | 44 |
2 files changed, 70 insertions, 28 deletions
diff --git a/sx-question-list.el b/sx-question-list.el index 59acbeb..86e9194 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -199,34 +199,32 @@ Used in the questions list to indicate a question was updated \"4d ago\"." (defun sx-question-list--print-info (data) "Convert `json-read' DATA into tabulated-list format." - (list - data - (vector - (list (int-to-string (cdr (assoc 'score data))) - 'face - (if (cdr (assoc 'upvoted data)) 'sx-question-list-score-upvoted - 'sx-question-list-score)) - (list (int-to-string (cdr (assoc 'answer_count data))) - 'face - (if (sx-question--accepted-answer data) - 'sx-question-list-answers-accepted - 'sx-question-list-answers)) - (concat - (propertize - (cdr (assoc 'title data)) - 'face - (if (sx-question--read-p data) - 'sx-question-list-read-question - ;; Increment `sx-question-list--unread-count' for the mode-line. - (cl-incf sx-question-list--unread-count) - 'sx-question-list-unread-question)) - (propertize " " 'display "\n ") - (propertize (concat (sx-time-since (cdr (assoc 'last_activity_date data))) - sx-question-list-ago-string) - 'face 'sx-question-list-date) - (propertize (concat " [" (mapconcat #'identity (cdr (assoc 'tags data)) "] [") "]") - 'face 'sx-question-list-tags) - (propertize " " 'display "\n"))))) + (sx-assoc-let data + (list + data + (vector + (list (int-to-string score) + 'face (if upvoted 'sx-question-list-score-upvoted + 'sx-question-list-score)) + (list (int-to-string answer_count) + 'face (if (sx-question--accepted-answer data) + 'sx-question-list-answers-accepted + 'sx-question-list-answers)) + (concat + (propertize + title + 'face (if (sx-question--read-p data) + 'sx-question-list-read-question + ;; Increment `sx-question-list--unread-count' for the mode-line. + (cl-incf sx-question-list--unread-count) + 'sx-question-list-unread-question)) + (propertize " " 'display "\n ") + (propertize (concat (sx-time-since last_activity_date) + sx-question-list-ago-string) + 'face 'sx-question-list-date) + (propertize (concat " [" (mapconcat #'identity tags "] [") "]") + 'face 'sx-question-list-tags) + (propertize " " 'display "\n")))))) (defun sx-question-list-view-previous (n) "Hide this question, move to previous one, display it." @@ -68,6 +68,50 @@ a string, just return it." cons-cell)))) data)))) + +;;; Interpreting request data +(defvar sx--api-symbols + '(accept_rate answer_count answer_id answers body body_markdown close_vote_count upvoted downvoted + comment_count comment_id creation_date delete_vote_count display_name + edited favorite_count is_accepted is_answered last_activity_date + last_edit_date last_editor link owner profile_image question_id + reopen_vote_count reputation score tags title user_id user_type view_count) + "") + +(defun sx--deep-search (symbol list) + "Non-nil if SYMBOL is contained somewhere inside LIST." + (cond + ((symbolp list) + (eq symbol list)) + ((not (listp list)) + nil) + (t + (remove nil (mapcar (lambda (x) (sx--deep-search symbol x)) list))))) + +(defmacro sx-assoc-let (alist &rest body) + "Execute BODY while let-binding api symbols to their values in ALIST. +Any api symbol is any symbol listed in `sx--api-symbols'. Only +those present in BODY are letbound, which leads to optimal +performance. + +For instance the following code + + (stack-core-with-data alist + (list title body)) + +is equivalent to + + (let ((title (cdr (assoc 'title alist))) + (body (cdr (assoc 'body alist)))) + (list title body))" + (declare (indent 1) + (debug t)) + (let ((symbols (cl-member-if + (lambda (x) (sx--deep-search x body)) + sx--api-symbols))) + `(let ,(mapcar (lambda (x) `(,x (cdr (assoc ',x ,alist)))) symbols) + ,@body))) + (provide 'sx) ;;; sx.el ends here |