From 049555600add426d2e539648e6e2927e6e7e4360 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 4 Dec 2014 14:47:12 +0000 Subject: Create sx-tag file --- sx-tag.el | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 sx-tag.el diff --git a/sx-tag.el b/sx-tag.el new file mode 100644 index 0000000..82f7ddb --- /dev/null +++ b/sx-tag.el @@ -0,0 +1,69 @@ +;;; sx-tag.el --- Retrieving list of tags and handling tags. -*- lexical-binding: t; -*- + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + + + +;;; Code: +(eval-when-compile + '(require 'cl-lib)) + +(require 'sx) +(require 'sx-method) + + +;;; Getting the list from a site +(defvar sx-tag-filter '((tag.name)) + "Filter used when querying tags.") + +(defun sx-tag--get-some-tags-containing (site string) + "Return at most 100 tags for SITE containing STRING. +Returns an array." + (sx-method-call 'tags + :auth nil + :filter sx-tag-filter + :site site + :keywords `((page . 1) (pagesize . 100) (inname . ,string)))) + +(defun sx-tag--get-some-tag-names-containing (site string) + "Return at most 100 tag names for SITE containing STRING. +Returns a list." + (mapcar (lambda (x) (cdr (assoc 'name x))) + (sx-tag--get-some-tags-containing site string))) + + +;;; Check tag validity +(defun sx-tag--invalid-name-p (site tags) + "Nil if TAGS exist in SITE. +TAGS can be a string (the tag name) or a list of strings. +Fails if TAGS is a list with more than 100 items. +Return the list of invalid tags in TAGS." + (and (listp tags) (> (length tags) 100) + (error "Invalid argument. TAG has more than 100 items")) + (let ((result + (mapcar + (lambda (x) (cdr (assoc 'name x))) + (sx-method-call 'tags + :id (sx--thing-as-string tags) + :submethod 'info + :auth nil + :filter sx-tag-filter + :site site + :keywords '((page . 1) (pagesize . 100)))))) + (cl-remove-if (lambda (x) (member x result)) tags))) + +(provide 'sx-tag) +;;; sx-tag.el ends here -- cgit v1.2.3 From 9a8a3842f31a3e31e04e073689bdf1e29330f356 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 5 Dec 2014 14:50:53 +0000 Subject: Check tags before sending in compose-mode --- sx-compose.el | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/sx-compose.el b/sx-compose.el index d7d3ff3..5d22bf7 100644 --- a/sx-compose.el +++ b/sx-compose.el @@ -79,6 +79,10 @@ Is invoked between `sx-compose-before-send-hook' and "Headers inserted when composing a new question. Used by `sx-compose-create'.") +(defvar sx-compose--site nil + "Site which the curent compose buffer belongs to.") +(make-variable-buffer-local 'sx-compose--site) + ;;; Major-mode (define-derived-mode sx-compose-mode markdown-mode "Compose" @@ -113,6 +117,8 @@ contents to the API, then calls `sx-compose-after-send-functions'." (run-hook-with-args 'sx-compose-after-send-functions (current-buffer) result))))) + +;;; Functions for use in hooks (defun sx-compose-quit (buffer _) "Kill BUFFER." (interactive (list (current-buffer) nil)) @@ -125,6 +131,26 @@ contents to the API, then calls `sx-compose-after-send-functions'." (with-current-buffer buffer (kill-new (buffer-string))))) +(defun sx-compose--check-tags () + "Check if tags in current compose buffer are valid." + (save-excursion + (goto-char (point-min)) + (unless (search-forward-regexp + "^Tags : *\\([^[:space:]].*\\) *$" + (next-single-property-change (point-min) 'sx-compose-separator) + 'noerror) + (error "No Tags header found")) + (let ((invalid-tags + (sx-tag--invalid-name-p + (split-string (match-string 1) "[[:space:],;]" + 'omit-nulls "[[:space:]]") + sx-compose--site))) + (if invalid-tags + ;; If the user doesn't want to create the tags, we return + ;; nil and sending is aborted. + (y-or-n-p "Following tags don't exist. Create them? %s " invalid-tags) + t)))) + ;;; Functions to help preparing buffers (defun sx-compose-create (site parent &optional before-functions after-functions) @@ -146,6 +172,7 @@ respectively added locally to `sx-compose-before-send-hook' and (null (cdr (assoc 'answer_id 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 @@ -170,6 +197,8 @@ respectively added locally to `sx-compose-before-send-hook' and (add-hook 'sx-compose-before-send-hook it nil t)) (dolist (it (reverse after-functions)) (add-hook 'sx-compose-after-send-functions it nil t)) + (when is-question + (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) "")) -- cgit v1.2.3