diff options
Diffstat (limited to 'sx-compose.el')
-rw-r--r-- | sx-compose.el | 78 |
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 |