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 ()