From 7da9b2567c2635dfab5f9400fb76297f61b80be4 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 1 Jan 2015 16:57:49 -0500 Subject: Test sx-time-since --- test/test-printing.el | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/test-printing.el b/test/test-printing.el index 6225bf6..60382b2 100644 --- a/test/test-printing.el +++ b/test/test-printing.el @@ -27,6 +27,18 @@ after being run through `sx-question--tag-format'." ;;; Tests +(ert-deftest time-since () + (cl-letf (((symbol-function #'float-time) + (lambda () 1420148997.))) + (should + (string= + "67m" + (sx-time-since 1420145000.))) + (should + (string= + "12h" + (sx-time-since 1420105000.))))) + (ert-deftest question-list-tag () "Test `sx-question--tag-format'." (should -- cgit v1.2.3 From 54849b2564c3d9bb95bc3512b568e30aa21a3db4 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 1 Jan 2015 23:29:55 -0500 Subject: Update Makefile Clean compiled files before every test. This ensures that the changes made during the current session are applied when re-testing. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 7b0b698..a72bea1 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ $(VERSIONS) :: evm use emacs-24.$@-bin emacs --version cask install + cask clean-elc emacs --batch -L . -l ert -l test/tests.el -f ert-run-tests-batch-and-exit install_cask: -- cgit v1.2.3 From 3b275a93789a568d23ece65086ffebb8de430f3a Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Thu, 1 Jan 2015 23:40:20 -0500 Subject: Add test for user entry functions --- test/tests.el | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/tests.el b/test/tests.el index d709600..7bfc86c 100644 --- a/test/tests.el +++ b/test/tests.el @@ -59,3 +59,19 @@ (mapc #'sx-load-test '(api macros printing util)) + +(ert-deftest user-entry-functions () + "Ensures all entry functions are autoloaded." + (should + (cl-every + #'fboundp + '(sx-ask + sx-authenticate + sx-bug-report + sx-tab-frontpage + sx-tab-hot + sx-tab-month + sx-tab-newest + sx-tab-topvoted + sx-tab-week + sx-version)))) -- cgit v1.2.3 From 7a75cd61e822a4895b85bc17780b163bd6876ca7 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Sun, 4 Jan 2015 17:26:16 -0500 Subject: Add more autoloads to test --- test/tests.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/tests.el b/test/tests.el index 5eec57c..493d7dc 100644 --- a/test/tests.el +++ b/test/tests.el @@ -69,10 +69,14 @@ '(sx-ask sx-authenticate sx-bug-report + sx-switchto-map + sx-tab-featured sx-tab-frontpage sx-tab-hot sx-tab-month sx-tab-newest + sx-tab-starred sx-tab-topvoted + sx-tab-unanswered sx-tab-week sx-version)))) -- cgit v1.2.3 From 2d4b14482c92997b3c97731795e1eb6f054fecf6 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 15 Jan 2015 19:13:33 -0200 Subject: Hitting RET on link buttons calls sx-open-link --- sx-button.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sx-button.el b/sx-button.el index 5a2f052..e00b086 100644 --- a/sx-button.el +++ b/sx-button.el @@ -98,9 +98,9 @@ usually part of a code-block." (defun sx-button-follow-link (&optional pos) "Follow link at POS. If POS is nil, use `point'." (interactive) - (browse-url - (or (get-text-property (or pos (point)) 'sx-button-url) - (sx-user-error "No url under point: %s" (or pos (point)))))) + (let ((url (or (get-text-property (or pos (point)) 'sx-button-url) + (sx-user-error "No url under point: %s" (or pos (point)))))) + (sx-open-link url))) ;;; Help-echo definitions -- cgit v1.2.3 From 802f778bb28506d9be92618913c8db0cb4eda539 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 16 Jan 2015 12:42:53 -0200 Subject: load test-state --- test/tests.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tests.el b/test/tests.el index 493d7dc..be1552b 100644 --- a/test/tests.el +++ b/test/tests.el @@ -59,7 +59,7 @@ (apply #'message message args))) (mapc #'sx-load-test - '(api macros printing util search)) + '(api macros printing util search state)) (ert-deftest user-entry-functions () "Ensures all entry functions are autoloaded." -- cgit v1.2.3 From 148da420d9f464f3cc8046fed99a103af0fd7bed Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 16 Jan 2015 12:52:14 -0200 Subject: Test displaying a question --- test/test-printing.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test-printing.el b/test/test-printing.el index 677dca3..9512a5e 100644 --- a/test/test-printing.el +++ b/test/test-printing.el @@ -146,6 +146,14 @@ after being run through `sx-question--tag-format'." (should (equal object '((answers . [something "answer"])))))) + +;;; question-mode +(ert-deftest sx-display-question () + (should + (sx-display-question sx-test-data-questions)) + (should-error + (sx-display-question sx-test-data-questions nil 1))) + (ert-deftest sx-question-mode--fill-and-fontify () "Check complicated questions are filled correctly." (should @@ -202,3 +210,4 @@ if you used the Stack Exchange login method, you'd... [1]: http://i.stack.imgur.com/ktFTs.png [2]: http://i.stack.imgur.com/5l2AY.png [3]: http://i.stack.imgur.com/22myl.png"))) + -- cgit v1.2.3 From 2de9020ac40daedab8ca0df194e8f4eb6ae20478 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 21 Jan 2015 22:26:57 -0200 Subject: Fix the universe and make the world right again. Amongst other things, this should put an end to whale hunting, malaria, and issues such as #238, #209 and #206. --- sx-request.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx-request.el b/sx-request.el index 2650c55..8f672ec 100644 --- a/sx-request.el +++ b/sx-request.el @@ -160,7 +160,7 @@ the main content of the response is returned." (url-inhibit-uncompression t) (url-request-data (sx-request--build-keyword-arguments args nil)) (request-url (concat sx-request-api-root method)) - (url-request-method (and request-method (symbol-name request-method))) + (url-request-method (and request-method (upcase (symbol-name request-method)))) (url-request-extra-headers '(("Content-Type" . "application/x-www-form-urlencoded"))) (response-buffer (url-retrieve-synchronously request-url))) -- cgit v1.2.3 From a2d526c4b12ffa1cece78be7e6bfedf0b2b60576 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 24 Jan 2015 01:01:37 -0200 Subject: Less demanding final regexp for questions. --- sx.el | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sx.el b/sx.el index e0609a7..26151b3 100644 --- a/sx.el +++ b/sx.el @@ -148,12 +148,7 @@ with a `link' property)." ;; From URL (string-match (rx "/questions/" ;; Question ID - (group-n 1 (+ digit)) "/" - ;; Optional question title - (optional (+ (not (any "/"))) "/") - ;; Garbage at the end - (optional (and (any "?#") (* any))) - string-end) + (group-n 1 (+ digit)) "/") link)) (push '(type . question) result))) (push (cons 'id (string-to-number (match-string-no-properties 1 link))) -- cgit v1.2.3 From f8710a5c08185efca16fb552a3d58893282d320e Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Wed, 28 Jan 2015 16:53:55 -0600 Subject: Ensure printing of full data structure for cache Bind `print-{depth,level}' to nil before writing to the file. This should force `prin1' to spell out the entire data structure. Should fix #244. --- sx-cache.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sx-cache.el b/sx-cache.el index 3e8e08f..b17149f 100644 --- a/sx-cache.el +++ b/sx-cache.el @@ -73,8 +73,9 @@ DATA will be written as returned by `prin1'. CACHE is resolved to a file name by `sx-cache-get-file-name'." (sx-cache--ensure-sx-cache-directory-exists) - (write-region (prin1-to-string data) nil - (sx-cache-get-file-name cache)) + (let (print-length print-level) + (write-region (prin1-to-string data) nil + (sx-cache-get-file-name cache))) data) (defun sx-cache--invalidate (cache &optional vars init-method) -- cgit v1.2.3 From ba4489691847ed1cff2f33f1bfa9aeda85af2a6b Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 3 Feb 2015 13:17:59 -0200 Subject: New function sx--squash-whitespace --- sx.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sx.el b/sx.el index 26151b3..14af94d 100644 --- a/sx.el +++ b/sx.el @@ -331,6 +331,10 @@ GET-FUNC and performs the actual comparison." (funcall ,get-func a) (funcall ,get-func b)))) +(defun sx--squash-whitespace (string) + "Return STRING with consecutive whitespace squashed together." + (replace-regexp-in-string "[ \r\n]+" " " string)) + ;;; Printing request data (defvar sx--overlays nil -- cgit v1.2.3 From f275e00c221c506cd4f22144649649e65179e3cc Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 3 Feb 2015 13:20:56 -0200 Subject: Use sx--squash-whitespace in sx-question-mode--print-comment Fix #246 --- sx-question-print.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sx-question-print.el b/sx-question-print.el index f9ecfab..778b580 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -286,10 +286,10 @@ The comment is indented, filled, and then printed according to (format sx-question-mode-comments-format (sx-user--format "%d" .owner) (substring - ;; We fill with three spaces at the start, so the comment is - ;; slightly indented. (sx-question-mode--fill-and-fontify - (concat " " .body_markdown)) + ;; We fill with three spaces at the start, so the comment is + ;; slightly indented. + (concat " " (sx--squash-whitespace .body_markdown))) ;; Then we remove the spaces from the first line, since we'll ;; add the username there anyway. 3)))))) -- cgit v1.2.3 From 3116757fbbbd2a16a5809d316067338a9492e78f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 3 Feb 2015 13:39:30 -0200 Subject: Fix test --- test/test-printing.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test-printing.el b/test/test-printing.el index 9512a5e..1eea281 100644 --- a/test/test-printing.el +++ b/test/test-printing.el @@ -150,6 +150,8 @@ after being run through `sx-question--tag-format'." ;;; question-mode (ert-deftest sx-display-question () (should + (sx-display-question (elt sx-test-data-questions 0))) + (should-error (sx-display-question sx-test-data-questions)) (should-error (sx-display-question sx-test-data-questions nil 1))) -- cgit v1.2.3 From cf2e0f10498a4fe3f65d20454dee621062d194fd Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 3 Feb 2015 16:32:42 -0200 Subject: Really fix test --- test/test-printing.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test-printing.el b/test/test-printing.el index 1eea281..bcc3dd9 100644 --- a/test/test-printing.el +++ b/test/test-printing.el @@ -149,8 +149,9 @@ after being run through `sx-question--tag-format'." ;;; question-mode (ert-deftest sx-display-question () - (should - (sx-display-question (elt sx-test-data-questions 0))) + ;; Check it doesn't error. + (sx-display-question (elt sx-test-data-questions 0)) + ;; Check it does error. (should-error (sx-display-question sx-test-data-questions)) (should-error -- cgit v1.2.3 From 4ed76728809666cee41336dc5191dcf982806f38 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 3 Feb 2015 16:55:21 -0200 Subject: Don't freak out because question_id is nil. --- sx-question.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sx-question.el b/sx-question.el index 1df4900..1fde1aa 100644 --- a/sx-question.el +++ b/sx-question.el @@ -148,7 +148,8 @@ See `sx-question--user-read-list'." ;; Question wasn't present. (t (sx-sorted-insert-skip-first - q-cell site-cell (lambda (x y) (> (car x) (car y)))))))) + q-cell site-cell + (lambda (x y) (> (or (car x) -1) (or (car y) -1)))))))) ;; Save the results. ;; @TODO This causes a small lag on `j' and `k' as the list gets ;; large. Should we do this on a timer? -- cgit v1.2.3 From 5c877938e4f3d8da9dbfb289d30159d7e0ab75ee Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Fri, 6 Feb 2015 21:01:53 -0600 Subject: Note MELPA release in README [ci skip] --- README.org | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.org b/README.org index b9888a7..a4db7e5 100644 --- a/README.org +++ b/README.org @@ -35,6 +35,9 @@ section. Add comments with =c=. As always, =C-h m= is the definitive resource for the functions of this mode. * Installation +SX is now available on MELPA! Install it via the usual method or run =M-x +package-install RET sx RET=. + To install the development version, follow the usual steps: - Clone this repository - Add this directory to your ~load-path~ -- cgit v1.2.3 From 2b4f8654f0c6329ba87eeb5f96910aa8e7badcfa Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Fri, 6 Feb 2015 21:09:55 -0600 Subject: Update README.org --- README.org | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.org b/README.org index a4db7e5..9bc8081 100644 --- a/README.org +++ b/README.org @@ -49,8 +49,6 @@ If you are going to be doing any asking / answering / commenting / upvoting / downvoting / /etc./, you must use ~sx-authenticate~ to provide SX with an authentication token to act on your behalf. -Eventually, this package will be available on MELPA. - * Contributing Please help contribute! Doing any of the following will help us immensely: - [[https://github.com/vermiculus/sx.el/issues/new][Open an issue]] -- cgit v1.2.3 From b9fbc65cd222e6666361667cf576063de4ca7c2e Mon Sep 17 00:00:00 2001 From: Steve Purcell Date: Sat, 7 Feb 2015 14:05:55 +0000 Subject: Add MELPA badges to README --- README.org | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.org b/README.org index 9bc8081..4071561 100644 --- a/README.org +++ b/README.org @@ -1,6 +1,8 @@ #+Title: SX -- Stack Exchange for Emacs [[https://travis-ci.org/vermiculus/sx.el][https://travis-ci.org/vermiculus/sx.el.svg?branch=master]] +[[http://melpa.org/#/sx][file:http://melpa.org/packages/sx-badge.svg]] +[[http://stable.melpa.org/#/sx][file:http://stable.melpa.org/packages/sx-badge.svg]] [[https://gitter.im/vermiculus/sx.el?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge][https://badges.gitter.im/Join Chat.svg]] [[https://www.waffle.io/vermiculus/sx.el][https://badge.waffle.io/vermiculus/sx.el.svg]] -- cgit v1.2.3 From dbabcbebe6773fcd17fbb18daa686d821afe0ef9 Mon Sep 17 00:00:00 2001 From: William Kunkel Date: Sat, 7 Feb 2015 19:55:36 -0500 Subject: Add new icon --- resources/sx.svg | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 resources/sx.svg diff --git a/resources/sx.svg b/resources/sx.svg new file mode 100644 index 0000000..56d0129 --- /dev/null +++ b/resources/sx.svg @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From ad3c2c9c05705512415afb469c8545b875c7cfe8 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 7 Feb 2015 23:31:54 -0200 Subject: Hot Fix #249. Searching without query --- sx-search.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx-search.el b/sx-search.el index aefd12e..c1e1e23 100644 --- a/sx-search.el +++ b/sx-search.el @@ -84,7 +84,7 @@ prefix argument, the user is asked for everything." (when current-prefix-arg (setq tags (sx-tag-multiple-read site (concat "Tags" (when query " (optional)")))) - (when (and (not query) (string= "" tags)) + (unless (or query tags) (sx-user-error "Must supply either QUERY or TAGS")) (setq excluded-tags (sx-tag-multiple-read site "Excluded tags (optional)"))) -- cgit v1.2.3 From 208c91548a100d6a214b2161351d0a04d60adb8d Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 7 Feb 2015 23:54:58 -0200 Subject: Version bump --- sx.el | 4 ++-- sx.org | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sx.el b/sx.el index 14af94d..33b36b6 100644 --- a/sx.el +++ b/sx.el @@ -4,7 +4,7 @@ ;; Author: Sean Allred ;; URL: https://github.com/vermiculus/sx.el/ -;; Version: 0.1 +;; Version: 0.2 ;; Keywords: help, hypermedia, tools ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5") (json "1.3") (markdown-mode "2.0") (let-alist "1.0.3")) @@ -28,7 +28,7 @@ ;;; Code: (require 'tabulated-list) -(defconst sx-version "0.1" "Version of the `sx' package.") +(defconst sx-version "0.2" "Version of the `sx' package.") (defgroup sx nil "Customization group for the `sx' package." diff --git a/sx.org b/sx.org index e206cc2..014b0de 100644 --- a/sx.org +++ b/sx.org @@ -1,4 +1,4 @@ -#+MACRO: version 0.1 +#+MACRO: version 0.2 #+MACRO: versiondate 16 November 2014 #+MACRO: updated last updated {{{versiondate}}} -- cgit v1.2.3 From 5cd3c39fe75009f48db499bb1bff52d37b57e529 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Wed, 11 Feb 2015 07:33:36 -0600 Subject: Include bug report instructions in CONTRIBUTING Should provide some meta-help with issues like #255. This file is advertised when creating an issue, so it's the best we can do. --- CONTRIBUTING.org | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CONTRIBUTING.org b/CONTRIBUTING.org index 3fcf111..cc9f8ce 100644 --- a/CONTRIBUTING.org +++ b/CONTRIBUTING.org @@ -1,9 +1,24 @@ +** Found a Bug? +Open an issue! Please include: +- a description of what you are trying to do +- the behavior you actually see +- steps we can take to reproduce the bug +If the bug actually causes Emacs to issue an error, please +additionally include the backtrace that led up to the error. To do +this, use ~M-x toggle-debug-on-error~ to make sure that the setting is +/enabled/. Now, when the error occurs, a =*Backtrace*= window will +open with most of the information that we typically need. Copy and +paste this into your bug report. (To get out of the =*Backtrace*= +window and Emacs' subsequent 'debug mode', press =q=.) + +** Don't Know Your Way Around? If you need help, search the issue tracker to see if anyone has asked your question before. If it hasn't, a good place to ask first is our chat room on [[https://gitter.im/vermiculus/sx.el][Gitter]]. Opening an issue is welcome of course, but chat will likely be faster for you. If a code change needs to be made, an issue can be written up as necessary. +** Want to Help? Have a great idea for SX? Again, discuss it on [[https://gitter.im/vermiculus/sx.el][Gitter]] first! Don't limit ideas to mimicking the official website, either -- this is Emacs; we should take advantage of its abilities. -- cgit v1.2.3 From 384855876c6fcb0048551ceed335805babc19b1f Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Wed, 11 Feb 2015 08:18:28 -0600 Subject: Hotfix sx-search autoload Should fix #255 --- sx-search.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx-search.el b/sx-search.el index c1e1e23..cd2f4e7 100644 --- a/sx-search.el +++ b/sx-search.el @@ -62,7 +62,7 @@ KEYWORDS is passed to `sx-method-call'." :filter sx-browse-filter)) -;;; User command +;;;###autoload (defun sx-search (site query &optional tags excluded-tags) "Display search on SITE for question titles containing QUERY. When TAGS is given, it is a lists of tags, one of which must -- cgit v1.2.3 From 285204874ce284bd4e2815c21097b678c4cd8cd6 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 11 Feb 2015 15:01:16 +0000 Subject: Define sx-question-list--order --- sx-question-list.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sx-question-list.el b/sx-question-list.el index 92b4c07..d10309f 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -420,6 +420,10 @@ Non-interactively, DATA is a question alist." "Site being displayed in the *question-list* buffer.") (make-variable-buffer-local 'sx-question-list--site) +(defvar sx-question-list--order nil + "Order being displayed in the *question-list* buffer.") +(make-variable-buffer-local 'sx-question-list--order) + (defun sx-question-list-refresh (&optional redisplay no-update) "Update the list of questions. If REDISPLAY is non-nil (or if interactive), also call `tabulated-list-print'. -- cgit v1.2.3 From 96ae2ad5cb8d8827a1062c66806a60fdae79d3b2 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 11 Feb 2015 15:06:08 +0000 Subject: Document sx-question-list--order --- sx-question-list.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sx-question-list.el b/sx-question-list.el index d10309f..04004b3 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -259,6 +259,10 @@ The full list of variables which can be set is: 5. `sx-question-list--dataset' This is only used if both 3 and 4 are nil. It can be used to display a static list. + 6. `sx-question-list--order' + Set this to the `sort' method that should be used when + requesting the list, if that makes sense. If it doesn't + leave it as nil. \\ If none of these is configured, the behaviour is that of a \"Frontpage\", for the site given by @@ -282,7 +286,7 @@ Adding further questions to the bottom of the list is done by: display; otherwise, decrement `sx-question-list--pages-so-far'. If `sx-question-list--site' is given, items 3 and 4 should take it -into consideration. +into consideration. The same holds for `sx-question-list--order'. \\{sx-question-list-mode-map}" (hl-line-mode 1) -- cgit v1.2.3 From db202249de34136cf43b9f9926d41f0964a184c6 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 11 Feb 2015 15:30:03 +0000 Subject: Define sx-question-list--interactive-order-prompt --- sx-question-list.el | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sx-question-list.el b/sx-question-list.el index 04004b3..d2745db 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -230,6 +230,22 @@ This is ignored if `sx-question-list--refresh-function' is set.") ": Quit") "Header-line used on the question list.") +(defconst sx-question-list--order-methods + '(("Recent Activity" . activity) + ("Creation Date" . creation) + ("Most Voted" . votes) + ("Hot" . hot)) + "Alist of possible values to be passed to the `sort' keyword.") + +(defun sx-question-list--interactive-order-prompt (&optional prompt) + "Interactively prompt for a sorting order. +PROMPT is displayed to the user. If it is omitted, a default one +is used." + (let ((order (sx-completing-read + (or prompt "Order questions by: ") + (mapcar #'car sx-question-list--order-methods)))) + (cdr-safe (assoc-string order sx-question-list--order-methods)))) + ;;; Mode Definition (define-derived-mode sx-question-list-mode -- cgit v1.2.3 From 3293b8a2f75aa92c348cfa82e60b6e5a1e39f088 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 11 Feb 2015 15:30:23 +0000 Subject: Define sx-question-list-order-by Command for switching the ordering method. --- sx-question-list.el | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sx-question-list.el b/sx-question-list.el index d2745db..907ff39 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -616,6 +616,19 @@ Sets `sx-question-list--site' and then call (setq sx-question-list--site site) (sx-question-list-refresh 'redisplay))) +(defun sx-question-list-order-by (sort) + "Order questions in the current list by the method SORT. +Sets `sx-question-list--order' and then calls +`sx-question-list-refresh' with `redisplay'." + (interactive + (list (when sx-question-list--order + (sx-question-list--interactive-order-prompt)))) + (unless sx-question-list--order + (sx-user-error "This list can't be reordered")) + (when (and sort (symbolp sort)) + (setq sx-question-list--order sort) + (sx-question-list-refresh 'redisplay))) + (provide 'sx-question-list) ;;; sx-question-list.el ends here -- cgit v1.2.3 From 0f6749ea36669ed0d8be4f284244813ea30ff4cd Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 11 Feb 2015 15:41:08 +0000 Subject: Improve order-methods --- sx-question-list.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sx-question-list.el b/sx-question-list.el index 907ff39..7757503 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -234,8 +234,10 @@ This is ignored if `sx-question-list--refresh-function' is set.") '(("Recent Activity" . activity) ("Creation Date" . creation) ("Most Voted" . votes) + ("Score" . votes) ("Hot" . hot)) "Alist of possible values to be passed to the `sort' keyword.") +(make-variable-buffer-local 'sx-question-list--order-methods) (defun sx-question-list--interactive-order-prompt (&optional prompt) "Interactively prompt for a sorting order. -- cgit v1.2.3 From c56c78f4a285a9c48a7917eda016efbf00553b5a Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 11 Feb 2015 15:41:16 +0000 Subject: Add ordering to question lists created by sx-search --- sx-search.el | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sx-search.el b/sx-search.el index cd2f4e7..7b4e6c0 100644 --- a/sx-search.el +++ b/sx-search.el @@ -52,7 +52,6 @@ fail. EXCLUDED-TAGS is only is used if TAGS is also provided. KEYWORDS is passed to `sx-method-call'." (sx-method-call 'search :keywords `((page . ,page) - (sort . activity) (intitle . ,query) (tagged . ,tags) (nottagged . ,excluded-tags) @@ -61,6 +60,16 @@ KEYWORDS is passed to `sx-method-call'." :auth t :filter sx-browse-filter)) +(defconst sx-search--order-methods + (cons '("Relevance" . relevance) + (cl-remove-if (lambda (x) (eq (cdr x) 'hot)) + (default-value 'sx-question-list--order-methods))) + "Alist of possible values to be passed to the `sort' keyword.") + +(defvar sx-search-default-order 'activity + "Default ordering method used on new searches. +Possible values are the cdrs of `sx-search--order-methods'.") + ;;;###autoload (defun sx-search (site query &optional tags excluded-tags) @@ -98,8 +107,11 @@ prefix argument, the user is asked for everything." (lambda (page) (sx-search-get-questions sx-question-list--site page - query tags excluded-tags))) + query tags excluded-tags + `((sort . ,sx-question-list--order))))) (setq sx-question-list--site site) + (setq sx-question-list--order sx-search-default-order) + (setq sx-question-list--order-methods sx-search--order-methods) (sx-question-list-refresh 'redisplay) (switch-to-buffer (current-buffer)))) -- cgit v1.2.3 From 2c2becfa47d0b13d633f85a7c18f4d40193dc454 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 11 Feb 2015 15:52:16 +0000 Subject: sx-search-get-questions make KEYWORDS a &rest argument. --- sx-search.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sx-search.el b/sx-search.el index 7b4e6c0..55964b9 100644 --- a/sx-search.el +++ b/sx-search.el @@ -39,7 +39,9 @@ ;;; Basic function -(defun sx-search-get-questions (site page query &optional tags excluded-tags keywords) +(defun sx-search-get-questions (site page query + &optional tags excluded-tags + &rest keywords) "Like `sx-question-get-questions', but restrict results by a search. Perform search on SITE. PAGE is an integer indicating which page @@ -108,7 +110,7 @@ prefix argument, the user is asked for everything." (sx-search-get-questions sx-question-list--site page query tags excluded-tags - `((sort . ,sx-question-list--order))))) + (cons 'sort sx-question-list--order)))) (setq sx-question-list--site site) (setq sx-question-list--order sx-search-default-order) (setq sx-question-list--order-methods sx-search--order-methods) -- cgit v1.2.3 From 21d1b2594efaff4089d2bab736e0a18a1ee1a9db Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 12 Feb 2015 14:16:50 -0200 Subject: Get rid of sx-question-list--update-mode-line --- sx-inbox.el | 6 +----- sx-question-list.el | 24 ++++-------------------- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/sx-inbox.el b/sx-inbox.el index 21589fb..3048509 100644 --- a/sx-inbox.el +++ b/sx-inbox.el @@ -127,11 +127,7 @@ These are identified by their links.") (setq tabulated-list-format [("Type" 30 t nil t) ("Date" 10 t :right-align t) ("Title" 0)]) (setq mode-line-format sx-inbox--mode-line) - (setq header-line-format sx-inbox--header-line) - ;; @TODO: This will no longer be necessary once we properly - ;; refactor sx-question-list-mode. - (remove-hook 'tabulated-list-revert-hook - #'sx-question-list--update-mode-line t)) + (setq header-line-format sx-inbox--header-line)) ;;; Keybinds diff --git a/sx-question-list.el b/sx-question-list.el index 7757503..de15704 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -308,7 +308,8 @@ into consideration. The same holds for `sx-question-list--order'. \\{sx-question-list-mode-map}" (hl-line-mode 1) - (sx-question-list--update-mode-line) + (setq mode-line-format + sx-question-list--mode-line-format) (setq sx-question-list--pages-so-far 0) (setq tabulated-list-format [(" V" 3 t :right-align t) @@ -320,8 +321,6 @@ into consideration. The same holds for `sx-question-list--order'. (setq tabulated-list-sort-key nil) (add-hook 'tabulated-list-revert-hook #'sx-question-list-refresh nil t) - (add-hook 'tabulated-list-revert-hook - #'sx-question-list--update-mode-line nil t) (setq header-line-format sx-question-list--header-line)) (defcustom sx-question-list-date-sort-method 'last_activity_date @@ -400,14 +399,8 @@ Non-interactively, DATA is a question alist." ;; "Unanswered", etc. "Variable describing current tab being viewed.") -(defvar sx-question-list--total-count 0 - "Holds the total number of questions in the current buffer.") -(make-variable-buffer-local 'sx-question-list--total-count) - (defconst sx-question-list--mode-line-format - '(" " - mode-name - " " + '(" " mode-name ": " (:propertize sx-question-list--current-tab face mode-line-buffer-id) " [" @@ -418,7 +411,7 @@ Non-interactively, DATA is a question alist." ", " "Total: " (:propertize - (:eval (int-to-string sx-question-list--total-count)) + (:eval (int-to-string (length tabulated-list-entries))) face mode-line-buffer-id) "] ") "Mode-line construct to use in question-list buffers.") @@ -429,15 +422,6 @@ Non-interactively, DATA is a question alist." (cl-count-if-not #'sx-question--read-p sx-question-list--dataset))) -(defun sx-question-list--update-mode-line () - "Fill the mode-line with useful information." - ;; All the data we need is right in the buffer. - (when (derived-mode-p 'sx-question-list-mode) - (setq mode-line-format - sx-question-list--mode-line-format) - (setq sx-question-list--total-count - (length tabulated-list-entries)))) - (defvar sx-question-list--site nil "Site being displayed in the *question-list* buffer.") (make-variable-buffer-local 'sx-question-list--site) -- cgit v1.2.3 From ade5fe434b5fd031db8cd4e601f26f2933354ab2 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 12 Feb 2015 14:18:55 -0200 Subject: Compiler warnings --- sx-button.el | 10 +++++----- sx.el | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sx-button.el b/sx-button.el index 5a2f052..46855e7 100644 --- a/sx-button.el +++ b/sx-button.el @@ -77,23 +77,23 @@ This is usually a link's URL, or the content of a code block." (point) 'sx-button-copy-type) content))))) -(defun sx-button-edit-this (text-or-marker &optional major-mode) - "Open a temp buffer populated with the string TEXT-OR-MARKER using MAJOR-MODE. +(defun sx-button-edit-this (text-or-marker &optional majormode) + "Open a temp buffer populated with the string TEXT-OR-MARKER using MAJORMODE. When given a marker (or interactively), use the 'sx-button-copy and the 'sx-mode text-properties under the marker. These are usually part of a code-block." (interactive (list (point-marker))) ;; Buttons receive markers. (when (markerp text-or-marker) - (setq major-mode (get-text-property text-or-marker 'sx-mode)) + (setq majormode (get-text-property text-or-marker 'sx-mode)) (unless (setq text-or-marker (get-text-property text-or-marker 'sx-button-copy)) (sx-message "Nothing of interest here."))) (with-current-buffer (pop-to-buffer (generate-new-buffer "*sx temp buffer*")) (insert text-or-marker) - (when major-mode - (funcall major-mode)))) + (when majormode + (funcall majormode)))) (defun sx-button-follow-link (&optional pos) "Follow link at POS. If POS is nil, use `point'." diff --git a/sx.el b/sx.el index 33b36b6..73d874f 100644 --- a/sx.el +++ b/sx.el @@ -204,7 +204,7 @@ is intentionally skipped." (while (and ;; We're not at the end. (cdr-safe tail) ;; We're not at the right place. - (,(or predicate #'<) x (cadr tail))) + (funcall (or ,predicate #'<) x (cadr tail))) (setq tail (cdr tail))) (setcdr tail (cons x (cdr tail))))) -- cgit v1.2.3 From 85109b7dd2ffb896151ccef2c014c7d9ea33e682 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 12 Feb 2015 14:59:46 -0200 Subject: Define possible values for answer sorting --- sx-question-print.el | 19 +++++++++++++++---- sx.el | 6 ++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/sx-question-print.el b/sx-question-print.el index 778b580..4f50560 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -153,13 +153,24 @@ replaced with the comment." :type 'boolean :group 'sx-question-mode) +(defconst sx-question-mode--sort-methods + (let ((methods + '(("Higher-scoring" . sx-answer-higher-score-p) + ("Newer" . sx-answer-newer-p) + ("More active" . sx-answer-more-active-p)))) + (append (mapcar (lambda (x) (cons (concat (car x) " first") (cdr x))) + methods) + (mapcar (lambda (x) (cons (concat (car x) " last") + (sx--invert-predicate (cdr x)))) + methods)))) + (defcustom sx-question-mode-answer-sort-function #'sx-answer-higher-score-p "Function used to sort answers in the question buffer." - :type '(choice - (const :tag "Higher-scoring first" sx-answer-higher-score-p) - (const :tag "Newer first" sx-answer-newer-p) - (const :tag "More active first" sx-answer-more-active-p)) + :type + (cons 'choice + (mapcar (lambda (x) `(const :tag ,(car x) ,(cdr x))) + sx-question-mode--sort-methods)) :group 'sx-question-mode) diff --git a/sx.el b/sx.el index 33b36b6..381f78e 100644 --- a/sx.el +++ b/sx.el @@ -335,6 +335,12 @@ GET-FUNC and performs the actual comparison." "Return STRING with consecutive whitespace squashed together." (replace-regexp-in-string "[ \r\n]+" " " string)) +(defun sx--invert-predicate (predicate) + "Return PREDICATE function with arguments inverted. +For instance (sx--invert-predicate #'<) is the same as #'>. +Note this is not the same as negating PREDICATE." + (lambda (&rest args) (apply predicate (reverse args)))) + ;;; Printing request data (defvar sx--overlays nil -- cgit v1.2.3 From fe7e31a55cdd9c25f3d0c1fba088d5499a887af9 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 12 Feb 2015 15:00:05 -0200 Subject: Sort answers with O --- sx-question-mode.el | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sx-question-mode.el b/sx-question-mode.el index 6125416..846ad7f 100644 --- a/sx-question-mode.el +++ b/sx-question-mode.el @@ -214,6 +214,7 @@ Letters do not insert themselves; instead, they are commands. ("v" sx-visit-externally) ("u" sx-upvote) ("d" sx-downvote) + ("O" sx-question-mode-order-by) ("q" quit-window) (" " scroll-up-command) ("a" sx-answer) @@ -256,6 +257,18 @@ query the api." (unless (derived-mode-p 'sx-question-mode) (error "Not in `sx-question-mode'"))) +(defun sx-question-mode-order-by (sort) + "Order answers in the current buffer by the method SORT. +Sets `sx-question-list--order' and then calls +`sx-question-list-refresh' with `redisplay'." + (interactive + (list (let ((order (sx-completing-read "Order answers by: " + (mapcar #'car sx-question-mode--sort-methods)))) + (cdr-safe (assoc-string order sx-question-mode--sort-methods))))) + (when (and sort (functionp sort)) + (setq sx-question-mode-answer-sort-function sort) + (sx-question-mode-refresh 'no-update))) + (provide 'sx-question-mode) ;;; sx-question-mode.el ends here -- cgit v1.2.3 From b7d1d7c47e6bbb907df90ee078ef18ba47412b75 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 12 Feb 2015 18:54:41 -0200 Subject: Try sx-open-link, THEN do sx-visit-externally --- sx-button.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sx-button.el b/sx-button.el index e00b086..992c654 100644 --- a/sx-button.el +++ b/sx-button.el @@ -100,7 +100,12 @@ usually part of a code-block." (interactive) (let ((url (or (get-text-property (or pos (point)) 'sx-button-url) (sx-user-error "No url under point: %s" (or pos (point)))))) - (sx-open-link url))) + ;; If we didn't recognize the link, this errors immediately. If + ;; we mistakenly recognize it, it will error when we try to fetch + ;; whatever we thought it was. + (condition-case nil (sx-open-link url) + ;; When it errors, don't blame the user, just visit externally. + (error (sx-visit-externally url))))) ;;; Help-echo definitions -- cgit v1.2.3 From 1f73185f411de81a5e26152377c499498d732d8c Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 12 Feb 2015 21:26:03 -0200 Subject: require 'sx-tag --- sx-question-list.el | 1 + 1 file changed, 1 insertion(+) diff --git a/sx-question-list.el b/sx-question-list.el index 07355d0..333fd83 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -27,6 +27,7 @@ (require 'sx) (require 'sx-time) +(require 'sx-tag) (require 'sx-site) (require 'sx-question) (require 'sx-question-mode) -- cgit v1.2.3 From cb29144eb54eb8541f469995a13909ec0bdb1c1d Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 14 Feb 2015 15:46:39 -0200 Subject: Fix declare-function --- sx-button.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx-button.el b/sx-button.el index 8a4bcc0..9f6d3b3 100644 --- a/sx-button.el +++ b/sx-button.el @@ -169,7 +169,7 @@ usually part of a code-block." 'face 'sx-user-name :supertype 'sx-button) -(declare-function sx-search-tag-at-point "sx-tag") +(declare-function sx-search-tag-at-point "sx-search") (define-button-type 'sx-button-tag 'action #'sx-search-tag-at-point 'help-echo sx-button--tag-help-echo -- cgit v1.2.3 From 9140a717b13b2e4919164b249f6d4b83b47ba53e Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 14 Feb 2015 15:48:53 -0200 Subject: Add an sx-tag-meta property to tags. --- sx-search.el | 12 +++++++++--- sx-tag.el | 13 ++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/sx-search.el b/sx-search.el index b33efff..b245cbe 100644 --- a/sx-search.el +++ b/sx-search.el @@ -126,9 +126,15 @@ prefix argument, the user is asked for everything." (let ((tag (save-excursion (when pos (goto-char pos)) (or (get-text-property (point) 'sx-tag) - (thing-at-point 'symbol))))) - (sx-search (or sx-question-list--site - (sx-assoc-let sx-question-mode--data .site_par)) + (thing-at-point 'symbol)))) + (meta (save-excursion + (when pos (goto-char pos)) + (get-text-property (point) 'sx-tag-meta))) + (site (replace-regexp-in-string + (rx string-start "meta.") "" + (or sx-question-list--site + (sx-assoc-let sx-question-mode--data .site_par))))) + (sx-search (concat (when meta "meta.") site) nil tag))) (provide 'sx-search) diff --git a/sx-tag.el b/sx-tag.el index 316226b..a59e0d7 100644 --- a/sx-tag.el +++ b/sx-tag.el @@ -142,17 +142,20 @@ tags." ;;; Printing -(defun sx-tag--format (tag) - "Format and return TAG for display." +(defun sx-tag--format (tag &optional meta) + "Format and return TAG for display. +If META is non-nil, the tag is for the meta site." (with-temp-buffer - (sx-tag--insert tag) + (sx-tag--insert tag meta) (buffer-string))) -(defun sx-tag--insert (tag) - "Insert TAG button." +(defun sx-tag--insert (tag &optional meta) + "Insert TAG button. +If META is non-nil, the tag is for the meta site." (insert-text-button (concat "[" tag "]") 'sx-button-copy tag 'sx-tag tag + 'sx-tag-meta meta :type 'sx-button-tag)) (provide 'sx-tag) -- cgit v1.2.3 From ded9c419cbbbe77446681460e4352168a8b33e80 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 14 Feb 2015 15:58:01 -0200 Subject: Define sx-tag--format-tags to format multiple tags. --- sx-tag.el | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sx-tag.el b/sx-tag.el index a59e0d7..3c00ae2 100644 --- a/sx-tag.el +++ b/sx-tag.el @@ -158,6 +158,19 @@ If META is non-nil, the tag is for the meta site." 'sx-tag-meta meta :type 'sx-button-tag)) +(defun sx-tag--format-tags (tags &optional site) + "Format and concatenate a sequence of TAGS. +Returns a string of all tags in TAGS, separated by a space. + +SITE is the site to which the tags refer, it is only used to +decide whether they are main or meta tags. SITE can also be t or +nil, which respectively indicate meta and main." + (let ((is-meta + (if (stringp site) (string-match (rx string-start "meta.") site) + site))) + (mapconcat (lambda (tag) (sx-tag--format tag is-meta)) + tags " "))) + (provide 'sx-tag) ;;; sx-tag.el ends here -- cgit v1.2.3 From b8124d4056632ae3eb1381b19db743625a715548 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 14 Feb 2015 15:58:17 -0200 Subject: Use sx-tag--format-tags --- sx-question-list.el | 2 +- sx-question-print.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sx-question-list.el b/sx-question-list.el index 333fd83..6bae225 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -166,7 +166,7 @@ Also see `sx-question-list-refresh'." " " ;; @TODO: Make this width customizable. (Or maybe just make ;; the whole thing customizable) - (format "%-40s" (mapconcat #'sx-tag--format .tags " ")) + (format "%-40s" (sx-tag--format-tags .tags sx-question-list--site)) " " (sx-user--format "%15d %4r" .owner) (propertize " " 'display "\n"))))))) diff --git a/sx-question-print.el b/sx-question-print.el index 190c924..e535091 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -223,7 +223,7 @@ DATA can represent a question or an answer." ;; Tags (sx-question-mode--insert-header sx-question-mode-header-tags - (mapconcat #'sx-tag--format .tags " ") + (sx-tag--format-tags .tags .site_par) nil)) ;; Body (insert "\n" -- cgit v1.2.3 From 3b0008b6fc32548905510cf86ab5651e529b84ee Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 14 Feb 2015 16:02:01 -0200 Subject: Understand [meta-tag:TAG] links --- sx-question-print.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sx-question-print.el b/sx-question-print.el index e535091..abf3236 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -320,7 +320,8 @@ E.g.: (defconst sx-question-mode--link-regexp ;; Done at compile time. - (rx (or (and "[tag:" (group-n 5 (+ (not (any " ]")))) "]") + (rx (or (and "[" (optional (group-n 6 "meta-")) "tag:" + (group-n 5 (+ (not (any " ]")))) "]") (and "[" (group-n 1 (1+ (not (any "]")))) "]" (or (and "(" (group-n 2 (1+ (not (any ")")))) ")") (and "[" (group-n 3 (1+ (not (any "]")))) "]"))) @@ -373,7 +374,8 @@ E.g.: (let ((tag (match-string-no-properties 5))) (if (and tag (> (length tag) 0)) (progn (replace-match "") - (sx-tag--insert tag)) + ;; `match-string' 6 is the "meta-" prefix. + (sx-tag--insert tag (match-string 6))) ;; Other links are link-buttons. (let* ((text (match-string-no-properties 1)) (url (or (match-string-no-properties 2) -- cgit v1.2.3 From 2f398913b77d190f2e0c96ba15296c231ba21e18 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 14 Feb 2015 16:44:01 -0200 Subject: Show the site name on the mode-lien --- sx-question-list.el | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sx-question-list.el b/sx-question-list.el index de15704..06af161 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -400,7 +400,13 @@ Non-interactively, DATA is a question alist." "Variable describing current tab being viewed.") (defconst sx-question-list--mode-line-format - '(" " mode-name ": " + '(" " + (:propertize + (:eval (mapconcat #'capitalize + (split-string sx-question-list--site "\\.") + " ")) + face mode-line-buffer-id) + " " mode-name ": " (:propertize sx-question-list--current-tab face mode-line-buffer-id) " [" -- cgit v1.2.3 From d4531c7a605e4d442632c7b54accbefc465a4601 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 20 Feb 2015 20:01:27 -0200 Subject: Fix "Asked on" for answers --- sx-question-print.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sx-question-print.el b/sx-question-print.el index abf3236..056c265 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -63,7 +63,7 @@ Some faces of this mode might be defined in the `sx-user' group." :type 'string :group 'sx-question-mode) -(defcustom sx-question-mode-header-author-format "\nAuthor: %d %r" +(defcustom sx-question-mode-header-author-format "\nAuthor: %d %r" "String used to display the question author at the header. % constructs have special meaning here. See `sx-user--format'." :type 'string @@ -74,7 +74,7 @@ Some faces of this mode might be defined in the `sx-user' group." "Face used on the question date in the question buffer." :group 'sx-question-mode-faces) -(defcustom sx-question-mode-header-date "\nAsked on: " +(defcustom sx-question-mode-header-date "\nPosted on: " "String used before the question date at the header." :type 'string :group 'sx-question-mode) @@ -95,12 +95,12 @@ Some faces of this mode might be defined in the `sx-user' group." "Face used for downvoted score in the question buffer." :group 'sx-question-mode-faces) -(defcustom sx-question-mode-header-tags "\nTags: " +(defcustom sx-question-mode-header-tags "\nTags: " "String used before the question tags at the header." :type 'string :group 'sx-question-mode) -(defcustom sx-question-mode-header-score "\nScore: " +(defcustom sx-question-mode-header-score "\nScore: " "String used before the question score at the header." :type 'string :group 'sx-question-mode) -- cgit v1.2.3 From 3ff90f54e74d034224d70fe90bc2fc67aae6d8f4 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 20 Feb 2015 20:02:22 -0200 Subject: Improve legibility of sx-question-mode--print-section --- sx-question-print.el | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sx-question-print.el b/sx-question-print.el index 056c265..8ba0157 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -193,17 +193,20 @@ DATA can represent a question or an answer." 'sx-question-mode--section (if .title 1 2) 'sx-button-copy .share_link :type 'sx-question-mode-title) + ;; Sections can be hidden with overlays (sx--wrap-in-overlay '(sx-question-mode--section-content t) + ;; Author (insert (sx-user--format (propertize sx-question-mode-header-author-format 'face 'sx-question-mode-header) .owner)) + + ;; Date (sx-question-mode--insert-header - ;; Date sx-question-mode-header-date (concat (sx-time-seconds-to-date .creation_date) @@ -212,6 +215,8 @@ DATA can represent a question or an answer." (sx-time-since .last_edit_date) (sx-user--format "%d" .last_editor)))) 'sx-question-mode-date) + + ;; Score and upvoted/downvoted status. (sx-question-mode--insert-header sx-question-mode-header-score (format "%s" .score) @@ -219,6 +224,8 @@ DATA can represent a question or an answer." ((eq .upvoted t) 'sx-question-mode-score-upvoted) ((eq .downvoted t) 'sx-question-mode-score-downvoted) (t 'sx-question-mode-score))) + + ;; Tags (when .title ;; Tags (sx-question-mode--insert-header -- cgit v1.2.3 From 60df6a23b27bc1ff1dfa8f3bdd37c1c4543d980f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 20 Feb 2015 20:08:53 -0200 Subject: Up and Down arrows when you vote --- sx-question-print.el | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sx-question-print.el b/sx-question-print.el index 8ba0157..bd764da 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -219,11 +219,11 @@ DATA can represent a question or an answer." ;; Score and upvoted/downvoted status. (sx-question-mode--insert-header sx-question-mode-header-score - (format "%s" .score) - (cond - ((eq .upvoted t) 'sx-question-mode-score-upvoted) - ((eq .downvoted t) 'sx-question-mode-score-downvoted) - (t 'sx-question-mode-score))) + (format "%s%s" .score + (cond ((eq .upvoted t) "↑") ((eq .downvoted t) "↓") (t ""))) + (cond ((eq .upvoted t) 'sx-question-mode-score-upvoted) + ((eq .downvoted t) 'sx-question-mode-score-downvoted) + (t 'sx-question-mode-score))) ;; Tags (when .title -- cgit v1.2.3 From bbc6383dea772a62c7ddc8bbcfec72e2ddd14969 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 20 Feb 2015 20:09:18 -0200 Subject: Indicate which answer is accepted --- sx-question-print.el | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sx-question-print.el b/sx-question-print.el index bd764da..62253a7 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -131,6 +131,16 @@ the editor's name." :type 'string :group 'sx-question-mode) +(defface sx-question-mode-accepted + '((t :foreground "ForestGreen" :inherit sx-question-mode-title)) + "Face used for accepted answers in the question buffer." + :group 'sx-question-mode-faces) + +(defcustom sx-question-mode-answer-accepted-title "Accepted Answer" + "Title used at the start of accepted \"Answer\" section." + :type 'string + :group 'sx-question-mode) + (defcustom sx-question-mode-comments-title " Comments" "Title used at the start of \"Comments\" sections." :type 'string @@ -188,10 +198,14 @@ DATA can represent a question or an answer." (insert sx-question-mode-header-title) (insert-text-button ;; Questions have title, Answers don't - (or .title sx-question-mode-answer-title) + (cond (.title) + ((eq .is_accepted t) sx-question-mode-answer-accepted-title) + (t sx-question-mode-answer-title)) ;; Section level 'sx-question-mode--section (if .title 1 2) 'sx-button-copy .share_link + 'face (if (eq .is_accepted t) 'sx-question-mode-accepted + 'sx-question-mode-title) :type 'sx-question-mode-title) ;; Sections can be hidden with overlays -- cgit v1.2.3 From 755322c4ba96c6ce5a836cfa601da993f8031ac1 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 21 Feb 2015 10:43:00 -0200 Subject: Configure question-mode mode-line --- sx-question-mode.el | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sx-question-mode.el b/sx-question-mode.el index 6125416..2d06e5b 100644 --- a/sx-question-mode.el +++ b/sx-question-mode.el @@ -69,6 +69,7 @@ Returns the question buffer." (defun sx-question-mode--erase-and-print-question (data) "Erase contents of buffer and print question given by DATA. Also marks the question as read with `sx-question--mark-read'." + (sx--ensure-site data) (sx-question--mark-read data) (let ((inhibit-read-only t)) (erase-buffer) @@ -183,6 +184,34 @@ property." ": Quit") "Header-line used on the question list.") +(defconst sx-question-mode--mode-line + '(" " + ;; `sx-question-mode--data' is guaranteed to have through + ;; `sx--ensure-site' already, so we use `let-alist' instead of + ;; `sx-assoc-let' to improve performance (since the mode-line is + ;; updated a lot). + (:propertize + (:eval (let-alist sx-question-mode--data .site_par)) + face mode-line-buffer-id) + " " mode-name + " [" + "Answers: " + (:propertize + (:eval (number-to-string (let-alist sx-question-mode--data .answer_count))) + face mode-line-buffer-id) + ", " + "Stars: " + (:propertize + (:eval (number-to-string (or (let-alist sx-question-mode--data .favorite_count) 0))) + face mode-line-buffer-id) + ", " + "Views: " + (:propertize + (:eval (number-to-string (let-alist sx-question-mode--data .view_count))) + face mode-line-buffer-id) + "] ") + "Mode-line construct to use in `sx-question-mode' buffers.") + (define-derived-mode sx-question-mode special-mode "Question" "Major mode to display and navigate a question and its answers. Letters do not insert themselves; instead, they are commands. @@ -190,6 +219,7 @@ Letters do not insert themselves; instead, they are commands. \\ \\{sx-question-mode}" (setq header-line-format sx-question-mode--header-line) + (setq header-line-format sx-question-mode--mode-line) ;; Determine how to close this window. (unless (window-parameter nil 'quit-restore) (set-window-parameter -- cgit v1.2.3 From d73ba0621e1e73df155a09126ecef8df8c2d232a Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 21 Feb 2015 10:48:28 -0200 Subject: Standardize prettification of site names. --- sx-question-list.el | 4 +--- sx-question-mode.el | 9 +++++++-- sx.el | 6 ++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sx-question-list.el b/sx-question-list.el index def490b..32bc140 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -397,9 +397,7 @@ Non-interactively, DATA is a question alist." (defconst sx-question-list--mode-line-format '(" " (:propertize - (:eval (mapconcat #'capitalize - (split-string sx-question-list--site "\\.") - " ")) + (:eval (sx--pretty-site-parameter sx-question-list--site)) face mode-line-buffer-id) " " mode-name ": " (:propertize sx-question-list--current-tab diff --git a/sx-question-mode.el b/sx-question-mode.el index 2d06e5b..d4b7f8d 100644 --- a/sx-question-mode.el +++ b/sx-question-mode.el @@ -191,7 +191,8 @@ property." ;; `sx-assoc-let' to improve performance (since the mode-line is ;; updated a lot). (:propertize - (:eval (let-alist sx-question-mode--data .site_par)) + (:eval (sx--pretty-site-parameter + (let-alist sx-question-mode--data .site_par))) face mode-line-buffer-id) " " mode-name " [" @@ -216,10 +217,14 @@ property." "Major mode to display and navigate a question and its answers. Letters do not insert themselves; instead, they are commands. +Don't activate this mode directly. Instead, to print a question +on the current buffer use +`sx-question-mode--erase-and-print-question'. + \\ \\{sx-question-mode}" (setq header-line-format sx-question-mode--header-line) - (setq header-line-format sx-question-mode--mode-line) + (setq mode-line-format sx-question-mode--mode-line) ;; Determine how to close this window. (unless (window-parameter nil 'quit-restore) (set-window-parameter diff --git a/sx.el b/sx.el index 73d874f..fc0af92 100644 --- a/sx.el +++ b/sx.el @@ -187,6 +187,12 @@ If ALIST doesn't have a `site' property, one is created using the ,(macroexpand `(let-alist ,alist ,@body)))) +(defun sx--pretty-site-parameter (site) + "Returned a pretty and capitalized version of string SITE." + (mapconcat #'capitalize + (split-string site "\\.") + " ")) + ;;; Utility Functions (defun sx-completing-read (&rest args) -- cgit v1.2.3 From 83538b215f75256b86987b999504a2d87d0db307 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 21 Feb 2015 16:23:37 -0200 Subject: Make question-mode--data buffer local --- sx-question-mode.el | 1 + 1 file changed, 1 insertion(+) diff --git a/sx-question-mode.el b/sx-question-mode.el index d4b7f8d..6d62e80 100644 --- a/sx-question-mode.el +++ b/sx-question-mode.el @@ -48,6 +48,7 @@ Common values for this variable are `pop-to-buffer' and `switch-to-buffer'." (defvar sx-question-mode--data nil "The data of the question being displayed.") +(make-variable-buffer-local 'sx-question-mode--data) (defun sx-question-mode--get-window () "Return a window displaying a question, or nil." -- cgit v1.2.3 From 24090d48422233b31f9eef041814e99c47c2534d Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 26 Feb 2015 11:28:48 -0300 Subject: Manually string-trim for older emacsen. Fix #267 --- sx-compose.el | 6 ++---- sx.el | 5 +++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sx-compose.el b/sx-compose.el index eb5e2eb..ae13fb6 100644 --- a/sx-compose.el +++ b/sx-compose.el @@ -193,8 +193,7 @@ tags. Return a list of already inserted tags." 'noerror) (error "No Tags header found")) (save-match-data - (split-string (match-string 1) (rx (any space ",;")) - 'omit-nulls (rx space)))) + (sx--split-string (match-string 1) (rx (any space ",;"))))) (defun sx-compose--check-tags () "Check if tags in current compose buffer are valid." @@ -313,8 +312,7 @@ 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)) + (push (cons 'tags (sx--split-string (match-string 1) "[[:space:],;]")) keywords) ;; And erase the header so it doesn't get sent. (delete-region diff --git a/sx.el b/sx.el index 33b36b6..ee7f0a6 100644 --- a/sx.el +++ b/sx.el @@ -189,6 +189,11 @@ If ALIST doesn't have a `site' property, one is created using the ;;; Utility Functions +(defun sx--split-string (string &optional separators) + "Split STRING into substrings bounded by matches for SEPARATORS." + (mapcar (lambda (s) (replace-regexp-in-string "\\` +\\| +\\'" "" s)) + (split-string string separators 'omit-nulls))) + (defun sx-completing-read (&rest args) "Like `completing-read', but possibly use ido. All ARGS are passed to `completing-read' or `ido-completing-read'." -- cgit v1.2.3