diff options
Diffstat (limited to 'sx.el')
-rw-r--r-- | sx.el | 116 |
1 files changed, 69 insertions, 47 deletions
@@ -61,7 +61,16 @@ DATA can also be the link itself." (cdr (assoc 'link data))))) (when (stringp link) (replace-regexp-in-string - "^https?://\\(?:\\(?1:[^/]+\\)\\.stackexchange\\|\\(?2:[^/]+\\)\\)\\.[^.]+/.*$" + (rx string-start + "http" (optional "s") "://" + (or + (sequence + (group-n 1 (+ (not (any "/")))) + ".stackexchange") + (group-n 2 (+ (not (any "/"))))) + "." (+ (not (any "."))) + "/" (* any) + string-end) "\\1\\2" link)))) (defun sx--ensure-site (data) @@ -77,15 +86,64 @@ with a `link' property)." (cdr data))))) data)) +(defun sx--link-to-data (link) + "Convert string LINK into data that can be displayed." + (let ((result (list (cons 'site (sx--site link))))) + ;; Try to strip a question or answer ID + (when (or + ;; Answer + (and (or (string-match + ;; From 'Share' button + (rx "/a/" + ;; Question ID + (group (+ digit)) + ;; User ID + "/" (+ digit) + ;; Answer ID + (group (or (sequence "#" (* any)) "")) + string-end) link) + (string-match + ;; From URL + (rx "/questions/" (+ digit) "/" + (+ (not (any "/"))) "/" + ;; User ID + (optional (group (+ digit))) + (optional "/") + (group (or (sequence "#" (* any)) "")) + string-end) link)) + (push '(type . answer) result)) + ;; Question + (and (or (string-match + ;; From 'Share' button + (rx "/q/" + ;; Question ID + (group (+ digit)) + ;; User ID + (optional "/" (+ digit)) + ;; Answer or Comment ID + (group (or (sequence "#" (* any)) "")) + string-end) link) + (string-match + ;; From URL + (rx "/questions/" + ;; Question ID + (group (+ digit)) + "/") link)) + (push '(type . question) result))) + (push (cons 'id (string-to-number (match-string-no-properties 1 link))) + result)) + result)) + (defmacro sx-assoc-let (alist &rest body) "Identical to `let-alist', except `.site' has a special meaning. If ALIST doesn't have a `site' property, one is created using the `link' property." (declare (indent 1) (debug t)) + (require 'let-alist) `(progn - (require 'let-alist) (sx--ensure-site ,alist) - (let-alist ,alist ,@body))) + ,(macroexpand + `(let-alist ,alist ,@body)))) ;;; Browsing filter @@ -94,6 +152,7 @@ If ALIST doesn't have a `site' property, one is created using the question.comments question.answers question.last_editor + question.last_activity_date question.accepted_answer_id question.link question.upvoted @@ -114,6 +173,7 @@ If ALIST doesn't have a `site' property, one is created using the comment.comment_id answer.answer_id answer.last_editor + answer.last_activity_date answer.link answer.share_link answer.owner @@ -127,6 +187,11 @@ See `sx-question-get-questions' and `sx-question-get-question'.") ;;; Utility Functions +(defun sx-completing-read (&rest args) + "Like `completing-read', but possibly use ido. +All ARGS are passed to `completing-read' or `ido-completing-read'." + (apply (if ido-mode #'ido-completing-read #'completing-read) + args)) (defmacro sx-sorted-insert-skip-first (newelt list &optional predicate) "Inserted NEWELT into LIST sorted by PREDICATE. @@ -184,50 +249,6 @@ and sequences of strings." (funcall first-f sequence-sep) ";")))))) -(defun sx--filter-data (data desired-tree) - "Filter DATA and return the DESIRED-TREE. - -For example: - - (sx--filter-data - '((prop1 . value1) - (prop2 . value2) - (prop3 - (test1 . 1) - (test2 . 2)) - (prop4 . t)) - '(prop1 (prop3 test2))) - -would yield - - ((prop1 . value1) - (prop3 - (test2 . 2)))" - (if (vectorp data) - (apply #'vector - (mapcar (lambda (entry) - (sx--filter-data - entry desired-tree)) - data)) - (delq - nil - (mapcar (lambda (cons-cell) - ;; @TODO the resolution of `f' is O(2n) in the worst - ;; case. It may be faster to implement the same - ;; functionality as a `while' loop to stop looking the - ;; list once it has found a match. Do speed tests. - ;; See edfab4443ec3d376c31a38bef12d305838d3fa2e. - (let ((f (or (memq (car cons-cell) desired-tree) - (assoc (car cons-cell) desired-tree)))) - (when f - (if (and (sequencep (cdr cons-cell)) - (sequencep (elt (cdr cons-cell) 0))) - (cons (car cons-cell) - (sx--filter-data - (cdr cons-cell) (cdr f))) - cons-cell)))) - data)))) - (defun sx--shorten-url (url) "Shorten URL hiding anything other than the domain. Paths after the domain are replaced with \"...\". @@ -321,6 +342,7 @@ removed from the display name before it is returned." (format "[%s]" (car kar)) (cdr kar) string))) string)) + (defcustom sx-init-hook nil "Hook run when SX initializes. Run after `sx-init--internal-hook'." |