Mercurial > emacs
comparison lisp/textmodes/tex-mode.el @ 21314:7d4a55d38b2c
(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.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 30 Mar 1998 04:21:52 +0000 |
parents | dd5c2baa6674 |
children | 9e91515ab6ed |
comparison
equal
deleted
inserted
replaced
21313:47c514f3eed4 | 21314:7d4a55d38b2c |
---|---|
951 (setq text (buffer-substring (match-beginning 1) (match-end 1)))) | 951 (setq text (buffer-substring (match-beginning 1) (match-end 1)))) |
952 (indent-to indentation) | 952 (indent-to indentation) |
953 (insert "\\end" text) | 953 (insert "\\end" text) |
954 (if new-line-needed (insert ?\n)))) | 954 (if new-line-needed (insert ?\n)))) |
955 | 955 |
956 (defun tex-compilation-parse-errors () | |
957 "Parse the current buffer as error messages. | |
958 This makes a list of error descriptors, compilation-error-list. | |
959 For each source-file, line-number pair in the buffer, | |
960 the source file is read in, and the text location is saved in | |
961 compilation-error-list. The function `next-error', assigned to | |
962 \\[next-error], takes the next error off the list and visits its location. | |
963 | |
964 This function works on TeX compilations only. It is necessary for | |
965 that purpose, since TeX does not put file names on the same line as | |
966 line numbers for the errors." | |
967 (setq compilation-error-list nil) | |
968 (message "Parsing error messages...") | |
969 (modify-syntax-entry ?\{ "_") | |
970 (modify-syntax-entry ?\} "_") | |
971 (modify-syntax-entry ?\[ "_") | |
972 (modify-syntax-entry ?\] "_") | |
973 (let (text-buffer | |
974 last-filename last-linenum) | |
975 ;; Don't reparse messages already seen at last parse. | |
976 (goto-char compilation-parsing-end) | |
977 ;; Don't parse the first two lines as error messages. | |
978 ;; This matters for grep. | |
979 (if (bobp) | |
980 (forward-line 2)) | |
981 (while (re-search-forward "^l\.[0-9]+ " nil t) | |
982 (let (linenum filename | |
983 error-marker text-marker) | |
984 ;; Extract file name and line number from error message. | |
985 ;; Line number is 2 away from beginning of line: "l.23" | |
986 (beginning-of-line) | |
987 (goto-char (+ (point) 2)) | |
988 (setq linenum (read (current-buffer))) | |
989 ;; The file is the one that was opened last and is still open. | |
990 ;; We need to find the last open parenthesis. | |
991 (insert ?\)) | |
992 (backward-sexp) | |
993 (forward-char) | |
994 (setq filename (current-word)) | |
995 ;; Locate the erring file and line. | |
996 (if (and (equal filename last-filename) | |
997 (= linenum last-linenum)) | |
998 nil | |
999 (skip-chars-backward "^(") | |
1000 (backward-char) | |
1001 (forward-sexp) | |
1002 (backward-delete-char 1) | |
1003 (setq error-marker (point-marker)) | |
1004 ;; text-buffer gets the buffer containing this error's file. | |
1005 (if (not (equal filename last-filename)) | |
1006 (setq text-buffer | |
1007 (and (file-exists-p (setq last-filename filename)) | |
1008 (find-file-noselect filename)) | |
1009 last-linenum 0)) | |
1010 (if text-buffer | |
1011 ;; Go to that buffer and find the erring line. | |
1012 (save-excursion | |
1013 (set-buffer text-buffer) | |
1014 (if (zerop last-linenum) | |
1015 (progn | |
1016 (goto-char 1) | |
1017 (setq last-linenum 1))) | |
1018 (forward-line (- linenum last-linenum)) | |
1019 (setq last-linenum linenum) | |
1020 (setq text-marker (point-marker)) | |
1021 (setq compilation-error-list | |
1022 (cons (list error-marker text-marker) | |
1023 compilation-error-list))))) | |
1024 (forward-line 1))) | |
1025 (setq compilation-parsing-end (point-max))) | |
1026 (message "Parsing error messages...done") | |
1027 (setq compilation-error-list (nreverse compilation-error-list))) | |
1028 | |
1029 ;;; Invoking TeX in an inferior shell. | 956 ;;; Invoking TeX in an inferior shell. |
1030 | 957 |
1031 ;;; Why use a shell instead of running TeX directly? Because if TeX | 958 ;;; Why use a shell instead of running TeX directly? Because if TeX |
1032 ;;; gets stuck, the user can switch to the shell window and type at it. | 959 ;;; gets stuck, the user can switch to the shell window and type at it. |
1033 | 960 |
1080 (defun tex-send-command (command &optional file background) | 1007 (defun tex-send-command (command &optional file background) |
1081 "Send COMMAND to TeX shell process, substituting optional FILE for *. | 1008 "Send COMMAND to TeX shell process, substituting optional FILE for *. |
1082 Do this in background if optional BACKGROUND is t. If COMMAND has no *, | 1009 Do this in background if optional BACKGROUND is t. If COMMAND has no *, |
1083 FILE will be appended, preceded by a blank, to COMMAND. If FILE is nil, no | 1010 FILE will be appended, preceded by a blank, to COMMAND. If FILE is nil, no |
1084 substitution will be made in COMMAND. COMMAND can be any expression that | 1011 substitution will be made in COMMAND. COMMAND can be any expression that |
1085 evaluates to a command string." | 1012 evaluates to a command string. |
1013 | |
1014 Return the process in which TeX is running." | |
1086 (save-excursion | 1015 (save-excursion |
1087 (let* ((cmd (eval command)) | 1016 (let* ((cmd (eval command)) |
1088 (proc (or (get-process "tex-shell") (error "No TeX subprocess"))) | 1017 (proc (or (get-process "tex-shell") (error "No TeX subprocess"))) |
1089 (buf (process-buffer proc)) | 1018 (buf (process-buffer proc)) |
1090 (star (string-match "\\*" cmd)) | 1019 (star (string-match "\\*" cmd)) |
1103 (if (= (buffer-modified-tick buf) tex-send-command-modified-tick) | 1032 (if (= (buffer-modified-tick buf) tex-send-command-modified-tick) |
1104 (accept-process-output proc)) | 1033 (accept-process-output proc)) |
1105 (goto-char (process-mark proc)) | 1034 (goto-char (process-mark proc)) |
1106 (insert string) | 1035 (insert string) |
1107 (comint-send-input) | 1036 (comint-send-input) |
1108 (setq tex-send-command-modified-tick (buffer-modified-tick buf))))) | 1037 (setq tex-send-command-modified-tick (buffer-modified-tick buf)) |
1038 proc))) | |
1109 | 1039 |
1110 (defun tex-delete-last-temp-files (&optional not-all) | 1040 (defun tex-delete-last-temp-files (&optional not-all) |
1111 "Delete any junk files from last temp file. | 1041 "Delete any junk files from last temp file. |
1112 If NOT-ALL is non-nil, save the `.dvi' file." | 1042 If NOT-ALL is non-nil, save the `.dvi' file." |
1113 (if tex-last-temp-file | 1043 (if tex-last-temp-file |
1124 (delete-file (concat dir (car list)))) | 1054 (delete-file (concat dir (car list)))) |
1125 (setq list (cdr list)))))) | 1055 (setq list (cdr list)))))) |
1126 | 1056 |
1127 (add-hook 'kill-emacs-hook 'tex-delete-last-temp-files) | 1057 (add-hook 'kill-emacs-hook 'tex-delete-last-temp-files) |
1128 | 1058 |
1059 (defvar tex-start-tex-marker nil | |
1060 "Marker pointing after last TeX-running command in the TeX shell buffer.") | |
1061 | |
1062 (defun tex-start-tex (command file) | |
1063 "Start a TeX run, using COMMAND on FILE." | |
1064 (let* ((cmd (concat command " \\\\nonstopmode\\\\input")) | |
1065 (star (string-match "\\*" cmd)) | |
1066 (compile-command | |
1067 (if star (concat (substring cmd 0 star) | |
1068 file (substring cmd (1+ star))) | |
1069 (concat cmd " " file)))) | |
1070 (with-current-buffer (process-buffer (tex-send-command compile-command)) | |
1071 (save-excursion | |
1072 (forward-line -1) | |
1073 (setq tex-start-tex-marker (point-marker))) | |
1074 (make-local-variable 'compilation-parse-errors-function) | |
1075 (setq compilation-parse-errors-function 'tex-compilation-parse-errors)))) | |
1076 | |
1077 (defun tex-compilation-parse-errors (limit-search find-at-least) | |
1078 "Parse the current buffer as error messages. | |
1079 This makes a list of error descriptors, `compilation-error-list'. | |
1080 For each source-file, line-number pair in the buffer, | |
1081 the source file is read in, and the text location is saved in | |
1082 `compilation-error-list'. The function `next-error', assigned to | |
1083 \\[next-error], takes the next error off the list and visits its location. | |
1084 | |
1085 If LIMIT-SEARCH is non-nil, don't bother parsing past that location. | |
1086 If FIND-AT-LEAST is non-nil, don't bother parsing after finding that | |
1087 | |
1088 This function works on TeX compilations only. It is necessary for | |
1089 that purpose, since TeX does not put file names on the same line as | |
1090 line numbers for the errors." | |
1091 (require 'thingatpt) | |
1092 (setq compilation-error-list nil) | |
1093 (message "Parsing error messages...") | |
1094 (let ((old-lc-syntax (char-syntax ?\{)) | |
1095 (old-rc-syntax (char-syntax ?\})) | |
1096 (old-lb-syntax (char-syntax ?\[)) | |
1097 (old-rb-syntax (char-syntax ?\])) | |
1098 (num-found 0) last-filename last-linenum last-position) | |
1099 (unwind-protect | |
1100 (progn | |
1101 (modify-syntax-entry ?\{ "_") | |
1102 (modify-syntax-entry ?\} "_") | |
1103 (modify-syntax-entry ?\[ "_") | |
1104 (modify-syntax-entry ?\] "_") | |
1105 ;; Don't reparse messages already seen at last parse. | |
1106 (goto-char (max (or compilation-parsing-end 0) | |
1107 tex-start-tex-marker)) | |
1108 ;; Don't parse the first two lines as error messages. | |
1109 ;; This matters for grep. | |
1110 (if (bobp) (forward-line 2)) | |
1111 (while (re-search-forward | |
1112 "^l\\.\\([0-9]+\\) \\(\\.\\.\\.\\)?\\(.*\\)$" | |
1113 (and (or (null find-at-least) | |
1114 (>= num-found find-at-least)) limit-search) t) | |
1115 ;; Extract file name and line number from error message. | |
1116 ;; Line number is 2 away from beginning of line: "l.23" | |
1117 ;; The file is the one that was opened last and is still open. | |
1118 ;; We need to find the last open parenthesis. | |
1119 (let* ((linenum (string-to-int (match-string 1))) | |
1120 (error-text (regexp-quote (match-string 3))) | |
1121 (filename | |
1122 (save-excursion | |
1123 (backward-up-list 1) | |
1124 (skip-syntax-forward "(_") | |
1125 (while (not (file-readable-p | |
1126 (thing-at-point 'filename))) | |
1127 (skip-syntax-backward "(_") | |
1128 (backward-up-list 1) | |
1129 (skip-syntax-forward "(_")) | |
1130 (thing-at-point 'filename))) | |
1131 (error-marker | |
1132 (save-excursion | |
1133 (re-search-backward "^! " nil t) | |
1134 (point-marker))) | |
1135 (new-file (or (null last-filename) | |
1136 (not (string-equal last-filename filename)))) | |
1137 (error-location | |
1138 (save-excursion | |
1139 (if (equal filename | |
1140 (expand-file-name (concat tex-zap-file ".tex"))) | |
1141 (set-buffer tex-last-buffer-texed) | |
1142 (set-buffer (find-file-noselect filename))) | |
1143 (if new-file | |
1144 (goto-line linenum) | |
1145 (goto-char last-position) | |
1146 (forward-line (- linenum last-linenum))) | |
1147 ;first try a forward search | |
1148 ;for the error text, then a | |
1149 ;backward search limited by | |
1150 ;the last error | |
1151 (let ((starting-point (point))) | |
1152 (or (re-search-forward error-text nil t) | |
1153 (re-search-backward | |
1154 error-text | |
1155 (marker-position last-position) t) | |
1156 (goto-char starting-point))) | |
1157 (point-marker)))) | |
1158 (setq last-filename filename) | |
1159 (if (or new-file | |
1160 (not (= last-position error-location))) | |
1161 (progn | |
1162 (setq num-found (1+ num-found)) | |
1163 (setq last-position error-location) | |
1164 (setq last-linenum linenum) | |
1165 (setq compilation-error-list | |
1166 (nconc compilation-error-list | |
1167 (list (cons error-marker | |
1168 error-location))))))))) | |
1169 (modify-syntax-entry ?\{ (char-to-string old-lc-syntax)) | |
1170 (modify-syntax-entry ?\} (char-to-string old-rc-syntax)) | |
1171 (modify-syntax-entry ?\[ (char-to-string old-lb-syntax)) | |
1172 (modify-syntax-entry ?\] (char-to-string old-rb-syntax)))) | |
1173 (setq compilation-parsing-end (point)) | |
1174 (message "Parsing error messages...done")) | |
1175 | |
1129 ;;; The commands: | 1176 ;;; The commands: |
1130 | 1177 |
1131 (defun tex-region (beg end) | 1178 (defun tex-region (beg end) |
1132 "Run TeX on the current region, via a temporary file. | 1179 "Run TeX on the current region, via a temporary file. |
1133 The file's name comes from the variable `tex-zap-file' and the | 1180 The file's name comes from the variable `tex-zap-file' and the |
1206 (write-region (concat "\n" tex-trailer) nil | 1253 (write-region (concat "\n" tex-trailer) nil |
1207 tex-out-file t nil)))) | 1254 tex-out-file t nil)))) |
1208 ;; Record the file name to be deleted afterward. | 1255 ;; Record the file name to be deleted afterward. |
1209 (setq tex-last-temp-file tex-out-file) | 1256 (setq tex-last-temp-file tex-out-file) |
1210 (tex-send-command tex-shell-cd-command zap-directory) | 1257 (tex-send-command tex-shell-cd-command zap-directory) |
1211 (tex-send-command tex-command tex-out-file) | 1258 (tex-start-tex tex-command tex-out-file) |
1212 (tex-display-shell) | 1259 (tex-display-shell) |
1213 (setq tex-print-file tex-out-file) | 1260 (setq tex-print-file tex-out-file) |
1214 (setq tex-last-buffer-texed (current-buffer)))) | 1261 (setq tex-last-buffer-texed (current-buffer)))) |
1215 | 1262 |
1216 (defun tex-buffer () | 1263 (defun tex-buffer () |
1235 (save-some-buffers)) | 1282 (save-some-buffers)) |
1236 (if (tex-shell-running) | 1283 (if (tex-shell-running) |
1237 (tex-kill-job) | 1284 (tex-kill-job) |
1238 (tex-start-shell)) | 1285 (tex-start-shell)) |
1239 (tex-send-command tex-shell-cd-command file-dir) | 1286 (tex-send-command tex-shell-cd-command file-dir) |
1240 (tex-send-command tex-command source-file) | 1287 (tex-start-tex tex-command source-file) |
1241 (tex-display-shell) | 1288 (tex-display-shell) |
1242 (setq tex-last-buffer-texed (current-buffer)) | 1289 (setq tex-last-buffer-texed (current-buffer)) |
1243 (setq tex-print-file source-file))) | 1290 (setq tex-print-file source-file))) |
1244 | 1291 |
1245 (defun tex-generate-zap-file-name () | 1292 (defun tex-generate-zap-file-name () |
1309 (setq test-name (tex-append (buffer-file-name) ".dvi")) | 1356 (setq test-name (tex-append (buffer-file-name) ".dvi")) |
1310 (buffer-file-name))) | 1357 (buffer-file-name))) |
1311 (setq print-file-name-dvi test-name)) | 1358 (setq print-file-name-dvi test-name)) |
1312 (if (not (file-exists-p print-file-name-dvi)) | 1359 (if (not (file-exists-p print-file-name-dvi)) |
1313 (error "No appropriate `.dvi' file could be found") | 1360 (error "No appropriate `.dvi' file could be found") |
1361 (if (tex-shell-running) | |
1362 (tex-kill-job) | |
1363 (tex-start-shell)) | |
1314 (tex-send-command | 1364 (tex-send-command |
1315 (if alt tex-alt-dvi-print-command tex-dvi-print-command) | 1365 (if alt tex-alt-dvi-print-command tex-dvi-print-command) |
1316 print-file-name-dvi t)))) | 1366 print-file-name-dvi t)))) |
1317 | 1367 |
1318 (defun tex-alt-print () | 1368 (defun tex-alt-print () |