aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sx-question-list.el54
-rw-r--r--sx.el44
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."
diff --git a/sx.el b/sx.el
index cd8af95..e467a9e 100644
--- a/sx.el
+++ b/sx.el
@@ -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
+ 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