aboutsummaryrefslogtreecommitdiff
path: root/sx-compose.el
diff options
context:
space:
mode:
Diffstat (limited to 'sx-compose.el')
-rw-r--r--sx-compose.el78
1 files changed, 53 insertions, 25 deletions
diff --git a/sx-compose.el b/sx-compose.el
index 5d22bf7..d27d2f3 100644
--- a/sx-compose.el
+++ b/sx-compose.el
@@ -43,7 +43,7 @@
;;; Faces and Variables
-(defvar sx-compose-before-send-hook nil
+(defvar sx-compose-before-send-hook nil
"Hook run before POSTing to the API.
Functions are called without arguments and should return non-nil.
@@ -54,7 +54,7 @@ notifying the user.
Current buffer is the compose-mode buffer whose content is about
to be POSTed.")
-(defvar sx-compose-after-send-functions nil
+(defvar sx-compose-after-send-functions nil
"Hook run after POSTing to the API.
Functions on this hook should take two arguments, the
`sx-compose-mode' buffer (which not be live) and the data
@@ -70,12 +70,15 @@ Is invoked between `sx-compose-before-send-hook' and
(defvar sx-compose--question-headers
(concat
#("Title: " 0 7 (intangible t read-only t rear-nonsticky t))
+ "%s"
#("\n" 0 1 (read-only t))
#("Tags : " 0 7 (read-only t intangible t rear-nonsticky t))
+ "%s"
#("\n" 0 1 (read-only t rear-nonsticky t))
- #("________________________________________\n\n"
- 0 42 (read-only t rear-nonsticky t intangible t
- sx-compose-separator t)))
+ #("________________________________________\n"
+ 0 41 (read-only t rear-nonsticky t intangible t
+ sx-compose-separator t))
+ "\n")
"Headers inserted when composing a new question.
Used by `sx-compose-create'.")
@@ -120,9 +123,12 @@ contents to the API, then calls `sx-compose-after-send-functions'."
;;; Functions for use in hooks
(defun sx-compose-quit (buffer _)
- "Kill BUFFER."
+ "Close BUFFER's window and kill it."
(interactive (list (current-buffer) nil))
(when (buffer-live-p buffer)
+ (let ((w (get-buffer-window buffer)))
+ (when (window-live-p w)
+ (delete-window w)))
(kill-buffer buffer)))
(defun sx-compose--copy-as-kill (buffer _)
@@ -155,9 +161,9 @@ 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 an `sx-compose-mode' buffer.
-SITE is the site where it will be posted.
+SITE is the site where it will be posted.
-If composing questions, PARENT is nil.
+If composing questions, PARENT is nil.
If composing answers, it is the `question_id'.
If editing answers or questions, it should be the alist data
related to that object.
@@ -169,20 +175,24 @@ respectively added locally to `sx-compose-before-send-hook' and
(error "Invalid PARENT"))
(let ((is-question
(and (listp parent)
- (null (cdr (assoc 'answer_id parent))))))
+ (or (null parent)
+ (cdr (assoc 'title parent))))))
(with-current-buffer (sx-compose--get-buffer-create site parent)
(sx-compose-mode)
(setq sx-compose--site site)
(setq sx-compose--send-function
(if (consp parent)
(sx-assoc-let parent
- (lambda () (sx-method-call (if .title 'questions 'answers)
+ (lambda () (sx-method-call (cond
+ (.title 'questions)
+ (.comment_id 'comments)
+ (t 'answers))
:auth 'warn
:url-method "POST"
:filter sx-browse-filter
:site site
:keywords (sx-compose--generate-keywords is-question)
- :id (or .answer_id .question_id)
+ :id (or .comment_id .answer_id .question_id)
:submethod 'edit)))
(lambda () (sx-method-call 'questions
:auth 'warn
@@ -201,19 +211,32 @@ respectively added locally to `sx-compose-before-send-hook' and
(add-hook 'sx-compose-before-send-hook #'sx-compose--check-tags nil t))
;; If the buffer is empty, the draft didn't exist. So prepare the
;; question.
- (when (and is-question (string= (buffer-string) ""))
- (let ((inhibit-point-motion-hooks))
- (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? "))
+ (when (or (string= (buffer-string) "")
+ (y-or-n-p "Draft buffer exists. Reset it? "))
+ (let ((inhibit-point-motion-hooks t)
+ (inhibit-read-only t))
(erase-buffer)
- (insert (cdr (assoc 'body_markdown parent)))))
+ (when (consp parent)
+ (insert (cdr (assoc 'body_markdown parent))))
+ (when is-question
+ (sx-compose--print-question-headers
+ (when (consp parent) parent))
+ (unless (consp parent)
+ (goto-char (point-min))
+ (goto-char (line-end-position))))))
;; Return the buffer
(current-buffer))))
+(defun sx-compose--print-question-headers (question)
+ "Print question headers for the compose buffer.
+If QUESTION is non-nil, fill the headers with the data from
+QUESTION."
+ (sx-assoc-let question
+ (goto-char (point-min))
+ (insert
+ (format sx-compose--question-headers
+ (or .title "") (mapconcat #'identity .tags " ")))))
+
(defun sx-compose--generate-keywords (is-question)
"Reading current buffer, generate a keywords alist.
Keywords meant to be used in `sx-method-call'.
@@ -223,7 +246,7 @@ other keywords are read from the header "
`(,@(when is-question
(let ((inhibit-point-motion-hooks t)
(inhibit-read-only t)
- (header-end
+ (header-end
(next-single-property-change
(point-min) 'sx-compose-separator))
keywords)
@@ -238,8 +261,8 @@ other keywords are read from the header "
(unless (search-forward-regexp "^Tags : *\\([^[:space:]].*\\) *$"
header-end 'noerror)
(error "No Tags header found"))
- (push (cons 'tags (split-string (match-string 1) "[[:space:],;]"
- 'omit-nulls "[[:space:]]"))
+ (push (cons 'tags (split-string (match-string 1)
+ "[[:space:],;]" 'omit-nulls))
keywords)
;; And erase the header so it doesn't get sent.
(delete-region
@@ -269,8 +292,13 @@ the id property."
site data)))
(t
(get-buffer-create
- (format "*sx draft edit %s %s*"
- site (sx-assoc-let data (or .answer_id .question_id)))))))
+ (sx-assoc-let data
+ (format "*sx draft edit %s %s %s*"
+ site
+ (cond (.title "question")
+ (.comment_id "comment")
+ (t "answer"))
+ (or .comment_id .answer_id .question_id)))))))
(provide 'sx-compose)
;;; sx-compose.el ends here