From bd1937c21db3f62c4f04e72a1322fcd711f724a4 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 08:53:24 +0000 Subject: Switch to live-data in the question list. --- stack-question-list.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stack-question-list.el b/stack-question-list.el index f565490..7053339 100644 --- a/stack-question-list.el +++ b/stack-question-list.el @@ -25,7 +25,6 @@ (require 'stack-question) (require 'tabulated-list) (require 'cl-lib) -(load "test/tests.el") ;;; Customization @@ -144,7 +143,7 @@ Letters do not insert themselves; instead, they are commands. If REDISPLAY is non-nil, also call `tabulated-list-print'." (interactive '(t)) ;; Obviously this needs to be changed. - (let ((question-list (stack-test-sample-data "questions" "test"))) + (let ((question-list (stack-core-make-request "questions"))) ;; Print the result. (setq tabulated-list-entries (mapcar #'stack-question-list--print-info question-list))) -- cgit v1.2.3 From 556fde7052a4e6a9f0546c1a1c186fe13c412086 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 08:53:45 +0000 Subject: Variable fine-tuning --- stack-question-list.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stack-question-list.el b/stack-question-list.el index 7053339..760d3a1 100644 --- a/stack-question-list.el +++ b/stack-question-list.el @@ -28,7 +28,7 @@ ;;; Customization -(defcustom stack-question-list-height 15 +(defcustom stack-question-list-height 12 "Height, in lines, of stack-mode's *question-list* buffer." :type 'integer :group 'stack-question-list) @@ -117,7 +117,6 @@ Letters do not insert themselves; instead, they are commands. ;; Add a setter to protect the value. :group 'stack-question-list) - (defun stack-question-list--date-more-recent-p (x y) "Non-nil if tabulated-entry X is newer than Y." (stack-question--< -- cgit v1.2.3 From 35dc5c5a572a1fbf8e21195f98b3089f22c68775 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 08:59:27 +0000 Subject: Add mode-line information to the question list --- stack-question-list.el | 58 ++++++++++++++++++++++++++++++++++++++++++++------ stack-question.el | 4 ++++ 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/stack-question-list.el b/stack-question-list.el index 760d3a1..e19005b 100644 --- a/stack-question-list.el +++ b/stack-question-list.el @@ -133,15 +133,53 @@ Letters do not insert themselves; instead, they are commands. ("g" stack-question-list-refresh) ([?\r] stack-question-list-display-question))) +(defvar stack-question-list--current-page "Latest" + ;; Other values (once we implement them) are "Top Voted", + ;; "Unanswered", etc. + "Variable describing current page being viewed.") + +(defvar stack-question-list--unread-count 0 + "Holds the number of unread questions in the current buffer.") +(make-variable-buffer-local 'stack-question-list--unread-count) + +(defvar stack-question-list--total-count 0 + "Holds the total number of questions in the current buffer.") +(make-variable-buffer-local 'stack-question-list--total-count) + +(defconst stack-question-list--mode-line-format + '(" " + mode-name + " " + (:propertize stack-question-list--current-page + face mode-line-buffer-id) + " [" + "Unread: " + (:propertize + (:eval (int-to-string stack-question-list--unread-count)) + face mode-line-buffer-id) + ", " + "Total: " + (:propertize + (:eval (int-to-string stack-question-list--total-count)) + face mode-line-buffer-id) + "] ") + "Mode-line construct to use in question-list buffers.") + (defun stack-question-list--update-mode-line () "Fill the mode-line with useful information." - nil) + ;; All the data we need is right in the buffer. + (when (derived-mode-p 'stack-question-list-mode) + (setq mode-line-format + stack-question-list--mode-line-format) + (setq stack-question-list--total-count + (length tabulated-list-entries)))) (defun stack-question-list-refresh (&optional redisplay) "Update the list of questions. If REDISPLAY is non-nil, also call `tabulated-list-print'." (interactive '(t)) - ;; Obviously this needs to be changed. + ;; Reset the mode-line unread count (we rebuild it here). + (setq stack-question-list--unread-count 0) (let ((question-list (stack-core-make-request "questions"))) ;; Print the result. (setq tabulated-list-entries @@ -170,11 +208,14 @@ Used in the questions list to indicate a question was updated \"4d ago\"." 'stack-question-list-answers-accepted 'stack-question-list-answers)) (concat - (propertize (ca 'title) - 'face - (if (stack-question--read-p data) - 'stack-question-list-read-question - 'stack-question-list-unread-question)) + (propertize + (ca 'title) + 'face + (if (stack-question--read-p data) + 'stack-question-list-read-question + ;; Increment `stack-question-list--unread-count' for the mode-line. + (cl-incf stack-question-list--unread-count) + 'stack-question-list-unread-question)) (propertize " " 'display "\n ") (propertize (concat (stack--time-since (ca 'last_activity_date)) stack-question-list-ago-string) @@ -213,6 +254,9 @@ focus the relevant window." (interactive '(nil t)) (unless data (setq data (tabulated-list-get-id))) (unless data (error "No question here!")) + (when (stack-question--read-p data) + (cl-decf stack-question-list--unread-count) + (stack-question--mark-read data)) (unless (window-live-p stack-question--window) (setq stack-question--window (split-window-below stack-question-list-height))) diff --git a/stack-question.el b/stack-question.el index 9858391..9fd5fcc 100644 --- a/stack-question.el +++ b/stack-question.el @@ -58,6 +58,10 @@ ;; @TODO: (cl-evenp (random))) +(defun stack-question--mark-read (question) + "Mark QUESTION as being read, until it is updated again." + nil) + (defun stack-question--< (property x y &optional pred) "Non-nil if PROPERTY attribute of question X is less than that of Y. With optional argument predicate, use it instead of `<'." -- cgit v1.2.3 From 18c5a08dfb377d13afe463f5892ee2aa575b9e66 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 09:00:10 +0000 Subject: Add tests for the question-list --- test/tests.el | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/test/tests.el b/test/tests.el index efad2d0..9bf63fd 100644 --- a/test/tests.el +++ b/test/tests.el @@ -6,7 +6,10 @@ (unintern symbol))))) ;;; Tests -(defvar stack-test-data-dir "data-samples/" +(defvar stack-test-data-dir + (expand-file-name + "data-samples/" + (or load-file-name "./")) "") (defun stack-test-sample-data (method &optional directory) @@ -31,10 +34,11 @@ (require 'stack-core) (require 'stack-question) +(require 'stack-question-list) (ert-deftest test-basic-request () - "Test basic request functionality" - (should (stack-core-make-request "sites"))) + "Test basic request functionality" + (should (stack-core-make-request "sites"))) (ert-deftest test-question-retrieve () "Test the ability to receive a list of questions." @@ -53,7 +57,7 @@ '((1 . t) (2 . [1 2]) (3)) (stack-core-filter-data '((0 . 3) (1 . t) (a . five) (2 . [1 2]) ("5" . bop) (3) (p . 4)) - '(1 2 3)))) + '(1 2 3)))) ;; complex (should (equal @@ -97,3 +101,16 @@ (delete-file (stack-cache-get-file-name stack-filter-cache-file)))) + +(ert-deftest question-list-display () + (cl-letf (((symbol-function 'stack-core-make-request) + (lambda (&rest _) stack-test-data-questions))) + (call-interactively 'list-questions)) + (goto-char (point-min)) + (should (looking-at " 1 0 Focus-hook: attenuate colours when losing focus [0-9]+d ago \\[frames\\] \\[hooks\\] \\[focus\\]")) + (stack-question-list-next 5) + (should (looking-at " 0 1 Babel doesn't wrap results in verbatim [0-9]+d ago \\[org-mode\\]")) + (call-interactively 'stack-question-list-display-question) + (should (equal (buffer-name) "*stack-question*")) + (stack-question-list-previous 4) + (should (looking-at " 2 1 "Making tag completion table" Freezes/Blocks -- how to disable [0-9]+d ago \\[autocomplete\\]"))) -- cgit v1.2.3 From d09556032b645d05bcb2a0164c8bb0e6f8ebf25f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 11:40:59 +0000 Subject: Fix question list tests --- test/tests.el | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/test/tests.el b/test/tests.el index 9bf63fd..b8001ae 100644 --- a/test/tests.el +++ b/test/tests.el @@ -107,10 +107,18 @@ (lambda (&rest _) stack-test-data-questions))) (call-interactively 'list-questions)) (goto-char (point-min)) - (should (looking-at " 1 0 Focus-hook: attenuate colours when losing focus [0-9]+d ago \\[frames\\] \\[hooks\\] \\[focus\\]")) + (should (equal (buffer-name) "*question-list*")) + (should (string-match + "^ 1 0 Focus-hook: attenuate colours when losing focus [ 0-9]+[ydhms] ago \\[frames\\] \\[hooks\\] \\[focus\\]" + (thing-at-point 'line))) (stack-question-list-next 5) - (should (looking-at " 0 1 Babel doesn't wrap results in verbatim [0-9]+d ago \\[org-mode\\]")) + (should (string-match + "^ 0 1 Babel doesn't wrap results in verbatim [ 0-9]+[ydhms] ago \\[org-mode\\]" + (thing-at-point 'line))) (call-interactively 'stack-question-list-display-question) (should (equal (buffer-name) "*stack-question*")) + (switch-to-buffer "*question-list*") (stack-question-list-previous 4) - (should (looking-at " 2 1 "Making tag completion table" Freezes/Blocks -- how to disable [0-9]+d ago \\[autocomplete\\]"))) + (should (string-match + "^ 2 1 "Making tag completion table" Freezes/Blocks -- how to disable [ 0-9]+[ydhms] ago \\[autocomplete\\]" + (thing-at-point 'line)))) -- cgit v1.2.3 From 3ecb37471a46a82c56ecca738fc4f6879d37c258 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 13:37:06 +0000 Subject: Add a no-update argument to stack-question-list-refresh --- stack-question-list.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/stack-question-list.el b/stack-question-list.el index e19005b..8b52aca 100644 --- a/stack-question-list.el +++ b/stack-question-list.el @@ -174,10 +174,12 @@ Letters do not insert themselves; instead, they are commands. (setq stack-question-list--total-count (length tabulated-list-entries)))) -(defun stack-question-list-refresh (&optional redisplay) +(defun stack-question-list-refresh (&optional redisplay no-update) "Update the list of questions. -If REDISPLAY is non-nil, also call `tabulated-list-print'." - (interactive '(t)) +If REDISPLAY is non-nil, also call `tabulated-list-print'. +If the prefix argument NO-UPDATE is nil, query stack-exchange for +a new list before redisplaying." + (interactive "pP") ;; Reset the mode-line unread count (we rebuild it here). (setq stack-question-list--unread-count 0) (let ((question-list (stack-core-make-request "questions"))) @@ -275,7 +277,7 @@ focus the relevant window." (generate-new-buffer "*question-list*"))) (with-current-buffer stack-question-list--buffer (stack-question-list-mode) - (stack-question-list-refresh 'redisplay)) + (stack-question-list-refresh 'redisplay no-update)) (switch-to-buffer stack-question-list--buffer)) (defalias 'stack-list-questions #'list-questions) -- cgit v1.2.3 From a201a9ca279701a442f7a04f7111be419e13fdaa Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 13:46:42 +0000 Subject: Handle small windows more gracefully. --- stack-question-list.el | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/stack-question-list.el b/stack-question-list.el index 8b52aca..d658b17 100644 --- a/stack-question-list.el +++ b/stack-question-list.el @@ -261,10 +261,20 @@ focus the relevant window." (stack-question--mark-read data)) (unless (window-live-p stack-question--window) (setq stack-question--window - (split-window-below stack-question-list-height))) + (condition-case er + (split-window-below stack-question-list-height) + (error + ;; If the window is too small to split, use current one. + (if (string-match + "Window # too small for splitting" + (car (cdr-safe er))) + nil + (error (cdr er))))))) (stack-question--display data stack-question--window) (when focus - (select-window stack-question--window))) + (if stack-question--window + (select-window stack-question--window) + (switch-to-buffer stack-question--buffer)))) (defvar stack-question-list--buffer nil "Buffer where the list of questions is displayed.") -- cgit v1.2.3 From 299a0ac21a7bc65383a1cd9a000c9d4cc8750d2d Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 13:47:01 +0000 Subject: Fix question list testing (for real). --- test/tests.el | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/test/tests.el b/test/tests.el index b8001ae..8a9f5e1 100644 --- a/test/tests.el +++ b/test/tests.el @@ -9,7 +9,7 @@ (defvar stack-test-data-dir (expand-file-name "data-samples/" - (or load-file-name "./")) + (or (file-name-directory load-file-name) "./")) "") (defun stack-test-sample-data (method &optional directory) @@ -35,6 +35,7 @@ (require 'stack-core) (require 'stack-question) (require 'stack-question-list) +(require 'cl-lib) (ert-deftest test-basic-request () "Test basic request functionality" @@ -102,23 +103,29 @@ (stack-cache-get-file-name stack-filter-cache-file)))) +(defmacro line-should-match (regexp) + "" + `(let ((line (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))) + (message "Line here is: %S" line) + (should (string-match ,regexp line)))) + (ert-deftest question-list-display () - (cl-letf (((symbol-function 'stack-core-make-request) + (cl-letf (((symbol-function #'stack-core-make-request) (lambda (&rest _) stack-test-data-questions))) - (call-interactively 'list-questions)) - (goto-char (point-min)) - (should (equal (buffer-name) "*question-list*")) - (should (string-match - "^ 1 0 Focus-hook: attenuate colours when losing focus [ 0-9]+[ydhms] ago \\[frames\\] \\[hooks\\] \\[focus\\]" - (thing-at-point 'line))) - (stack-question-list-next 5) - (should (string-match - "^ 0 1 Babel doesn't wrap results in verbatim [ 0-9]+[ydhms] ago \\[org-mode\\]" - (thing-at-point 'line))) - (call-interactively 'stack-question-list-display-question) - (should (equal (buffer-name) "*stack-question*")) - (switch-to-buffer "*question-list*") - (stack-question-list-previous 4) - (should (string-match - "^ 2 1 "Making tag completion table" Freezes/Blocks -- how to disable [ 0-9]+[ydhms] ago \\[autocomplete\\]" - (thing-at-point 'line)))) + (list-questions nil) + (switch-to-buffer "*question-list*") + (goto-char (point-min)) + (should (equal (buffer-name) "*question-list*")) + (line-should-match + "^ 1 0 Focus-hook: attenuate colours when losing focus [ 0-9]+[ydhms] ago \\[frames\\] \\[hooks\\] \\[focus\\]") + (stack-question-list-next 5) + (line-should-match + "^ 0 1 Babel doesn't wrap results in verbatim [ 0-9]+[ydhms] ago \\[org-mode\\]") + (call-interactively 'stack-question-list-display-question) + (should (equal (buffer-name) "*stack-question*")) + (switch-to-buffer "*question-list*") + (stack-question-list-previous 4) + (line-should-match + "^ 2 1 "Making tag completion table" Freezes/Blocks -- how to disable [ 0-9]+[ydhms] ago \\[autocomplete\\]"))) -- cgit v1.2.3 From 9ba2bece6b1fcfca5c55fca431775d3e25e1ce2f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 13:54:26 +0000 Subject: package-initialize on tests --- test/tests.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/tests.el b/test/tests.el index 8a9f5e1..c632adf 100644 --- a/test/tests.el +++ b/test/tests.el @@ -32,10 +32,14 @@ stack-test-data-sites (stack-test-sample-data "sites")) +(setq package-user-dir + (expand-file-name (format "../../.cask/%s/elpa" emacs-version) + stack-test-data-dir)) +(package-initialize) +(require 'cl-lib) (require 'stack-core) (require 'stack-question) (require 'stack-question-list) -(require 'cl-lib) (ert-deftest test-basic-request () "Test basic request functionality" -- cgit v1.2.3 From 2d076d9874800e0ab28ef1dd3d3d72e0a95a9f3d Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 14:34:20 +0000 Subject: Remove cl-flet (not defined for < 24.3) --- stack-question-list.el | 57 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/stack-question-list.el b/stack-question-list.el index d658b17..c3f78bb 100644 --- a/stack-question-list.el +++ b/stack-question-list.el @@ -196,35 +196,34 @@ Used in the questions list to indicate a question was updated \"4d ago\"." (defun stack-question-list--print-info (data) "Convert `json-read' DATA into tabulated-list format." - (cl-flet ((ca (x) (cdr (assoc x data)))) - (list - data - (vector - (list (int-to-string (ca 'score)) - 'face - (if (ca 'upvoted) 'stack-question-list-score-upvoted - 'stack-question-list-score)) - (list (int-to-string (ca 'answer_count)) - 'face - (if (stack-question--accepted-answer data) - 'stack-question-list-answers-accepted - 'stack-question-list-answers)) - (concat - (propertize - (ca 'title) - 'face - (if (stack-question--read-p data) - 'stack-question-list-read-question - ;; Increment `stack-question-list--unread-count' for the mode-line. - (cl-incf stack-question-list--unread-count) - 'stack-question-list-unread-question)) - (propertize " " 'display "\n ") - (propertize (concat (stack--time-since (ca 'last_activity_date)) - stack-question-list-ago-string) - 'face 'stack-question-list-date) - (propertize (concat " [" (mapconcat #'identity (ca 'tags) "] [") "]") - 'face 'stack-question-list-tags) - (propertize " " 'display "\n")))))) + (list + data + (vector + (list (int-to-string (cdr (assoc 'score data))) + 'face + (if (cdr (assoc 'upvoted data)) 'stack-question-list-score-upvoted + 'stack-question-list-score)) + (list (int-to-string (cdr (assoc 'answer_count data))) + 'face + (if (stack-question--accepted-answer data) + 'stack-question-list-answers-accepted + 'stack-question-list-answers)) + (concat + (propertize + (cdr (assoc 'title data)) + 'face + (if (stack-question--read-p data) + 'stack-question-list-read-question + ;; Increment `stack-question-list--unread-count' for the mode-line. + (cl-incf stack-question-list--unread-count) + 'stack-question-list-unread-question)) + (propertize " " 'display "\n ") + (propertize (concat (stack--time-since (cdr (assoc 'last_activity_date data))) + stack-question-list-ago-string) + 'face 'stack-question-list-date) + (propertize (concat " [" (mapconcat #'identity (cdr (assoc 'tags data)) "] [") "]") + 'face 'stack-question-list-tags) + (propertize " " 'display "\n"))))) (defun stack-question-list-view-previous (n) "Hide this question, move to previous one, display it." -- cgit v1.2.3 From 6ff3660dedd1310709460ece74b6079f33e91c57 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 14:40:30 +0000 Subject: Fix test regexp --- test/tests.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/tests.el b/test/tests.el index c632adf..7f7395a 100644 --- a/test/tests.el +++ b/test/tests.el @@ -123,13 +123,13 @@ (goto-char (point-min)) (should (equal (buffer-name) "*question-list*")) (line-should-match - "^ 1 0 Focus-hook: attenuate colours when losing focus [ 0-9]+[ydhms] ago \\[frames\\] \\[hooks\\] \\[focus\\]") + "^\\s-+1\\s-+0\\s-+Focus-hook: attenuate colours when losing focus [ 0-9]+[ydhms] ago\\s-+\\[frames\\] \\[hooks\\] \\[focus\\]") (stack-question-list-next 5) (line-should-match - "^ 0 1 Babel doesn't wrap results in verbatim [ 0-9]+[ydhms] ago \\[org-mode\\]") + "^\\s-+0\\s-+1\\s-+Babel doesn't wrap results in verbatim [ 0-9]+[ydhms] ago\\s-+\\[org-mode\\]") (call-interactively 'stack-question-list-display-question) (should (equal (buffer-name) "*stack-question*")) (switch-to-buffer "*question-list*") (stack-question-list-previous 4) (line-should-match - "^ 2 1 "Making tag completion table" Freezes/Blocks -- how to disable [ 0-9]+[ydhms] ago \\[autocomplete\\]"))) + "^\\s-+2\\s-+1\\s-+"Making tag completion table" Freezes/Blocks -- how to disable [ 0-9]+[ydhms] ago\\s-+\\[autocomplete\\]"))) -- cgit v1.2.3 From d3139e8e478e46c5b125eb8a9327beaacf439b50 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 14:44:30 +0000 Subject: Comment out "*stack-question*" buffer test --- test/tests.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/tests.el b/test/tests.el index 7f7395a..74ef158 100644 --- a/test/tests.el +++ b/test/tests.el @@ -127,8 +127,9 @@ (stack-question-list-next 5) (line-should-match "^\\s-+0\\s-+1\\s-+Babel doesn't wrap results in verbatim [ 0-9]+[ydhms] ago\\s-+\\[org-mode\\]") - (call-interactively 'stack-question-list-display-question) - (should (equal (buffer-name) "*stack-question*")) + ;; ;; Use this when we have a real stack-question buffer. + ;; (call-interactively 'stack-question-list-display-question) + ;; (should (equal (buffer-name) "*stack-question*")) (switch-to-buffer "*question-list*") (stack-question-list-previous 4) (line-should-match -- cgit v1.2.3 From fb64417863367cf33ae80f2e8d10d67f588c1c0b Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 6 Nov 2014 15:33:37 +0000 Subject: Use stack-question-get-questions --- stack-question-list.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/stack-question-list.el b/stack-question-list.el index c3f78bb..924e90e 100644 --- a/stack-question-list.el +++ b/stack-question-list.el @@ -174,6 +174,9 @@ Letters do not insert themselves; instead, they are commands. (setq stack-question-list--total-count (length tabulated-list-entries)))) +(defvar stack-question-list--current-site "emacs" + "Site being displayed in the *question-list* buffer.") + (defun stack-question-list-refresh (&optional redisplay no-update) "Update the list of questions. If REDISPLAY is non-nil, also call `tabulated-list-print'. @@ -182,7 +185,8 @@ a new list before redisplaying." (interactive "pP") ;; Reset the mode-line unread count (we rebuild it here). (setq stack-question-list--unread-count 0) - (let ((question-list (stack-core-make-request "questions"))) + (let ((question-list (stack-question-get-questions + stack-question-list--current-site))) ;; Print the result. (setq tabulated-list-entries (mapcar #'stack-question-list--print-info question-list))) -- cgit v1.2.3