aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Malabarba <bruce.connor.am@gmail.com>2015-01-16 13:30:58 -0200
committerArtur Malabarba <bruce.connor.am@gmail.com>2015-01-16 13:30:58 -0200
commit006c85d3a241e20b6b03ab4499dbc467f8431ddd (patch)
tree4799ce852da6e4308080669aa577906ef56f8bbc
parentbed5191a0137cb115656baf6ae3535b2a646d0b2 (diff)
parent389e433953bba4003b102748dbbf5f8a9b421a51 (diff)
Merge branch 'master' into tag-buttons
Conflicts: sx-question.el
-rw-r--r--sx-filter.el16
-rw-r--r--sx-question-list.el9
-rw-r--r--sx-question-print.el15
-rw-r--r--sx-question.el15
-rw-r--r--sx.el21
-rw-r--r--test/test-macros.el5
6 files changed, 51 insertions, 30 deletions
diff --git a/sx-filter.el b/sx-filter.el
index af3717f..1ccf611 100644
--- a/sx-filter.el
+++ b/sx-filter.el
@@ -47,7 +47,7 @@ Structure:
;;; Creation
(defmacro sx-filter-from-nil (included)
- "Creates a filter data structure with INCLUDED fields.
+ "Create a filter data structure with INCLUDED fields.
All wrapper fields are included by default."
`(quote
((,@(sx--tree-expand
@@ -64,23 +64,21 @@ All wrapper fields are included by default."
.page_size
.quota_max
.quota_remaining
- .total)
- nil none)))
+ )
+ nil nil)))
;;; @TODO allow BASE to be a precompiled filter name
(defun sx-filter-compile (&optional include exclude base)
"Compile INCLUDE and EXCLUDE into a filter derived from BASE.
-INCLUDE and EXCLUDE must both be lists; BASE should be a string.
+INCLUDE and EXCLUDE must both be lists; BASE should be a symbol.
Returns the compiled filter as a string."
(let ((keyword-arguments
`((include . ,(if include (sx--thing-as-string include)))
(exclude . ,(if exclude (sx--thing-as-string exclude)))
(base . ,(if base base)))))
- (let ((response (elt (sx-request-make
- "filter/create"
- keyword-arguments) 0)))
- (sx-assoc-let response
+ (let ((result (elt (sx-request-make "filter/create" keyword-arguments) 0)))
+ (sx-assoc-let result
.filter))))
@@ -93,7 +91,7 @@ Returns the compiled filter as a string."
(defun sx-filter-get (&optional include exclude base)
"Return the string representation of the given filter.
-If the filter data exist in `sx--filter-alist', that value will
+If the filter data exists in `sx--filter-alist', that value will
be returned. Otherwise, compile INCLUDE, EXCLUDE, and BASE into
a filter with `sx-filter-compile' and push the association onto
`sx--filter-alist'. Re-cache the alist with `sx-cache-set' and
diff --git a/sx-question-list.el b/sx-question-list.el
index 256bdb4..63484e1 100644
--- a/sx-question-list.el
+++ b/sx-question-list.el
@@ -303,11 +303,10 @@ into consideration.
;; Add a setter to protect the value.
:group 'sx-question-list)
-(defun sx-question-list--date-more-recent-p (x y)
- "Non-nil if tabulated-entry X is newer than Y."
- (sx--<
- sx-question-list-date-sort-method
- (car x) (car y) #'>))
+(sx--create-comparator sx-question-list--date-more-recent-p
+ "Non-nil if tabulated-entry A is newer than B."
+ #'> (lambda (x)
+ (cdr (assq sx-question-list-date-sort-method (car x)))))
;;; Keybinds
diff --git a/sx-question-print.el b/sx-question-print.el
index d7c2a20..b53b86a 100644
--- a/sx-question-print.el
+++ b/sx-question-print.el
@@ -148,6 +148,15 @@ replaced with the comment."
:type 'boolean
:group 'sx-question-mode)
+(defcustom sx-question-mode-answer-sort-function
+ #'sx-answer-higher-score-p
+ "Function used to sort answers in the question buffer."
+ :type '(choice
+ (const :tag "Higher-scoring first" sx-answer-higher-score-p)
+ (const :tag "Newer first" sx-answer-newer-p)
+ (const :tag "More active first" sx-answer-more-active-p))
+ :group 'sx-question-mode)
+
;;; Functions
;;;; Printing the general structure
@@ -162,11 +171,7 @@ QUESTION must be a data structure returned by `json-read'."
(sx-question-mode--print-section question)
(sx-assoc-let question
(mapc #'sx-question-mode--print-section
- (cl-sort .answers
- ;; Highest-voted first. @TODO: custom sorting
- (lambda (a b)
- (> (cdr (assoc 'score a))
- (cdr (assoc 'score b)))))))
+ (cl-sort .answers sx-question-mode-answer-sort-function)))
(insert "\n\n ")
(insert-text-button "Write an Answer" :type 'sx-button-answer)
;; Go up
diff --git a/sx-question.el b/sx-question.el
index 0f73795..039d416 100644
--- a/sx-question.el
+++ b/sx-question.el
@@ -176,13 +176,26 @@ If no cache exists for it, initialize one with SITE."
;;;; Other data
-
(defun sx-question--accepted-answer-id (question)
"Return accepted answer in QUESTION or nil if none exists."
(sx-assoc-let question
(and (integerp .accepted_answer_id)
.accepted_answer_id)))
+
+;;; Question Mode Answer-Sorting Functions
+(sx--create-comparator sx-answer-higher-score-p
+ "Return t if answer A has a higher score than answer B."
+ #'> (lambda (x) (cdr (assq 'score x))))
+
+(sx--create-comparator sx-answer-newer-p
+ "Return t if answer A was posted later than answer B."
+ #'> (lambda (x) (cdr (assq 'creation_date x))))
+
+(sx--create-comparator sx-answer-more-active-p
+ "Return t if answer A was updated after answer B."
+ #'> (lambda (x) (cdr (assq 'last_activity_date x))))
+
(provide 'sx-question)
;;; sx-question.el ends here
diff --git a/sx.el b/sx.el
index 36ecfca..a385a84 100644
--- a/sx.el
+++ b/sx.el
@@ -259,6 +259,20 @@ whenever BODY evaluates to nil."
:filter (lambda (&optional _)
(when (progn ,@body) ,def)))))
+(defmacro sx--create-comparator (name doc compare-func get-func)
+ "Define a new comparator called NAME with documentation DOC.
+COMPARE-FUNC is a function that takes the return value of
+GET-FUNC and performs the actual comparison."
+ (declare (indent 1) (doc-string 2))
+ `(progn
+ ;; In using `defalias', the macro supports both function
+ ;; symbols and lambda expressions.
+ (defun ,name (a b)
+ ,doc
+ (funcall ,compare-func
+ (funcall ,get-func a)
+ (funcall ,get-func b)))))
+
;;; Printing request data
(defvar sx--overlays nil
@@ -354,13 +368,6 @@ Run after `sx-init--internal-hook'."
This is used internally to set initial values for variables such
as filters.")
-(defun sx--< (property x y &optional predicate)
- "Non-nil if PROPERTY attribute of alist X is less than that of Y.
-With optional argument PREDICATE, use it instead of `<'."
- (funcall (or predicate #'<)
- (cdr (assoc property x))
- (cdr (assoc property y))))
-
(defmacro sx-init-variable (variable value &optional setter)
"Set VARIABLE to VALUE using SETTER.
SETTER should be a function of two arguments. If SETTER is nil,
diff --git a/test/test-macros.el b/test/test-macros.el
index 1634603..5e0eac9 100644
--- a/test/test-macros.el
+++ b/test/test-macros.el
@@ -39,6 +39,5 @@
.page
.page_size
.quota_max
- .quota_remaining
- .total)
- nil none))))
+ .quota_remaining)
+ nil nil))))