aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sx-interaction.el80
1 files changed, 40 insertions, 40 deletions
diff --git a/sx-interaction.el b/sx-interaction.el
index 1603ca7..64bcc40 100644
--- a/sx-interaction.el
+++ b/sx-interaction.el
@@ -48,46 +48,46 @@
;;; Using data in buffer
-(cl-defun sx--data-here (&key (error t)
- (type nil)
- (question-read-p nil))
- "Get the alist regarding object under point.
+(defun sx--data-here (&optional type noerror)
+ "Get the alist regarding object under point of type TYPE.
Looks at the text property `sx--data-here'. If it's not set, it
looks at a few other reasonable variables. If those fail too, it
throws an error.
-Possible keyword arguments are:
-
- :error If explicit given as nil, no errors are thrown.
- :type Symbol restricting the type of object desired. Possible
- values are 'question, 'answer, 'comment. If nothing is found of
- that type.
- :question-read-p If non-nil, and if object found is a question,
- throw a `user-error' if it isn't `sx-question--read-p'. If
- object found is not a question, this argument is ignored."
- (let ((result
- (or (let ((data (get-char-property (point) 'sx--data-here)))
- (if (null type) data
- (sx-assoc-let type
- ;; Is data of the right type?
- (cl-case type
- (question (when .title data))
- (answer (when .answer_id data))
- (comment (when .comment_id data))))))
- ;; The following two only ever return questions.
- (when (or (null type) (eq type 'question))
- ;; @TODO: `sx-question-list-mode' may one day display answers.
- (or (and (derived-mode-p 'sx-question-list-mode)
- (tabulated-list-get-id))
- (and (derived-mode-p 'sx-question-mode)
- sx-question-mode--data)))
- ;; Nothing was found
- (and error (error "No %s found here" (or type "data"))))))
- ;; If we found a question, we may need to check if it's read.
- (if (and question-read-p (assoc 'title result))
- (if (sx-question--read-p result) result
- (user-error "Question still unread. View it before acting on it"))
- result)))
+TYPE is a symbol restricting the type of object desired. Possible
+values are 'question, 'answer, 'comment, or nil (for any type).
+
+If no object of the requested type could be returned, an error is
+thrown unless NOERROR is non-nil."
+ (or (let ((data (get-char-property (point) 'sx--data-here)))
+ (if (null type) data
+ (sx-assoc-let type
+ ;; Is data of the right type?
+ (cl-case type
+ (question (when .title data))
+ (answer (when .answer_id data))
+ (comment (when .comment_id data))))))
+ ;; The following two only ever return questions.
+ (when (or (null type) (eq type 'question))
+ ;; @TODO: `sx-question-list-mode' may one day display answers.
+ ;; Ideally, it would use the `sx--data-here' (so no special
+ ;; handling would be necessary.
+ (or (and (derived-mode-p 'sx-question-list-mode)
+ (tabulated-list-get-id))
+ (and (derived-mode-p 'sx-question-mode)
+ sx-question-mode--data)))
+ ;; Nothing was found
+ (and (null noerror)
+ (error "No %s found here" (or type "data")))))
+
+(defun sx--error-if-unread (data)
+ "Throw a user-error if DATA is an unread question.
+If it's not a question, or if it is read, return DATA."
+ ;; If we found a question, we may need to check if it's read.
+ (if (assoc 'title data)
+ (if (sx-question--read-p data) data
+ (user-error "Question not yet read. View it before acting on it"))
+ data))
(defun sx--maybe-update-display (&optional buffer)
"Refresh whatever is displayed in BUFFER or the current buffer.
@@ -157,7 +157,7 @@ If WINDOW nil, the window is decided by
"Apply or remove upvote from DATA.
DATA can be a question, answer, or comment. Interactively, it is
guessed from context at point."
- (interactive (list (sx--data-here :question-read-p t)))
+ (interactive (list (sx--error-if-unread (sx--data-here))))
(sx-assoc-let data
(sx-set-vote data "upvote" (null (eq .upvoted t)))))
@@ -165,7 +165,7 @@ guessed from context at point."
"Apply or remove downvote from DATA.
DATA can be a question or an answer. Interactively, it is guessed
from context at point."
- (interactive (list (sx--data-here :question-read-p t)))
+ (interactive (list (sx--error-if-unread (sx--data-here))))
(sx-assoc-let data
(sx-set-vote data "downvote" (null (eq .downvoted t)))))
@@ -204,7 +204,7 @@ it is guessed from context at point.
If DATA is a comment, the comment is posted as a reply to it.
TEXT is a string. Interactively, it is read from the minibufer."
- (interactive (list (sx--data-here :question-read-p t) 'query))
+ (interactive (list (sx--error-if-unread (sx--data-here)) 'query))
;; When clicking the "Add a Comment" button, first arg is a marker.
(when (markerp data)
(setq data (sx--data-here))
@@ -319,7 +319,7 @@ context at point. "
;; If the user tries to answer a question that's not viewed, he
;; probaby hit the button by accident.
(interactive
- (list (sx--data-here :question-read-p t :type 'question)))
+ (list (sx--error-if-unread (sx--data-here 'question))))
;; When clicking the "Write an Answer" button, first arg is a marker.
(when (markerp data) (setq data (sx--data-here)))
(let ((buffer (current-buffer)))