aboutsummaryrefslogtreecommitdiff
path: root/sx.el
diff options
context:
space:
mode:
Diffstat (limited to 'sx.el')
-rw-r--r--sx.el82
1 files changed, 53 insertions, 29 deletions
diff --git a/sx.el b/sx.el
index a1e504e..7ed56d3 100644
--- a/sx.el
+++ b/sx.el
@@ -25,7 +25,8 @@
;;; Code:
-;;; Requirements
+;;; Utility Functions
+
(defun sx-message (format-string &rest args)
"Display a message"
(message "[stack] %s" (apply #'format format-string args)))
@@ -70,48 +71,71 @@ a string, just return it."
;;; 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."
+(defun sx--deep-dot-search (data)
+ "Find symbols somewhere inside DATA which start with a `.'.
+Returns a list where each element is a cons cell. The car is the
+symbol, the cdr is the symbol without the `.'."
(cond
- ((symbolp list)
- (eq symbol list))
- ((not (listp list))
- nil)
- (t
- (remove nil (mapcar (lambda (x) (sx--deep-search symbol x)) list)))))
+ ((symbolp data)
+ (let ((name (symbol-name data)))
+ (when (string-match "\\`\\." name)
+ ;; Return the cons cell inside a list, so it can be appended
+ ;; with other results in the clause below.
+ (list (cons data (intern (replace-match "" nil nil name)))))))
+ ((not (listp data)) nil)
+ (t (apply
+ #'append
+ (remove nil (mapcar #'sx--deep-dot-search data))))))
(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.
+ "Execute BODY while let-binding dotted symbols to their values in ALIST.
+Dotted symbol is any symbol starting with a `.'. 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))
+ (list .title .body))
is equivalent to
- (let ((title (cdr (assoc 'title alist)))
- (body (cdr (assoc 'body alist))))
- (list title body))"
+ (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)
+ (let ((symbol-alist (sx--deep-dot-search body)))
+ `(let ,(mapcar (lambda (x) `(,(car x) (cdr (assoc ',(cdr x) ,alist))))
+ symbol-alist)
,@body)))
+(defcustom sx-init-hook nil
+ "Hook run when stack-mode initializes.
+
+Run after `sx-init--internal-hook'.")
+
+(defvar sx-init--internal-hook nil
+ "Hook run when stack-mode initializes.
+
+This is used internally to set initial values for variables such
+as filters.")
+
+(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,
+`set' is used."
+ (eval
+ `(add-hook
+ 'sx-init--internal-hook
+ (lambda ()
+ (,(or setter #'setq) ,variable ,value))))
+ nil)
+
+(defun stack-initialize ()
+ (run-hooks
+ 'sx-init--internal-hook
+ 'sx-init-hook))
+
(provide 'sx)
;;; sx.el ends here