From c6d0ee75c520041e9117422f7b8d5e86ca6cd5d4 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 2 Dec 2014 00:32:03 +0000 Subject: sx-answer to start composing from the question buffer --- sx-interaction.el | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index 305e61c..3f8242c 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -189,13 +189,48 @@ OBJECT can be a question or an answer." (setcdr com-cell (apply #'vector - (append - (cl-map 'list #'identity - (cdr com-cell)) - (list comment))))) + (append + (cl-map 'list #'identity + (cdr com-cell)) + (list comment))))) ;; No previous comments, add it manually. (setcdr object (cons (car object) (cdr object))) (setcar object `(comments . [,comment]))))) + +;;; Answering +(defun sx-answer (data) + "Start composing an answer for question given by DATA. +DATA is a question alist. Interactively, it is guessed from +context at point. + +TEXT is a string. Interactively, it is read from the minibufer." + ;; Answering doesn't really make sense from anywhere other than + ;; inside a question. So we don't need `sx--data-here' here. + (interactive (list sx-question-mode--data)) + ;; When clicking the "Write an Answer" button, first arg is a marker. + (when (markerp data) (setq data (sx--data-here))) + (let ((buffer (current-buffer))) + (sx-assoc-let data + (pop-to-buffer + (sx-compose--create + .site .question_id nil + ;; After change functions + (lambda (_ res) + (sx--add-answer-to-question-object res sx-question-mode--data) + (when (buffer-live-p buffer) + (with-current-buffer buffer + (sx-question-mode-refresh 'no-update))))))))) + +(defun sx--add-answer-to-question-object (answer question) + "Add alist ANSWER to alist QUESTION in the right place." + (let ((cell (assoc 'answers question))) + (if cell + (setcdr cell (apply #'vector + (append (cdr cell) (list answer)))) + ;; No previous comments, add it manually. + (setcdr question (cons (car question) (cdr question))) + (setcar question `(answers . [,answer]))))) + (provide 'sx-interaction) ;;; sx-interaction.el ends here -- cgit v1.2.3 From 5fbfe0929d2d9f3e0747679db8add0d61a2184a4 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 2 Dec 2014 00:52:25 +0000 Subject: Fix doc --- sx-interaction.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index 3f8242c..1a773f4 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -202,9 +202,7 @@ OBJECT can be a question or an answer." (defun sx-answer (data) "Start composing an answer for question given by DATA. DATA is a question alist. Interactively, it is guessed from -context at point. - -TEXT is a string. Interactively, it is read from the minibufer." +context at point. " ;; Answering doesn't really make sense from anywhere other than ;; inside a question. So we don't need `sx--data-here' here. (interactive (list sx-question-mode--data)) -- cgit v1.2.3 From b8d3e61e0d02796fdd4d0c973dc4fbc9e856baa6 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 2 Dec 2014 00:57:44 +0000 Subject: Simplify update-display code --- sx-interaction.el | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index 1a773f4..8673400 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -37,13 +37,15 @@ (and (derived-mode-p 'sx-question-mode) sx-question-mode--data))) -(defun sx--maybe-update-display () - "Refresh the question list if we're inside it." - (cond - ((derived-mode-p 'sx-question-list-mode) - (sx-question-list-refresh 'redisplay 'no-update)) - ((derived-mode-p 'sx-question-mode) - (sx-question-mode-refresh 'no-update)))) +(defun sx--maybe-update-display (&optional buffer) + "Refresh whatever is displayed in BUFFER or the current buffer. +If BUFFER is not live, nothing is done." + (setq buffer (or buffer (current-buffer))) + (when (buffer-live-p buffer) + (cond ((derived-mode-p 'sx-question-list-mode) + (sx-question-list-refresh 'redisplay 'no-update)) + ((derived-mode-p 'sx-question-mode) + (sx-question-mode-refresh 'no-update))))) (defun sx--copy-data (from to) "Copy all fields of alist FORM onto TO. @@ -216,9 +218,7 @@ context at point. " ;; After change functions (lambda (_ res) (sx--add-answer-to-question-object res sx-question-mode--data) - (when (buffer-live-p buffer) - (with-current-buffer buffer - (sx-question-mode-refresh 'no-update))))))))) + (sx--maybe-update-display buffer))))))) (defun sx--add-answer-to-question-object (answer question) "Add alist ANSWER to alist QUESTION in the right place." -- cgit v1.2.3 From 59c49ce60fcfa1fac4827beb11a04c0ef8585b9a Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 2 Dec 2014 01:20:09 +0000 Subject: Editing implemented Fix #11 --- sx-compose.el | 5 +++++ sx-interaction.el | 31 +++++++++++++++++++++++++++---- sx-question-mode.el | 1 + 3 files changed, 33 insertions(+), 4 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-compose.el b/sx-compose.el index e09240f..dcb1bb0 100644 --- a/sx-compose.el +++ b/sx-compose.el @@ -165,6 +165,11 @@ respectively added locally to `sx-compose-before-send-hook' and (insert sx-compose--question-headers) (goto-char (point-min)) (goto-char (line-end-position)))) + (when (consp parent) + (when (or (string= (buffer-string) "") + (y-or-n-p "Draft buffer exists. Reset it? ")) + (erase-buffer) + (insert (cdr (assoc 'body_markdown parent))))) ;; Return the buffer (current-buffer)))) diff --git a/sx-interaction.el b/sx-interaction.el index 8673400..df871dd 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -199,6 +199,28 @@ OBJECT can be a question or an answer." (setcdr object (cons (car object) (cdr object))) (setcar object `(comments . [,comment]))))) + +;;; Editing +(defun sx-edit (data) + "Start editing an answer or question given by DATA. +DATA is an answer or question alist. Interactively, it is guessed +from context at point." + ;; Answering doesn't really make sense from anywhere other than + ;; inside a question. So we don't need `sx--data-here' here. + (interactive (list (sx--data-here))) + ;; If we ever make an "Edit" button, first arg is a marker. + (when (markerp data) (setq data (sx--data-here))) + (sx-assoc-let data + (when .comment_id (user-error "Editing comments is not supported yet")) + (let ((buffer (current-buffer))) + (pop-to-buffer + (sx-compose--create + .site data nil + ;; After send functions + (list (lambda (_ res) + (sx--copy-data (elt res 0) data) + (sx--maybe-update-display buffer)))))))) + ;;; Answering (defun sx-answer (data) @@ -215,10 +237,11 @@ context at point. " (pop-to-buffer (sx-compose--create .site .question_id nil - ;; After change functions - (lambda (_ res) - (sx--add-answer-to-question-object res sx-question-mode--data) - (sx--maybe-update-display buffer))))))) + ;; After send functions + (list (lambda (_ res) + (sx--add-answer-to-question-object + (elt res 0) sx-question-mode--data) + (sx--maybe-update-display buffer)))))))) (defun sx--add-answer-to-question-object (answer question) "Add alist ANSWER to alist QUESTION in the right place." diff --git a/sx-question-mode.el b/sx-question-mode.el index 24b2cfb..cc4c082 100644 --- a/sx-question-mode.el +++ b/sx-question-mode.el @@ -189,6 +189,7 @@ Letters do not insert themselves; instead, they are commands. ("q" quit-window) (" " scroll-up-command) ("a" sx-answer) + ("e" sx-edit) (,(kbd "S-SPC") scroll-down-command) ([backspace] scroll-down-command) ([tab] forward-button) -- cgit v1.2.3 From 1174858c8f7e87546e671c7322850e2c9e22de4d Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 2 Dec 2014 01:33:59 +0000 Subject: Implement a command for asking. --- sx-interaction.el | 17 +++++++++++++++++ sx-question-list.el | 1 + sx-tab.el | 22 +++++++++++++++------- 3 files changed, 33 insertions(+), 7 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index df871dd..ce00889 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -26,6 +26,8 @@ (require 'sx-question) (require 'sx-question-mode) (require 'sx-question-list) +(require 'sx-compose) +(require 'sx-tab) ;;; Using data in buffer @@ -221,6 +223,21 @@ from context at point." (sx--copy-data (elt res 0) data) (sx--maybe-update-display buffer)))))))) + +;;; Asking +(defun sx-ask (site) + "Start composing a question for SITE. +SITE is a string, indicating where the question will be posted." + ;; Answering doesn't really make sense from anywhere other than + ;; inside a question. So we don't need `sx--data-here' here. + (interactive (list (sx-tab--interactive-site-prompt))) + (let ((buffer (current-buffer))) + (pop-to-buffer + (sx-compose--create + site nil nil + ;; After send functions + (list (lambda (_ res) (sx--maybe-update-display buffer))))))) + ;;; Answering (defun sx-answer (data) diff --git a/sx-question-list.el b/sx-question-list.el index 9709b99..2bfcce0 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -299,6 +299,7 @@ into consideration. ("K" sx-question-list-previous-far) ("g" sx-question-list-refresh) (":" sx-question-list-switch-site) + ("a" sx-ask) ("v" sx-visit) ("u" sx-toggle-upvote) ("d" sx-toggle-downvote) diff --git a/sx-tab.el b/sx-tab.el index 5026a73..873e213 100644 --- a/sx-tab.el +++ b/sx-tab.el @@ -26,13 +26,24 @@ (require 'sx) (require 'sx-question-list) -(require 'sx-interaction) (defcustom sx-tab-default-site "emacs" "Name of the site to use by default when listing questions." :type 'string :group 'sx) +(defun sx-tab--interactive-site-prompt () + "Query the user for a site." + (let ((default (or sx-question-list--site + (sx-assoc-let sx-question-mode--data + .site) + sx-tab-default-site))) + (funcall (if ido-mode #'ido-completing-read #'completing-read) + (format "Site (%s): " default) + (sx-site-get-api-tokens) nil t nil nil + default))) + +;;; The main macro (defmacro sx-tab--define (tab pager &optional printer refresher &rest body) "Define a StackExchange tab called TAB. @@ -56,7 +67,7 @@ variables, but before refreshing the display." `(progn (defvar ,buffer-variable nil ,(format "Buffer where the %s questions are displayed." - tab)) + tab)) (defun ,(intern (concat "sx-tab-" name)) (&optional no-update site) @@ -64,13 +75,10 @@ variables, but before refreshing the display." NO-UPDATE (the prefix arg) is passed to `sx-question-list-refresh'. If SITE is nil, use `sx-tab-default-site'." - tab) + tab) (interactive (list current-prefix-arg - (funcall (if ido-mode #'ido-completing-read #'completing-read) - (format "Site (%s): " sx-tab-default-site) - (sx-site-get-api-tokens) nil t nil nil - sx-tab-default-site))) + (sx-tab--interactive-site-prompt))) (sx-initialize) (unless site (setq site sx-tab-default-site)) ;; Create the buffer -- cgit v1.2.3 From f800936f58d13d8de97eab4b57d3965256482e38 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 2 Dec 2014 02:18:25 +0000 Subject: Refactor sx-compose-create --- sx-compose.el | 8 ++++---- sx-interaction.el | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-compose.el b/sx-compose.el index 0ae1f93..273e02d 100644 --- a/sx-compose.el +++ b/sx-compose.el @@ -67,7 +67,7 @@ Is invoked between `sx-compose-before-send-hook' and 0 42 (read-only t rear-nonsticky t intangible t sx-compose-separator t))) "Headers inserted when composing a new question. -Used by `sx-compose--create'.") +Used by `sx-compose-create'.") ;;; Major-mode @@ -79,7 +79,7 @@ API. This mode won't function if `sx-compose--send-function' isn't set. To make sure you set it correctly, you can create the buffer -with the `sx-compose--create' function. +with the `sx-compose-create' function. \\ \\{sx-compose-mode}" @@ -117,8 +117,8 @@ contents to the API, then calls `sx-compose-after-send-functions'." ;;; Functions to help preparing buffers -(defun sx-compose--create (site parent &optional before-functions after-functions) - "Create a `sx-compose-mode' buffer. +(defun sx-compose-create (site parent &optional before-functions after-functions) + "Create an `sx-compose-mode' buffer. SITE is the site where it will be posted. If composing questions, PARENT is nil. diff --git a/sx-interaction.el b/sx-interaction.el index ce00889..85d681c 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -216,7 +216,7 @@ from context at point." (when .comment_id (user-error "Editing comments is not supported yet")) (let ((buffer (current-buffer))) (pop-to-buffer - (sx-compose--create + (sx-compose-create .site data nil ;; After send functions (list (lambda (_ res) @@ -233,7 +233,7 @@ SITE is a string, indicating where the question will be posted." (interactive (list (sx-tab--interactive-site-prompt))) (let ((buffer (current-buffer))) (pop-to-buffer - (sx-compose--create + (sx-compose-create site nil nil ;; After send functions (list (lambda (_ res) (sx--maybe-update-display buffer))))))) @@ -252,7 +252,7 @@ context at point. " (let ((buffer (current-buffer))) (sx-assoc-let data (pop-to-buffer - (sx-compose--create + (sx-compose-create .site .question_id nil ;; After send functions (list (lambda (_ res) -- cgit v1.2.3 From ac7a451140e4a431c956092dd77d3df4e74bfbf4 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 2 Dec 2014 02:23:43 +0000 Subject: Header Commentary to sx-interaction --- sx-interaction.el | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index 85d681c..d0c4c47 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -19,6 +19,21 @@ ;;; Commentary: +;; This file holds a series of functions for performing arbitrary +;; interactions with arbitrary objects (objects here always mean the +;; alist of a question, answer, or comment). All commands take at +;; least a DATA argument corresponding to the object which, when +;; called interactively, is always derived from the context at point +;; (usually using the `sx--data-here' function). +;; +;; Interactions represented here involve voting, commenting, asking, +;; answering, editing. +;; +;; These are commands are meant to be available throughout the +;; interface. So it didn't make sense to put them in a specific +;; module. They also rely on a lot of dependencies, so they couldn't +;; be put in sx.el. + ;;; Code: @@ -70,7 +85,7 @@ If DATA is a question, also mark it as read." (let ((link (when (stringp .link) (funcall (if copy-as-kill #'kill-new #'browse-url) - .link)))) + .link)))) (when (and (called-interactively-p 'any) copy-as-kill) (message "Copied: %S" link))) (when (and .title (not copy-as-kill)) -- cgit v1.2.3 From 7373bde63cbb066d9aa4f05d0ac04d7ec2781cba Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 3 Dec 2014 15:08:29 +0000 Subject: Extend sx--data-here --- sx-interaction.el | 73 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 24 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index 9a5bbcb..1603ca7 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -36,6 +36,8 @@ ;;; Code: +(eval-when-compile + '(require 'cl-lib)) (require 'sx) (require 'sx-question) @@ -46,20 +48,46 @@ ;;; Using data in buffer -(defun sx--data-here (&optional noerror) - "Get data for the question or other object under point. -If NOERROR is non-nil, don't throw an error on failure. - -This 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." - (or (get-text-property (point) 'sx--data-here) - (and (derived-mode-p 'sx-question-list-mode) - (tabulated-list-get-id)) - (and (derived-mode-p 'sx-question-mode) - sx-question-mode--data) - (and (null noerror) - (error "No question data found here")))) +(cl-defun sx--data-here (&key (error t) + (type nil) + (question-read-p nil)) + "Get the alist regarding object under point. +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))) (defun sx--maybe-update-display (&optional buffer) "Refresh whatever is displayed in BUFFER or the current buffer. @@ -129,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))) + (interactive (list (sx--data-here :question-read-p t))) (sx-assoc-let data (sx-set-vote data "upvote" (null (eq .upvoted t))))) @@ -137,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))) + (interactive (list (sx--data-here :question-read-p t))) (sx-assoc-let data (sx-set-vote data "downvote" (null (eq .downvoted t))))) @@ -176,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) 'query)) + (interactive (list (sx--data-here :question-read-p t) 'query)) ;; When clicking the "Add a Comment" button, first arg is a marker. (when (markerp data) (setq data (sx--data-here)) @@ -255,8 +283,6 @@ OBJECT can be a question or an answer." "Start editing an answer or question given by DATA. DATA is an answer or question alist. Interactively, it is guessed from context at point." - ;; Answering doesn't really make sense from anywhere other than - ;; inside a question. So we don't need `sx--data-here' here. (interactive (list (sx--data-here))) ;; If we ever make an "Edit" button, first arg is a marker. (when (markerp data) (setq data (sx--data-here))) @@ -276,8 +302,6 @@ from context at point." (defun sx-ask (site) "Start composing a question for SITE. SITE is a string, indicating where the question will be posted." - ;; Answering doesn't really make sense from anywhere other than - ;; inside a question. So we don't need `sx--data-here' here. (interactive (list (sx-tab--interactive-site-prompt))) (let ((buffer (current-buffer))) (pop-to-buffer @@ -292,9 +316,10 @@ SITE is a string, indicating where the question will be posted." "Start composing an answer for question given by DATA. DATA is a question alist. Interactively, it is guessed from context at point. " - ;; Answering doesn't really make sense from anywhere other than - ;; inside a question. So we don't need `sx--data-here' here. - (interactive (list sx-question-mode--data)) + ;; 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))) ;; When clicking the "Write an Answer" button, first arg is a marker. (when (markerp data) (setq data (sx--data-here))) (let ((buffer (current-buffer))) -- cgit v1.2.3 From 665668a3fcf6122837bca8845c98cf77872e18b9 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 3 Dec 2014 19:50:27 +0000 Subject: Refactor :question-read-p in data-here as a separate function --- sx-interaction.el | 80 +++++++++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'sx-interaction.el') 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))) -- cgit v1.2.3 From e549dce5556c9550eedf220d247764e84b4879b7 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 3 Dec 2014 19:52:34 +0000 Subject: Slight simplification --- sx-interaction.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index 64bcc40..89050c3 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -84,9 +84,9 @@ thrown unless NOERROR is non-nil." "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")) + (if (and (assoc 'title data) + (null (sx-question--read-p data))) + (user-error "Question not yet read. View it before acting on it") data)) (defun sx--maybe-update-display (&optional buffer) -- cgit v1.2.3