diff --git a/tex-buf.el b/tex-buf.el index e006ea6..ed67f91 100644 --- a/tex-buf.el +++ b/tex-buf.el @@ -353,6 +353,13 @@ asked if it is positive, and suppressed if it is not." (read-from-minibuffer (concat name " command: ") command nil nil))) + ;; Kill the frame and buffer associated to the error overview before running + ;; the command. + (if (frame-live-p TeX-error-overview-frame) + (delete-frame TeX-error-overview-frame)) + (if (get-buffer TeX-error-overview-buffer-name) + (kill-buffer TeX-error-overview-buffer-name)) + ;; Now start the process (setq file (funcall file)) (TeX-process-set-variable file 'TeX-command-next TeX-command-Show) @@ -924,12 +931,18 @@ NAME is the name of the process.") "Cleanup TeX output buffer after running TeX. Parse the output buffer to collect errors and warnings if the -variable `TeX-parse-all-errors' is non-nil." +variable `TeX-parse-all-errors' is non-nil. + +Open the error overview if +`TeX-error-overview-open-after-TeX-run' is non-nil and there are +errors or warnings to show." (if (TeX-TeX-sentinel-check process name) () (message (concat name ": formatted " (TeX-current-pages))) (if TeX-parse-all-errors (TeX-parse-all-errors)) + (if (and TeX-error-overview-open-after-TeX-run TeX-error-list) + (TeX-error-overview)) (setq TeX-command-next TeX-command-Show))) (defun TeX-current-pages () @@ -993,9 +1006,15 @@ Warnings can be indicated by LaTeX or packages." "Cleanup TeX output buffer after running LaTeX. Parse the output buffer to collect errors and warnings if the -variable `TeX-parse-all-errors' is non-nil." +variable `TeX-parse-all-errors' is non-nil. + +Open the error overview if +`TeX-error-overview-open-after-TeX-run' is non-nil and there are +errors or warnings to show." (if TeX-parse-all-errors (TeX-parse-all-errors)) + (if (and TeX-error-overview-open-after-TeX-run TeX-error-list) + (TeX-error-overview)) (cond ((TeX-TeX-sentinel-check process name)) ((and (save-excursion (re-search-forward @@ -1900,7 +1919,7 @@ warning." (defgroup TeX-error-description-faces nil "Faces used in error descriptions." :prefix "TeX-error-description-" - :group 'AUCTeX) + :group 'TeX-output) (defface TeX-error-description-error ;; This is the same as `error' face in latest GNU Emacs versions. @@ -2422,6 +2441,211 @@ error." (regexp :tag "Match") (string :format "Description:\n%v")))) +;;; Error Overview + +(defvar TeX-error-overview-active-buffer nil + "The active buffer for the current error overview.") + +(defvar TeX-error-overview-orig-frame nil + "Frame from which the error overview has been launched.") + +(defun TeX-error-overview-goto-source (&optional button) + "Go to the error point in the source. +If optional argument BUTTON is non-nil, go to source associated +to the selected error." + (interactive) + (let ((index (if button (button-get button 'id) (tabulated-list-get-id))) + (error-frame (selected-frame)) + item) + (if index + (progn + ;; Switch to source frame. + (select-frame TeX-error-overview-orig-frame) + ;; Get the error details. + (with-current-buffer TeX-error-overview-active-buffer + (setq item (nth index TeX-error-list) + TeX-error-last-visited index)) + (with-current-buffer TeX-command-buffer + ;; For consistency with `TeX-parse-TeX', use the same major mode as + ;; that of `TeX-command-buffer'. + (let ((default-major-mode major-mode)) + ;; Find the error and display the help. + (TeX-error-list-find-display-help item))) + ;; Return to the error overview frame. + (select-frame error-frame)) + (message "No more errors.")))) + +(defun TeX-error-overview-make-entries () + "Generate the list of errors to be printed using `tabulated-list-entries'." + (with-current-buffer (TeX-active-buffer) + (let ((error-list TeX-error-list) + (id 0) + entry line type entries) + (while error-list + (setq entry (pop error-list) + type (nth 0 entry) + line (nth 2 entry)) + (add-to-list + 'entries + (list + ;; ID + id + (vector + ;; File + (nth 1 entry) + ;; Line + (if (numberp line) + (number-to-string line) + "") + ;; Type + (cond + ((equal type 'error) + (propertize "Error" 'font-lock-face 'TeX-error-description-error)) + ((equal type 'warning) + (propertize "Warning" 'font-lock-face + 'TeX-error-description-warning)) + ((equal type 'bad-box) + (propertize "Bad box" 'font-lock-face + 'TeX-error-description-warning)) + (t + "")) + ;; Message + (list (nth 3 entry) + 'face 'link + 'follow-link t + 'id id + 'action 'TeX-error-overview-goto-source) + )) t) + (setq id (1+ id))) + entries))) + +(defun TeX-error-overview-next-error (&optional arg) + "Move to the next line and find the associated error. + +A prefix ARG specifies how many error messages to move; negative +means move back to previous error messages." + (interactive "p") + (if (= (forward-line arg) 0) + (TeX-error-overview-goto-source) + ;; If there are lines left to move we are at the beginning or at the end of + ;; the buffer and there are no more errors. + (message "No more errors."))) + +(defun TeX-error-overview-previous-error (&optional arg) + "Move to the previous line and find the associated error. + +Prefix arg N says how many error messages to move backward (or +forward, if negative)." + (interactive "p") + (TeX-error-overview-next-error (- arg))) + +(defvar TeX-error-overview-frame nil + "The frame of the error overview.") + +(defun TeX-error-overview-quit () + "Delete the error overview frame." + (interactive) + (delete-frame TeX-error-overview-frame) + (setq TeX-error-overview-orig-frame nil)) + +(defvar TeX-error-overview-mode-map + (let ((map (make-sparse-keymap)) + (menu-map (make-sparse-keymap))) + (define-key map "n" 'TeX-error-overview-next-error) + (define-key map "p" 'TeX-error-overview-previous-error) + (define-key map "q" 'TeX-error-overview-quit) + (define-key map "\C-m" 'TeX-error-overview-goto-source) + map) + "Local keymap for `TeX-error-overview-mode' buffers.") + +(defvar TeX-error-overview-list-entries nil + "List of errors to be used in the error overview.") + +(define-derived-mode TeX-error-overview-mode tabulated-list-mode + "TeX errors" + "Major mode for listing TeX errors." + (setq tabulated-list-format [("File" 25 nil) + ("Line" 4 nil :right-align t) + ("Type" 7 nil) + ("Message" 0 nil)] + tabulated-list-padding 1 + tabulated-list-entries TeX-error-overview-list-entries) + (tabulated-list-init-header) + (tabulated-list-print)) + +(defconst TeX-error-overview-buffer-name "*TeX errors*" + "Name of the buffer in which to show error list.") + +(defcustom TeX-error-overview-frame-parameters + '((name . "TeX errors") + (title . "TeX errors") + (height . 10) + (width . 80) + (top . (- 0)) + (left . (- 0)) + (unsplittable . t) + (minibuffer . nil) + (vertical-scroll-bars . t) + (tool-bar-lines . 0)) + "Parameters of the error overview frame." + :group 'TeX-output + :type 'alist + :options '((name string) (title string) (height integer) (width integer) + (top integer) (left integer) (unsplittable boolean) + (minibuffer boolean) (vertical-scroll-bars boolean) + (tool-bar-lines integer))) + +(defcustom TeX-error-overview-open-after-TeX-run nil + "Whether to open automatically the error overview after running TeX." + :group 'TeX-output + :type 'boolean) + +(defun TeX-error-overview () + "Show an overview of the errors occurred in the last TeX run." + (interactive) + ;; Check requirements before start. + (if (functionp 'tabulated-list-mode) + (if (display-multi-frame-p) + (let ((active-buffer (TeX-active-buffer))) + (if active-buffer + (if (with-current-buffer active-buffer TeX-error-list) + (progn + (setq TeX-error-overview-list-entries + (TeX-error-overview-make-entries) + TeX-error-overview-active-buffer active-buffer + TeX-error-overview-orig-frame + (window-frame (selected-window))) + ;; Create the error overview buffer. This is + ;; automatically killed before running TeX commands, so if + ;; exists it is up-to-date and doesn't need to be + ;; re-created. + (unless (get-buffer TeX-error-overview-buffer-name) + (with-current-buffer (get-buffer-create + TeX-error-overview-buffer-name) + (TeX-error-overview-mode))) + (save-window-excursion + ;; Move point to the line associated to the last visited + ;; error. + (with-current-buffer TeX-error-overview-buffer-name + (goto-char (point-min)) + (forward-line (with-current-buffer active-buffer + TeX-error-last-visited)) + ;; Create a new frame. + (if (frame-live-p TeX-error-overview-frame) + ;; Do not create a duplicate frame if there is + ;; already one, just rise it. + (raise-frame TeX-error-overview-frame) + (setq TeX-error-overview-frame + (make-frame + TeX-error-overview-frame-parameters)) + (set-window-buffer (selected-window) + TeX-error-overview-buffer-name) + (set-window-dedicated-p (selected-window) t))))) + (message "No errror or warning to show.")) + (message "No process for this document."))) + (error "Error overview requires multi frame support.")) + (error "Error overview is available only in Emacs 24 or later."))) + ;;; Output mode (if (fboundp 'special-mode)