diff options
Diffstat (limited to 'sx-question-list.el')
-rw-r--r-- | sx-question-list.el | 109 |
1 files changed, 85 insertions, 24 deletions
diff --git a/sx-question-list.el b/sx-question-list.el index bed432f..b9f34a0 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -1,4 +1,4 @@ -;;; sx-question-list.el --- major-mode for navigating questions list -*- lexical-binding: t -*- +;;; sx-question-list.el --- major-mode for navigating questions list -*- lexical-binding: t; -*- ;; Copyright (C) 2014 Artur Malabarba @@ -106,6 +106,21 @@ "" :group 'sx-question-list-faces) +(defface sx-question-list-bounty + '((t :inherit font-lock-warning-face)) + "" + :group 'sx-question-list-faces) + +(defface sx-question-list-reputation + '((t :inherit sx-question-list-date)) + "" + :group 'sx-question-list-faces) + +(defface sx-question-list-user + '((t :inherit font-lock-builtin-face)) + "" + :group 'sx-question-list-faces) + ;;; Backend variables (defvar sx-question-list--print-function #'sx-question-list--print-info @@ -129,7 +144,7 @@ elements: Also see `sx-question-list-refresh'." (sx-assoc-let question-data (let ((favorite (if (member .question_id - (assoc .site + (assoc .site_par sx-favorites--user-favorite-list)) (if (char-displayable-p ?\x2b26) "\x2b26" "*") " "))) (list @@ -143,20 +158,35 @@ Also see `sx-question-list-refresh'." 'sx-question-list-answers-accepted 'sx-question-list-answers)) (concat + ;; First line (propertize .title 'face (if (sx-question--read-p question-data) 'sx-question-list-read-question 'sx-question-list-unread-question)) (propertize " " 'display "\n ") + ;; Second line (propertize favorite 'face 'sx-question-list-favorite) - " " - (propertize (concat (sx-time-since .last_activity_date) - sx-question-list-ago-string) + (if (and (numberp .bounty_amount) (> .bounty_amount 0)) + (propertize (format "%4d" .bounty_amount) + 'face 'sx-question-list-bounty) + " ") + " " + (propertize (format "%3s%s" + (sx-time-since .last_activity_date) + sx-question-list-ago-string) 'face 'sx-question-list-date) " " - (propertize (mapconcat #'sx-question--tag-format .tags " ") + ;; @TODO: Make this width customizable. (Or maybe just make + ;; the whole thing customizable) + (propertize (format "%-40s" (mapconcat #'sx-question--tag-format .tags " ")) 'face 'sx-question-list-tags) + " " + (let-alist .owner + (format "%15s %5s" + (propertize .display_name 'face 'sx-question-list-user) + (propertize (number-to-string .reputation) + 'face 'sx-question-list-reputation))) (propertize " " 'display "\n"))))))) (defvar sx-question-list--pages-so-far 0 @@ -198,6 +228,21 @@ and thus not displayed in the list of questions. This is ignored if `sx-question-list--refresh-function' is set.") (make-variable-buffer-local 'sx-question-list--dataset) +(defvar sx-question-list--header-line + '(" " + (:propertize "n p j k" face mode-line-buffer-id) + ": Navigate" + " " + (:propertize "RET" face mode-line-buffer-id) + ": View question" + " " + (:propertize "v" face mode-line-buffer-id) + ": Visit externally" + " " + (:propertize "q" face mode-line-buffer-id) + ": Quit") + "Header-line used on the question list.") + ;;; Mode Definition (define-derived-mode sx-question-list-mode @@ -265,10 +310,10 @@ into consideration. ;; it's not terribly intuitive. (setq tabulated-list-sort-key nil) (add-hook 'tabulated-list-revert-hook - #'sx-question-list-refresh nil t) + #'sx-question-list-refresh nil t) (add-hook 'tabulated-list-revert-hook - #'sx-question-list--update-mode-line nil t) - (tabulated-list-init-header)) + #'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 "Parameter which controls date sorting." @@ -288,7 +333,11 @@ into consideration. (mapc (lambda (x) (define-key sx-question-list-mode-map (car x) (cadr x))) - '(("n" sx-question-list-next) + '( + ;; S-down and S-up would collide with `windmove'. + ([down] sx-question-list-next) + ([up] sx-question-list-previous) + ("n" sx-question-list-next) ("p" sx-question-list-previous) ("j" sx-question-list-view-next) ("k" sx-question-list-view-previous) @@ -297,14 +346,18 @@ into consideration. ("J" sx-question-list-next-far) ("K" sx-question-list-previous-far) ("g" sx-question-list-refresh) - (":" sx-question-list-switch-site) - ("t" sx-question-list-switch-tab) - ("v" sx-visit) - ("u" sx-toggle-upvote) - ("d" sx-toggle-downvote) + ("t" sx-tab-switch) + ("a" sx-ask) + ("S" sx-search) + ("s" sx-switchto-map) + ("v" sx-visit-externally) + ("u" sx-upvote) + ("d" sx-downvote) ("h" sx-question-list-hide) ("m" sx-question-list-mark-read) - ([?\r] sx-display-question))) + ("*" sx-favorite) + ([?\r] sx-display) + )) (defun sx-question-list-hide (data) "Hide question under point. @@ -312,8 +365,13 @@ Non-interactively, DATA is a question alist." (interactive (list (if (derived-mode-p 'sx-question-list-mode) (tabulated-list-get-id) - (user-error "Not in `sx-question-list-mode'")))) + (sx-user-error "Not in `sx-question-list-mode'")))) (sx-question--mark-hidden data) + ;; The current entry will not be present after the list is + ;; redisplayed. To avoid `tabulated-list-mode' getting lost (and + ;; sending us to the top) we move to the next entry before + ;; redisplaying. + (forward-line 1) (when (called-interactively-p 'any) (sx-question-list-refresh 'redisplay 'noupdate))) @@ -323,7 +381,7 @@ Non-interactively, DATA is a question alist." (interactive (list (if (derived-mode-p 'sx-question-list-mode) (tabulated-list-get-id) - (user-error "Not in `sx-question-list-mode'")))) + (sx-user-error "Not in `sx-question-list-mode'")))) (sx-question--mark-read data) (sx-question-list-next 1) (when (called-interactively-p 'any) @@ -374,6 +432,7 @@ Non-interactively, DATA is a question alist." (defvar sx-question-list--site nil "Site being displayed in the *question-list* buffer.") +(make-variable-buffer-local 'sx-question-list--site) (defun sx-question-list-refresh (&optional redisplay no-update) "Update the list of questions. @@ -399,7 +458,11 @@ a new list before redisplaying." (setq tabulated-list-entries (mapcar sx-question-list--print-function (cl-remove-if #'sx-question--hidden-p question-list))) - (when redisplay (tabulated-list-print 'remember)) + (when redisplay + (tabulated-list-print 'remember) + ;; Display weird chars correctly + (set-buffer-multibyte nil) + (set-buffer-multibyte t)) (when window (set-window-start window old-start))) (sx-message "Done.")) @@ -424,9 +487,8 @@ Displayed in `sx-question-mode--window', replacing any question that may currently be there." (interactive "p") (sx-question-list-next n) - (sx-display-question - (tabulated-list-get-id) - nil + (sx-question-mode--display + (tabulated-list-get-id) (sx-question-list--create-question-window))) (defun sx-question-list--create-question-window () @@ -532,12 +594,11 @@ This does not update `sx-question-mode--window'." (defun sx-question-list-switch-site (site) "Switch the current site to SITE and display its questions. -Use `ido-completing-read' if variable `ido-mode' is active. Retrieve completions from `sx-site-get-api-tokens'. Sets `sx-question-list--site' and then call `sx-question-list-refresh' with `redisplay'." (interactive - (list (funcall (if ido-mode #'ido-completing-read #'completing-read) + (list (sx-completing-read "Switch to site: " (sx-site-get-api-tokens) (lambda (site) (not (equal site sx-question-list--site))) t))) |