aboutsummaryrefslogtreecommitdiff
path: root/sx.el
diff options
context:
space:
mode:
Diffstat (limited to 'sx.el')
-rw-r--r--sx.el116
1 files changed, 69 insertions, 47 deletions
diff --git a/sx.el b/sx.el
index be37766..151255e 100644
--- a/sx.el
+++ b/sx.el
@@ -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'."