summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2013-02-24 13:49:29 +0100
committerNicolas Goaziou <n.goaziou@gmail.com>2013-02-24 13:51:49 +0100
commita965c062133dea33dfddb5e3eabf373e2084b466 (patch)
tree9050d359cbdfe08159cd7bbe97e7168cf0ac42b4
parent398e8af56ed4abb0c4c6824fdcff7617097d5830 (diff)
downloadorg-mode-a965c062133dea33dfddb5e3eabf373e2084b466.tar.gz
ox: Use tabulated list mode for asynchronous stack
* lisp/ox.el (org-export-stack): Rewrite. (org-export-stack-refresh): Refactor. (org-export-stack-remove, org-export-stack-view): Apply renaming. (org-export-stack-mode-map): Use tabulated list map as a basis. (org-export-stack--generate, org-export-stack--num-predicate): New function.
-rw-r--r--lisp/ox.el142
1 files changed, 73 insertions, 69 deletions
diff --git a/lisp/ox.el b/lisp/ox.el
index 9961063..aa8bfa8 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -77,6 +77,7 @@
;;; Code:
(eval-when-compile (require 'cl))
+(require 'tabulated-list)
(require 'org-element)
(require 'org-macro)
(require 'ob-exp)
@@ -5142,74 +5143,27 @@ removed beforehand. Return the new stack."
"Menu for asynchronous export results and running processes."
(interactive)
(let ((buffer (get-buffer-create "*Org Export Stack*")))
- (set-buffer buffer)
- (when (zerop (buffer-size)) (org-export-stack-mode))
- (org-export-stack-refresh)
+ (with-current-buffer buffer
+ (org-export-stack-mode)
+ (tabulated-list-print t))
(pop-to-buffer buffer))
(message "Type \"q\" to quit, \"?\" for help"))
-(defun org-export--stack-source-at-point ()
- "Return source from export results at point in stack."
- (let ((source (car (nth (1- (org-current-line)) org-export-stack-contents))))
- (if (not source) (error "Source unavailable, please refresh buffer")
- (let ((source-name (if (stringp source) source (buffer-name source))))
- (if (save-excursion
- (beginning-of-line)
- (looking-at (concat ".* +" (regexp-quote source-name) "$")))
- source
- ;; SOURCE is not consistent with current line. The stack
- ;; view is outdated.
- (error "Source unavailable; type `g' to update buffer"))))))
-
(defun org-export-stack-clear ()
"Remove all entries from export stack."
(interactive)
(setq org-export-stack-contents nil))
-(defun org-export-stack-refresh (&rest dummy)
- "Refresh the asynchronous export stack.
-DUMMY is ignored. Unavailable sources are removed from the list.
-Return the new stack."
- (let ((inhibit-read-only t))
- (org-preserve-lc
- (erase-buffer)
- (insert (concat
- (let ((counter 0))
- (mapconcat
- (lambda (entry)
- (let ((proc-p (processp (nth 2 entry))))
- (concat
- ;; Back-end.
- (format " %-12s " (or (nth 1 entry) ""))
- ;; Age.
- (let ((data (nth 2 entry)))
- (if proc-p (format " %6s " (process-status data))
- ;; Compute age of the results.
- (org-format-seconds
- "%4h:%.2m "
- (float-time (time-since data)))))
- ;; Source.
- (format " %s"
- (let ((source (car entry)))
- (if (stringp source) source
- (buffer-name source)))))))
- ;; Clear stack from exited processes, dead buffers or
- ;; non-existent files.
- (setq org-export-stack-contents
- (org-remove-if-not
- (lambda (el)
- (if (processp (nth 2 el))
- (buffer-live-p (process-buffer (nth 2 el)))
- (let ((source (car el)))
- (if (bufferp source) (buffer-live-p source)
- (file-exists-p source)))))
- org-export-stack-contents)) "\n")))))))
+(defun org-export-stack-refresh ()
+ "Refresh the asynchronous export stack."
+ (interactive)
+ (tabulated-list-print t))
(defun org-export-stack-remove (&optional source)
"Remove export results at point from stack.
If optional argument SOURCE is non-nil, remove it instead."
(interactive)
- (let ((source (or source (org-export--stack-source-at-point))))
+ (let ((source (or source (org-export-stack--source-at-point))))
(setq org-export-stack-contents
(org-remove-if (lambda (el) (equal (car el) source))
org-export-stack-contents))))
@@ -5219,7 +5173,7 @@ If optional argument SOURCE is non-nil, remove it instead."
With an optional prefix argument IN-EMACS, force viewing files
within Emacs."
(interactive "P")
- (let ((source (org-export--stack-source-at-point)))
+ (let ((source (org-export-stack--source-at-point)))
(cond ((processp source)
(org-switch-to-buffer-other-window (process-buffer source)))
((bufferp source) (org-switch-to-buffer-other-window source))
@@ -5227,11 +5181,10 @@ within Emacs."
(defconst org-export-stack-mode-map
(let ((km (make-sparse-keymap)))
+ (set-keymap-parent km tabulated-list-mode-map)
(define-key km " " 'next-line)
- (define-key km "n" 'next-line)
(define-key km "\C-n" 'next-line)
(define-key km [down] 'next-line)
- (define-key km "p" 'previous-line)
(define-key km "\C-p" 'previous-line)
(define-key km "\C-?" 'previous-line)
(define-key km [up] 'previous-line)
@@ -5239,10 +5192,11 @@ within Emacs."
(define-key km "v" 'org-export-stack-view)
(define-key km (kbd "RET") 'org-export-stack-view)
(define-key km "d" 'org-export-stack-remove)
+ (define-key km "r" 'org-export-stack-refresh)
km)
"Keymap for Org Export Stack.")
-(define-derived-mode org-export-stack-mode special-mode "Org-Stack"
+(define-derived-mode org-export-stack-mode tabulated-list-mode "Org-Stack"
"Mode for displaying asynchronous export stack.
Type \\[org-export-stack] to visualize the asynchronous export
@@ -5256,17 +5210,67 @@ Removing entries in an Org Export Stack buffer doesn't affect
files or buffers, only the display.
\\{org-export-stack-mode-map}"
- (abbrev-mode 0)
- (auto-fill-mode 0)
- (setq buffer-read-only t
- buffer-undo-list t
- truncate-lines t
- header-line-format
- '(:eval
- (format " %-12s | %6s | %s" "Back-End" "Age" "Source")))
+ (setq tabulated-list-format
+ (vector (list "#" 4 'org-export-stack--num-predicate)
+ (list "Back-End" 12 t)
+ (list "Age" 6 nil)
+ (list "Source" 0 nil)))
+ (setq tabulated-list-sort-key (cons "#" nil))
+ (setq tabulated-list-entries 'org-export-stack--generate)
+ (add-hook 'tabulated-list-revert-hook 'org-export-stack--generate nil t)
(add-hook 'post-command-hook 'org-export-stack-refresh nil t)
- (set (make-local-variable 'revert-buffer-function)
- 'org-export-stack-refresh))
+ (tabulated-list-init-header))
+
+(defun org-export-stack--generate ()
+ "Generate the asynchronous export stack for display.
+Unavailable sources are removed from the list. Return a list
+appropriate for `tabulated-list-print'."
+ ;; Clear stack from exited processes, dead buffers or non-existent
+ ;; files.
+ (setq org-export-stack-contents
+ (org-remove-if-not
+ (lambda (el)
+ (if (processp (nth 2 el))
+ (buffer-live-p (process-buffer (nth 2 el)))
+ (let ((source (car el)))
+ (if (bufferp source) (buffer-live-p source)
+ (file-exists-p source)))))
+ org-export-stack-contents))
+ ;; Update `tabulated-list-entries'.
+ (let ((counter 0))
+ (mapcar (lambda (entry)
+ (let ((source (car entry)))
+ (list source
+ (vector
+ ;; Counter.
+ (number-to-string (incf counter))
+ ;; Back-End.
+ (if (nth 1 entry) (symbol-name (nth 1 entry)) "")
+ ;; Age.
+ (let ((info (nth 2 entry)))
+ (if (processp info) (symbol-name (process-status info))
+ (org-format-seconds "%h:%.2m"
+ (float-time (time-since info)))))
+ ;; Source.
+ (if (stringp source) source (buffer-name source))))))
+ org-export-stack-contents)))
+
+(defun org-export-stack--num-predicate (A B)
+ (< (string-to-number (aref (nth 1 A) 0))
+ (string-to-number (aref (nth 1 B) 0))))
+
+(defun org-export-stack--source-at-point ()
+ "Return source from export results at point in stack."
+ (let ((source (car (nth (1- (org-current-line)) org-export-stack-contents))))
+ (if (not source) (error "Source unavailable, please refresh buffer")
+ (let ((source-name (if (stringp source) source (buffer-name source))))
+ (if (save-excursion
+ (beginning-of-line)
+ (looking-at (concat ".* +" (regexp-quote source-name) "$")))
+ source
+ ;; SOURCE is not consistent with current line. The stack
+ ;; view is outdated.
+ (error "Source unavailable; type `r' to refresh buffer"))))))