From 50465fe9cb68978088da2be1a88549892c6b3146 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 8 Jan 2015 16:03:54 -0200 Subject: Don't use .total the total property doubles the time taken for the request, according to https://api.stackexchange.com/docs/paging --- sx-filter.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx-filter.el b/sx-filter.el index a3f6861..72ab6b2 100644 --- a/sx-filter.el +++ b/sx-filter.el @@ -64,7 +64,7 @@ All wrapper fields are included by default." .page_size .quota_max .quota_remaining - .total) + ) nil none))) ;;; @TODO allow BASE to be a precompiled filter name -- cgit v1.2.3 From 7818811a7ca2666a007007caa8b32be7787e932d Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 8 Jan 2015 16:09:54 -0200 Subject: Docs --- sx-filter.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sx-filter.el b/sx-filter.el index 72ab6b2..a35b51d 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 @@ -70,7 +70,7 @@ All wrapper fields are included by default." ;;; @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 @@ -93,7 +93,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 -- cgit v1.2.3 From 55682ee682c983f66c0a05b63ecb0ab4e5832cba Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 8 Jan 2015 16:10:05 -0200 Subject: Style --- sx-filter.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sx-filter.el b/sx-filter.el index a35b51d..bdbdab9 100644 --- a/sx-filter.el +++ b/sx-filter.el @@ -77,10 +77,8 @@ Returns the compiled filter as a string." `((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)))) -- cgit v1.2.3 From 117f78c3e16fa32f82e75f43a7aac24afd9a37d5 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 8 Jan 2015 16:11:54 -0200 Subject: Build filters from default. --- sx-filter.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx-filter.el b/sx-filter.el index bdbdab9..0df9b5e 100644 --- a/sx-filter.el +++ b/sx-filter.el @@ -65,7 +65,7 @@ All wrapper fields are included by default." .quota_max .quota_remaining ) - nil none))) + nil nil))) ;;; @TODO allow BASE to be a precompiled filter name (defun sx-filter-compile (&optional include exclude base) -- cgit v1.2.3 From 0edc2c089f45672e9390ef98db468e4d690c09df Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 8 Jan 2015 18:27:37 -0200 Subject: Fix test --- test/test-macros.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-macros.el b/test/test-macros.el index 1634603..a43d383 100644 --- a/test/test-macros.el +++ b/test/test-macros.el @@ -41,4 +41,4 @@ .quota_max .quota_remaining .total) - nil none)))) + nil nil)))) -- cgit v1.2.3 From ef5b4639cb8e70f2d4ddd26a7621f1361ccb1af7 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 14 Jan 2015 17:20:11 -0200 Subject: Remove .total from tests too --- test/test-macros.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test-macros.el b/test/test-macros.el index a43d383..5e0eac9 100644 --- a/test/test-macros.el +++ b/test/test-macros.el @@ -39,6 +39,5 @@ .page .page_size .quota_max - .quota_remaining - .total) + .quota_remaining) nil nil)))) -- cgit v1.2.3 From 3328a62d42ff3ca62c31366a4cd0cfd38a3ec663 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 15 Jan 2015 00:01:32 -0500 Subject: Create and implement comparator creation macro This obsoletes `sx--<'. --- sx-question-list.el | 10 +++++----- sx.el | 24 +++++++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/sx-question-list.el b/sx-question-list.el index 1b7fe5a..5909156 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -322,11 +322,11 @@ 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 (assoc sx-question-list-date-sort-method + (car x))))) ;;; Keybinds diff --git a/sx.el b/sx.el index e080271..87907de 100644 --- a/sx.el +++ b/sx.el @@ -259,6 +259,23 @@ 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)) + (let ((gpf (intern (format " %S--get-prop-function" name))) + (cf (intern (format " %S--compare-function" name)))) + ;; Leading space to hide from completion systems + `(progn + ;; In using `defalias', the macro supports both function + ;; symbols and lambda expressions. + (defalias ',gpf ,get-func) + (defalias ',cf ,compare-func) + (defun ,name (a b) + ,doc + (,cf (,gpf a) (,gpf b)))))) + ;;; Printing request data (defvar sx--overlays nil @@ -349,13 +366,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, -- cgit v1.2.3 From 8e9983d1c9edab01335e3923bb5b50ad5a91ed1f Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 15 Jan 2015 00:09:31 -0500 Subject: Abstract sorting function --- sx-question-print.el | 6 +----- sx-question.el | 7 +++++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sx-question-print.el b/sx-question-print.el index 737844a..210f99a 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -180,11 +180,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-answer-higher-score-p))) (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 b9fc78a..d624f45 100644 --- a/sx-question.el +++ b/sx-question.el @@ -187,6 +187,13 @@ If no cache exists for it, initialize one with SITE." "Formats TAG for display." (concat "[" tag "]")) + +;;; 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 (assoc 'score x)))) + (provide 'sx-question) ;;; sx-question.el ends here -- cgit v1.2.3 From 9b093f7a7a02e31dc6985619f5277ee945f6f90d Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 15 Jan 2015 00:22:04 -0500 Subject: Small bugfix Everything must now be a proper function. --- sx-question-list.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sx-question-list.el b/sx-question-list.el index 5909156..cb5bc33 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -324,9 +324,9 @@ into consideration. (sx--create-comparator sx-question-list--date-more-recent-p "Non-nil if tabulated-entry A is newer than B." - > (lambda (x) - (cdr (assoc sx-question-list-date-sort-method - (car x))))) + #'> (lambda (x) + (cdr (assoc sx-question-list-date-sort-method + (car x))))) ;;; Keybinds -- cgit v1.2.3 From fe912f7a4871f7beedeafe5f29feb57ca65ecc47 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 15 Jan 2015 00:22:33 -0500 Subject: Abstract sorting function into customizable option --- sx-question-print.el | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sx-question-print.el b/sx-question-print.el index 210f99a..c19b0c3 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -166,6 +166,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 "Older first" sx-answer-older-p) + (const :tag "More active first" sx-answer-more-active-p)) + :group 'sx-question-mode) + ;;; Functions ;;;; Printing the general structure @@ -180,7 +189,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 #'sx-answer-higher-score-p))) + (cl-sort .answers sx-question-list--sort-answer-function))) (insert "\n\n ") (insert-text-button "Write an Answer" :type 'sx-button-answer) ;; Go up -- cgit v1.2.3 From 087ff1fdf3c4d42510d59a91659f166763baec57 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 15 Jan 2015 00:22:51 -0500 Subject: Add more sorting functions --- sx-question.el | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sx-question.el b/sx-question.el index d624f45..7c687e8 100644 --- a/sx-question.el +++ b/sx-question.el @@ -194,6 +194,14 @@ If no cache exists for it, initialize one with SITE." "Return t if answer A has a higher score than answer B." #'> (lambda (x) (cdr (assoc 'score x)))) +(sx--create-comparator sx-answer-older-p + "Return t if answer A was posted later than answer B." + #'< (lambda (x) (cdr (assoc 'creation_date x)))) + +(sx--create-comparator sx-answer-more-active-p + "Return t if answer A was updated after answer B." + #'> (lambda (x) (cdr (assoc 'last_activity_date x)))) + (provide 'sx-question) ;;; sx-question.el ends here -- cgit v1.2.3 From 67f1cd1dc24560a21eef8186590020d26d9e55d7 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 15 Jan 2015 00:26:14 -0500 Subject: Fix letbinding `gpf' used to stand for `get-property-function', but this was abstracted into a `get-function'. The letbinding was never changed. This commit also conveniently allows me to say: Fix #226. --- sx.el | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sx.el b/sx.el index 87907de..1cfba12 100644 --- a/sx.el +++ b/sx.el @@ -264,17 +264,17 @@ whenever BODY evaluates to nil." COMPARE-FUNC is a function that takes the return value of GET-FUNC and performs the actual comparison." (declare (indent 1) (doc-string 2)) - (let ((gpf (intern (format " %S--get-prop-function" name))) - (cf (intern (format " %S--compare-function" name)))) + (let ((gf (intern (format " %S--get-prop-function" name))) + (cf (intern (format " %S--compare-function" name)))) ;; Leading space to hide from completion systems `(progn ;; In using `defalias', the macro supports both function ;; symbols and lambda expressions. - (defalias ',gpf ,get-func) - (defalias ',cf ,compare-func) + (defalias ',gf ,get-func) + (defalias ',cf ,compare-func) (defun ,name (a b) ,doc - (,cf (,gpf a) (,gpf b)))))) + (,cf (,gf a) (,gf b)))))) ;;; Printing request data -- cgit v1.2.3 From b9eab6419e514fc6e1ce3096892bccd8a8ffb121 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Fri, 16 Jan 2015 00:40:26 -0500 Subject: Use assq instead of assoc --- sx-question-list.el | 3 +-- sx-question.el | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sx-question-list.el b/sx-question-list.el index cb5bc33..41bebda 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -325,8 +325,7 @@ into consideration. (sx--create-comparator sx-question-list--date-more-recent-p "Non-nil if tabulated-entry A is newer than B." #'> (lambda (x) - (cdr (assoc sx-question-list-date-sort-method - (car x))))) + (cdr (assq sx-question-list-date-sort-method (car x))))) ;;; Keybinds diff --git a/sx-question.el b/sx-question.el index 7c687e8..e199966 100644 --- a/sx-question.el +++ b/sx-question.el @@ -192,15 +192,15 @@ If no cache exists for it, initialize one with SITE." (sx--create-comparator sx-answer-higher-score-p "Return t if answer A has a higher score than answer B." - #'> (lambda (x) (cdr (assoc 'score x)))) + #'> (lambda (x) (cdr (assq 'score x)))) (sx--create-comparator sx-answer-older-p "Return t if answer A was posted later than answer B." - #'< (lambda (x) (cdr (assoc 'creation_date x)))) + #'< (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 (assoc 'last_activity_date x)))) + #'> (lambda (x) (cdr (assq 'last_activity_date x)))) (provide 'sx-question) ;;; sx-question.el ends here -- cgit v1.2.3 From 7470438d4455e38e4f7b749579470d4af2b66751 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Fri, 16 Jan 2015 00:43:21 -0500 Subject: Change older-p to newer-p Older functions generally have more votes anyway -- new answers need initial the attention. --- sx-question-print.el | 2 +- sx-question.el | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sx-question-print.el b/sx-question-print.el index c19b0c3..031e06b 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -171,7 +171,7 @@ replaced with the comment." "Function used to sort answers in the question buffer." :type '(choice (const :tag "Higher-scoring first" sx-answer-higher-score-p) - (const :tag "Older first" sx-answer-older-p) + (const :tag "Newer first" sx-answer-newer-p) (const :tag "More active first" sx-answer-more-active-p)) :group 'sx-question-mode) diff --git a/sx-question.el b/sx-question.el index e199966..e39634b 100644 --- a/sx-question.el +++ b/sx-question.el @@ -194,9 +194,9 @@ If no cache exists for it, initialize one with SITE." "Return t if answer A has a higher score than answer B." #'> (lambda (x) (cdr (assq 'score x)))) -(sx--create-comparator sx-answer-older-p +(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)))) + #'> (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." -- cgit v1.2.3 From 6c4e7c6b95e8bd7d83e5d0f868d9fb3a70c7a974 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Fri, 16 Jan 2015 00:45:35 -0500 Subject: Don't define aliases with comparators The aliases were created in the fear that runtime would be slower to interpret the duplicated lambda expressions for get-func. After testing, this was found not to be the case. `funcall' is a much nicer solution. --- sx.el | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/sx.el b/sx.el index 1cfba12..829570f 100644 --- a/sx.el +++ b/sx.el @@ -264,17 +264,14 @@ whenever BODY evaluates to nil." COMPARE-FUNC is a function that takes the return value of GET-FUNC and performs the actual comparison." (declare (indent 1) (doc-string 2)) - (let ((gf (intern (format " %S--get-prop-function" name))) - (cf (intern (format " %S--compare-function" name)))) - ;; Leading space to hide from completion systems - `(progn - ;; In using `defalias', the macro supports both function - ;; symbols and lambda expressions. - (defalias ',gf ,get-func) - (defalias ',cf ,compare-func) - (defun ,name (a b) - ,doc - (,cf (,gf a) (,gf b)))))) + `(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 -- cgit v1.2.3 From 389e433953bba4003b102748dbbf5f8a9b421a51 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Fri, 16 Jan 2015 08:54:13 -0500 Subject: Hotfix: wrong variable name Fix #234 --- sx-question-print.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx-question-print.el b/sx-question-print.el index a25ff52..f9ecfab 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -176,7 +176,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 sx-question-list--sort-answer-function))) + (cl-sort .answers sx-question-mode-answer-sort-function))) (insert "\n\n ") (insert-text-button "Write an Answer" :type 'sx-button-answer) ;; Go up -- cgit v1.2.3