# HG changeset patch # User Richard M. Stallman # Date 891231712 0 # Node ID 7d4a55d38b2c6b4604cfab9ea8efd1134c43105f # Parent 47c514f3eed44aa9bc8107c2da61c54582c89e7a (tex-send-command): Return the process. (tex-start-tex): New function. (tex-region, tex-file): Use tex-start-tex. (tex-start-tex-marker): New variable. (tex-compilation-parse-errors): Completely rewritten. (tex-print): Reset or restart the subshell before using it. diff -r 47c514f3eed4 -r 7d4a55d38b2c lisp/textmodes/tex-mode.el --- a/lisp/textmodes/tex-mode.el Mon Mar 30 03:08:51 1998 +0000 +++ b/lisp/textmodes/tex-mode.el Mon Mar 30 04:21:52 1998 +0000 @@ -953,79 +953,6 @@ (insert "\\end" text) (if new-line-needed (insert ?\n)))) -(defun tex-compilation-parse-errors () - "Parse the current buffer as error messages. -This makes a list of error descriptors, compilation-error-list. -For each source-file, line-number pair in the buffer, -the source file is read in, and the text location is saved in -compilation-error-list. The function `next-error', assigned to -\\[next-error], takes the next error off the list and visits its location. - -This function works on TeX compilations only. It is necessary for -that purpose, since TeX does not put file names on the same line as -line numbers for the errors." - (setq compilation-error-list nil) - (message "Parsing error messages...") - (modify-syntax-entry ?\{ "_") - (modify-syntax-entry ?\} "_") - (modify-syntax-entry ?\[ "_") - (modify-syntax-entry ?\] "_") - (let (text-buffer - last-filename last-linenum) - ;; Don't reparse messages already seen at last parse. - (goto-char compilation-parsing-end) - ;; Don't parse the first two lines as error messages. - ;; This matters for grep. - (if (bobp) - (forward-line 2)) - (while (re-search-forward "^l\.[0-9]+ " nil t) - (let (linenum filename - error-marker text-marker) - ;; Extract file name and line number from error message. - ;; Line number is 2 away from beginning of line: "l.23" - (beginning-of-line) - (goto-char (+ (point) 2)) - (setq linenum (read (current-buffer))) - ;; The file is the one that was opened last and is still open. - ;; We need to find the last open parenthesis. - (insert ?\)) - (backward-sexp) - (forward-char) - (setq filename (current-word)) - ;; Locate the erring file and line. - (if (and (equal filename last-filename) - (= linenum last-linenum)) - nil - (skip-chars-backward "^(") - (backward-char) - (forward-sexp) - (backward-delete-char 1) - (setq error-marker (point-marker)) - ;; text-buffer gets the buffer containing this error's file. - (if (not (equal filename last-filename)) - (setq text-buffer - (and (file-exists-p (setq last-filename filename)) - (find-file-noselect filename)) - last-linenum 0)) - (if text-buffer - ;; Go to that buffer and find the erring line. - (save-excursion - (set-buffer text-buffer) - (if (zerop last-linenum) - (progn - (goto-char 1) - (setq last-linenum 1))) - (forward-line (- linenum last-linenum)) - (setq last-linenum linenum) - (setq text-marker (point-marker)) - (setq compilation-error-list - (cons (list error-marker text-marker) - compilation-error-list))))) - (forward-line 1))) - (setq compilation-parsing-end (point-max))) - (message "Parsing error messages...done") - (setq compilation-error-list (nreverse compilation-error-list))) - ;;; Invoking TeX in an inferior shell. ;;; Why use a shell instead of running TeX directly? Because if TeX @@ -1082,7 +1009,9 @@ Do this in background if optional BACKGROUND is t. If COMMAND has no *, FILE will be appended, preceded by a blank, to COMMAND. If FILE is nil, no substitution will be made in COMMAND. COMMAND can be any expression that -evaluates to a command string." +evaluates to a command string. + +Return the process in which TeX is running." (save-excursion (let* ((cmd (eval command)) (proc (or (get-process "tex-shell") (error "No TeX subprocess"))) @@ -1105,7 +1034,8 @@ (goto-char (process-mark proc)) (insert string) (comint-send-input) - (setq tex-send-command-modified-tick (buffer-modified-tick buf))))) + (setq tex-send-command-modified-tick (buffer-modified-tick buf)) + proc))) (defun tex-delete-last-temp-files (&optional not-all) "Delete any junk files from last temp file. @@ -1126,6 +1056,123 @@ (add-hook 'kill-emacs-hook 'tex-delete-last-temp-files) +(defvar tex-start-tex-marker nil + "Marker pointing after last TeX-running command in the TeX shell buffer.") + +(defun tex-start-tex (command file) + "Start a TeX run, using COMMAND on FILE." + (let* ((cmd (concat command " \\\\nonstopmode\\\\input")) + (star (string-match "\\*" cmd)) + (compile-command + (if star (concat (substring cmd 0 star) + file (substring cmd (1+ star))) + (concat cmd " " file)))) + (with-current-buffer (process-buffer (tex-send-command compile-command)) + (save-excursion + (forward-line -1) + (setq tex-start-tex-marker (point-marker))) + (make-local-variable 'compilation-parse-errors-function) + (setq compilation-parse-errors-function 'tex-compilation-parse-errors)))) + +(defun tex-compilation-parse-errors (limit-search find-at-least) + "Parse the current buffer as error messages. +This makes a list of error descriptors, `compilation-error-list'. +For each source-file, line-number pair in the buffer, +the source file is read in, and the text location is saved in +`compilation-error-list'. The function `next-error', assigned to +\\[next-error], takes the next error off the list and visits its location. + +If LIMIT-SEARCH is non-nil, don't bother parsing past that location. +If FIND-AT-LEAST is non-nil, don't bother parsing after finding that + +This function works on TeX compilations only. It is necessary for +that purpose, since TeX does not put file names on the same line as +line numbers for the errors." + (require 'thingatpt) + (setq compilation-error-list nil) + (message "Parsing error messages...") + (let ((old-lc-syntax (char-syntax ?\{)) + (old-rc-syntax (char-syntax ?\})) + (old-lb-syntax (char-syntax ?\[)) + (old-rb-syntax (char-syntax ?\])) + (num-found 0) last-filename last-linenum last-position) + (unwind-protect + (progn + (modify-syntax-entry ?\{ "_") + (modify-syntax-entry ?\} "_") + (modify-syntax-entry ?\[ "_") + (modify-syntax-entry ?\] "_") + ;; Don't reparse messages already seen at last parse. + (goto-char (max (or compilation-parsing-end 0) + tex-start-tex-marker)) + ;; Don't parse the first two lines as error messages. + ;; This matters for grep. + (if (bobp) (forward-line 2)) + (while (re-search-forward + "^l\\.\\([0-9]+\\) \\(\\.\\.\\.\\)?\\(.*\\)$" + (and (or (null find-at-least) + (>= num-found find-at-least)) limit-search) t) + ;; Extract file name and line number from error message. + ;; Line number is 2 away from beginning of line: "l.23" + ;; The file is the one that was opened last and is still open. + ;; We need to find the last open parenthesis. + (let* ((linenum (string-to-int (match-string 1))) + (error-text (regexp-quote (match-string 3))) + (filename + (save-excursion + (backward-up-list 1) + (skip-syntax-forward "(_") + (while (not (file-readable-p + (thing-at-point 'filename))) + (skip-syntax-backward "(_") + (backward-up-list 1) + (skip-syntax-forward "(_")) + (thing-at-point 'filename))) + (error-marker + (save-excursion + (re-search-backward "^! " nil t) + (point-marker))) + (new-file (or (null last-filename) + (not (string-equal last-filename filename)))) + (error-location + (save-excursion + (if (equal filename + (expand-file-name (concat tex-zap-file ".tex"))) + (set-buffer tex-last-buffer-texed) + (set-buffer (find-file-noselect filename))) + (if new-file + (goto-line linenum) + (goto-char last-position) + (forward-line (- linenum last-linenum))) + ;first try a forward search + ;for the error text, then a + ;backward search limited by + ;the last error + (let ((starting-point (point))) + (or (re-search-forward error-text nil t) + (re-search-backward + error-text + (marker-position last-position) t) + (goto-char starting-point))) + (point-marker)))) + (setq last-filename filename) + (if (or new-file + (not (= last-position error-location))) + (progn + (setq num-found (1+ num-found)) + (setq last-position error-location) + (setq last-linenum linenum) + (setq compilation-error-list + (nconc compilation-error-list + (list (cons error-marker + error-location))))))))) + (modify-syntax-entry ?\{ (char-to-string old-lc-syntax)) + (modify-syntax-entry ?\} (char-to-string old-rc-syntax)) + (modify-syntax-entry ?\[ (char-to-string old-lb-syntax)) + (modify-syntax-entry ?\] (char-to-string old-rb-syntax)))) + (setq compilation-parsing-end (point)) + (message "Parsing error messages...done")) + ;;; The commands: (defun tex-region (beg end) @@ -1208,7 +1255,7 @@ ;; Record the file name to be deleted afterward. (setq tex-last-temp-file tex-out-file) (tex-send-command tex-shell-cd-command zap-directory) - (tex-send-command tex-command tex-out-file) + (tex-start-tex tex-command tex-out-file) (tex-display-shell) (setq tex-print-file tex-out-file) (setq tex-last-buffer-texed (current-buffer)))) @@ -1237,7 +1284,7 @@ (tex-kill-job) (tex-start-shell)) (tex-send-command tex-shell-cd-command file-dir) - (tex-send-command tex-command source-file) + (tex-start-tex tex-command source-file) (tex-display-shell) (setq tex-last-buffer-texed (current-buffer)) (setq tex-print-file source-file))) @@ -1311,6 +1358,9 @@ (setq print-file-name-dvi test-name)) (if (not (file-exists-p print-file-name-dvi)) (error "No appropriate `.dvi' file could be found") + (if (tex-shell-running) + (tex-kill-job) + (tex-start-shell)) (tex-send-command (if alt tex-alt-dvi-print-command tex-dvi-print-command) print-file-name-dvi t))))